See beginning in microsoft.public.win32.programmer.directx.video newsgroup.

This sample is demonstrating COM aggregation to embed an existing filter an re-expose it as a new filter having inner filter pre-initialized.

The Visual Studio C++.NET 2008 projects contains a DirectShow filter class that registers itself under Video Capture Sources category and embeds File Source (Async) Filter inside initialized to stream clock.avi file from Windows directory.

The code of interest is in Filter.h. CFilter class is the implementation of the DirectShow filter.

CFilter registers itself as a filter through static UpdateRegistry method, which overrides stock DECLARE_REGISTRY_RESOURCEID macro and adds IFilterMapper2 interface calls to register/unregister the filter.

To take an advantage of aggregating another object we need DECLARE_PROTECT_FINAL_CONSTRUCT macro to be able to instantiate inner (that is aggregated) object on the very start (we cannot do this right in constructor), DECLARE_GET_CONTROLLING_UNKNOWN macro to declare member menthod that exposes controlling unknown.

In a FinalConstruct method we instantiate aggregated object (note GetControllingUnknown() argument which indicates instantiating as aggregated):

ATLENSURE_SUCCEEDED(m_pInnerUnknown.CoCreateInstance(CLSID_AsyncReader, GetControllingUnknown()));

and initialize the object through IFileSourceFilter::Load. The inner object is ready and we are to expose its functionality as if implemented natively. We need to update object’s COM MAP for this:

BEGIN_COM_MAP(CFilter)
	COM_INTERFACE_ENTRY(IFilter)
	// NOTE: We still implement IDispatch through IFilter but we hide it to hopefully expose inner filter's IDispatch
	//COM_INTERFACE_ENTRY(IDispatch)
	// NOTE: We are hiding inner filter IFileSourceFilter to avoid GraphEdit prompts for file path on filter insertion
	COM_INTERFACE_ENTRY_NOINTERFACE(IFileSourceFilter)
	COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pInnerUnknown)
END_COM_MAP()

COM_INTERFACE_ENTRY_AGGREGATE_BLIND will expose all inner object interfaces (except mentioned higher on the map) to the outside world. And we explicitly suppress IFileSourceFilter through COM_INTERFACE_ENTRY_NOINTERFACE to prevent GraphEdit from discovering it and popping up a file dialog to select a source file.

Source code: DirectShowWrapperSourceFilterSample.01.zip (note that Release build binary is included)

Tags: , , , , , , ,