Pergunta

Eu estou usando libavcodec (mais recente git a partir de 3/3/10) para codificar pcm cru para aac (Suporte libfaac habilitado). I fazer isso chamando avcodec_encode_audio repetidamente com codec_context-> frame_size amostras de cada vez. Os quatro primeiros ligações retornar com sucesso, mas a quinta chamada nunca retorna. Quando eu uso gdb Para quebrar, a pilha está corrompido.

Se eu usar o Audacity para exportar os dados de PCM para um arquivo .wav, então eu posso usar De linha de comando ffmpeg para converter para AAC, sem quaisquer problemas, então eu tenho certeza que é algo que eu estou fazendo errado.

Eu escrevi um pequeno programa de testes que duplica o meu problema. Ele lê o dados de teste de um arquivo, que está disponível aqui: http://birdie.protoven.com/audio.pcm (~ 2 segundos de sinal de 16 bit LE pcm)

Eu posso fazer tudo funcionar se eu usar FAAC diretamente, mas o código seria um pouco mais limpo se eu poderia usar apenas libavcodec, como eu também estou codificação de vídeo, e escrever tanto para um mp4.

ffmpeg informação de versão:

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

Existe algo que eu não sou a criação, ou a criação incorretamente no meu codec contexto, talvez? Qualquer ajuda é muito apreciada!

Aqui está o meu código de teste:

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

Solução

O problema parece ir longe, se a taxa de bits é inferior a 386000. Não sei por que isso é, como eu pode codificar a taxas de bits maior do que usando FAAC diretamente. Mas 128000 é bom o suficiente para os meus propósitos, assim que eu sou capaz de seguir em frente.

Outras dicas

Eu estou tentando compressa em formato aac também um tem alguns outros problemas na codificação. Existem algumas características em última revisão do ffmpeg (2.8.0). Em primeiro lugar, o senhor checou se o formato de amostra é suportado? Na minha versão do formato suportado apenas é AV_SAMPLE_FMT_FLTP. verificação formato é no exemplo:

/ * Verificação de que um determinado formato de amostra é suportado pelo codificador * / check_sample_fmt int (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 você observar os formatos suportados apenas AV_SAMPLE_FMT_FLTP é suportado pelo codec AAC. Você deve usar swresample (como sugerido) para converter em formato flutuador planare, ou você pode fazê-lo com a mão. Você deve usar avcodec_open2 com opções sperimental estrita, a fim de codec aberto. relação

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top