DirectShow Filter Graph Spy – CLSID_FilterGraphNoThread

At the time of original implementation I intentionally left off a variation of Filter Graph Manager that runs on application thread, CLSID_FilterGraphNoThread. MSDN says:

CLSID_FilterGraphNoThread creates the Filter Graph Manager on the application’s thread. If you use this CLSID, the thread that calls CoCreateInstance must have a message loop that dispatches messages; otherwise, deadlocks can occur. Also, before the application thread exits, it must release the Filter Graph Manager and all graph objects (such as filters, pins, reference clocks, and so forth).

I have never needed to use this CLSID (by the way Windows SDK has one more CLSID – CLSID_FilterGraphPrivateThread – but it does not seem to be documented) and for this reason I left it for the time a need in it comes up. However it appeared that this CLSID was not created just for fun, there was a need in it. Filter graphs of Windows Media Player playing well known Windows’ clock.avi appeared to be not published on Running Object Table. Why?

Process Monitor showed clearly that Windows Media Player created filter graph through CLSID_FilterGraphNoThread and quite obviously it was not intercepted by Filter Graph Spy (still I wonder what made it different previous time when I could see WMP’s graph).

In order to extend spy’s support to CLSID_FilterGraphNoThread I moved most of the code from CSpy COM class into CSpyT template class and derived two COM classes from it, CSpy and CNoThreadSpy, in order to cover and “COM Treat As” both DirectShow/Quartz COM classes.

////////////////////////////////////////////////////////////
// CSpy

class ATL_NO_VTABLE CSpy :
    public CSpyT<CSpy, &CLSID_FilterGraph>,
    public CComCoClass<CSpy, &CLSID_Spy>
{
public:
    enum { IDR = IDR_SPY };

public:
// CSpy
};

OBJECT_ENTRY_AUTO(__uuidof(Spy), CSpy)

////////////////////////////////////////////////////////////
// CNoThreadSpy

class ATL_NO_VTABLE CNoThreadSpy :
    public CSpyT<CNoThreadSpy, &CLSID_FilterGraphNoThread>,
    public CComCoClass<CNoThreadSpy, &CLSID_NoThreadSpy>
{
public:
    enum { IDR = IDR_NOTHREADSPY };

public:
// CNoThreadSpy
};

OBJECT_ENTRY_AUTO(__uuidof(NoThreadSpy), CNoThreadSpy)

A partial Visual C++ .NET 2008 source code is available from SVN, release binary included.

Leave a Reply