簡體   English   中英

使用libavcodec將音頻編碼到aac

[英]Encode audio to aac with libavcodec

我正在使用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,那么代碼會更清晰一些,因為我也編碼視頻,並將兩者寫入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 * 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 float格式,或者您可以手動執行。 你應該使用avcodec_open2和options strict sperimental來打開編解碼器。 問候

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM