使用Media Foundation对通过桌面复制获得的D3D表面进行编码

时间:2019-06-01 12:38:35

标签: c++ h.264 direct3d ms-media-foundation desktop-duplication

我想对Desktop Duplication API框架进行编码,以便在使用Media Foundation对其进行编码后通过网络发送。当我调用IMFTransform :: ProcessInput时,我陷入了E_NOTIMPL错误,这让我有些茫然。

这些是我到目前为止所完成的步骤,我将详细介绍它们,因为花了我几天的时间来收集网络上稀疏分散的信息中的所有内容,因此,如果解决了该问题,有望对其他人有所帮助。下面的所有内容均会显示一个S_OK:

  • 我正在通过Duplication API获取表面,并使用MFCreateVideoSampleFromSurface从表面创建IMFSample
  • 我正在从使用MFT_CATEGORY_VIDEO_ENCODER和MFVideoFormat_H264初始化的IMFActivate中使用IMFActivate :: ActivateObject获取视频编码器
  • 我正在使用比特率,帧率,长宽比等在输入上初始化IMFMediaType。最重要的是:MFVideoFormat_NV12,似乎是唯一可与DXF_FORMAT_B8G8R8A8_UNORM一起使用的桌面复制API。
  • 除了MFVideoFormat_H264作为SUB_TYPE之外,我还在输出上设置了与上述相同的IMFMediatype。
  • 我先用上面的2调用IMFTransform :: SetOutputType,然后再调用IMFTransform :: SetInputType。
  • 我将IMFSample时间设置为0,因为它似乎不是由MFCreateVideaSampleFromSurface设置的。还将输入FPS设置为MFFrameRateToAverageTimePerFrame的SampleDuration。

所有这些之后,我使用上面创建的IMFSample调用MFTransform :: ProcessInput,并获得“未实现的E_NOTIMPL”作为HRESULT。我已经读过我应该在上面的IMFTransform编码器中设置一个IMFDXGIDeviceManager,所以我使用了以下方法:

    我的ID3D11Device中的
  • MFCreateDXGIDeviceManager,与桌面复制API和任意重置令牌一起使用。
  • 使用设备和令牌执行IMFDXGIDeviceManager :: ResetDevice。
  • 调用IMFTransform :: ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER,reinterpret_cast(m_pDXDeviceManager)。

在最后一步,我的HRESULT上出现另一个“未实现E_NOTIMPL”,在那儿我不知道自己在做什么错了或需要做什么。

1 个答案:

答案 0 :(得分:0)

要做的第一件事是检查您的编码器是否为MF_SA_D3D11_AWARE

我认为不是,请阅读:MFT_MESSAGE_SET_D3D_MANAGER

  

如果MFT不支持此消息,则应返回E_NOTIMPL

但是有一件事很奇怪:DirectX Surface Buffer

  

调用IMFMediaBuffer :: Lock。通常不建议这样做,因为它会迫使对象从Direct3D表面复制内存,然后再次返回。

ProcessInput应该起作用了。