协商媒体类型

[与此页面关联的功能(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.
}