DirectX 11およびWindows 7でハードウェアアクセラレーションビデオ/H.264デコードを使用するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/19846770

質問

私は一日中研究してきましたが、それほど遠くまではありません。 DirectX11を使用してWindows 7を使用しています。(最終出力はDX11テクスチャのビデオフレームになることです)非常に大きなH.264ビデオファイルをデコードしたいのですが、CPUは(LIBAVを使用)しません。それを切ります。

DXVA2を使用してLIBAVのhwaccel機能を調べましたが、D3D9インターフェイスでのみ作成できるIdirectxvideodeCoderを作成する必要がある場合は、ロードブロックにヒットします。 (DX11を使用していません)

DXVAドキュメントを調べたときはいつでも、DX11を参照しませんが、これはDX10または11で削除されましたか? (これの確認は見つかりません。また、DXVA2が冗長であると言う場所でも、おそらくDXVA-HDによってスーパーになっているということですか?)

それから、私はMedia Foundation SDKを検討しました。u003Cd3d11.h> 、しかし、これは何も生じません)。また、最小限のWindows 8を指定して使用します。

MFを使用すると、Windows 8 SDKが必要です。これには、すべてのDirectX LIBS/ヘッダーが含まれています。

それで、これによりWindows 7とのギャップが残ります...ハードウェアがアクセル化されたビデオデコードを取得することは可能ですか?もしそうなら、どのAPIを使用するはずですか?

編集:別のフォローアップとして、私のMediaFoundation(およびAVF、Android、Magic Leapなど)の実装は私のオープンソースプロジェクトにありますhttps://github.com/newchromantics/poph264edit2:しかし、それがwin7をサポートするかどうかはわかりません:)

役に立ちましたか?

解決

D3D11には、基本的にDXVA2であるビデオAPIがあり、上記のわずかに変更されたインターフェイスがあります。続行するには、H.264ビットストリームをよく理解する必要があります(本当に!)。つまり、SPS構造とPPS構造のフィールドとエンコードされたフレームのすべてのスライスを抽出するために、手元にH.264パーサーがあることを確認してください。

1)ID3D11DeviceからID3D11Videodeviceインスタンスを取得し、D3D11デバイスコンテキストからID3D11DeviceからID3D11VideoContextを取得します。 (Win8では機能します)

2)H.264のID3D11VideDeCoderインスタンスを作成します。ID3D11111VIDEODEVICE:: GETVIDEODECODERPROFILECOUNT、GETVIDEODECODERPROFILE、CHECKVIDEDECODERFORFAT ...出力として、最善の策はDXGI_FORMAT_NV12です。

3)個々のフレームのデコード参照 Media FoundationでのDirect3D 11ビデオデコードのサポート:

  • id3d11videocontext :: decoderbeginframe(decoder、outputView->デコードされたフレームテクスチャ)
  • 塗りつぶしバッファ:
    • d3d11_video_decoder_buffer_picture_parameters
    • d3d11_video_decoder_buffer_inverse_quantization_matrix
    • D3D11_VIDEO_DECODER_BUFFER_BITSTREAM
    • d3d11_video_decoder_buffer_slice_control

バッファーには、対応するDXVA2構造で満たされています(DXVA2.Hを参照)完全なDXVA2仕様はここにあります。それに応じてH.264 SPS/PPSフィールドをマッピングする必要があります。

見る:

それで:

  • id3d11videocontext :: filed fill buffersをコミットするためにバッファを送信します
  • id3d11videocontext :: decoderendframeの現在のフレームを完了します

3)d3d11_video_decoder_buffer_picture_parametersバッファーには、すべての参照フレーム/表面に関する情報も含まれています - 自分で管理する必要があります。

それは非常に複雑で、FFMPEGとメディアプレーヤーのクラシックをチェックし、どちらもDXVA2(DX11を介してではありませんが)サポートを持っています。

4)NV12からRGB(A)に変換され、一部のGPU(D3D11機能レベル)により、NV12をシェーダー入力として使用できます。 NV12を直接使用できない場合は、D3D11サポートを備えたすべてのGPUのNV12/YUV420-> RGB変換を備えたD3D11Videoprocessorインターフェイスを見てください。

変換は次のようなコードで実行できます。

// Setup ID3D11Video*
ID3D11VideoProcessor * d3dVideoProc = ...;
ID3D11VideoDevice    * d3dVideoDevice = ...;
ID3D11VideoProcessorEnumerator * d3dVideoProcEnum = ...;


ID3D11Texture2D * srcTextureNV12Fmt = ...;
ID3D11Texture2D * dstTextureRGBFmt = ...;

// Use Video Processor

// Create views for VideoProc In/Output
ID3D11VideoProcessorInputView * videoProcInputView;
ID3D11VideoProcessorOutputView * videoProcOutputView;

{

    D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputViewDesc = { 0 };
    inputViewDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
    inputViewDesc.Texture2D.ArraySlice = arraySliceIdx;
    inputViewDesc.Texture2D.MipSlice = 0;
    hr = d3dVideoDevice->CreateVideoProcessorInputView(srcTextureNV12Fmt, d3dVideoProcEnum, &inputViewDesc, &videoProcInputView);
}


{
    D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputViewDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D };
    outputViewDesc.Texture2D.MipSlice = 0;
    hr = d3dVideoDevice->CreateVideoProcessorOutputView(dstTextureRGBFmt, d3dVideoProcEnum, &outputViewDesc, &videoProcOutputView);
}


// Setup streams
D3D11_VIDEO_PROCESSOR_STREAM streams = { 0 };
streams.Enable = TRUE;
streams.pInputSurface = videoProcInputView.get();

RECT srcRect = { /* source rectangle in pixels*/ };
RECT dstRect = { /* destination rectangle in pixels*/ };

// Perform VideoProc Blit Operation (with color conversion)
hr = videoCtx_->VideoProcessorBlt(d3dVideoProc, videoProcOutputView.get(), 0, 1, &streams);

他のヒント

フォローアップとして、私は現在、Windows 7,8と10を使用してMediaFoundationを使用しています(または8+の場合はWindows SDK)

それははるかに少ない形式(またはむしろ解像度/プロファイルレベル)をサポートしていますが、現在、ハードウェアの加速を使用しているかどうかは正確にはわかりません...

しかし、このAPIは互換性があり、これは元のクエリでした

DirectX 11およびWindows 7でハードウェアアクセラレーションビデオ/H.264デコードを使用するにはどうすればよいですか?

できません。

id3d11videodeviceは、Windows 8でのみAvalaibleです id3d11videodevice.

ID3D11VideodeCoderは、Windows 8のみであることができます id3d11videodecoder.

Windows 7では、ハードウェア加速ビデオ/H.264にDirectX 9を使用できます。マイクロソフトに感謝します。良い新しい、Idirect3D9Exは機能します...ええ...他の良いニュース、GPUデコードパフォーマンスは、Windows 7のDirectX9を使用して非常に良いです。

Windows 7とDirectX 9のソースコードは次のとおりです。 MOFO7777, 、H264DXVA2DECODERプロジェクトの下。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top