Uso del asignador de filtros

[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.

El asignador de filtros es un objeto COM que enumera los filtros DirectShow en función de varios criterios de búsqueda. El asignador de filtros puede ser menos eficaz que el enumerador de dispositivos del sistema, por lo que si necesita filtros de una categoría determinada, debe usar el enumerador de dispositivos del sistema. Pero si necesita buscar un filtro que admita una determinada combinación de tipos multimedia, pero no se encuentra en una categoría de corte claro, es posible que tenga que usar el asignador de filtros. (Un ejemplo sería un filtro de representador o un filtro de descodificador).

El asignador de filtros expone la interfaz IFilterMapper2 . Para buscar un filtro, llame al método IFilterMapper2::EnumMatchingFilters . Este método toma varios parámetros que definen los criterios de búsqueda y devuelve un enumerador para los filtros coincidentes. El enumerador admite la interfaz IEnumMoniker y proporciona un moniker único para cada filtro coincidente.

En el ejemplo siguiente se enumeran los filtros que aceptan entrada de vídeo digital (DV) y tienen al menos un pin de salida, de cualquier tipo de medio. (El filtro Descodificador de vídeo DV coincide con estos criterios).

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

El método EnumMatchingFilters tiene un número bastante grande de parámetros, que se comentan en el ejemplo. Entre los significativos de este ejemplo se incluyen:

  • Valor mínimo de mérito: el filtro debe tener un valor de mérito por encima de MERIT_DO_NOT_USE.
  • Tipos de entrada: el llamador pasa una matriz que contiene pares de tipos principales y subtipos. Solo coincidirán los filtros que admitan al menos uno de estos pares.
  • Coincidencia exacta: un filtro puede registrar valores NULL para el tipo principal, subtipo, categoría de patilla o medio. A menos que especifique la coincidencia exacta, un valor NULL actúa como carácter comodín y coincide con cualquier valor que especifique. Con coincidencia exacta, el filtro debe coincidir exactamente con los criterios. Sin embargo, si proporciona un parámetro NULL en los criterios de búsqueda, siempre actúa como un valor comodín o "no importa", que coincide con cualquier filtro.

Enumerar dispositivos y filtros

Conexión inteligente