2017-08-04 27 views
1

私はDirectXを初めて使用しています。ビデオを読み込んでクワッドに表示する簡単なアプリケーションを作成しようとしています。IMFSample *をID3D11ShaderResourceViewに変換する*

Windows Media Foundation(IMFSourceReader)を使用してビデオを読み、サンプルがデコードされたときにコールバックを送信します(IMFSample)。

このIMFSample *をID3D11ShaderResourceView *に変換して、それをテクスチャとして使用して四角形を描画したい場合は、変換に失敗します。ここで

私は(私は無関連のエラーチェックを削除)何をすべきかです:

HRESULT SourceReaderCB::OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex, DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample) 
{ 
    ... 
    DWORD NumBuffers = 0; 
    hr = pSample->GetBufferCount(&NumBuffers); 

    if (FAILED(hr) || NumBuffers < 1) 
    { 
     ... 
    } 

    IMFMediaBuffer* SourceMediaPtr = nullptr; 
    hr = pSample->GetBufferByIndex(0, &SourceMediaPtr); 

    if (FAILED(hr)) 
    { 
     ... 
    } 

    ComPtr<IMFMediaBuffer> _pInputBuffer = SourceMediaPtr; 
    ComPtr<IMF2DBuffer2> _pInputBuffer2D2; 

    bool isVideoFrame = (_pInputBuffer.As(&_pInputBuffer2D2) == S_OK); 
    if (isVideoFrame) 
    { 
     IMFDXGIBuffer* pDXGIBuffer = NULL; 
     ID3D11Texture2D* pSurface = NULL; 

     hr = _pInputBuffer->QueryInterface(__uuidof(IMFDXGIBuffer), (LPVOID*)&pDXGIBuffer); 
     if (FAILED(hr)) 
     { 
      SafeRelease(&SourceMediaPtr); 
      goto done; 
     } 

     hr = pDXGIBuffer->GetResource(__uuidof(ID3D11Texture2D), (LPVOID*)&pSurface); 
     if (FAILED(hr)) 
     { 
      ... 
     } 

     ID3D11ShaderResourceView* resourceView; 

     if (pSurface) 
     { 
      D3D11_TEXTURE2D_DESC textureDesc; 
      pSurface->GetDesc(&textureDesc); 

      D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc; 
      shaderResourceViewDesc.Format = DXGI_FORMAT_R8_UNORM; 
      shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 
      shaderResourceViewDesc.Texture2D.MostDetailedMip = 0; 
      shaderResourceViewDesc.Texture2D.MipLevels = 1; 

      ID3D11ShaderResourceView* resourceView; 
      hr = d3d11device->CreateShaderResourceView(pSurface, &shaderResourceViewDesc, &resourceView); 
      if (FAILED(hr)) 
      { 
       ... // CODE FAILS HERE 
      } 
      ... 
     } 
    } 
} 

私の最初の問題は、(私が持っているだろう、私はおそらく私だけ赤いイメージを与えるであろうDXGI_FORMAT_R8_UNORMとしてshaderResourceViewDesc.Formatを設定することですこれを後で調べる)。

ID3D11ShaderResourceViewへID3D11Texture2Dの変換は、次のエラーメッセージで失敗し、私はIUSに直面しています秒と、ブロッキングの問題:

ID3D11Device::CreateShaderResourceView: A ShaderResourceView cannot be created of a Resource that did not specify the D3D11_BIND_SHADER_RESOURCE BindFlag. [ STATE_CREATION ERROR #129: CREATESHADERRESOURCEVIEW_INVALIDRESOURCE] 

私は私を防ぎ、テクスチャの作成時に欠落しているフラグがあることを理解して私がしたいことをするためには、WMFによってデータバッファが作成されるので、私はこの問題を解決するために何をすべきかはわかりません。

答えて

1

デバッグ出力は、それがD3D11_TEXTURE2D_DESC structureBindFlagフィールドで指定されたD3D11_BIND_SHADER_RESOURCEフラグ(なしで作成されたとしてテクスチャは、互換性がないことを示唆しているあなたの助けを

ありがとう。あなたはすでにメディア財団が作成したテクスチャを読ん

いくつかのケースでは、作成フラグを変更することができますが、一般的なケースでは、互換性のあるテクスチャを独自に作成し、テクスチャ間でデータをコピーしてから、テクスチャをオリジナルとしてではなくCreateShaderResourceViewメソッドテクスチャ。

+0

はこれを試み、それが働きました。ありがとう。 –

1

私はあなたがコードを見て、私はあなたの方法が間違っていると言うことができます - 犯罪ではありません。まず、ビデオデコーダはシンプルなテクスチャを作成します。あなたの状況ではDirectX11テクスチャです。通常のテクスチャです。シェーダリソースではないため、シェーダコードでは使用できません。私の見解では、あなたのタスクを解決するための2つの方法があります: - Walkthrough: Using MF to render video in a Direct3D app -

  1. 研究のために、このリンク現在の方法「チュートリアル:マイクロソフトメディア財団を使用してのWindows Phone 8用の」 - あなたのコードから私はあなたのことを見WindowsStore用の書き込みソリューションを試してください - UWPとWindows Phoneのコードは実行可能です - このコードにはMediaEnginePlayerが必要です - MediaEnginePlayerクラスはMF APIをラップするヘルパークラスとして機能します。

  2. DX11VideoRenderer - これはDirectX11を使用したMedia Foundationレンダラの完全なコードです.Direx11ビデオプロセッサを使用して、デコーダからの通常のビデオテクスチャを使用する非常に良い例が含まれています。スワップチェーンのレンダリングビデオテクスチャに変換します。 2.1。スワップチェーンからレンダリングテクスチャを取得する:

    // Get Backbuffer 
    hr = m_pSwapChain1->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pDXGIBackBuffer); 
    if (FAILED(hr)) 
    { 
        break; 
    } 
    

    2.2。

    // 
    // Create Output View of Output Surfaces. 
    // 
    D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC OutputViewDesc; 
    ZeroMemory(&OutputViewDesc, sizeof(OutputViewDesc)); 
    if (m_b3DVideo && m_bStereoEnabled) 
    { 
        OutputViewDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2DARRAY; 
    } 
    else 
    { 
        OutputViewDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D; 
    } 
    OutputViewDesc.Texture2D.MipSlice = 0; 
    OutputViewDesc.Texture2DArray.MipSlice = 0; 
    OutputViewDesc.Texture2DArray.FirstArraySlice = 0; 
    if (m_b3DVideo && 0 != m_vp3DOutput) 
    { 
        OutputViewDesc.Texture2DArray.ArraySize = 2; // STEREO 
    } 
    
    QueryPerformanceCounter(&lpcStart); 
    
    hr = m_pDX11VideoDevice->CreateVideoProcessorOutputView(pDXGIBackBuffer, m_pVideoProcessorEnum, &OutputViewDesc, &pOutputView); 
    

2.3:ビデオ・プロセッサのテクスチャ出力ビューのレンダリングから作成します。ビデオプロセッサ用の通常のデコーダビデオテクスチャ入力ビューから作成:

2.4。スワップチェーンからテクスチャをレンダリングする上で、通常のデコーダビデオテクスチャのブリッティングを行います。

D3D11_VIDEO_PROCESSOR_STREAM StreamData; 
    ZeroMemory(&StreamData, sizeof(StreamData)); 
    StreamData.Enable = TRUE; 
    StreamData.OutputIndex = 0; 
    StreamData.InputFrameOrField = 0; 
    StreamData.PastFrames = 0; 
    StreamData.FutureFrames = 0; 
    StreamData.ppPastSurfaces = NULL; 
    StreamData.ppFutureSurfaces = NULL; 
    StreamData.pInputSurface = pLeftInputView; 
    StreamData.ppPastSurfacesRight = NULL; 
    StreamData.ppFutureSurfacesRight = NULL; 

    if (m_b3DVideo && MFVideo3DSampleFormat_MultiView == m_vp3DOutput && pRightTexture2D) 
    { 
     StreamData.pInputSurfaceRight = pRightInputView; 
    } 

    hr = pVideoContext->VideoProcessorBlt(m_pVideoProcessor, pOutputView, 0, 1, &StreamData); 
    if (FAILED(hr)) 
    { 
     break; 
    } 

はい、彼らは、複雑なコードのセクションであり、それを理解するための研究全体DX11VideoRendererプロジェクトを必要とする - それは時間の膨大な量になります。

よろしく、

エフゲニーPereguda

+0

長年の詳細な回答をありがとうございました。私はDirectX APIで実際には非常に新しいです –

関連する問題