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

Posted

技术标签:

【中文标题】UWP 硬件视频解码 - DirectX12 与 Media Foundation【英文标题】:UWP Hardware Video Decoding - DirectX12 vs Media Foundation 【发布时间】:2020-11-10 17:14:44 【问题描述】:

我想使用 DirectX 12 将 H264 文件的每一帧加载到纹理中并进行渲染。然而,关于这样做的信息很少甚至没有,而且微软网站的表面文档也很有限。

Media Foundation 有大量示例并提供支持硬件的解码。媒体基金会是 DirectX 的包装器,还是在做其他事情?

如果不是,与 DX 12 方法相比,Media Foundation 等效方法的优化程度要低多少?

本质上,Media Foundation 和 DirectX12 视频解码之间的最大区别是什么?

我已经在我的引擎中使用 DirectX 12,所以这是专门针对 DX12 的。

提前致谢。

【问题讨论】:

在媒体基金会的情况下,它正在做的是使用转换 (MFT),如果你愿意的话,就像一个插件(编码器、解码器、转换器等)。通常,它会自动使用显卡驱动程序(基本上是 Amd、Intel、Nvidia)提供的启用硬件的转换。您也可以明确地使用它们(或者也可以使用 Windows one - 软件)。这些转换本身通常是 MF 的包装器,使用内部供应商二进制文件。我没有使用过 DirectX 12 视频,从文档中,不清楚它在内部使用的是什么 同样在 MF 的情况下,您通常可以将转换与 DirectX 连接,所以一切都可以在硬件中发生(RGB 视频 -> nv12 -> h264):docs.microsoft.com/en-us/windows/win32/medfound/… 再一次,这里什么都没有那个关于 DirectX12 的文档 谢谢!是的,这对于转换是有道理的。不幸的是,表面在 DirectX12 中不作为一个概念存在,这意味着无法使用文章中描述的 D3D Aware 内容。我想我暂时只进行媒体基础硬件转换。 DX12 视频真的不够。 【参考方案1】:

硬件视频解码来自 DXVA (DXVA2) API。它的 DirectX 11 演变是 D3D11 API 的 D3D11 视频设备的一部分。 Microsoft 以媒体基础 API 原语的格式提供硬件加速解码器的包装器,例如 H.264 Video Decoder。该解码器提供硬件解码功能以及回退到软件解码场景。

请注意,尽管 Media Foundation 可用于 UWP 开发,但您的选择是有限的,并且不会直接向您提供上述转换之类的原语。但是,如果您使用更高级别的 API(尤其是 Media Foundation Source Reader 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 以糟糕的文档和难以开始的开发而闻名,那么 Direct3D 12 视频解码的信息为零,您将不得不享受先锋的感觉。

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

【讨论】:

一个有趣的事情是“Direct3D 12 Video APIs”一章在“Microsoft Media Foundation”下。我没有测试过,但我认为 IMFDXGIDeviceManager::ResetDevice 支持 ID3D12Device 虽然它没有正式记录。 @SimonMourier 我认为这不太可能。 Media Foundation 中对 D3D12 的支持需要从定义 MF_SA_D3D12_AWARE 开始,类似于 MF_SA_D3D11_AWARE。我们还没有看到。 也许它只适用于 MF_SA_D3D_AWARE 或 MF_SA_D3D11_AWARE:i.imgur.com/M2a2DpK.png MF_SA_D3D_AWARE 适用于 D3D9,并且大部分已过时。 D3D12 应该有自己的明确指示,特别是添加它不需要任何成本。我的假设是 MF+D3D12 远未公开。【参考方案2】:

如果您将 D3D12 设备传递给 IMFDXGIDeviceManager::ResetDevice,您将收到很多由 Media Foundation 引起的 D3D12 错误。

如果您缓慢调用 IMFSourceReader::ReadSample,则可以避免这些错误。采用同步或异步模式都可以使用此方法。而且,它应该有多慢取决于运行程序的机器。我在 ReadSample 调用之间使用 ::Sleep(1) 以同步模式播放来自网络的流,而 ::Sleep(3) 用于同步模式以在我的机器上播放本地 mp4 文件。

别问我是谁。我的名字是'先驱者'。

【讨论】:

是的,您会收到这些错误,因为您需要等待命令分配器完成处理命令,然后再调用重置。使用 DX11 及更早版本,这是为您完成的,但使用 DX12,此功能掌握在您手中!调用 sleep 只会在大多数情况下起作用,绝对不是生产解决方案。 对,我明白了。由于这些命令分配器是由 Media Foundation 内部创建的,您是否知道如何/在哪里等待命令执行? 命令分配器/列表是 DX12 API 的一部分,用于向 GPU 发送命令。如果您仅将 SourceReader 与 DXGIManager 一起使用,那么它将被抽象出来并在幕后调用。 MSFT 网站上有关于如何使用 DX12 视频加速的信息,但并没有真正的帮助。

以上是关于UWP 硬件视频解码 - DirectX12 与 Media Foundation的主要内容,如果未能解决你的问题,请参考以下文章

在 DirectX 表面缓冲区上执行转置操作

对话安谋科技周华:编解码硬件的机遇与挑战

Android MediaCodec硬件解码视频播放

多路RTSP流解码:最高可支持12路视频编解码

微软工程师详细介绍了Windows 11原生DX12视频编码API

UWP开发细节记录:DirectX::XMMATRIX 的坑