示例视频 DSP 插件中的视频格式协商

在Windows 媒体播放器将视频 DSP 插件插入信号链之前,播放器必须确定该插件是否可以处理正在播放的视频。 插件和播放器就支持的视频格式进行通信的过程称为格式协商。

提供支持的输入和输出类型

如果 DSP 插件充当 DirectX Media 对象 (DMO) ,则播放器会通过对 IMediaObject::GetInputType 和 IMediaObject::GetOutputType 进行一系列调用来查询插件支持的格式。

如果 DSP 插件充当媒体基础转换 (MFT) ,则播放器会通过对 IMFTransform::GetInputAvailableType 和 IMFTransform::GetOutputAvailableType 进行一系列调用来查询其支持的格式。

Windows 媒体播放器插件向导生成的示例视频插件将受支持的视频格式列表存储为 GUID 数组。 以下代码来自主 .cpp 文件:

static const GUID*    k_guidValidSubtypes[] = {
    &MEDIASUBTYPE_NV12,
    &MEDIASUBTYPE_YV12,
    &MEDIASUBTYPE_YUY2,
    &MEDIASUBTYPE_UYVY,
    &MEDIASUBTYPE_RGB32,
    &MEDIASUBTYPE_RGB24,
    &MEDIASUBTYPE RGB555,
    &MEDIASUBTYPE RGB565
};

玩家可以按任意顺序调用 IMediaObject::GetInputTypeIMediaObject::GetOutputType ,因此插件代码必须预测这一点。 同样,玩家可以按任意顺序调用 IMFTransform::GetInputAvailableTypeIMFTransform::GetOutputAvailableTypeGetOutputType 和 GetOutputAvailableType 的示例实现测试是否已定义输入类型。 如果有,该插件将响应它仅支持该类型。 否则,插件将返回与提供的索引对应的类型,如以下代码所示:

// If input type has been defined, then use that as output type.
if (GUID_NULL != m_mtInput.majortype)
{
    hr = ::MoCopyMediaType( pmt, &m_mtInput );
}
else // Otherwise use default for this plug-in.
{
    ::ZeroMemory( pmt, sizeof( DMO_MEDIA_TYPE ) );
    pmt->majortype = MEDIATYPE_Video;
    pmt->subtype = *k_guidValidSubtypes[dwTypeIndex];     
}

设置输入和输出类型

如果 DSP 插件充当DMO,Windows 媒体播放器通过调用 IMediaObject::SetInputTypeIMediaObject::SetOutputType 来设置媒体类型,并将指针传递给每个函数,该指针指向表示所请求媒体类型的DMO_MEDIA_TYPE结构。

如果 DSP 插件充当 MFT,Windows 媒体播放器通过调用 IMFTransform::SetInputTypeIMFTransform::SetOutputType 来设置媒体类型,并将指针传递给每个函数,该接口指向表示所请求媒体类型的 IMFMediaType 接口。

不能保证 Player 将按任何特定顺序调用格式协商方法,因此插件代码必须处理任何情况。 例如,如果播放器在调用 SetInputType 之前调用 SetOutputType,则插件拒绝建议的输出媒体类型是一个有效的操作过程。 IMediaObject::SetOutputType 的示例实现中的以下代码演示了以下内容:

if( GUID_NULL != m_mtInput.majortype )
{
    // Validate that the output media type matches our requirements 
    // and matches our input type (if set).
    hr = ValidateMediaType(pmt, &m_mtInput);
}
else
{
    hr = DMO_E_TYPE_NOT_ACCEPTED;
}

SetInputTypeSetOutputType 的示例插件实现调用名为 ValidateMediaType 的自定义函数。 此插件函数对建议的媒体类型执行一系列测试,旨在确保媒体类型格式良好且受插件支持。 ValidateMediaType 执行以下测试:

  • 验证 majortypeformattype 成员是否包含正确的值。
  • 验证 子类型 成员是否与受支持的格式之一匹配。
  • 验证 BITMAPINFOHEADERVIDEOINFOHEADER 或 VIDEOINFOHEADER2 结构中的信息是否包含有效值。
  • 测试输入和输出媒体类型是否匹配,因为插件不会将格式从输入转换为输出。

如果建议的媒体类型通过验证测试,则存储在成员变量中: m_mtInput 输入媒体类型, m_mtOutput 输出媒体类型。

实现视频 DSP 插件