Using the Filter Mapper
Microsoft DirectShow 9.0 |
The Filter Mapper is a COM object that enumerates filters based on various search criteria. The Filter Mapper is less efficient than the System Device Enumerator, so if you need filters from a particular category, you should use the System Device Enumerator. But if you need to locate a filter that supports a certain combination of media types, but does not fall into a clear-cut category, you might need to use the Filter Mapper. (An example would be a renderer filter or a decoder filter.)
The Filter Mapper exposes the IFilterMapper2 interface. To search for a filter, call the IFilterMapper2::EnumMatchingFilters method. This method takes several parameters that define the search criteria, and returns an enumerator for the matching filters. The enumerator supports the IEnumMoniker interface, and supplies a unique moniker for each matching filter.
The following example enumerates filters that accept digital video (DV) input and have at least one output pin, of any media type. (The DV Video Decoder filter matches these criteria.)
IFilterMapper2 *pMapper = NULL; IEnumMoniker *pEnum = NULL; hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC, IID_IFilterMapper2, (void **) &pMapper); if (FAILED(hr)) { // Error handling omitted for clarity. } GUID arrayInTypes[2]; arrayInTypes[0] = MEDIATYPE_Video; arrayInTypes[1] = MEDIASUBTYPE_dvsd; hr = pMapper->EnumMatchingFilters( &pEnum, 0, // Reserved. TRUE, // Use exact match? MERIT_DO_NOT_USE+1, // Minimum merit. TRUE, // At least one input pin? 1, // Number of major type/subtype pairs for input. arrayInTypes, // Array of major type/subtype pairs for input. NULL, // Input medium. NULL, // Input pin category. FALSE, // Must be a renderer? TRUE, // At least one output pin? 0, // Number of major type/subtype pairs for output. NULL, // Array of major type/subtype pairs for output. NULL, // Output medium. NULL); // Output pin category. // Enumerate the monikers. IMoniker *pMoniker; ULONG cFetched; while (pEnum->Next(1, &pMoniker, &cFetched) == S_OK) { IPropertyBag *pPropBag = NULL; hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); if (SUCCEEDED(hr)) { // To retrieve the friendly name of the filter, do the following: VARIANT varName; VariantInit(&varName); hr = pPropBag->Read(L"FriendlyName", &varName, 0); if (SUCCEEDED(hr)) { // Display the name in your UI somehow. } VariantClear(&varName); // To create an instance of the filter, do the following: IBaseFilter *pFilter; hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter); // Now add the filter to the graph. Remember to release pFilter later. // Clean up. pPropBag->Release(); } pMoniker->Release(); } // Clean up. pMapper->Release(); pEnum->Release();
The EnumMatchingFilters method has a fairly large number of parameters, which are commented in the example. The significant ones for this example include:
- Minimum merit value: The filter must have a merit value above MERIT_DO_NOT_USE.
- Input types: The caller passes an array containing pairs of major types and subtypes. Only filters that support at least one of these pairs will match.
- Exact match: A filter can register NULL values for major type, subtype, pin category, or medium. Unless you specify exact matching, a NULL value acts as a wildcard, matching any value that you specify. With exact matching, the filter must exactly match your criteria. However, if you give a NULL parameter in the search criteria, it always acts as a wildcard or "don't care" value, matching any filter.