Frage

Ich bin mit libavcodec (letzte git ab 3/3/10) roh pcm zu aac kodieren (Libfaac Unterstützung aktiviert). Ich tue dies durch den Aufruf avcodec_encode_audio wiederholt mit codec_context-> frame_size Proben jedes Mal. Die ersten vier Anrufe Rückkehr erfolgreich, aber der fünfte Aufruf gibt nie. Wenn ich gdb zu brechen, korrupte der Stapel ist.

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

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 der signierten 16-Bit- LE pcm)

Ich kann es alle Arbeiten machen, wenn ich FAAC direkt verwenden, aber der Code würde ein wenig sauberer sein, wenn ich nur libavcodec verwenden könnte, wie ich es auch Video-Codierung bin, und beide Schreiben auf eine 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

Gibt es etwas, das ich nicht einstellen, oder falsch in meinem Codec einstellen Kontext, 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);
}
War es hilfreich?

Lösung

Das Problem scheint weg zu gehen, wenn die Bitrate weniger als 386000. nicht sicher ist, warum dies so ist, wie ich direkt bei Bitraten höher als die Verwendung von FAAC kodieren kann. Aber 128000 ist gut genug für meine Zwecke, so dass ich bin in der Lage vorwärts zu bewegen.

Andere Tipps

Ich versuche, in aac-Format zu komprimieren zu einem paar anderen Problemen bei der Codierung hat. Es gibt einige Features in der letzten Überarbeitung von ffmpeg (2.8.0). Im ersten, haben überprüfen Sie, ob die Probe Format 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 vom Geber unterstützt wird * / 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;

}

Wenn Sie unterstützten Formate beobachten, nur AV_SAMPLE_FMT_FLTP wird von AAC-Codec unterstützt. Sie sollten swresample verwenden (wie vorgeschlagen) in planare Float-Format zu konvertieren, oder Sie können es von Hand machen. Sie sollten mit den Optionen strengen sperimental verwenden, um avcodec_open2 zu Codec zu öffnen. Grüße

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top