Usando o Mapeador de Filtros

[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

O Mapeador de Filtro é um objeto COM que enumera filtros DirectShow com base em vários critérios de pesquisa. O Mapeador de Filtro pode ser menos eficiente do que o Enumerador de Dispositivo do Sistema, portanto, se você precisar de filtros de uma categoria específica, deverá usar o Enumerador de Dispositivo do Sistema. Mas se você precisar localizar um filtro que dê suporte a uma determinada combinação de tipos de mídia, mas não se enquadrar em uma categoria de corte claro, talvez seja necessário usar o Mapeador de Filtro. (Um exemplo seria um filtro de renderizador ou um filtro de decodificador.)

O Mapeador de Filtro expõe a interface IFilterMapper2 . Para pesquisar um filtro, chame o método IFilterMapper2::EnumMatchingFilters . Esse método usa vários parâmetros que definem os critérios de pesquisa e retorna um enumerador para os filtros correspondentes. O enumerador dá suporte à interface IEnumMoniker e fornece um moniker exclusivo para cada filtro correspondente.

O exemplo a seguir enumera filtros que aceitam entrada de vídeo digital (DV) e têm pelo menos um pino de saída, de qualquer tipo de mídia. (O filtro do Decodificador de Vídeo DV corresponde a esses critérios.)

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

O método EnumMatchingFilters tem um número bastante grande de parâmetros, que são comentados no exemplo. Os significativos para este exemplo incluem:

  • Valor mínimo de mérito: o filtro deve ter um valor de mérito acima de MERIT_DO_NOT_USE.
  • Tipos de entrada: o chamador passa uma matriz que contém pares de tipos e subtipos principais. Somente os filtros que dão suporte a pelo menos um desses pares corresponderão.
  • Correspondência exata: um filtro pode registrar valores NULL para o tipo principal, subtipo, categoria de pino ou médio. A menos que você especifique a correspondência exata, um valor NULL atua como um curinga, correspondendo a qualquer valor que você especificar. Com a correspondência exata, o filtro deve corresponder exatamente aos seus critérios. No entanto, se você fornecer um parâmetro NULL nos critérios de pesquisa, ele sempre atuará como um curinga ou valor "não se importe", correspondendo a qualquer filtro.

Enumerando dispositivos e filtros

Conexão Inteligente