2010-03-09 99 views
13

我使用libavcodec(最新git截至3月3日)編碼原始pcm到aac (啓用了libfaac支持)。我通過每次使用codec_context-> frame_size樣本重複調用avcodec_encode_audio 來做到這一點。前四個 調用成功返回,但第五個調用不再返回。當我使用gdb 中斷時,堆棧損壞。使用libavcodec編碼音頻到aac

如果我有膽識的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); 
} 
+0

可以請你與我分享整個項目嗎?我正在開發libav來編碼視頻/音頻。 – suitianshi 2015-02-26 03:33:54

回答

4

這個問題似乎消失,如果比特率小於386000.不知道這是爲什麼,因爲我可以在比特率比直接使用FAAC更高編碼。但是128000對我來說足夠了,所以我能夠繼續前進。

0

我試圖以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 float格式進行轉換,或者您可以手動完成。 你應該使用avcodec_open2選項嚴格sperimental爲了打開編解碼器。 關於