优化h264 MediaFoundation编码

时间:2019-07-10 00:34:06

标签: h.264 video-encoding screen-capture ms-media-foundation direct3d11

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

结果,我在目标帧或应用程序的图像的每一帧都得到了一个ID3D11Texture2D的回调,我希望将其用作MediaFoundation的SinkWriter的输入,以在mp4容器文件中创建h264。

我面临两个问题:

  • 纹理不能被CPU读取,并且尝试将其映射失败
  • 我认为纹理具有填充(图像跨度>像素宽度*像素格式大小)

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

  • 使用ID3D11DeviceContext::CopyResource将原始纹理复制到使用D3D11_USAGE_STAGINGD3D11_CPU_ACCESS_READ标志创建的新纹理
  • 由于纹理也具有填充,因此请创建一个IMFMediaBuffer缓冲区,并用MFCreateDXGISurfaceBuffer包裹它,并将其强制转换为IMF2DBuffer并使用IMF2DBuffer::ContiguousCopyTo来< em>我用MFCreateMemoryBuffer创建的IMFMediaBuffer

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

有什么更好的方法? MediaFoundation是否足够聪明以处理具有填充的输入帧?

1 个答案:

答案 0 :(得分:0)

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

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