Encoder l'audio vers aac avec libavcodec
Je suis en utilisant libavcodec (dernière git que de 3/3/10) pour encoder les raw pcm aac
(libfaac support activé). - Je le faire en appelant avcodec_encode_audio
à plusieurs reprises avec codec_context->frame_size échantillons à chaque fois. Les quatre premiers
les appels de retour avec succès, mais le cinquième appel à ne jamais revenir. Lorsque j'utilise gdb
à la pause, la pile est endommagée.
Si j'utilise audacity pour exporter les données pcm à un .fichier wav, alors je peux utiliser
en ligne de commande ffmpeg pour convertir en aac sans aucun problème, donc je suis sûr que c'est
quelque chose que je fais mal.
J'ai écrit un petit programme de test qui duplique mon problème. Il lit le
des données de test à partir d'un fichier, qui est disponible ici:
http://birdie.protoven.com/audio.pcm (~2 secondes, signé de 16 bits, LE pcm)
Je peux le faire tout le travail si j'utilise FAAC directement, mais le code sera un peu plus propre si je pouvais libavcodec, comme je le suis également de l'encodage de la vidéo et de l'écriture à la fois à une mp4.
version de 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
Est-il quelque chose que je ne suis pas un paramètre ou un réglage incorrect 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);
}
source d'informationauteur ryan
Vous devez vous connecter pour publier un commentaire.
Le problème semble disparaître si le débit est inférieur à 386000. Je ne sais pas pourquoi c'est, comme je peux encoder à des débits plus élevés que l'aide FAAC directement. Mais 128000 est assez bon pour mes fins, je suis donc en mesure d'aller de l'avant.
Je suis d'essayer de les compresser au format aac et aussi un avoir d'autres problèmes de codage. Il y a certaines caractéristiques de la dernière révision de ffmpeg (2.8.0). Dans la première, avez-vous vérifier si le format de l'échantillon est pris en charge ? Dans ma version le seul format supporté est AV_SAMPLE_FMT_FLTP. Format de vérification dans l'exemple:
/* vérifiez que l'échantillon donné, le format est pris en charge par le codeur */
int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
{
const enum AVSampleFormat *p = codec->sample_fmts;
}
Si vous observez des formats pris en charge, seuls les AV_SAMPLE_FMT_FLTP est pris en charge par le codec AAC. Vous devez utiliser swresample (comme l'a suggéré) pour convertir en planare format flottant, ou vous pouvez le faire à la main.
Vous devez utiliser avcodec_open2 avec des options stricte sperimental afin d'ouvrir codec.
ce qui concerne