Video Format Negotiation in the Sample Video DSP Plug-in

Before Windows Media Player inserts a video DSP plug-in into the signal chain, the Player must determine whether the plug-in can process the video being played. The process by which the plug-in and the Player communicate about supported video formats is called format negotiation.

Providing the Supported Input and Output Types

If the DSP plug-in is acting as a DirectX Media Object (DMO), the Player queries the plug-in about its supported formats by making a sequence of calls to IMediaObject::GetInputType and IMediaObject::GetOutputType.

If the DSP plug-in is acting as a Media Foundation Transform (MFT), the Player queries the plug-in about its supported formats by making a sequence of calls to IMFTransform::GetInputAvailableType and IMFTransform::GetOutputAvailableType.

The sample video plug-in generated by the Windows Media Player Plug-in Wizard stores the list of supported video formats as an array of GUIDs. The following code is from the main .cpp file:

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

The Player can call IMediaObject::GetInputType and IMediaObject::GetOutputType in any order, so the plug-in code must anticipate this. Similary, the Player can call IMFTransform::GetInputAvailableType and IMFTransform::GetOutputAvailableType in any order. The sample implementations of GetOutputType and GetOutputAvailableType test whether the input type has already been defined. If it has, the plug-in responds that it supports only that type. Otherwise, the plug-in returns the type that corresponds to the supplied index, as the following code demonstrates:

// 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];     
}

Setting the Input and Output Types

If the DSP plug-in is acting as a DMO, Windows Media Player sets the media type by calling IMediaObject::SetInputType and IMediaObject::SetOutputType, passing to each function a pointer to a DMO_MEDIA_TYPE structure that represents the requested media type.

If the DSP plug-in is acting as an MFT, Windows Media Player sets the media type by calling IMFTransform::SetInputType and IMFTransform::SetOutputType, passing to each function a pointer to an IMFMediaType interface that represents the requested media type.

There is no guarantee that the Player will call format negotiation methods in any particular order, so plug-in code must handle any case. For instance, if the Player calls SetOutputType before calling SetInputType, it is a valid course of action for the plug-in to reject the proposed output media type. The following code from the sample implementation of IMediaObject::SetOutputType demonstrates this:

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;
}

The sample plug-in implementations of SetInputType and SetOutputType call the custom function named ValidateMediaType. This plug-in function performs a series of tests on the proposed media type designed to ensure that the media type is well-formed and supported by the plug-in. ValidateMediaType performs the following tests:

  • Verifies that the majortype and formattype members contain the correct values.
  • Verifies that the subtype member matches one of the supported formats.
  • Verifies that the information in the BITMAPINFOHEADER and VIDEOINFOHEADER or VIDEOINFOHEADER2 structures contain valid values.
  • Tests whether the input and output media types match because the plug-in does not convert formats from input to output.

If the proposed media type passes the validation tests, it is stored in a member variable: m_mtInput for the input media type, m_mtOutput for the output media type.

Implementing a Video DSP Plug-in