使用筛选器映射器

[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayerIMFMediaEngine媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

筛选器映射器是一个 COM 对象,它基于各种搜索条件枚举 DirectShow 筛选器。 筛选器映射器的效率可能低于系统设备枚举器,因此,如果需要来自特定类别的筛选器,则应使用系统设备枚举器。 但是,如果需要查找支持某种媒体类型组合的筛选器,但不属于明文类别,则可能需要使用筛选器映射器。 (一个示例是呈现器筛选器或解码器筛选器。)

筛选器映射器公开 IFilterMapper2 接口。 若要搜索筛选器,请调用 IFilterMapper2::EnumMatchingFilters 方法。 此方法采用多个定义搜索条件的参数,并返回匹配筛选器的枚举器。 枚举器支持 IEnumMoniker 接口,并为每个匹配的筛选器提供唯一的名字对象。

以下示例枚举接受数字视频 (DV) 输入并具有至少一个任何媒体类型的输出引脚的筛选器。 (DV 视频解码器 筛选器匹配这些条件。)

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();

EnumMatchingFilters 方法具有相当多的参数,这些参数在示例中进行了注释。 此示例的重要内容包括:

  • 最小优点值:筛选器的功绩值必须高于 MERIT_DO_NOT_USE。
  • 输入类型:调用方传递包含主要类型和子类型对的数组。 只有至少支持其中一对的筛选器才会匹配。
  • 完全匹配:筛选器可以注册主要类型、子类型、引脚类别或介质的 NULL 值。 除非指定完全匹配, 否则 NULL 值充当通配符,与指定的任何值匹配。 使用完全匹配时,筛选器必须与条件完全匹配。 但是,如果在搜索条件中提供 NULL 参数,则它始终充当通配符或“不关心”值,与任何筛选器匹配。

枚举设备和筛选器

智能连接