Filtri dei driver di classe WDM

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation invece di DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

Se un dispositivo di acquisizione usa un driver WDM (Windows Driver Model), il grafico potrebbe richiedere determinati filtri upstream dal filtro di acquisizione. Questi filtri sono denominati filtri driver di classe di flusso o filtri WDM. Supportano funzionalità aggiuntive fornite dall'hardware. Ad esempio, una scheda di tuner TV ha funzioni per l'impostazione del canale. Il filtro corrispondente è il filtro tuner TV , che espone l'interfaccia IAMTVTuner . Per rendere disponibile questa funzionalità all'applicazione, è necessario connettere il filtro Tuner tv al filtro di acquisizione.

L'interfaccia ICaptureGraphBuilder2 offre il modo più semplice per aggiungere filtri WDM al grafo. A un certo punto durante la compilazione del grafico, chiamare FindInterface o RenderStream. Uno di questi metodi individua automaticamente i filtri WDM necessari e li connette al filtro di acquisizione. Nella parte restante di questa sezione viene descritto come aggiungere manualmente filtri WDM. Tuttavia, tenere presente che l'approccio consigliato consiste semplicemente nel chiamare uno di questi metodi ICaptureGraphBuilder2 .

I pin in un filtro WDM supportano uno o più supporti. Un supporto definisce un metodo di comunicazione, ad esempio un bus. È necessario connettere i pin che supportano lo stesso supporto. La struttura REGPINMEDIUM , equivalente alla struttura KSPIN_MEDIUM usata per i driver di streaming del kernel, definisce un supporto in DirectShow. Il membro clsMedium della struttura REGPINMEDIUM specifica l'identificatore di classe (CLSID) per il supporto. Per recuperare il supporto di un pin, chiamare il metodo IKsPin::KsQueryMediums . Questo metodo restituisce un puntatore a un blocco di memoria che contiene una struttura KSMULTIPLE_ITEM , seguita da zero o più strutture REGPINMEDIUM . Ogni struttura REGPINMEDIUM identifica un supporto supportato dal pin.

Non connettere un pin se il supporto ha un CLSID di GUID_NULL o KSMEDIUMSETID_Standard. Si tratta di valori predefiniti che indicano che il pin non supporta supporti.

Inoltre, non connettere un pin a meno che il filtro non richieda esattamente un'istanza connessa del pin. In caso contrario, l'applicazione potrebbe tentare di connettere vari pin che non devono avere connessioni, il che può causare l'interruzione della risposta del programma. Per individuare il numero di istanze necessarie, recuperare il set di proprietà KSPROPERTY_PIN_NECESSARYINSTANCES, come illustrato nell'esempio di codice seguente. (Per brevità, questo esempio non testa i codici restituiti o rilascia alcuna interfaccia. L'applicazione deve eseguire entrambe le operazioni, naturalmente.

// 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.
    } 
}

Lo pseudocodice seguente è una struttura estremamente breve che illustra come trovare e connettere i filtri WDM. Omette molti dettagli ed è destinato solo a mostrare i passaggi generali necessari per l'applicazione.

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.)
}

Argomenti relativi all'acquisizione avanzata