我想使用ffmpeg库进行音频转码。现在我没有文件了,但是我只能听噪音。
我的程序的步骤是:
1)打开输入文件并使用avcodec_decode_audio4以原始格式解码
2)编码并保存原始格式。
我不知道我在哪里错。这是我的代码。

/*
 * File:   newmain.c
 * Author: antonello
 *
 * Created on 23 gennaio 2013, 11.24
 */

#include <stdio.h>
#include <stdlib.h>


#include <libavutil/samplefmt.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#include <libavcodec/old_codec_ids.h>

static AVCodecContext *get_encoder(int sampleRate, int channels, int audioBitrate)
{
    AVCodecContext  *audioCodec;
    AVCodec *codec;



    //Set up audio encoder
    codec = avcodec_find_encoder(CODEC_ID_AAC);
    if (codec == NULL)
    {
        printf("avcodec_find_encoder: ERROR\n");
        return NULL;
    }
    audioCodec = avcodec_alloc_context();
    audioCodec->bit_rate = audioBitrate;
    audioCodec->sample_fmt = AV_SAMPLE_FMT_S16P;
    audioCodec->sample_rate = sampleRate;
    audioCodec->channels = channels;
    audioCodec->profile = FF_PROFILE_AAC_MAIN;
    audioCodec->channel_layout=AV_CH_LAYOUT_MONO;
    //audioCodec->time_base = (AVRational){1, sampleRate};
    audioCodec->time_base.num  = 1;
    audioCodec->time_base.den  = sampleRate;

    audioCodec->codec_type = AVMEDIA_TYPE_AUDIO;
    if (avcodec_open(audioCodec, codec) < 0)
    {
        printf("avcodec_open: ERROR\n");
        return NULL;
    }

    return audioCodec;
}


int main(int argc, char** argv) {
  AVFormatContext *aFormatCtx_decoder = NULL;
  AVFormatContext *aFormatCtx_encoder = NULL;
  int             i, audioStream;
  AVPacket        packet_decoder;
  AVPacket        packet_encoder;
  int             got_frame=0;
  int             complete_decode=0;
  int             len;
  AVFrame         *decoded_frame = NULL;
  AVCodecContext  *aCodec_decoderCtx = NULL;
  AVCodec         *aCodec_decoder = NULL;
  FILE            *outfile;
  //reding input file
  avcodec_register_all();

   //register all codecs
    av_register_all();

 //open file
    if(avformat_open_input(&aFormatCtx_decoder, "sample.aac", NULL, NULL)!=0){
        fprintf(stderr, "Could not open source file \n");
        return -1; // Couldn't open file
    }

  // Retrieve stream information
  if(avformat_find_stream_info(aFormatCtx_decoder, NULL)<0){
      fprintf(stderr, "Couldn't find stream information \n");
      return -1; // Couldn't find stream information
  }

  // Dump information about file onto standard error
  //av_dump_format(aFormatCtx_decode, 0, argv[1], 0);

  // Find the first audio stream
  audioStream=-1;

  for(i=0; i<aFormatCtx_decoder->nb_streams; i++) {
    if(aFormatCtx_decoder->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
       audioStream < 0) {
      audioStream=i;
    }
  }
  if(audioStream==-1){
      fprintf(stderr, "File haven't sudio stream \n");
      return -1;
  }

  //get audio codec contex
  aCodec_decoderCtx=aFormatCtx_decoder->streams[audioStream]->codec;
  //get audio codec
  aCodec_decoder = avcodec_find_decoder(aCodec_decoderCtx->codec_id);
  aCodec_decoder->sample_fmts=AV_SAMPLE_FMT_S16P;
  if(!aCodec_decoder) {
    fprintf(stderr, "Unsupported codec!\n");
    return -1;//Unsupported codec!
  }
  //open codec
  // Open codec
  if(avcodec_open2(aCodec_decoderCtx, aCodec_decoder, NULL)<0)
    return -1; // Could not open codec
  // allocate audio frame
  decoded_frame = avcodec_alloc_frame();
  if (!decoded_frame) {
    fprintf(stderr, "Could not allocate audio frame\n");
    return -1;//Could not allocate audio frame
    }
  aCodec_decoderCtx->bit_rate=12000;
  aFormatCtx_encoder=get_encoder(8000,1,12000);
  av_init_packet(&packet_encoder);

  printf("param %d %d %d",aCodec_decoderCtx->sample_fmt,aCodec_decoderCtx->channels,aCodec_decoderCtx->bit_rate);

  outfile = fopen("out.aac", "wb");
    if (!outfile) {
        printf(stderr, "Could not open outfile \n");
        return -1;//Could not open outfile
    }
  while(av_read_frame(aFormatCtx_decoder, &packet_decoder)>=0) {
     // decode frame
     len = avcodec_decode_audio4(aCodec_decoderCtx, decoded_frame, &got_frame, &packet_decoder);
        if (len < 0) {
            fprintf(stderr, "Error while decoding\n");
            return -1;
            }

        if (got_frame){
          avcodec_encode_audio2(aFormatCtx_encoder,&packet_encoder,decoded_frame,&complete_decode);
          if(complete_decode){
          //    printf("complete decode frame");
              fwrite(packet_encoder.data, 1, packet_encoder.size, outfile);
              av_free_packet(&packet_encoder);
          }
        }



    }
  fclose(outfile);
    return (EXIT_SUCCESS);
}

最佳答案

您不能设置sample_fmts变量的任意值:
aCodec_decoder->sample_fmts=AV_SAMPLE_FMT_S16P; // It's wrong
解码将始终使用编解码器设置的参数执行。
您必须创建SwrContext并执行到目标的格式转换(SwrContext转换样本格式,样本速率和 channel 布局)

07-28 12:58