2010-03-09 13 views
13

Ich benutze libavcodec (letzter Git seit 3/3/10), um raw pcm zu aac (Libfaac-Unterstützung aktiviert) zu kodieren. Ich tue dies, indem ich avcodec_encode_audio wiederholt mit codec_context-> frame_size Proben jedes Mal anrufe. Die ersten vier -Aufrufe werden erfolgreich zurückgegeben, aber der fünfte Aufruf wird nie zurückgegeben. Wenn ich gdb verwende, um zu brechen, ist der Stapel beschädigt.Audio zu aac mit libavcodec codieren

Wenn ich Dreistigkeit verwenden, die PCM-Daten in eine WAV-Datei zu exportieren, dann kann ich Befehlszeilen ffmpeg verwenden, um aac ohne Probleme zu konvertieren, so bin ich sicher, dass es etwas, was ich falsch tue.

Ich habe ein kleines Testprogramm geschrieben, das mein Problem dupliziert. Es liest die Testdaten aus einer Datei, die hier zur Verfügung: http://birdie.protoven.com/audio.pcm (~ 2 Sekunden 16-Bit-LE pcm unterzeichnet)

Ich kann es alle Arbeit machen, wenn es FAAC direkt verwenden, aber der Code wäre ein etwas sauberer, wenn ich nur libavcodec benutzen könnte, da ich auch Video kodiere und beides auf einen mp4 schreibe.

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 

Gibt es etwas, was ich Einstellung nicht oder falsch in meinem Codec Kontext einstellen, vielleicht? Jede Hilfe wird sehr geschätzt!

Hier ist mein Testcode:

#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

Können Sie bitte das gesamte Projekt mit mir teilen? Ich arbeite an libav, um auch Video/Audio zu kodieren. – suitianshi

Antwort

4

Das Problem scheint weg zu gehen, wenn die Bitrate weniger als 386000. nicht sicher ist, warum dies so ist, wie ich bei Bitraten höher als die Verwendung von FAAC direkt kodieren kann. Aber 128000 ist gut genug für meine Zwecke, also kann ich weitermachen.

0

Ich versuche, in aac-Format zu komprimieren, auch einige andere Probleme bei der Codierung. Es gibt einige Funktionen in der letzten Revision von ffmpeg (2.8.0). Haben Sie zuerst überprüft, ob das Beispielformat unterstützt wird? In meiner Version ist das einzige unterstützte Format AV_SAMPLE_FMT_FLTP. Formatüberprüfung ist in Beispiel:

/* überprüfen, ob eine bestimmte Probe Format durch den Encoder */ int check_sample_fmt (AVCodec * Codec, Enum AVSampleFormat sample_fmt) unterstützt wird { const Enum AVSampleFormat * p = codec-> sample_fmts ;

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

}

Wenn Sie unterstützten Formate beobachten, nur AV_SAMPLE_FMT_FLTP wird von AAC-Codec unterstützt. Sie sollten swresample (wie vorgeschlagen) verwenden, um im Planare-Float-Format zu konvertieren, oder Sie können es von Hand tun. Sie sollten avcodec_open2 mit Optionen strict sperimental verwenden, um Codec zu öffnen. grüße

Verwandte Themen