The case of incorrect behavior of stock DirectX Media Objects

Since Microsoft Windows Vista, Media Foundation API offers a set of convenient Digital Signal Processors for video and audio processing. These include conversion helpers for video and audio, dual interfaced as Media Foundation Transforms (MFTs) and DirectX Media Objects (DMOs). Earlier posts shed some light on DMO interfaces, and use of DMOs in DirectShow graphs with the help of DMO Wrapper Filter.

It appears, however, that some of the stock DMOs are exhibiting unexpected behavior in part of setting media types for input and output streams. IMediaObject::SetInputType and IMediaObject::SetOutputType methods are not only expected to set media types, but also test and clear them depending on flags passed in arguments:

There are three modes defined, depending on value of dwFlags parameter:

  • 0 – [test and] set media type
  • DMO_SET_TYPEF_TEST_ONLY – test only media type
  • DMO_SET_TYPEF_CLEAR – clear media type already set

When the DMO backs a DirectShow filter through DMO Wrapper Filter, there might be (and there definitely are in case of interactive operation in GraphEdit-like application) tests and sets, and resets too during pipeline building stage, and correct support for all flags is important for proper operation.

Unfortunately, some DMOs do not honor the flags and implement incorrect behavior. In particular,

  • Color Converter DSP (CLSID_CColorConvertDMO) does not do it right withDMO_SET_TYPEF_TEST_ONLY and is unable to test media types – instead it sets them
  • Video Resizer DSP (CLSID_CResizerDMO) does it even worse: it ignores both DMO_SET_TYPEF_TEST_ONLY and DMO_SET_TYPEF_CLEAR and attempts to set the media type even if the request was to clear

The project below (SVN, Trac) demonstrates the problem in action.

An attempt to test and print current media type shows that testing actually sets the media type:

const HRESULT nTrySetInputTypeResult = pMediaObject->SetInputType(0, &InputMediaType, DMO_SET_TYPEF_TEST_ONLY);
_tprintf(_T("nTrySetInputTypeResult 0x%08x\n"), nTrySetInputTypeResult);
PrintInputType(pMediaObject, DMO_E_TYPE_NOT_SET, _T("we only tested, we did not set it"));

Output:

nTrySetInputTypeResult 0x00000000
nGetInputCurrentTypeResult 0x00000000 <<--- Incorrect, we only tested, we did not set it
Input: biWidth 1920, biHeight 1080

An attempt to clear produces a failure, since it is treated as an attempt to set and no real media type was passed as an argument:

const HRESULT nResetInputTypeResult = pMediaObject->SetInputType(0, NULL, DMO_SET_TYPEF_CLEAR);
_tprintf(_T("nResetInputTypeResult 0x%08x%s\n"), nResetInputTypeResult, FAILED(nResetInputTypeResult) ? _T(" <<--- Incorrect") : _T(""));

Output:

nResetInputTypeResult 0x80004003 <<--- Incorrect

The problem is posted to Microsoft Connect as Digital Signal Processors do not honor flags arguments on DMO interface IMediaObject when setting input/output types where you can upvote it if you suffer from the bug, and also read back from Microsoft when they follow up.

Leave a Reply