Microsoft DirectX 9.0

Setting Media Types on a DMO

Before a DMO can process any data, the client must set the media type for each stream. (There is one minor exception to this rule; see Optional Streams.) To find the number of streams, call the IMediaObject::GetStreamCount method:

DWORD cInput = 0, cOutput = 0;
pDMO->GetStreamCount(&cInput, &cOutput);

This method returns two values, the number of inputs and the number of outputs. These values are fixed for the lifetime of the DMO.

Preferred Types

For every stream, the DMO assigns a list of possible media types, in order of preference. For example, the preferred types might be 32-RGB, 24-bit RGB, and 16-bit RGB, in that order. When the client sets the media types, it can use these lists as a hint. To retrieve a preferred type for a stream, call the IMediaObject::GetInputType method or IMediaObject::GetOutputType method. Specify the stream number and an index value for the type (starting from zero). For example, the following code retrieves the first preferred type from the first input stream:

DMO_MEDIA_TYPE mt
hr = pDMO->GetInputType(0, 0, &mt)
if (SUCCEEDED(hr))
{
    // Examine this media type (not shown).
    /* ... */

    // Free the format block.
    MoFreeMediaType(&mt);
}

To enumerate all of the preferred media types on a given stream, use a loop that increments the type index until the method returns DMO_E_NO_MORE_ITEMS, as shown in the following example:

DMO_MEDIA_TYPE mt;
DWORD iType = 0;
while (hr = pDMO->GetInputType(0, iType, &mt), SUCCEEDED(hr))
{
    // Examine this media type (not shown).
    /* ... */

    // Free the format block.
    MoFreeMediaType(&mt);
    ++dwType;
}

You should note the following points about preferred types:

In short, the client should treat the preferred types as guidelines only. The only way to know for certain which types are supported is to test them, as described in the next section.

Setting the Media Type on a Stream

Use the IMediaObject::SetInputType and IMediaObject::SetOutputType methods to set the type for each stream. You must provide a DMO_MEDIA_TYPE structure that contains a complete description of the media type. The following example sets the media type on input stream 0, using 44.1-kHz 16-bit stereo PCM audio:

DMO_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(DMO_MEDIA_TYPE));
// Allocate memory for the format block.
HRESULT hr = MoInitMediaType(&mt, sizeof(WAVEFORMATEX));
if (SUCCEEDED(hr))
{
    // Set the type GUIDs.
    mt.majortype  = MEDIATYPE_Audio;
    mt.subtype    = MEDIASUBTYPE_PCM;
    mt.formattype = FORMAT_WaveFormatEx;

    // Initialize the format block.
    WAVEFORMATEX *pWave = reinterpret_cast<WAVEFORMATEX*>(mt.pbFormat);
    pWave->wFormatTag = WAVE_FORMAT_PCM;
    pWave->nChannels = 2;
    pWave->nSamplesPerSec = 44100;
    pWave->wBitsPerSample = 16;
    pWave->nBlockAlign = (pWave->nChannels * pWave->wBitsPerSample) / 8;
    pWave->nAvgBytesPerSec = pWave->nSamplesPerSec * pWave->nBlockAlign;
    pWave->cbSize = 0;

    // Set the media type.
    hr = pDMO->SetInputType(0, &mt, 0); 

    // Release the format block.
    MoFreeMediaType(&mt);
}

To test a media type without setting it, call SetInputType or SetOutputType with the DMO_SET_TYPEF_TEST_ONLY flag. The method returns S_OK if the type is acceptable, or S_FALSE otherwise:

if (S_OK == pDMO->SetInputType(DMO_SET_TYPEF_TEST_ONLY, &mt, 0)
{
    // Media type is OK.
}

Because the settings on one stream can affect another stream, you might need to clear a stream's media type. To do this, call SetInputType or SetOutputType with the DMO_SET_TYPEF_CLEAR flag.

For a decoder DMO, the client would typically set the input type first, and then choose an output type. For an encoder DMO, the client would set the output type first, and then the input type.