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);