硬件 MRT
注意
本主题适用于 Windows 7 或更高版本。
本主题介绍如何编写媒体基础转换 (MFT) ,充当硬件编码器、解码器或数字信号处理器的代理 (DSP) 。
重要
如果硬件编解码器使用 AVStream 多媒体类驱动程序,则它不需要自定义 MFT。 媒体基础为此提供 AVStream 代理。 本主题中的信息仅适用于硬件编解码器不使用 AVStream 的特殊情况。 有关详细信息,请参阅 AVStream 中的硬件编解码器支持。
本主题包含以下各节:
简介
任何不基于 AVStream 的硬件编解码器都必须提供其自己的 MFT 才能充当驱动程序的代理。 硬件编解码器可能包含多个不同的功能块:
- 编码器
- 解码器
- 帧缩放/格式转换
其中每个函数都应由单独的 MFT 管理。 硬件 MFT 绝不应充当多用途“转码器”。而是将编码函数放入编码器 MFT 中,将解码函数放入解码器 MFT 中。 如果硬件提供帧缩放和格式转换,请将这些函数放在在 MFT_CATEGORY_VIDEO_PROCESSOR 类别中注册的单独视频处理器中。 如果硬件不支持帧缩放或格式转换,则 Media Foundation 提供软件视频处理器。
硬件 MRT 具有以下一般要求:
硬件 MFT 属性
硬件 MFT 必须实现以下与属性相关的方法:
- IMFTransform::GetAttributes:返回全局 MFT 属性的属性存储。
- IMFTransform::GetInputStreamAttributes:返回输入流的属性存储。
- IMFTransform::GetOutputStreamAttributes:返回输出流的属性存储。
首次创建 MFT 时,它必须在其自己的全局属性存储 (设置以下属性,即 GetAttributes) 返回的属性存储:
Attribute | 说明 |
---|---|
MF_TRANSFORM_ASYNC | 必须设置为 TRUE。 指示 MFT 执行异步处理。 |
MFT_ENUM_HARDWARE_URL_Attribute | 包含硬件设备的符号链接。 拓扑加载程序使用此属性的存在来测试 MFT 是否表示硬件设备。 |
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE | 必须设置为 TRUE。 指示 MFT 支持动态格式更改。 |
硬件握手序列
如果两个 MCT 表示同一物理设备,它们可以在硬件中交换数据,例如,通过硬件总线交换数据。 无需将数据复制到系统内存中,然后再复制回设备。
在下图中,标记为“A”和“B”的 MCT 表示同一硬件中的功能块。 例如,在转码方案中,“A”可能表示硬件解码器,“B”可能表示硬件编码器。 “A”和“B”之间的数据流发生在硬件中。 标记为“C”的 MFT 是软件 MFT。 从“B”到“C”的数据流使用系统内存。
若要建立硬件连接,这两个硬件 MRT 必须使用专用信道。 此连接是在格式协商期间、设置媒体类型之前和对 ProcessInput 的第一次调用之前建立的。 连接过程的工作原理如下:
拓扑加载程序检查两个 MRT 是否存在 MFT_ENUM_HARDWARE_URL_Attribute 属性。 请注意,它不会检查此属性的值。
如果 两 个 MRT 上都存在MFT_ENUM_HARDWARE_URL_Attribute,则拓扑加载程序将执行以下操作:
- 拓扑加载程序在 上游 MFT (A) 上调用 IMFTransform::GetOutputStreamAttributes。 此方法返回 IMFAttributes 指针。 将此指针表示为 pUpstream。
- 拓扑加载程序在下游 MFT (B) 上调用 IMFTransform::GetInputStreamAttributes 。 此调用还返回 IMFAttributes 指针。 将此指针表示为 pDownstream。
- 拓扑加载程序通过调用 IMFAttributes::SetUnknown 在 pDownstream 上设置MFT_CONNECTED_STREAM_ATTRIBUTE属性。 属性的值是 pUpstream 指针。
- 拓扑加载程序在 pDownstream 和 pUpstream 上将 MFT_CONNECTED_TO_HW_STREAM 属性设置为 TRUE。
此时,下游 MFT 具有指向上游 MFT 的属性存储的指针,如下图所示。
注意
为清楚起见,此图将流和属性存储显示为不同的对象,但实现不需要这样做。
下游 MFT 使用 IMFAttributes 指针与 MFT 上游建立专用信道。 由于通道是专用的,因此确切的机制由 实现定义。 例如,MFT 可能会查询专用 COM 接口。
在步骤 4 中,下游 MFT 必须验证两个 MFT 是否共享同一个物理设备。 否则,它们必须回退到使用系统内存进行数据传输。 这使 MFT 能够与软件 MFT 和其他硬件设备一起正常运行。
如果握手成功,并且两个 MRT 共享一个专用数据通道,则它们不使用下一部分) 连接点中描述的标准数据处理模型 (。 具体而言,下游 MFT 不发送 METransformNeedInput 事件;有关详细信息,请参阅本主题的下一部分。
数据处理
当硬件 MFT 使用系统内存进行数据传输时,该过程如下所示:
- 为了请求更多输入,MFT 发送 METransformNeedInput 事件。
- METransformNeedInput 事件导致管道调用 IMFTransform::P rocessInput。
- 当 MFT 具有输出数据时,MFT 会发送 METransformHaveOutput 事件。
- METransformHaveOutput 事件导致管道调用 IMFTransform::P rocessOutput。
有关详细信息,请参阅 异步 MRT。
但是,如果 MFT 使用硬件通道,则不会在硬件连接点发送这些事件,因为所有数据传输都发生在硬件内部。 因此,管道不会在连接点调用 ProcessInput 或 ProcessOutput 。
例如,请考虑本主题中的第一个关系图。 根据此配置,数据处理将按如下方式进行:
- “A”发送 METransformNeedInput 以请求数据。
- 管道在“A”上调用 ProcessInput 。
- “A”和“B”处理硬件中的数据。
- 处理完成后,“B”发送 METransformHaveOutput 事件。
- 管道在“B”上调用 ProcessOutput 。
配对解码器/编码器
如果解码器和编码器位于同一硬件芯片上,则转码时最好将它们一起使用。 也就是说,选择其中一个应在转码管道中选择另一个。 为了确保选择匹配的硬件编解码器,这两个编解码器 MCT 都应提供自定义媒体类型。 创建自定义媒体类型:
- 根据需要将 MF_MT_MAJOR_TYPE 属性设置为 MFMediaType_Audio 或 MFMediaType_Video。
- 将 MF_MT_SUBTYPE 属性设置为自定义 GUID 值。
其他类型属性是可选的。 解码器从其 IMFTransform::GetOutputAvailableType 返回自定义类型,编码器从其 IMFTransform::GetInputAvailableType 方法返回自定义类型。 在这两种情况下,自定义类型必须是列表中的第一个条目, (dwTypeIndex = 0) 。
若要使用软件编解码器,编解码器还应返回至少一种标准格式,例如用于视频的 NV12。 标准格式应出现在自定义类型 (dwTypeIndex> 0) 之后。 如果两个编解码器必须始终配对且无法与软件编解码器互操作,则 MMFT 应仅返回自定义格式,而不返回任何标准格式。
相关主题