Filtros de controlador de clase WDM
[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEnginey captura de audio y 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 captura de audio y vídeo 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.
Si un dispositivo de captura usa un controlador de Windows Driver Model (WDM), el gráfico podría requerir determinados filtros ascendentes desde el filtro de captura. Estos filtros se denominan filtros de controlador de clase de flujo o filtros WDM. Admiten funcionalidad adicional proporcionada por el hardware. Por ejemplo, una tarjeta de sintonizador de TV tiene funciones para establecer el canal. El filtro correspondiente es el filtro de de tuner tv, que expone la interfazIAMTVTuner. Para que esta funcionalidad esté disponible para la aplicación, debe conectar el filtro de sintonizador de TV al filtro de captura.
La interfaz ICaptureGraphBuilder2 proporciona la manera más fácil de agregar filtros WDM al grafo. En algún momento al compilar el gráfico, llame a findInterface o RenderStream. Cualquiera de estos métodos localizará automáticamente los filtros WDM necesarios y los conectará al filtro de captura. En el resto de esta sección se describe cómo agregar filtros WDM manualmente. Sin embargo, tenga en cuenta que el enfoque recomendado es simplemente llamar a uno de estos métodos ICaptureGraphBuilder2.
Las patillas de un filtro WDM admiten uno o varios medios. Un medio define un método de comunicación, como un bus. Debe conectar patillas que admitan el mismo medio. La estructura REGPINMEDIUM, que es equivalente a la estructura de KSPIN_MEDIUM usada para los controladores de streaming de kernel, define un medio en DirectShow. El miembro clsMedium del REGPINMEDIUM estructura especifica el identificador de clase (CLSID) del medio. Para recuperar el medio de un pin, llame al método IKsPin::KsQueryMediums. Este método devuelve un puntero a un bloque de memoria que contiene una estructura de KSMULTIPLE_ITEM, seguida de cero o más estructuras REGPINMEDIUM. Cada estructura REGPINMEDIUM identifica un medio que admite la patilla.
No conecte un pin si el medio tiene un CLSID de GUID_NULL o KSMEDIUMSETID_Standard. Estos son valores predeterminados que indican que el pin no admite medios.
Además, no conecte un pin a menos que el filtro requiera exactamente una instancia conectada de ese pin. De lo contrario, la aplicación podría intentar conectar varios pines que no deben tener conexiones, lo que puede hacer que el programa deje de responder. Para averiguar el número de instancias necesarias, recupere el conjunto de propiedades KSPROPERTY_PIN_NECESSARYINSTANCES, como se muestra en el ejemplo de código siguiente. (Por motivos de brevedad, este ejemplo no prueba ningún código de retorno ni libera ninguna interfaz. La aplicación debe hacer ambas cosas, por supuesto).
// Obtain the pin factory identifier.
IKsPinFactory *pPinFactory;
hr = pPin->QueryInterface(IID_IKsPinFactory, (void **)&pPinFactory);
ULONG ulFactoryId;
hr = pPinFactory->KsPinFactory(&ulFactoryId);
// Get the "instance" property from the filter.
IKsControl *pKsControl;
hr = pFilter->QueryInterface(IID_IKsControl, (void **)&pKsControl);
KSP_PIN ksPin;
ksPin.Property.Set = KSPROPSETID_Pin;
ksPin.Property.Id = KSPROPERTY_PIN_NECESSARYINSTANCES;
ksPin.Property.Flags = KSPROPERTY_TYPE_GET;
ksPin.PinId = ulFactoryId;
ksPin.Reserved = 0;
KSPROPERTY ksProp;
ULONG ulInstances, bytes;
pKsControl->KsProperty((PKSPROPERTY)&ksPin, sizeof(ksPin),
&ulInstances, sizeof(ULONG), &bytes);
if (hr == S_OK && bytes == sizeof(ULONG))
{
if (ulInstances == 1)
{
// Filter requires one instance of this pin.
// This pin is OK.
}
}
El pseudocódigo siguiente es un esquema extremadamente breve que muestra cómo buscar y conectar los filtros WDM. Omite muchos detalles y solo está pensado para mostrar los pasos generales que tendría que realizar la aplicación.
Add supporting filters:
{
foreach input pin:
skip if (pin is connected)
Get pin medium
skip if (medium is GUID_NULL or KSMEDIUMSETID_Standard)
Query filter for KSPROPERTY_PIN_NECESSARYINSTANCES property
skip if (necessary instances != 1)
Match an existing pin || Find a matching filter
}
Match an existing pin:
{
foreach filter in the graph
foreach unconnected pin
Get pin medium
if (mediums match)
connect the pins
}
Find a matching filter:
{
Query the filter graph manager for IFilterMapper2.
Find a filter with an output pin that matches the medium.
Add the filter to the graph.
Connect the pins.
Add supporting filters. (Recursive call.)
}
Temas relacionados