使用Media Foundation对通过桌面复制获得的D3D表面进行编码 [英] Encoding a D3D Surface obtained through Desktop Duplication using Media Foundation

查看:422
本文介绍了使用Media Foundation对通过桌面复制获得的D3D表面进行编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to encode Desktop Duplication API frames to send over the network after encoding them with Media Foundation. I'm stuck with a E_NOTIMPL error when I call IMFTransform::ProcessInput, leaving me a little in the dark.

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

These are the steps I've done up until now, I'm detailing them because it took me days to gather everything from the scarce scattered info across the web, so if it's resolved it will hopefully help others. Everything below is met with an S_OK:

  • 我正在通过Duplicat 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,因此我使用了以下方法:

After all of this, I call the MFTransform::ProcessInput with the IMFSample created above, and get a "E_NOTIMPL not implemented" as an HRESULT. I've read that I should set an IMFDXGIDeviceManager to my IMFTransform encoder above, so I did that using:

    我的ID3D11Device中的
  • MFCreateDXGIDeviceManager,与桌面复制API和任意重置令牌一起使用.
  • 使用设备和令牌执行IMFDXGIDeviceManager :: ResetDevice.
  • 调用IMFTransform :: ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER,reinterpret_cast(m_pDXDeviceManager).
  • MFCreateDXGIDeviceManager from my ID3D11Device used with Desktop Duplication API and an arbitrary reset token.
  • Doing an IMFDXGIDeviceManager::ResetDevice with the device and token.
  • Calling IMFTransform::ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, reinterpret_cast(m_pDXDeviceManager).

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

On this last step I get another "E_NOTIMPL not implemented" on my HRESULT, and that's where I don't know what I'm doing wrong anymore or what needs to be done.

推荐答案

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

The first thing to do, is to check if your encoder is MF_SA_D3D11_AWARE

我认为不行,请阅读以下内容:

I think it does not, reading this : MFT_MESSAGE_SET_D3D_MANAGER

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

If an MFT does not support this message, it should return E_NOTIMPL

但是有一件事很奇怪: DirectX表面缓冲区

But one thing is strange : DirectX Surface Buffer

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

Call IMFMediaBuffer::Lock. Generally this is not recommended, because it forces the object to copy memory from the Direct3D surface and then back again.

ProcessInput应该起作用了.

ProcessInput should have worked.

这篇关于使用Media Foundation对通过桌面复制获得的D3D表面进行编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆