Direct3D-Aware MRT

本主题介绍如何实现视频 (MFT) 的 Direct3D 感知 媒体基础转换。

如果视频 MFT 可以处理包含 Direct3D 图面的样本,则将其视为 Direct3D 感知。 在视频 MFT 中支持 Direct3D 的典型原因是使用 DirectX 视频加速 (DXVA) 启用硬件加速解码。

本主题介绍使 MFT Direct3D 感知所需的步骤。 本主题不介绍 DXVA 解码的机制。 有关 DXVA 的信息,请参阅 DirectX 视频加速 2.0

重要

从 Windows 8 开始,可以使用 IMFDXGIDeviceManager 代替 IDirect3DDeviceManager9。 对于 Windows 应用商店应用,必须使用 IMFDXGIDeviceManager 和 Microsoft Direct3D 11。 有关详细信息,请参阅 Direct3D 11 视频 API

 

  1. 实现 IMFTransform::GetAttributes 方法。 此方法返回指向属性存储的指针。
  2. MFT 必须在其自己的属性存储中将 MF_SA_D3D_AWARE 属性的值设置为 TRUE 。 从 Windows 8 开始,如果使用 Direct3D 11,请使用 MF_SA_D3D11_AWARE
  3. 在格式协商期间,如果使用 Direct3D 11 ) 属性时MF_SA_D3D_AWARE (或MF_SA_D3D11_AWARE,则客户端可能会将MFT_MESSAGE_SET_D3D_MANAGER消息发送到 MFT。 ulParam 事件参数是指向 IDirect3DDeviceManager9 接口的指针。 从 Windows 8 开始,可以使用 IMFDXGIDeviceManager 而不是 IDirect3DDeviceManager9。 客户端不需要发送此消息。
  4. MFT 调用 IDirect3DDeviceManager9::GetVideoService 来查询所需的 DXVA 服务。 从 Windows 8 开始,如果使用 IMFDXGIDeviceManager,MFT 将调用 IMFDXGIDeviceManager::GetVideoService。 通常,解码器将查询 IDirectXVideoDecoderService,视频处理器将查询 IDirectXVideoProcessorService
  5. 假设上一步成功, IMFTransform::GetInputAvailableTypeIMFTransform::GetOutputAvailableType 方法必须返回与 DXVA 兼容的格式。
  6. 客户端在 MFT 上配置媒体类型。 如果媒体类型与 DXVA 不兼容,MFT 必须 返回错误代码MF_E_UNSUPPORTED_D3D_TYPE
  7. 此时,有两个选项,具体取决于客户端是否找到合适的 DXVA 格式。
    • 如果客户端成功配置 DXVA 格式,它可能会开始处理。 此时,MFT 可以使用 DXVA 进行处理,或回退到软件处理。
    • 或者,如果客户端找不到可接受的 DXVA 格式,客户端可能会发送另一个 MFT_MESSAGE_SET_D3D_MANAGER 消息,这次将 ulParam 设置为 NULL。 如果 IMFDXGIDeviceManager) 和任何其他 DXVA 接口使用,并且还原软件处理,MFT 必须释放 IDirect3DDeviceManager9 指针 (IMFDXGIDeviceManager 指针。 此时,MFT 不得使用 DXVA 处理。

必须准备可识别 Direct3D 的 MFT 来处理包含 Direct3D 图面的样本。 该示例只包含一个媒体缓冲区。 若要从缓冲区获取 Direct3D 图面,请调用 MFGetService 函数并指定 MR_BUFFER_SERVICE 服务。 有关详细信息,请参阅 DirectX Surface Buffer

使用 DXVA 的 MFT 必须分配自己的输出样本,如下所示:

  1. IMFTransform::GetOutputStreamInfo 方法中,设置 MFT_OUTPUT_STREAM_PROVIDES_SAMPLES 标志。
  2. 创建 DXVA 图面池,如 DXVA 规范中所述。
  3. 通过调用 MFCreateVideoSampleFromSurface 创建媒体示例。

MFT 应始终支持软件处理作为回退,因为 DXVA 处理可能不可用,原因如下:

  • GPU 可能不支持 DXVA。
  • 客户端可能不使用 Direct3D。
  • DXVA 配置文件不是针对每种视频格式定义的。

Direct3D 感知 MFT 必须具有单个输出流。 它不能有多个输出。

编写自定义 MFT