协商媒体类型

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

当 Filter Graph 管理器调用 IPin::Connect 方法时,它具有多个用于指定媒体类型的选项:

  • 完整类型: 如果完全指定了媒体类型,引脚将尝试与该类型连接。 如果不能,则连接尝试将失败。
  • 部分媒体类型: 如果主要类型、子类型或格式类型GUID_NULL,则媒体类型是 部分 的。 值GUID_NULL充当“通配符”,指示任何值都可以接受。 引脚协商与分部类型一致的类型。
  • 无媒体类型: 如果筛选器关系图管理器传递 NULL 指针,则引脚可以同意两个引脚都能接受的任何媒体类型。

如果引脚确实连接,则连接始终具有完整的媒体类型。 筛选器关系图管理器提供的媒体类型的用途是限制可能的连接类型。

在协商过程中,输出引脚通过调用输入引脚的 IPin::ReceiveConnection 方法来建议媒体类型。 输入引脚可以接受或拒绝建议的类型。 此过程将重复,直到输入引脚接受类型,或者输出引脚的类型用完并且连接失败。

输出引脚如何选择要建议的媒体类型取决于实现。 在 DirectShow 基类中,输出引脚在输入引脚上调用 IPin::EnumMediaTypes 。 此方法返回枚举器,该枚举器枚举输入引脚的首选媒体类型。 否则,输出引脚将枚举其自己的首选类型。

使用媒体类型

在接收 AM_MEDIA_TYPE 参数的任何函数中,始终在取消引用 pbFormat 成员之前验证 cbFormatformattype 的值。 以下代码不正确:

if (pmt->formattype == FORMAT_VideoInfo)
{
    VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    // Wrong!
}

以下代码正确:

if ((pmt->formattype == FORMAT_VideoInfo) && 
    (pmt->cbFormat > sizeof(VIDEOINFOHEADER) &&
    (pbFormat != NULL))
{
    VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    // Now you can dereference pVIH.
}