Domanda

sto usando libavcodec (ultima git come del 3/3/10) per codificare PCM prima al aac (Supporto libfaac abilitato). Faccio questo chiamando avcodec_encode_audio ripetutamente con codec_context-> campioni frame_size ogni volta. I primi quattro chiamate restituiscono correttamente, ma il quinto invito non ritorna mai. Quando uso gdb per rompere, lo stack è danneggiato.

Se uso audacia di esportare i dati PCM in un file .wav, quindi posso usare Della riga di comando ffmpeg per convertire in AAC senza problemi, quindi sono sicuro che è qualcosa che sto facendo male.

Ho scritto un piccolo programma di test che duplica il mio problema. E 'legge il dati di test da un file, che è disponibile qui: http://birdie.protoven.com/audio.pcm (~ 2 secondi di segno a 16 bit LE pcm)

Posso far funzionare il tutto se uso direttamente FAAC, ma il codice sarebbe un po 'più pulito se solo potessi usare libavcodec, come sto anche la codifica video, e la scrittura sia per un mp4.

informazioni sulla versione di 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

C'è qualcosa che io non sono l'impostazione, o impostare in modo non corretto nel mio codec contesto, forse? Ogni aiuto è molto apprezzato!

Ecco il mio codice di prova:

#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);
}
È stato utile?

Soluzione

Il problema sembra andare via se il bitrate è inferiore a 386000. Non capisco perché questo è, come posso codificare a bitrate superiore a quella con FAAC direttamente. Ma 128000 è abbastanza buono per i miei scopi, quindi sono in grado di andare avanti.

Altri suggerimenti

Sto tentando di comprimere in formato AAC anche un presentano alcuni altri problemi di codifica. Ci sono alcune caratteristiche in ultima revisione di ffmpeg (2.8.0). In un primo momento, avete controllato se il formato del campione è supportato? Nella mia versione l'unico formato supportato è AV_SAMPLE_FMT_FLTP. controllo Format è nell'esempio:

/ * verificare che un determinato formato di campionamento è supportato dal codificatore * / 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;

}

Se si osservano i formati supportati, solo AV_SAMPLE_FMT_FLTP è supportato da codec AAC. Si dovrebbe usare swresample (come suggerito) per convertire in formato float planare, oppure è possibile farlo a mano. Si dovrebbe usare avcodec_open2 con opzioni rigorosa sperimentale al fine di aprire codec. saluti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top