使用libavcodec将音频编码到aac

我正在使用libavcodec(截至3/3/10的最新git)将原始pcm编码为aac(启用了libfaac支持)。 我这样做是通过每次使用codec_context-> frame_size样本重复调用avcodec_encode_audio来实现的。 前四个调用成功返回,但第五个调用永远不会返回。 当我使用gdb中断时,堆栈已损坏。

如果我使用audacity将pcm数据导出到.wav文件,那么我可以使用命令行ffmpeg转换为aac而没有任何问题,所以我确定这是我做错了。

我写了一个小的测试程序来复制我的问题。 它从文件中读取测试数据,可在此处获取: http : //birdie.protoven.com/audio.pcm (签名16位LE pcm约2秒)

如果我直接使用FAAC,我可以完成所有工作,但如果我可以使用libavcodec,那么代码会更清晰,因为我也编码video,并将两者都写入mp4。

ffmpeg版本信息:

FFmpeg version git-c280040, Copyright (c) 2000-2010 the FFmpeg developers built on Mar 3 2010 15:40:46 with gcc 4.4.1 configuration: --enable-libfaac --enable-gpl --enable-nonfree --enable-version3 --enable-postproc --enable-pthreads --enable-debug=3 --enable-shared libavutil 50.10. 0 / 50.10. 0 libavcodec 52.55. 0 / 52.55. 0 libavformat 52.54. 0 / 52.54. 0 libavdevice 52. 2. 0 / 52. 2. 0 libswscale 0.10. 0 / 0.10. 0 libpostproc 51. 2. 0 / 51. 2. 0 

有没有我没有设置的东西,或者在我的编解码器环境中设置不正确,也许? 任何帮助是极大的赞赏!

这是我的测试代码:

 #include  #include  void EncodeTest(int sampleRate, int channels, int audioBitrate, uint8_t *audioData, size_t audioSize) { AVCodecContext *audioCodec; AVCodec *codec; uint8_t *buf; int bufSize, frameBytes; avcodec_register_all(); //Set up audio encoder codec = avcodec_find_encoder(CODEC_ID_AAC); if (codec == NULL) return; audioCodec = avcodec_alloc_context(); audioCodec->bit_rate = audioBitrate; audioCodec->sample_fmt = SAMPLE_FMT_S16; audioCodec->sample_rate = sampleRate; audioCodec->channels = channels; audioCodec->profile = FF_PROFILE_AAC_MAIN; audioCodec->time_base = (AVRational){1, sampleRate}; audioCodec->codec_type = CODEC_TYPE_AUDIO; if (avcodec_open(audioCodec, codec) frame_size * audioCodec->channels * 2; while (audioSize >= frameBytes) { int packetSize; packetSize = avcodec_encode_audio(audioCodec, buf, bufSize, (short *)audioData); printf("encoder returned %d bytes of data\n", packetSize); audioData += frameBytes; audioSize -= frameBytes; } } int main() { FILE *stream = fopen("audio.pcm", "rb"); size_t size; uint8_t *buf; if (stream == NULL) { printf("Unable to open file\n"); return 1; } fseek(stream, 0, SEEK_END); size = ftell(stream); fseek(stream, 0, SEEK_SET); buf = (uint8_t *)malloc(size); fread(buf, sizeof(uint8_t), size, stream); fclose(stream); EncodeTest(32000, 2, 448000, buf, size); } 

如果比特率小于386000,问题似乎就消失了。不知道为什么会这样,因为我可以比比直接使用FAAC更高的比特率进行编码。 但128000足以满足我的目的,所以我能够继续前进。

我试图压缩aac格式,在编码时也有一些其他问题。 ffmpeg(2.8.0)的最新修订版中有一些function。 首先,您是否检查了样本格式是否受支持? 在我的版本中,唯一支持的格式是AV_SAMPLE_FMT_FLTP。 格式检查在示例中:

/ *检查编码器是否支持给定的样本格式* / int check_sample_fmt(AVCodec * codec,enum AVSampleFormat sample_fmt){const enum AVSampleFormat * p = codec-> sample_fmts;

 while (*p != AV_SAMPLE_FMT_NONE) { if (*p == sample_fmt) return 1; p++; } return 0; 

}

如果您观察到支持的格式,则AAC编解码器仅支持AV_SAMPLE_FMT_FLTP。 您应该使用swresample(按照建议)转换为planare浮动格式,或者您可以手动执行。 你应该使用avcodec_open2和options strict sperimental来打开编解码器。 问候

    Interesting Posts