有效地在 Direct3D 中渲染从 Media Foundation 获取的视频

Rendering video in Direct3D obtained from Media Foundation efficiently

我想有效地使用我正在从媒体基础解码的实时视频。 最初,我是 运行 在解码每一帧后同步渲染功能。传入的帧率约为 25-30 fps,但我想以 60fps 的速度渲染图形(游戏)内容。 如果我异步执行此操作,我将得到损坏的输出/黑屏/两者或由于激进锁定而导致帧率非常低。由于 GPU 操作是异步的,因此我无法找到合理的关键部分。这通常是如何完成的?我可以使用我的临时表面之一(source、dest 或 g_pDecodedTexture)作为同步点,并使用 CRITICAL_SECTION 环绕写入 it/them,但我不知道关键在哪里部分应该继续呈现(阅读)线程。如果我包围整个渲染函数,我的帧率会很低,如果我不这样做,我会得到不正确的输出。也许还有另一种更合适的同步方法。

在渲染设置时

    hr = g_d3dDevice->CreateShaderResourceView(g_pDecodedTexture, &shaderResourceViewDesc, &g_pTextureRV);

在解码线程中

      void Decode()
      {
           MFT_OUTPUT_DATA_BUFFER output = { 0 };
           //...
           encoder->ProcessOutput(0,1,&output,&status);
           // 
           CComPtr<IMFMediaBuffer>  spMediaBuffer;
           CComPtr<IMFDXGIBuffer>   spDXGIBuffer;
           CComPtr<IDXGIResource>  spDecodedTexture;

           output.pSample->GetBufferByIndex(0, &spMediaBuffer);
           spMediaBuffer->QueryInterface(IID_PPV_ARGS(&spDXGIBuffer);
           spDXGIBuffer->GetResource(IID_PPV_ARGS(&spDecodedTexture);

           //....

            CComPtr<ID3D11Texture2D> source;
            spDXGIBuffer->QueryInterface<ID3D11Texture2D>(&source);

            //
            CComPtr<ID3D11Resource> dest;
            swapChain->GetBuffer(0, __uuidof(ID3D11Resource), (void**)&dest);
            deviceContext->CopyResource(dest, source);
            deviceContext->CopyResource(g_pDecodedTexture, source);          
       }

在渲染线程中

void Render()
{
    //...
    deviceContext->PSSetShaderResources(0, 1, &g_pTextureRV);
    //..

    m_deviceContext->VSSetShaderResources(0, 1, &g_pTextureRV);
    //..
    immediateContext->DrawIndexed(...);   
    //..
    immediateContext->DrawIndexed(...);   
    //..
    immediateContext->DrawIndexed(...);   
    //..
    immediateContext->DrawIndexed(...);   
    //
    Present();
}

您可以试试这个:在解码器之后插入帧率转换器 DSP。请确保您的输入格式与 DSP 兼容。将帧速率设置为 60 fps。

这样做,我认为你可以保持同步方法。

如果要手动以 60 fps 显示,我们需要更多代码来查看问题出在哪里。