Freigeben über


WDM-Klassentreiberfilter

[Das dieser Seite zugeordnete Feature DirectShow-ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngineund Audio/Video Capture in Media Foundationersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code MediaPlayer-, IMFMediaEngine und Audio-/Videoaufnahme in Media Foundation anstelle von DirectShow-verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, um die neuen APIs zu verwenden, falls möglich umgeschrieben werden.]

Wenn ein Aufnahmegerät einen Windows Driver Model (WDM)-Treiber verwendet, erfordert das Diagramm möglicherweise bestimmte Filter vor dem Aufnahmefilter. Diese Filter werden als Streamklassentreiberfilter oder WDM-Filter bezeichnet. Sie unterstützen zusätzliche Funktionen, die von der Hardware bereitgestellt werden. Beispielsweise verfügt eine TV-Tunerkarte über Funktionen zum Festlegen des Kanals. Der entsprechende Filter ist der TV Tuner Filter, der die IAMTVTuner Schnittstelle verfügbar macht. Um diese Funktionalität für die Anwendung verfügbar zu machen, müssen Sie den TV-Tuner-Filter mit dem Aufnahmefilter verbinden.

Die ICaptureGraphBuilder2--Schnittstelle bietet die einfachste Möglichkeit, WDM-Filter zum Diagramm hinzuzufügen. Rufen Sie beim Erstellen des Diagramms FindInterface oder RenderStream-auf. Eine dieser Methoden sucht automatisch die erforderlichen WDM-Filter und verbindet sie mit dem Aufnahmefilter. Im restlichen Abschnitt wird beschrieben, wie WDM-Filter manuell hinzugefügt werden. Beachten Sie jedoch, dass der empfohlene Ansatz einfach eine dieser ICaptureGraphBuilder2- Methoden aufruft.

Die Pins auf einem WDM-Filter unterstützen mindestens ein Medium. Ein Medium definiert eine Kommunikationsmethode, z. B. einen Bus. Sie müssen Pins verbinden, die dasselbe Medium unterstützen. Die REGPINMEDIUM Struktur, die der KSPIN_MEDIUM Struktur entspricht, die für Kernelstreamingtreiber verwendet wird, definiert ein Medium in DirectShow. Das clsMedium Member der REGPINMEDIUM Struktur gibt den Klassenbezeichner (CLSID) für das Medium an. Rufen Sie zum Abrufen des Mediums einer Pin die IKsPin::KsQueryMediums-Methode auf. Diese Methode gibt einen Zeiger auf einen Speicherblock zurück, der eine KSMULTIPLE_ITEM Struktur enthält, gefolgt von null oder mehr REGPINMEDIUM- Strukturen. Jede REGPINMEDIUM Struktur identifiziert ein Medium, das der Pin unterstützt.

Verbinden Sie keinen Pin, wenn das Medium über eine CLSID von GUID_NULL oder KSMEDIUMSETID_Standard verfügt. Dies sind Standardwerte, die angeben, dass der Pin keine Mittel unterstützt.

Verbinden Sie auch keine Pin, es sei denn, der Filter erfordert genau eine verbundene Instanz dieses Pins. Andernfalls versucht Ihre Anwendung möglicherweise, verschiedene Pins zu verbinden, die keine Verbindungen haben sollten, was dazu führen kann, dass das Programm nicht mehr reagiert. Um die Anzahl der erforderlichen Instanzen zu ermitteln, rufen Sie den KSPROPERTY_PIN_NECESSARYINSTANCES Eigenschaftensatz ab, wie im folgenden Codebeispiel gezeigt. (Aus Platzgründen testt dieses Beispiel keine Rückgabecodes oder gibt keine Schnittstellen frei. Ihre Bewerbung sollte natürlich beides tun.)

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

Der folgende Pseudocode ist eine äußerst kurze Gliederung, die zeigt, wie Sie die WDM-Filter suchen und verbinden. Es werden viele Details weggelassen und nur die allgemeinen Schritte angezeigt, die Ihre Anwendung ausführen müsste.

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

Erweiterte Erfassungsthemen