简体   繁体   English

使用libavcodec将音频编码到aac

[英]Encode audio to aac with libavcodec

I'm using libavcodec (latest git as of 3/3/10) to encode raw pcm to aac (libfaac support enabled). 我正在使用libavcodec(截至3/3/10的最新git)将原始pcm编码为aac(启用了libfaac支持)。 I do this by calling avcodec_encode_audio repeatedly with codec_context->frame_size samples each time. 我通过每次使用codec_context-> frame_size样本重复调用avcodec_encode_audio来完成此操作。 The first four calls return successfully, but the fifth call never returns. 前四个调用成功返回,但第五个调用永远不会返回。 When I use gdb to break, the stack is corrupt. 当我使用gdb中断时,堆栈已损坏。

If I use audacity to export the pcm data to a .wav file, then I can use command-line ffmpeg to convert to aac without any issues, so I'm sure it's something I'm doing wrong. 如果我使用audacity将pcm数据导出到.wav文件,那么我可以使用命令行ffmpeg转换为aac而没有任何问题,所以我确定这是我做错了。

I've written a small test program that duplicates my problem. 我写了一个小的测试程序来复制我的问题。 It reads the test data from a file, which is available here: http://birdie.protoven.com/audio.pcm (~2 seconds of signed 16 bit LE pcm) 它从文件中读取测试数据,可在此处获取: http//birdie.protoven.com/audio.pcm (签名16位LE pcm约2秒)

I can make it all work if I use FAAC directly, but the code would be a little cleaner if I could just use libavcodec, as I'm also encoding video, and writing both to an mp4. 如果我直接使用FAAC,我可以完成所有工作,但如果我可以使用libavcodec,那么代码会更清晰一些,因为我也编码视频,并将两者写入mp4。

ffmpeg version info: 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

Is there something I'm not setting, or setting incorrectly in my codec context, maybe? 有没有我没有设置的东西,或者在我的编解码器环境中设置不正确,也许? Any help is greatly appreciated! 任何帮助是极大的赞赏!

Here is my test code: 这是我的测试代码:

#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);
}

The problem seems to go away if the bitrate is less than 386000. Not sure why this is, as I can encode at bitrates higher than that using FAAC directly. 如果比特率小于386000,问题似乎就消失了。不知道为什么会这样,因为我可以比比直接使用FAAC更高的比特率进行编码。 But 128000 is good enough for my purposes, so I'm able to move forward. 但128000足以满足我的目的,所以我能够继续前进。

I'm attempting to compress in aac format too an have some other problems in encoding. 我试图压缩aac格式,在编码时也有一些其他问题。 There are some features in last revision of ffmpeg (2.8.0). ffmpeg(2.8.0)的最新修订版中有一些功能。 In first, did you check if the sample format is supported ? 首先,您是否检查了样本格式是否受支持? In my version the only supported format is AV_SAMPLE_FMT_FLTP. 在我的版本中,唯一支持的格式是AV_SAMPLE_FMT_FLTP。 Format checking is in example: 格式检查在示例中:

/* check that a given sample format is supported by the encoder */ int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) { const enum AVSampleFormat *p = codec->sample_fmts; / *检查编码器是否支持给定的样本格式* / 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;

} }

If you observe supported formats, only AV_SAMPLE_FMT_FLTP is supported by AAC codec. 如果您观察到支持的格式,则AAC编解码器仅支持AV_SAMPLE_FMT_FLTP。 You should use swresample (as suggested) to convert in planare float format, or you can do it by hand. 您应该使用swresample(按照建议)转换为planare float格式,或者您可以手动执行。 You should use avcodec_open2 with options strict sperimental in order to open codec. 你应该使用avcodec_open2和options strict sperimental来打开编解码器。 regards 问候

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM