Encode audio to aac with libavcodec

夙愿已清 提交于 2019-11-27 13:08:28

问题


I'm using libavcodec (latest git as of 3/3/10) to encode raw pcm to aac (libfaac support enabled). I do this by calling avcodec_encode_audio repeatedly with codec_context->frame_size samples each time. The first four calls return successfully, but the fifth call never returns. When I use gdb to break, the stack is corrupt.

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.

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)

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.

ffmpeg version info:

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

回答1:


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. But 128000 is good enough for my purposes, so I'm able to move forward.




回答2:


I'm attempting to compress in aac format too an have some other problems in encoding. There are some features in last revision of 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. 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;

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. You should use swresample (as suggested) to convert in planare float format, or you can do it by hand. You should use avcodec_open2 with options strict sperimental in order to open codec. regards



来源:https://stackoverflow.com/questions/2410459/encode-audio-to-aac-with-libavcodec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!