libavcodecのとAACオーディオエンコード
-
18-09-2019 - |
質問
私はAACに生のPCMをエンコードするためにlibavcodecの(3/3/10のとして、最新のgit)を使用しています (libfaacサポートが有効)。私はavcodec_encode_audioを呼び出すことによって、これを行います 繰り返しcodec_context-> frame_sizeサンプル毎時間。最初の4つの 呼び出しが正常に返しますが、第五の呼び出しは戻ることはありません。私は、GDBを使用する場合 破るために、スタックが破損しています。
私は、.wavファイルへのPCMデータをエクスポートするために大胆さを使用する場合は、、そして、私が使用することができます コマンドラインffmpegのは問題なくAACに変換するので、私はそれがだと確信しています 何かが私が間違ってやってます。
私は私の問題を複製し、小さなテストプログラムを書いています。これは、読み込み ここで利用可能であるファイルからテストデータ: 符号付き16ビットの http://birdie.protoven.com/audio.pcmする(〜2秒LEのPCM)
私は直接FAACを使用する場合、私はそれをすべての作業を行うことができますが、私はちょうどlibavcodecの使用ができれば、私はまた、ビデオをエンコードし、MP4に両方を書いているように、コードは、少しきれいになります。
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
私は設定、または私のコーデックで正しく設定していないよ何かがあります コンテキスト、多分?すべてのヘルプは大歓迎です!
ここに私のテストコードは、次のとおりです。
#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);
}
解決
問題は、ビットレート未満386000.ない私が直接FAACを使用してより高いビットレートでエンコードすることができるよう、なぜこれが、であることを確認している場合は離れて行くように思われます。しかし、128000は、私の目的のために十分であるので、私は前方に移動することができますよ。
他のヒント
私はあまりにもエンコーディングに他のいくつかの問題を抱えているAAC形式で圧縮しようとしています。 ffmpegの(2.8.0)の最後のリビジョンの一部の機能があります。サンプルフォーマットがサポートされている場合は最初に、あなたがチェックしましたか?私のバージョンでのみサポートされている形式はAV_SAMPLE_FMT_FLTPです。フォーマットチェックは一例であります:
/ * / *与えられたサンプルフォーマットがエンコーダによって支持されていることを確認 int型check_sample_fmt(AVCodec *コーデック、列挙型AVSampleFormat sample_fmt) { constの列挙AVSampleFormat * P = codec-> sample_fmts;
while (*p != AV_SAMPLE_FMT_NONE) {
if (*p == sample_fmt)
return 1;
p++;
}
return 0;
}
あなたがサポートされているフォーマットを遵守した場合は、、唯一AV_SAMPLE_FMT_FLTPはAACコーデックによってサポートされています。 (提案されるように)あなたはplanare float形式に変換するために、swresampleを使用する必要があります、またはあなたが手でそれを行うことができます。 あなたはコーデックを開くためにオプション厳しいsperimentalでavcodec_open2使用する必要があります。 よろしく