How To: Implement DirectShow Filter using DirectX Media Object DMO (Part 4: Merit)

Previously on the topic:

The implemented so far filter/DMO shown a problem related to its unexpectedly high “importance” in the system with the symptom of “auto-insertion” the filter when it is not necessary. For example, let us render an AVI file through Infinite Tee Pin Filter:

The problem is that DirectShow auto-inserts our Brightness/Contrast filter into the graph while it is obviously not expected, wanted or necessary:

The problem is high filter/DMO merit value and a popular YUY2 video format the filter is advertised to accept on input during DMO registration.

The merit is 0x00600800 and defined values are:

enum
{
    MERIT_PREFERRED     = 0x800000,
    MERIT_NORMAL        = 0x600000,
    MERIT_UNLIKELY      = 0x400000,
    MERIT_DO_NOT_USE    = 0x200000,
    MERIT_SW_COMPRESSOR = 0x100000,
    MERIT_HW_COMPRESSOR = 0x100050
};

So the filter’s merit is MERIT_NORMAL plus 0x800 DMO API adds to give DMOs an advantage over regular filters. If we followed merit choice guidelines (“A filter that should never be considered for ordinary playback should have a merit of MERIT_DO_NOT_USE or less“), we would have taken MERIT_DO_NOT_USE value or MERIT_UNLIKELY at the very most, because the nature of this filter is to provide additional processing feature when it is explicitly requested by the graph creator.

So in order to resolve the problem we need to override DMO’s default merit and review the registration step. To provide our own merit value for the filter, we need to create a REG_DWORD Merit value in advance under coclass registry key in HKEY_CLASSES_ROOT:

OLECHAR pszClassIdentifier[64] = { 0 };
ATLVERIFY(StringFromGUID2(GetObjectCLSID(), pszClassIdentifier, _countof(pszClassIdentifier)));
CRegKey Key;
CString sKeyName;
sKeyName.Format(_T("CLSID\\%ls"), pszClassIdentifier);
__C(HRESULT_FROM_WIN32(Key.Create(HKEY_CLASSES_ROOT, sKeyName)));
static const DWORD g_nMerit = MERIT_DO_NOT_USE;
__C(HRESULT_FROM_WIN32(Key.SetDWORDValue(_T("Merit"), g_nMerit)));

Note that another (even easier) way to pre-create this registry value is putting it into .RGS registration script file (MERIT_DO_NOT_USE = 0x00200000 = 2097152):

HKCR
{
	...
	NoRemove CLSID
	{
		ForceRemove {334BE85B-9DE4-4405-8EEE-9CBB2650F83D} = s 'BrightnessContrastObject Class'
		{
			...
			val Merit = d '2097152'

Source code: DmoBrightnessContrastSample.04.zip (note that Release build binary is included)

See also:

Continued by:

5 Replies to “How To: Implement DirectShow Filter using DirectX Media Object DMO (Part 4: Merit)”

  1. Hello

    I am trying to download the source code (DmoBrightnessContrastSample.04.zip) and I notice that all the download links (as well as the images) are broken.

    Could you please point me to the correct links, if any ?

    Thank you very much.

    Best,

    Benjamin Golinvaux (Belgium)

  2. Hi Roman,

    Great piece of work – your articles were a great help to me in implementing a DirectShow Filter using DMO. I downlooaded your code from the above link and it all worked great. Only one difference is that filter got registered in the “DMO Video Effects” category (as seen from GraphEdit). But as I in the screenshot in this article, your filter is between ACM Wrapper and Allocater fix which makes be believe that it goes in the “DirectShow Filters” category. I actually want my filter to go in the “DirectShow Filters” category but I can only do that when I change the category in your code and instead of DMOCATEGORY_VIDEO_EFFECT, I change the argument to DMOCATEGORY_VIDEO_DECODER in the DMORegister function (which makes sense as MSDN says as well). The only point I wanted to ask you is that how did you manage to have it go in the “DirectShow Filters” category while the DMORegister in your code still passes DMOCATEGORY_VIDEO_EFFECT as the argument. Is it due to some changes in a later version of DirectX SDK that I am probably using or did you change that in your code later on?

    Any other help or tip is greatly appreciated as well.

    Thanks,
    Shoaib.

  3. Is it due to some changes in a later version of DirectX SDK that I am probably using or did you change that in your code later on?

    For a DMO you are registering it with DMORegister (obviously) and it’s up to it where to actually register the filter. For example, Graph Edit and Graph Studio present filter lists in a bit different way: in particular DMO Decoders are shown separately by Graph Studio, while Graph Edit shows them under DirectShow Filters. I am not sure what is the reason:

    * one of the apps does it for presentation purposes
    * the apps enumerate differently and get different results

    I never investigated it myself, but my understanding is that Intelligent Connect itself is calling Filter Mapper‘s EnumMatchingFilters and it gives it the list of interest including DMOs (note this can be checked with my Spy). On the other hand you can always enumerate DMOs only using DMOEnum.

  4. Thanks for your feedback Roman.

    I actually wanted my filter to be pulled in always and I had gone even further ahead by registering it with MERIT_PREFERRED+1 merit but still Intelligent Connect didn’t pull it in by itself, unlike my expectations. That was my actual need to start with. Looking into MSDN and the Groups, the only reasoning I ended up with, was the Filter Category it is getting registered in and that the category’s merit is superseding the filter’s merit registered in it.

    Hence, because DirectShow Filters category has a merit of MERIT_NORMAL while the a DMO registered as …_VIDEO_EFFECT is either not mapped to any category (http://msdn.microsoft.com/en-us/library/dd375655.aspx), or the DMO Video Effects category in Graph Edit has a lower merit, Intelligent Connect is not pulling it in always. This prompted me to try registering it with …_VIDEO_DECODER to have it mapped to the DirectShow Filters and that actually resulted in the filter getting pulled in by Intelligent Connect.

    I have not used Graph Studio but whether DMO Decoders are shown separately or within DirectShow Filters, the case of DMO Video Effects still hangs uncertain as I saw your code registering it with that argument but it apparently ended up under DirectShow filters as it appeared to me from the screenshot in this article. But I just thought I might be actually wrong in assuming that the screenshot is from Graph Edit :)

Leave a Reply