Question

J'utilise libavcodec (dernière git au 3/3/10) pour encoder pcm brut à aac (Support libfaac activé). Je le fais en appelant avcodec_encode_audio à plusieurs reprises avec codec_context-> échantillons de frame_size à chaque fois. Les quatre premiers appels retour avec succès, mais le cinquième appel revient jamais. Quand j'utilise gdb à briser, la pile est corrompu.

Si je audace d'exporter les données pcm dans un fichier .wav, alors je peux utiliser ffmpeg ligne de commande pour convertir en aac sans aucun problème, donc je suis sûr qu'il est quelque chose que je fais mal.

J'ai écrit un petit programme de test qui fait double emploi avec mon problème. Il lit le les données de test à partir d'un fichier, qui est disponible ici: http://birdie.protoven.com/audio.pcm (~ 2 secondes signé 16 bits LE pcm)

Je peux le faire tout le travail si j'utilise FAAC directement, mais le code serait un peu plus propre si je pouvais simplement utiliser libavcodec, comme je suis aussi l'encodage vidéo, et de l'écriture à la fois à un mp4.

Version ffmpeg 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

Y at-il quelque chose que je ne suis pas un paramètre ou réglage de manière incorrecte dans mon codec contexte, peut-être? Toute aide est grandement appréciée!

Voici mon code de test:

#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);
}
Était-ce utile?

La solution

Le problème semble aller si le débit est inférieur à 386000. Je ne sais pas pourquoi il en est, comme je peux coder à des débits binaires plus élevés que l'utilisation FAAC directement. Mais 128000 est assez bon pour mes fins, je suis en mesure d'avancer.

Autres conseils

Je tente de compresser au format aac aussi un avoir d'autres problèmes dans le codage. Il y a quelques fonctionnalités de la dernière révision de ffmpeg (2.8.0). En premier lieu, avez-vous vérifié si le format de l'échantillon est pris en charge? Dans ma version le seul format pris en charge est AV_SAMPLE_FMT_FLTP. vérification de format est dans l'exemple:

/ * vérifier qu'un format échantillon donné est pris en charge par le codeur * / 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;

}

Si vous observez les formats pris en charge, ne AV_SAMPLE_FMT_FLTP est pris en charge par le codec AAC. Vous devez utiliser swresample (comme l'a suggéré) pour convertir au format float planare, ou vous pouvez le faire à la main. Vous devez utiliser avcodec_open2 avec des options sperimental strictes afin d'ouvrir le codec. ce qui a trait

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top