硬件 MFT

注意

本主题适用于 Windows 7 或更高版本。

 

本主题介绍如何编写媒体基础转换(MFT),该转换充当硬件编码器、解码器或数字信号处理器(DSP)的代理。

重要

如果硬件编解码器使用 AVStream 多媒体类驱动程序,则不需要自定义 MFT。 Media Foundation 为此提供了 AVStream 代理。 本主题中的信息仅适用于硬件编解码器不使用 AVStream 的特殊情况。 有关详细信息,请参阅 AVStream 中的硬件编解码器支持。

 

本主题包含以下部分:

介绍

任何不基于 AVStream 的硬件编解码器都必须提供自己的 MFT 来充当驱动程序的代理。 硬件编解码器可能包含多个不同的功能块:

  • 编码器
  • 译码器
  • 帧缩放/格式转换

其中每个函数都应由单独的 MFT 管理。 硬件 MFT 绝不应充当多用途“转码器”。相反,将编码函数放入编码器 MFT,并将解码函数放入解码器 MFT 中。 如果硬件提供帧缩放和格式转换,请将这些函数置于单独的视频处理器中,并在 MFT_CATEGORY_VIDEO_PROCESSOR 类别中注册。 如果硬件不支持帧缩放或格式转换,Media Foundation 提供软件视频处理器。

硬件 MFT 具有以下常规要求:

  • 硬件 MFT 必须使用新的异步处理模型,如 异步 MFT中所述。
  • 硬件 MFT 必须支持动态格式更改,如 动态格式更改中所述。

硬件 MFT 属性

硬件 MFT 必须实现以下与属性相关的方法:

首次创建 MFT 时,它必须在自己的全局属性存储(即 getAttributes 返回的属性存储)上设置以下属性:

属性 描述
MF_TRANSFORM_ASYNC 必须设置为 true 。 指示 MFT 执行异步处理。
MFT_ENUM_HARDWARE_URL_Attribute 包含硬件设备的符号链接。
拓扑加载程序使用此属性的存在来测试 MFT 是否表示硬件设备。
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE 必须设置为 true 。 指示 MFT 支持动态格式更改。

 

硬件握手序列

如果两个 MFT 表示相同的物理设备,则可以在硬件内交换数据,例如,通过硬件总线交换数据。 无需将数据复制到系统内存中,然后返回到设备。

在下图中,标记为“A”和“B”的 MFT 表示同一硬件中的功能块。 例如,在转码方案中,“A”可能表示硬件解码器,“B”可能表示硬件编码器。 “A”和“B”之间的数据流发生在硬件中。 标记为“C”的 MFT 是软件 MFT。 从“B”到“C”的数据流使用系统内存。

关系图,显示标记为 a 到 c 的框和硬件编解码器:指向 b 和编解码器,编解码器指向 b,b 指向 c

若要建立硬件连接,这两个硬件 MFT 必须使用专用信道。 此连接是在格式协商期间建立的,在设置媒体类型之前,在首次 调用 processInput之前建立。 连接过程如下所示:

  1. 拓扑加载程序检查两个 MFT 是否存在 MFT_ENUM_HARDWARE_URL_Attribute 属性。 请注意,它不检查此属性的值。

  2. 如果这两个 MFT 上都存在 MFT_ENUM_HARDWARE_URL_Attribute,拓扑加载程序将执行以下作:

    1. 拓扑加载程序调用 IMFTransform::GetOutputStreamAttributes 上游 MFT (A)。 此方法返回 IMFAttributes 指针。 让此指针在 pUpstream 表示。
    2. 拓扑加载程序调用 IMFTransform::GetInputStreamAttributes 下游 MFT (B)。 此调用还返回 IMFAttributes 指针。 pDownstream表示此指针。
    3. 拓扑加载程序通过调用 IMFAttributes::SetUnknownpDownstream 上设置 MFT_CONNECTED_STREAM_ATTRIBUTE 属性。 该属性的值是 pUpstream 指针
    4. 拓扑加载程序在 pDownstream pUpstream上将 MFT_CONNECTED_TO_HW_STREAM 属性设置为TRUE
  3. 此时,下游 MFT 具有指向上游 MFT 属性存储的指针,如下图所示。

    关系图,每个 mft 指向其流、每个指向其存储的流,以及输入存储,其中虚线指向输出存储

    注意

    为了清楚起见,此关系图将流和属性存储为不同的对象,但实现不需要这样做。

     

  4. 下游 MFT 使用 IMFAttributes 指针与上游 MFT 建立专用信道。 由于通道是专用的,因此确切的机制由实现定义。 例如,MFT 可能会查询专用 COM 接口。

在步骤 4 中,下游 MFT 必须验证这两个 MFT 是否共享同一物理设备。 否则,它们必须回退到使用系统内存进行数据传输。 这使 MFT 能够使用软件 MFT 和其他硬件设备正确运行。

如果握手成功,并且两个 MFT 共享专用数据通道,则它们不会在连接点使用标准数据处理模型(下一部分所述)。 具体而言,下游 MFT 不会发送 METransformNeedInput 事件;有关更多详细信息,请参阅本主题中的下一部分。

数据处理

当硬件 MFT 使用系统内存进行数据传输时,该过程的工作原理如下:

  1. 若要请求更多输入,MFT 将发送 METransformNeedInput 事件。
  2. METransformNeedInput 事件会导致管道调用 IMFTransform::P rocessInput
  3. 当 MFT 具有输出数据时,MFT 会发送 METransformHaveOutput 事件。
  4. METransformHaveOutput 事件会导致管道调用 IMFTransform::P rocessOutput

有关详细信息,请参阅 异步 MFT

但是,如果 MFT 使用硬件通道,则不会在硬件连接点发送这些事件,因为所有数据传输都在硬件内部发生。 因此,管道不会 在连接点调用 processInputProcessOutput

例如,请考虑本主题中的第一个关系图。 鉴于此配置,数据处理将如下所示:

  1. “A”发送 METransformNeedInput 以请求数据。
  2. 管道在“A”上 ProcessInput 调用。
  3. “A”和“B”处理硬件中的数据。
  4. 处理完成后,“B”将发送 METransformHaveOutput 事件。
  5. 管道在“B”上调用 ProcessOutput

配对解码器/编码器

如果解码器和编码器位于同一硬件芯片上,则转码时最好将它们一起使用。 也就是说,选择一个应在转码管道中选择另一个。 为了确保选择匹配的硬件编解码器,这两个编解码器 MFT 都应提供自定义媒体类型。 创建自定义媒体类型:

  • 根据需要将 MF_MT_MAJOR_TYPE 属性设置为 MFMediaType_AudioMFMediaType_Video
  • MF_MT_SUBTYPE 属性设置为自定义 GUID 值。

其他类型属性是可选的。 解码器从其 IMFTransform::GetOutputAvailableType返回自定义类型,编码器从其 IMFTransform::GetInputAvailableType 方法返回自定义类型。 在这两种情况下,自定义类型必须是列表中的第一个条目(dwTypeIndex = 0)。

若要使用软件编解码器,编解码器还应至少返回一种标准格式,例如 NV12 作为视频。 标准格式应出现在自定义类型之后(dwTypeIndex> 0)。 如果两个编解码器必须始终配对且无法与软件编解码器互作,则 MFT 应仅返回自定义格式,并且不返回任何标准格式。

注意

如果解码器不返回任何标准格式,则它不能用于播放 增强视频呈现器。 在这种情况下,应将其注册为仅转码解码器。 请参阅 Transcode-Only 解码器

 

编写自定义 MFT

实现编解码器 MFT

媒体基础转换