UWP硬件视频解码 - DirectX12 vs 媒体基金会

4
我想使用DirectX 12将H264文件的每一帧加载到纹理中并进行渲染。然而,关于如何实现这一点的信息很少,微软网站上提供的文档也很浅显。
Media Foundation有很多例子,并提供硬件加速解码。Media Foundation是DirectX的包装器还是在做其他事情?
如果不是,与DX 12方法相比,Media Foundation等效方法会少多少优化?
从根本上讲,Media Foundation和DirectX 12视频解码之间的主要区别是什么?
我已经在我的引擎中使用了DirectX 12,所以这个问题是与DX12相关的。
提前感谢你的回答。

在媒体基础架构的情况下,它所做的是使用转换(MFT),就像插件一样(编码器、解码器、转换器等)。通常情况下,它会自动使用与显卡驱动程序提供的硬件启用转换(Amd、Intel、Nvidia基本相同)。您还可以明确地使用它们(或者也可以使用Windows - 软件)。这些转换通常是MF的包装器,使用内部供应商二进制文件。我没有使用过DirectX 12视频,并且从文档中不清楚它在内部使用什么。 - Simon Mourier
在MF情况下,通常可以将转换器与DirectX连接起来,因此所有操作都可以在硬件中完成(RGB视频-> nv12-> h264):https://learn.microsoft.com/en-us/windows/win32/medfound/direct3d-aware-mfts。同样,在该文档中没有关于DirectX12的内容。 - Simon Mourier
谢谢!是的,关于转换的部分很有道理。不幸的是,在DirectX12中,Surface并不存在作为一个概念,这意味着文章中描述的D3D Aware无法使用。我想暂时我会选择Media Foundation硬件转换。实际上,对于DX12视频来说,没有足够的信息可供参考。 - pma07pg
2个回答

4

硬件视频解码来自DXVA(DXVA2)API。它的DirectX 11演化是D3D11 Video Device,是D3D11 API的一部分。Microsoft提供了在Media Foundation API原语格式中对硬件加速解码器的包装,例如H.264视频解码器。此解码器提供使用硬件解码能力以及回退到软件解码场景。

请注意,即使Media Foundation可用于UWP开发,您的选项也受到限制,不会直接提供像上述变换这样的原语。但是,如果您使用更高级别的API(尤其是Media Foundation 源阅读器API),则可以利用硬件加速的视频解码在您的UWP应用程序中。

Media Foundation实现提供与Direct3D 11的互操作性,特别是视频编解码方面,但不支持Direct3D 12。您将无法直接将Media Foundation和DirectX 12一起使用。您将需要实现Direct3D 11/12互操作性以在API之间传输数据(或者,在适用的情况下,使用共享访问相同GPU数据)。

或者,您可以转向底层ID3D12VideoDevice :: CreateVideoDecoder,它是上述DXVA2和Direct3D 11视频解码API的进一步演化,用法类似。

不幸的是,Media Foundation以文档质量差和难以开始开发而闻名,而直接使用D3D 12视频解码则没有任何信息,您将感受到先驱的感觉。

无论哪种方式,所有提到的都是相对较薄的硬件辅助视频解码实现的包装,性能相同。我建议走Media Foundation路线,并在必要时实现11/12互操作性。


有一件有趣的事情是,《Direct3D 12 视频 API》一章位于《Microsoft Media Foundation》下面。我没有测试过,但我认为 IMFDXGIDeviceManager::ResetDevice 支持 ID3D12Device,尽管它没有正式记录在文档中。 - Simon Mourier
@SimonMourier 我认为这是不太可能的。支持Media Foundation中的D3D12需要从定义MF_SA_D3D12_AWARE开始,类似于MF_SA_D3D11_AWARE。我们目前还没有看到它。 - Roman R.
也许它只能与MF_SA_D3D_AWARE或MF_SA_D3D11_AWARE一起使用:https://i.imgur.com/M2a2DpK.png - Simon Mourier
MF_SA_D3D_AWARE 是为了D3D9而设计的,现在已经大部分过时了。D3D12应该有自己的显式指示,特别是它不需要花费任何代价来添加。我认为,MF+D3D12还没有公开发布的计划。 - Roman R.

0

如果你将D3D12设备传递给IMFDXGIDeviceManager :: ResetDevice,可能会因Media Foundation而导致许多D3D12错误。

如果您缓慢调用IMFSourceReader :: ReadSample,则可以避免这些错误。使用此方法采用同步或异步模式都没有关系。而且,调用速度应根据运行程序的计算机而定。我在从网络播放流时的同步模式下,在ReadSample调用之间使用:: Sleep(1),在我的机器上播放本地mp4文件的同步模式下使用:: Sleep(3)。

不要问我是谁。我的名字是“先锋”。


是的,你会遇到这些错误,因为在调用重置之前,你需要等待命令分配器完成处理命令。在DX11及更早版本中,这一过程由系统自动完成,但在DX12中,这个权力掌握在你手中!调用sleep只能在大多数情况下起作用,绝对不是一个生产解决方案。 - pma07pg
好的,我明白了。你解决了如何/在哪里等待命令执行的问题吗?因为这些命令分配器是由Media Foundation内部创建的。 - Giovedi
命令分配器/列表是 DX12 API 的一部分,用于向 GPU 发送命令。如果你只使用 DXGIManager 中的 SourceReader,则该过程将被抽象化并在幕后调用。有关如何在 MSFT 网站上使用 DX12 视频加速的信息,但它实际上并没有太大帮助。 - pma07pg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接