高效渲染从 Media Foundation 获得的 Direct3D 视频

Posted

技术标签:

【中文标题】高效渲染从 Media Foundation 获得的 Direct3D 视频【英文标题】:Rendering video in Direct3D obtained from Media Foundation efficiently 【发布时间】:2015-12-15 08:39:05 【问题描述】:

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

在渲染设置时

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

【问题讨论】:

我想我可以帮助你,但是使用这段代码,我看不到临界区和线程的使用。你能提供一个我可以测试的示例代码吗?通常它应该在没有损坏帧和低帧率的情况下工作。 谢谢。它是更大代码库的一部分。我会看看我是否可以制作一个仍然显示问题的较小版本 【参考方案1】:

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

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

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

【讨论】:

我不知道那个 DSP。这很有趣。我会试一试

以上是关于高效渲染从 Media Foundation 获得的 Direct3D 视频的主要内容,如果未能解决你的问题,请参考以下文章

UWP 硬件视频解码 - DirectX12 与 Media Foundation

Windows Media Foundation 使用 IMFTransform 将 mp4 电影帧解码为 2D 纹理

使用 Microsoft Media Foundation 从文件播放视频

使用 Media Foundation 源阅读器阅读 3D(左右)视频

如何使用 Media Foundation 从 IMFSourceReader 播放音频缓冲区

使用 Media Foundation 将音频从文件播放到扬声器