2

コードを古いバージョンの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日間機能させようとしています:(

4

2 に答える 2

0

私はこの質問が古いことを知っていますが、後世のために: 私はいくつかのオーディオ リサンプリング コードに取り組んでおり、著者がリンクした mp3 と非常によく似たオーディオに到達した後、オーディオ サンプリング レートの不一致が原因であると特定しました。リサンプラーが期待する入力と実際のデータの間。

于 2016-06-17T10:10:05.133 に答える