4

次のようなワークフローがあります。

  1. 生の YUV フレームを取得します。
  2. Windows Media Foundation に渡して、H.264 フレームにエンコードします。
  3. 出力を FFmpeg AVPacket に変換します。
  4. av_interleaved_write_frame を含むパケットを、他のものと混合された出力ファイルに挿入します。

Windows 7では、これはうまく機能しました。Windows 8 では、av_interleaved_write_frame が壊れていました。この理由は、Windows 8 が出力に B フレームを導入したためです。これは、pts/dts をどのように設定しても、av_interleaved_write_frame が気に入らなかったためです。

0 B フレームを使用するようにエンコーダーを変更したところ、必要な出力が得られました。しかし...

エンコードされたフレームの約 10 ~ 15 秒後、ビデオはほぼ完全なものから非常にブロック状で非常に低いフレーム レートに劣化します。Windows 8 で利用可能なほとんどの設定を変更してエンコーダーを変更しようとしましたが、何も役に立たないようです。

影響を与えた唯一のことは、エンコーダーのビットレートを変更することでした. エンコーダーのビットレートを上げれば上げるほど、ビデオが劣化し始めるまでの時間が長くなります。

Windows 7 と Windows 8 の間で何が変更され、これが発生した可能性があるかについてのアイデアはありますか?

エンコーダーのセットアップから成功チェックを差し引いたもの (すべて成功)

IMFMediaType * mInputType = NULL;

MFCreateMediaType(&mOutputType);

mOutputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
mOutputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
mOutputType->SetUINT32(MF_MT_AVG_BITRATE, 10000000);

MFSetAttributeSize(mOutputType, MF_MT_FRAME_SIZE, frameWidth, frameHeight);
MFSetAttributeSize(mOutputType, MF_MT_FRAME_RATE, 30, 1);
MFSetAttributeSize(mOutputType, MF_MT_FRAME_RATE_RANGE_MAX, 30, 1);
MFSetAttributeSize(mOutputType, MF_MT_FRAME_RATE_RANGE_MIN, 15, 1);

mOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
mOutputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
mOutputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, 1);
mOutputType->SetUINT32(MF_MT_SAMPLE_SIZE, frameWidth * frameHeight * 2);
mOutputType->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Main);
mOutputType->SetUINT32(CODECAPI_AVEncCommonRateControlMode, eAVEncCommonRateControlMode_Quality);
mOutputType->SetUINT32(CODECAPI_AVEncCommonQuality, 80);

フレームのエンコードは基本的に次のとおりです。

  1. 受信 YUV データを格納するための MFCreateMemoryBuffer。
  2. MFCreateSample.
  3. バッファーをサンプルにアタッチします。
  4. サンプル時間と期間を設定します。
  5. プロセス入力
  6. 適切な出力サイズの ProcessOutput
  7. 成功したら、サンプルの情報を使用して AVPacket をビルドします
4

0 に答える 0