コードを古いバージョンのffmpeg(53)から新しいバージョン(54/55)に更新しています。動作していたコードは非推奨または削除されたため、更新に問題があります。
以前は、次のサンプル形式を使用してステレオMP3ファイルを作成できました。
SAMPLE_FMT_S16
それは私のソースストリームと完全に一致しました。これは現在、
AV_SAMPLE_FMT_S16
これはモノラル録音には問題なく機能しますが、ステレオMP3ファイルを作成しようとすると、avcodec_open2で次のようにバグが発生します。
指定されたsample_fmtはサポートされていません。」
試行錯誤の結果、
AV_SAMPLE_FMT_S16P
... avcodec_open2で受け入れられますが、MP3ファイルを作成して作成すると、サウンドが非常に歪んでしまいます。通常よりも約2オクターブ低くなり、バックグラウンドで大きなハム音が発生します。録音例を次に示します。
http://hosting.ispyconnect.com/example.mp3
私はffmpegの人たちから、これは呼び出す前にバイトストリームを手動でデインターリーブする必要があるためだと言われました。
avcodec_fill_audio_frame
それ、どうやったら出来るの?swrescaleライブラリを使用しようとしましたが成功せず、L / Rデータをavcodec_fill_audio_frameに手動でフィードしようとしましたが、取得した結果はインターリーブなしの場合とまったく同じように聞こえます。
エンコード用のコードは次のとおりです。
void add_audio_sample( AudioWriterPrivateData^ data, BYTE* soundBuffer, int soundBufferSize)
{
libffmpeg::AVCodecContext* c = data->AudioStream->codec;
memcpy(data->AudioBuffer + data->AudioBufferSizeCurrent, soundBuffer, soundBufferSize);
data->AudioBufferSizeCurrent += soundBufferSize;
uint8_t* pSoundBuffer = (uint8_t *)data->AudioBuffer;
DWORD nCurrentSize = data->AudioBufferSizeCurrent;
libffmpeg::AVFrame *frame;
int got_packet;
int ret;
int size = libffmpeg::av_samples_get_buffer_size(NULL, c->channels,
data->AudioInputSampleSize,
c->sample_fmt, 1);
while( nCurrentSize >= size) {
frame=libffmpeg::avcodec_alloc_frame();
libffmpeg::avcodec_get_frame_defaults(frame);
frame->nb_samples = data->AudioInputSampleSize;
ret = libffmpeg::avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, pSoundBuffer, size, 1);
if (ret<0)
{
throw gcnew System::IO::IOException("error filling audio");
}
//audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
libffmpeg::AVPacket pkt = { 0 };
libffmpeg::av_init_packet(&pkt);
ret = libffmpeg::avcodec_encode_audio2(c, &pkt, frame, &got_packet);
if (ret<0)
throw gcnew System::IO::IOException("error encoding audio");
if (got_packet) {
pkt.stream_index = data->AudioStream->index;
if (pkt.pts != AV_NOPTS_VALUE)
pkt.pts = libffmpeg::av_rescale_q(pkt.pts, c->time_base, c->time_base);
if (pkt.duration > 0)
pkt.duration = av_rescale_q(pkt.duration, c->time_base, c->time_base);
pkt.flags |= AV_PKT_FLAG_KEY;
if (libffmpeg::av_interleaved_write_frame(data->FormatContext, &pkt) != 0)
throw gcnew System::IO::IOException("unable to write audio frame.");
}
nCurrentSize -= size;
pSoundBuffer += size;
}
memcpy(data->AudioBuffer, data->AudioBuffer + data->AudioBufferSizeCurrent - nCurrentSize, nCurrentSize);
data->AudioBufferSizeCurrent = nCurrentSize;
}
何かアイデアを聞きたいです-私はこれを3日間機能させようとしています:(