Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
A version of this page is also available for
4/8/2010

This topic describes how to make a DirectShow filter self-registering. It addresses the following subjects:

This topic does not describe how to create a DLL. For information about creating DLLs, see Creating a DLL in DirectShow.

Layout of the Registry Keys

The DLL that contains the filter is registered as the filter's COM server. When an application calls CoCreateInstanceto create the filter, the Microsoft Windows COM library uses this registry entry to locate the DLL.

The registry entry for the DLL is as follows. See %_WINCEROOT%\Public\DirectX\Oak\Files\DirectX.reg for further examples.

DirectShow filter DLLs are registered by their class ID values. The complete registry entry for a DirectShow filter DLL begins with the HKEY_CLASSES_ROOT\CLSID\ <Filter CLSID>key. The following table shows the values for this key.

Value : type Description

@: REG_SZ

No default setting. The value of the <Filter CLSID>subkey is the friendly name of the filter.

Merit: REG_DWORD

Filter merit value. Filters with higher merit values are enumerated first.

The registry key for the filter DLL's file is HKEY_CLASSES_ROOT\CLSID\ <Filter CLSID> \InprocServer32. The following table shows the values for this key.

Value : type Description

@: REG_SZ

No default setting. This is the file name of the filter DLL.

ThreadingModel: REG_SZ

You must set this value to "Both".

Each filter pin is registered with its own registry key. The registry key for a pin is HKEY_CLASSES_ROOT\CLSID\ <Filter CLSID> \Pins\ <Pin Name>. Many filters just use a single input pin named "Input" and a single output pin named "Output". The following table shows the possible values for a filter pin subkey.

Value : type Description

Direction: REG_DWORD

No default setting. Set this value to 0 for input pins and 1 for output pins.

IsRendered: REG_DWORD

No default setting. Set this value to 0 if the pin renders its data and set to 1 if it does not.

AllowedZero: REG_DWORD

No default setting. Set this value to 0 if the filter requires this pin to be connected and set to 1 if it does not.

AllowedMany: REG_DWORD

No default setting. Set this value to 0 if the filter can only have a single pin of this type and set to 1 if it can have many pins of this type.

ConnectsToPin: REG_SZ

No default setting. Set this value to the name of the pin that this pin connects to.

To register a media type and subtype that a pin supports, create the registry key HKEY_CLASSES_ROOT\CLSID\ <Filter CLSID> \Pins\ <Pin Name> \Types\{ <Major type GUID> }\{ <Subtype GUID> }. Use a subtype GUID of 00000000-0000-0000-0000-000000000000 (GUID_NULL) to indicate that the pin can be queried to accept connections with any subtype within the major type. A pin can have multiple entries for the Typessubkey and a filter can have multiple pins.

The graph builder tries to assemble the correct filters to play back a specified source media during the intelligent connect process in the IGraphBuilder::RenderFilemethod. For more information, see Graph Building with Intelligent Connect. The graph builder enumerates the filter CLSIDs listed under the HKEY_CLASSES_ROOT\Filter\ <Filter CLSID>registry key to find candidates for the filter graph. The following table shows the allowable values for this key.

Value : type Description

@: REG_SZ

No default setting. The value of the <Filter CLSID>subkey is the friendly name of the filter.

The HKEY_CLASSES_ROOT\CLSID\ <Filter CLSID>registry key and subkeys are required to expose your filter to DirectShow and therefore make it available to applications through COM interfaces. The HKEY_CLASSES_ROOT\Filter\ <Filter CLSID>is only required if you want to make your filter to be discoverable by the intelligent connect process.

The following example shows a filter graph registry entry from DirectX.reg.

Copy Code
; DV Video Codec

[HKEY_CLASSES_ROOT\Filter\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}]
@="DV Video Decoder"

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}]
@="DV Video Decoder"
"Merit"=dword:00600000

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\InprocServer32]
@="quartz.DLL"
"ThreadingModel"="Both"

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins]

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins\Input]
"Direction"=dword:00000000
"IsRendered"=dword:00000000
"AllowedZero"=dword:00000000
"AllowedMany"=dword:00000000
"ConnectsToPin"="Output"

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins\Input\Types]

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins\Input\Types\{73646976-0000-0010-8000-00AA00389B71}]

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins\Input\Types\{73646976-0000-0010-8000-00AA00389B71}\]

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins\Input\Types\{73646976-0000-0010-8000-00AA00389B71}\{00000000-0000-0000-0000-000000000000}]

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins\Output]
"Direction"=dword:00000001
"IsRendered"=dword:00000000
"AllowedZero"=dword:00000000
"AllowedMany"=dword:00000000
"ConnectsToPin"="Input"

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins\Output\Types]

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins\Output\Types\{73646976-0000-0010-8000-00AA00389B71}]

[HKEY_CLASSES_ROOT\CLSID\{B1B77C00-C3E4-11cf-AF79-00AA00B67A42}\Pins\Output\Types\{73646976-0000-0010-8000-00AA00389B71}\{00000000-0000-0000-0000-000000000000}]

Registering a Filter

One can either register filters statically at run-time image creation time by adding appropriate entries to the Platform.reg file or dynamically as follows. Note that if the registry on the device in not in non-volatile RAM and one is registering filters dynamically, that Regsrv32.exe or RegsvrCE.exe must be explicitly called every time the registry information is lost or the filters will not be found by RenderFileand COM.

To register a filter
  1. Declare filter information.

  2. In the factory template for the filter, include a pointer to the filter information.

  3. Implement the DllRegisterServerfunction.

The sections that follow describe these steps in detail.

Declare Filter Information

The first step is to declare the filter information. DirectShow defines a set of structures for describing filters, pins, and media types.

Structure Description

AMOVIESETUP_FILTER

Describes a filter.

AMOVIESETUP_PIN

Describes a pin.

AMOVIESETUP_MEDIATYPE

Describes a media type.

These structures are nested. The AMOVIESETUP_FILTER structure has a pointer to an array of AMOVIESETUP_PIN structures, and each AMOVIESETUP_PIN structure has a pointer to an array of AMOVIESETUP_MEDIATYPE structures.

The structures provide enough information for the IFilterMapperinterface to locate a filter. They are not a complete description of a filter. For example, if the filter creates multiple instances of the same pin, declare one AMOVIESETUP_PIN structure for that pin. Also, a filter is not required to support every combination of media types that it registers.

Declare these structures as global variables within your DLL. The following example shows a filter with one output pin.

Copy Code
static const WCHAR g_wszName[] = L"Some Filter";

AMOVIESETUP_MEDIATYPE sudMediaTypes[] = {
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_RGB24 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_RGB32 },
};

AMOVIESETUP_PIN sudOutputPin = {
	L"Output", // Pin string name.
	FALSE, 	// Is this pin rendered?
	TRUE, 	 // Is it an output pin?
	FALSE, 	// Can the filter create zero instances?
	FALSE, 	// Does the filter create multiple instances?
	&GUID_NULL,  // Connects to filter.
	NULL, 	 // Connects to pin.
	2, 		// Number of media types.
	sudMediaTypes   // Pointer to media types.
};

AMOVIESETUP_FILTER sudFilterReg = {
	&CLSID_SomeFilter, // Filter CLSID.
	g_wszName, 		// Filter name.
	MERIT_NORMAL, 	 // Merit.
	1, 				// Number of pin types.
	&sudPins				// Pointer to pin information.
};

The filter name is declared as a static global variable, because it will be used again elsewhere.

Your filter must also override the base class GetSetupDatamethod to return the setup data structure as shown.

Copy Code
LPAMOVIESETUP_FILTER CSomeFilter::GetSetupData() 
{
	return (LPAMOVIESETUP_FILTER) & sudFilterReg;
}

Declare the Factory Template

The next step is to declare the factory template for your filter. A factory template is a C++ class that contains information for the class factory. In your DLL, declare a global array of factory templates, one for each filter or COM component in your DLL. The array must be named g_Templates. For more information about factory templates, see Creating a DLL in DirectShow.

The m_pAMovieSetup_Filtermember of the factory template is a pointer to the AMOVIESETUP_FILTERstructure described previously. The following example shows a factory template, using the structure given in the previous example.

Copy Code
CFactoryTemplate g_Templates[] =
{
	{
		g_wszName, 				// Name.
		&CLSID_SomeFilter, 		// CLSID.
		CSomeFilter::CreateInstance, // Creation function.
		NULL,
		&sudFilterReg				 // Pointer to filter
information.
}
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);

Implement DllRegisterServer

The final step is to implement the DllRegisterServerfunction. The DLL that contains the component must export this function. The function will be called by a set-up application, or when the user runs the Regsvr32.exe or RegsvrCE.exe tool.

The following example shows a minimal implementation of DllRegisterServer.

Copy Code
STDAPI DllRegisterServer(void)
{
	return AMovieDLLRegisterServer(TRUE);
}

The DirectShow function AMovieDLLRegisterServercreates registry entries for every component declared in the g_Templatesarray.

Filter categories introduced with AMovieDLLRegisterServer2are not currently supported on Windows Embedded CE.

Unregistering a Filter

To unregister a filter, implement the DllUnregisterServerfunction. Within this function, call the DirectShow function AMovieDLLUnregisterServer.

The following example shows how to unregister a filter.

Copy Code
STDAPI DllUnregisterServer()
{
	return AMovieDLLUnRegisterServer();
}

See Also