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::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
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 with
DMO_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_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"));
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(""));
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.