Pregunta

Estoy usando libavcodec (GIT última a partir del 3/3/10) para codificar PCM prima para aac (Apoyo libfaac activado). Lo hago llamando avcodec_encode_audio repetidamente con codec_context-> frame_size muestras cada vez. Los cuatro primeros llamadas responder con éxito, pero la quinta llamada nunca regresa. Cuando uso GDB para romper, la pila está dañado.

Si utilizo audacia de exportar los datos PCM en un archivo .wav, entonces puedo usar De línea de comandos ffmpeg para convertir a AAC sin ningún problema, así que estoy seguro de que es algo que estoy haciendo mal.

He escrito un pequeño programa de prueba que duplica mi problema. Se lee el datos de prueba de un archivo, que está disponible aquí: http://birdie.protoven.com/audio.pcm (~ 2 segundos de signo de 16 bits LE PCM)

Puedo hacer que todo funcione si uso FAAC directamente, pero el código sería un poco más limpio si tan sólo pudiera utilizar libavcodec, como también yo estoy codificación de vídeo, y la escritura tanto a un mp4.

versión de ffmpeg información:

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

¿Hay algo que no estoy dando, o establecer de forma incorrecta en mi códec contexto, tal vez? Cualquier ayuda es muy apreciada!

Aquí está mi código de prueba:

#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);
}
¿Fue útil?

Solución

El problema parece desaparecer si la tasa de bits es menor que 386000. No estoy seguro de por qué esto es, como puedo codificar a velocidades de bits más altas que la obtenida con FAAC directamente. Pero 128000 es lo suficientemente bueno para mis propósitos, por lo que soy capaz de seguir adelante.

Otros consejos

Estoy intentando comprimir en formato AAC también tienen una algunos otros problemas en la codificación. Hay algunas características en la última revisión de ffmpeg (2.8.0). En primer lugar, ¿verificó si es compatible con el formato de muestra? En mi versión el único formato soportado es AV_SAMPLE_FMT_FLTP. comprobación de formato es en el ejemplo:

/ * comprobar que un formato de muestra dada es apoyado por el codificador * / int check_sample_fmt (avcodec * códec, enumeración AVSampleFormat sample_fmt) {     const AVSampleFormat enum * p = codec-> sample_fmts;

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

}

Si usted observa los formatos soportados, solamente AV_SAMPLE_FMT_FLTP es compatible con el codec AAC. Debe utilizar swresample (como se sugiere) para convertir en formato flotante planare, o puede hacerlo a mano. Debe utilizar avcodec_open2 con opciones estricta sperimental con el fin de abrir códec. respecto

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top