高效渲染从 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(左右)视频