我想对桌面复制 API 帧进行编码,以便在使用 Media Foundation 对其进行编码后通过网络发送。当我调用IMFTransform::P rocessInput时,我遇到了一个E_NOTIMPL错误,让我有点蒙在鼓里。
这些是我到目前为止所做的步骤,我正在详细说明它们,因为我花了几天时间从网络上稀缺的分散信息中收集所有内容,所以如果它得到解决,它有望帮助其他人。以下所有内容都符合S_OK:
- 我正在通过复制API获取表面,使用MFCreateVideoSampleFromSurface从中创建IMFSample
- 我正在使用 IMFActivate::ActivateObject 从使用 MFT_CATEGORY_VIDEO_ENCODER 和 MFVideoFormat_H264 初始化的 IMFActivate 获得视频编码器
- 我正在使用比特率、帧率、纵横比等在输入上初始化 IMFMediaType,最重要的是:MFVideoFormat_NV12,似乎是唯一一个使用桌面复制 API DXGI_FORMAT_B8G8R8A8_UNORM的人。
- 我在输出上设置 IMFMediatype 与上述相同,除了MFVideoFormat_H264作为SUB_TYPE。
- 我用上面的 2 调用 IMFTransform::SetOutputType,然后调用 IMFTransform::SetInputType。
- 我将 IMFSample 时间设置为 0,因为它似乎不是由 MFCreateVideaSampleFromSurface 设置的。还使用 MFFrameRate设置为使用输入 FPS 设置每帧平均时间的采样持续时间。
在所有这些之后,我调用MFTransform::P rocessInput与上面创建的IMFSample,并得到一个"未实施E_NOTIMPL"作为HRESULT。我已经读到我应该为上面的 IMFTransform 编码器设置一个 IMFDXGIDeviceManager,所以我使用:
- MFCreateDXGIDeviceManager从我的ID3D11Device与桌面复制API和任意重置令牌一起使用。
- 使用设备和令牌执行 IMFDXGIDeviceManager::ResetDevice。
- 调用IMFTransform::P rocessMessage(MFT_MESSAGE_SET_D3D_MANAGER,reinterpret_cast(m_pDXDeviceManager)。
在最后一步中,我在 HRESULT 上得到了另一个"未实现E_NOTIMPL",这就是我不知道我做错了什么或需要做什么的地方。
首先要做的是检查编码器是否MF_SA_D3D11_AWARE
我认为它没有,阅读这个:MFT_MESSAGE_SET_D3D_MANAGER
如果 MFT 不支持此消息,则应返回E_NOTIMPL
但有一点很奇怪:DirectX Surface Buffer
调用 IMFMediaBuffer::Lock。通常不建议这样做,因为它会强制对象从 Direct3D 图面复制内存,然后再复制回来。
进程输入应该已经工作了。