音频编码使用libavcodec为AAC
-
18-09-2019 - |
题
我用libavccodec(最新的git为10年3月3日)来编码原始的PCM到AAC (libfaac支持启用)。我通过调用avcodec_encode_audio做到这一点 反复用每次codec_context-> frame_size样品。前四 调用返回成功,但第五调用永远不会返回。当我使用GDB 打破,堆栈被破坏。
如果我使用大胆到PCM数据导出到.wav文件,然后我可以使用 命令行的ffmpeg转换为AAC没有任何问题,所以我敢肯定,这 什么我做错了。
我已经写了复制我的问题,一个小的测试程序。它读取 从一个文件,它是可以在这里的测试数据: http://birdie.protoven.com/audio.pcm (〜符号16位为2秒LE PCM)
我可以把它所有的工作,如果我直接用FAAC,但代码将是干净了一点,如果我可以只使用libavcodec的,因为我也对视频进行编码,并编写既一个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 <stdio.h>
#include <libavcodec/avcodec.h>
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) < 0) return;
bufSize = FF_MIN_BUFFER_SIZE * 10;
buf = (uint8_t *)malloc(bufSize);
if (buf == NULL) return;
frameBytes = audioCodec->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)最后修订某些功能。在第一,你有没有检查是否支持样本格式?在我的版本是唯一支持的格式是AV_SAMPLE_FMT_FLTP。格式检查是例如:
/ *检查在给定样品格式由编码器支持* / INT check_sample_fmt(avcodec中*编解码器,枚举AVSampleFormat sample_fmt) { 常量枚举AVSampleFormat * P = codec-> sample_fmts;
while (*p != AV_SAMPLE_FMT_NONE) {
if (*p == sample_fmt)
return 1;
p++;
}
return 0;
}
如果你观察所支持的格式,只是AV_SAMPLE_FMT_FLTP由AAC编解码器的支持。您应该使用swresample(的建议)在planare浮点格式转换,或者你可以自己动手完成它。 你应该以开放的编解码器的选项严格sperimental avcodec_open2使用。 问候