优化 h264 MediaFoundation 编码

Posted

技术标签:

【中文标题】优化 h264 MediaFoundation 编码【英文标题】:Optimizing h264 MediaFoundation encoding 【发布时间】:2019-07-10 00:34:06 【问题描述】:

我正在编写一个使用UWP Screen Capture API 的屏幕捕获应用程序。

因此,我在每个帧都收到一个带有目标屏幕或应用程序图像的ID3D11Texture2D 的回调,我想将其用作 MediaFoundation 的 SinkWriter 的输入,以在 mp4 容器文件中创建一个 h264。

我面临两个问题:

纹理不是 CPU 可读的,尝试映射它失败 我假设纹理有填充(图像步幅 > 像素宽度 * 像素格式大小)

为了解决这些问题,我的方法是:

使用ID3D11DeviceContext::CopyResource 将原始纹理复制到使用D3D11_USAGE_STAGINGD3D11_CPU_ACCESS_READ 标志创建的新纹理中 由于 那个 纹理也有填充,创建一个 IMFMediaBuffer 缓冲区,用 MFCreateDXGISurfaceBuffer 将其包裹起来,将其转换为 IMF2DBuffer 并使用 IMF2DBuffer::ContiguousCopyTo另一个 IMFMediaBuffer我用MFCreateMemoryBuffer 创建的

所以我基本上每帧都复制两次,一次在 GPU 上,一次在 CPU 上,这可行,但似乎效率低下。

有什么更好的方法来做到这一点? MediaFoundation 是否足够智能以处理具有填充的输入帧?

【问题讨论】:

您可以查看这个问题和答案(c#,但仍然是一个很好的解释),详细了解如何实现将直接使用纹理作为输入的硬件 h264 编码(如 Roman 建议的那样):***.com/questions/44402898/… 【参考方案1】:

效率低下来自您尝试Map 而不是使用纹理作为视频编码器输入。 MF H.264 编码器,在大多数情况下是硬件编码器,可以将视频内存支持的纹理作为直接输入,这就是您想要做的(分别设置编码器 - 请参阅 D3D/DXGI 设备管理器)。

填充不适用于纹理帧。如果使用传统系统内存数据在帧中进行填充,Media Foundation 原语通常能够处理具有填充的数据:Image Stride 和MF_MT_DEFAULT_STRIDE,以及其他Video Format Attributes。

【讨论】:

以上是关于优化 h264 MediaFoundation 编码的主要内容,如果未能解决你的问题,请参考以下文章

MediaFoundation HEVC H265 编码

H264解码性能不佳

我如何解析 H264 文件和帧

安卓mediasoup webrtc h264 软编解码相关源码分析

安卓 webrtc 开启h264 软编解码

安卓 webrtc 开启h264 软编解码