优化 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_STAGING
和D3D11_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 编码的主要内容,如果未能解决你的问题,请参考以下文章