步骤 3: 支持媒体类型协商

[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayerIMFMediaEngine媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

这是 编写转换筛选器教程的步骤 3。

当两个引脚连接时,它们必须就连接的媒体类型达成一致。 媒体类型描述数据的格式。 如果没有媒体类型,筛选器可能会提供一种数据,而只让另一个筛选器将其视为其他数据。

协商媒体类型的基本机制是 IPin::ReceiveConnection 方法。 输出引脚使用建议的媒体类型在输入引脚上调用此方法。 输入引脚接受或拒绝连接。 如果它拒绝连接,输出引脚可以尝试其他媒体类型。 如果未找到合适的类型,连接将失败。 (可选)输入引脚可以通过 IPin::EnumMediaTypes 方法播发它喜欢的类型列表。 输出引脚在建议媒体类型时可以使用此列表,尽管它不必这样做。

CTransformFilter 类为此过程实现一个常规框架,如下所示:

  • 输入引脚没有首选媒体类型。 它完全依赖于上游筛选器来建议媒体类型。 对于视频数据,这是有意义的,因为媒体类型包括图像大小和帧速率。 通常,该信息必须由上游源筛选器或分析程序筛选器提供。 对于音频数据,可能的格式集较小,因此输入引脚提供一些首选类型可能很实用。 在这种情况下,请替代输入引脚上的 CBasePin::GetMediaType
  • 当上游筛选器建议媒体类型时,输入引脚将调用 CTransformFilter::CheckInputType 方法,该方法接受或拒绝该类型。
  • 除非先连接输入引脚,否则输出引脚不会连接。 此行为是转换筛选器的典型行为。 在大多数情况下,筛选器必须先确定输入类型,然后才能设置输出类型。
  • 当输出引脚连接时,它具有向下游筛选器建议的媒体类型列表。 它调用 CTransformFilter::GetMediaType 方法来生成此列表。 输出引脚还将尝试下游筛选器建议的任何媒体类型。
  • 为了检查特定输出类型是否与输入类型兼容,输出引脚调用 CTransformFilter::CheckTransform 方法。

前面列出的三个 CTransformFilter 方法是纯虚拟方法,因此派生类必须实现它们。 这些方法都不属于 COM 接口;它们只是基类提供的实现的一部分。

以下部分更详细地描述了每种方法:

筛选器连接方式

编写 DirectShow 筛选器