2010-03-09 9 views
13

Ham pcm'yi aac (libfaac desteği etkin) olarak kodlamak için libavcodec (3/3/10 en son git) kullanıyorum. Bunu her defasında codec_context-> frame_size örnekleriyle art arda avcodec_encode_audio çağırarak yapıyorum. İlk dört araması başarıyla geri döner, ancak beşinci çağrı asla geri dönmez. Gdb 'u kırmak için kullandığımda yığın bozuk. Bir .wav dosyası pcm verileri dışa cüretini kullanırsanızlibavcodec ile aac'ın seslenmesini kodlayın

, o zaman ben herhangi bir sorun olmadan aac dönüştürmek komut satırı ffmpeg kullanabilirsiniz, bu yüzden ben yanlış yapıyorum şey olduğuna eminim.

Sorunumu çoğaltan küçük bir sınama programı yazdım. Burada geçerli bir dosyanın içinde test verilerini okur: http://birdie.protoven.com/audio.pcm (~ imzalı 16 bitlik LE PCM 2 saniye) doğrudan Faac kullanırsanız

ben hepsini işler yapabilir, ama kod olacak bir Ben de video kodlama yaptığım gibi libavcodec'i kullanabiliyordum ve bir mp4'e yazabiliyordum.

ffmpeg versiyon bilgisi:

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 

bir şey ayarlayarak, ya da belki benim codec'i bağlamda yanlış ayar değilim var mı? Herhangi bir yardım büyük beğeni topluyor! Bu yüzden doğrudan Faac kullanarak daha yüksek bit hızlarında kodlamak gibi

#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

Tüm projeyi benimle paylaşabilir misiniz? Ben de video/ses kodlamak için libav üzerinde çalışıyorum. – suitianshi

cevap

4

sorun, bit hızı daha az 386000. emin değil ise gitmesini görünüyor:

İşte benim test kodudur. Ama 128000, amaçlarım için yeterince iyi, bu yüzden ileriye doğru hareket edebiliyorum.

0

Ayrıca aac biçiminde sıkıştırmaya çalışıyorum kodlamada başka sorunlarınız da var. Ffmpeg'in son gözden geçirmesinde bazı özellikler vardır (2.8.0). İlk olarak, örnek formatın desteklenip desteklenmediğini kontrol ettiniz mi? Benim versiyonumda desteklenen tek format AV_SAMPLE_FMT_FLTP.

/* */ int check_sample_fmt, belirli bir örnek biçimi kodlayıcı tarafından desteklendiğini kontrol (avcodec * çözücü, numaralama AVSampleFormat sample_fmt) { const numaralama AVSampleFormat * p = codec-> sample_fmts: Biçim kontrol örneğinde olduğu ; Desteklenen formatlar gözlemlerseniz

while (*p != AV_SAMPLE_FMT_NONE) { 
    if (*p == sample_fmt) 
     return 1; 
    p++; 
} 
return 0; 

}

, sadece AV_SAMPLE_FMT_FLTP AAC codec tarafından desteklenmektedir. Planare şamandıra formatında dönüştürmek için swresample (önerilen şekilde) kullanmalısınız, ya da el ile yapabilirsiniz. Codec'i açmak için avcodec_open2 seçeneklerini sıkı sperimental seçenekleri ile kullanmalısınız. ,

İlgili konular