I’m going to assume some familiarity with DirectShow and how it works, but if miss that mark and don’t explain something that isn’t common knowledge please let me know and I’ll dig into it further. There is a ton of really good information about DirectShow on MSDN and other places, so I don’t want to spend too much time explaining topics that have already been covered.
DirectShow uses graphs (where the graph in GraphEdit comes from) to control playback, applications add filters to the graph to actually render the content. Filters do all the work in a graph; extracting data from the container (mkv, asf, dvr-ms, etc), decoding it, and rendering it. They can do much more complex things, but in a simple playback graph that’s pretty much all there is too it.
When an application builds the playback graph, it can explicitly add all the filters, rely completely on DirectShow’s Intelligent Connect (IC) feature, or a little of both. Relying completely on IC isn’t very practical and often leads to undesirable results in an application, but for those applications that try to support a wide variety of media types it is an essential feature.
When using IC, the graph orders filters by merit and tests them to see if they support the type it’s looking for before allowing it to actually join the graph. Given this, it’s easy to see that merit is an essential part of controlling how the playback graph gets built. And it’s also a source of frustration when, after installing a new application, suddenly everything that used to work flawlessly doesn’t.
Simply, merit is a number. Since the graph tests filters in order according to merit (highest to lowest), the higher the number, the more likely it is that a particular filter will join the graph. Not all software venders are considerate to the ecosystem they are getting installed into and assign very high merit numbers to their filters (cough, ArcSoft) which then overrides the filter that used to get loaded.
DirectShow was designed to allow applications a way to provide “hints” to IC by adding filters to the graph before using IC to build the graph. When there are unconnected filters in the graph, it will temporarily ignore the normal merit based process and give them preference over a filter with higher merit that is not in the graph. Adding a filter in this way doesn’t guarantee that it will get used (even if it can decode the stream); only make it much more likely. Let’s ignore this scenario for now, because even when using it, sometimes unexpected results occur and we’ll get to how to fix those cases after a simple example.
There are several tools for examining and modifying filter merit; I usually use GraphStudio. GraphStudio is an open source replacement for GraphEdit. For the most part it provides a richer, more polished experience making it a much better alternative. To modify filter merit, the application must be running in an administrative context (right-click and select “Run as administrator” if UAC is enabled). Then select Graph -> Insert Filter to display the Filter Browser.
After the browser opens, you will see a list of the DirectShow filters (other categories are browsable, but beyond the scope of this topic) listed in alpha order, to the right is the filters Merit value. The number is in hex, but don’t let that scare you select the filter that you want to modify and click the “Change merit” button. GraphStudio provides a nice interface to change the number, along with an easy to understand explanation of the number assigned. Some numbers won’t resolve to a defined constant, but those are usually the kind that needs to be brought into line anyway, so it’s not a problem.
Now that we’re comfortable examining and changing Merit, let’s fix a common problem. OOTB Vista (versions with MC) provides a MPEG and Dolby Digital decoder that supports SPDIF pass-through. In most cases this is the filter that I want to render all audio streams of that type, before installing ArcSoft TME everything works the way I want without needing to intervene. Unfortunately, TME’s audio decoders are installed with obscenly hight merit values so now any time IC is used their decoders join instead of the MS one.
Before adjusting the merit, it’s worthwhile to discuss how to figure out problem cases like the one above. Generally, you’ll just notice that something isn’t right (HWA or AC3 pass-through is broken for e.g.); but it’s not always obvious what is causing the problem. So when something breaks, I find the easiest way to see why is to open up GraphStudio (or GraphEdit) and drop a sample file on it. IC will render the file for playback, and the culprit should identify itself.
Back to fixing the audio problem, open up GraphStudio (as an admin) and browse to the MS MPEG decoder. Looking at the merit value we can see that it’s already less likely to join a graph. Let’s give it a little bump, and then go look at the ArcSoft decoder and assign it a lower merit value.
I don’t generally like to go too low unless a filter is particularly offensive (although in that case you could always regsvr32 /u it, but then you risk breaking the application that installed the offending filter). As you can see, the default merit for the ArcSoft decoder is ridiculously high, choosing a more realistic value should get things back to normal.
It’s important to note that changing a filter’s merit probably won’t have an immediate effect. At the very least you will need to exit and re-launch it to see a difference, but in many cases it is necessary to log off before the change will register.
Occasionally, adjust the decoder’s merit doesn’t fix the problem; and here’s where adjusting merit gets complicated. Where there is a media type incompatibility between a filter earlier in the chain (generally the demultiplexer / splitter) and the decoder, the change really needs to be made to that filter instead.
As an example, I have PowerDVD 7 and ArcSoft TME installed on my extender PC which uses Intel G45HD graphics. In order to get smooth playback for H.264 and VC-1 content, I need to split between the two application's filters to get hardware acceleration (HWA) to work properly (ArcSoft’s H.264 decoder doesn’t do HWA on G45HD; and Cyberlink’s VC-1 decoder produces jerky playback, even when HWA is working, on all my PCs). There are a couple complicating factors taking the simple approach; first ArcSoft’s video decoder is an all-in-one filter (i.e. one filter decodes H.264, MPEG-2, VC-1) so we can’t modify the filter’s merit too low or it won’t join the graph when we need it, and second the ArcSoft decoder won’t connect to the Cyberlink demulipexer or vice versa. Getting the Cyberlink H.264 filter to always take preference was easy, set the merit to MERIT_PREFERRED and it worked every time. Leaving the ArcSoft’s merit alone (MERIT_NORMAL) and setting the Cyberlink VC-1 decoder to MERIT_UNLIKELY did not solve the issue because Cyberlink’s demultipexer had a merit above MERIT_NORMAL, and the ArcSoft demulitplexer was marked with MERIT_UNLIKELY. The solution in this case was to set the two demulitplexer’s merit equal (I went with MERIT_NORMAL), and setting the Cyberlink VC-1 decoder to MERIT_DO_NOT_USE.
Getting everything right does take some trial and error, so don't get frustrated when it doesn't work the first time out (having to log off/on does make it any less frustrating :)).