Filterzentrierte Verarbeitung

Wenn ein Filter filterzentrierte Verarbeitung verwendet, ruft AVStream standardmäßig die von minidriver bereitgestellte AVStrMiniFilterProcess-Rückrufroutine auf, wenn datenframes auf jedem Pin instance verfügbar sind. Minidriver können dieses Standardverhalten ändern, indem sie den Flags-Member der KSPIN_DESCRIPTOR_EX-Struktur festlegen.

Um eine filterzentrierte Verarbeitung zu implementieren, geben Sie einen Zeiger auf eine von Minidriver bereitgestellte AVStrMiniFilterProcess-Rückrufroutine im Process-Member der KSFILTER_DISPATCH-Struktur an. Legen Sie das Process-Element von KSPIN_DISPATCH auf NULL fest.

AVStream ruft AVStrMiniFilterProcess nur auf, wenn alle folgenden Bedingungen erfüllt sind:

  • Frames sind für Pins verfügbar, für die Frames für die Verarbeitung erforderlich sind. Minidriver können das Verarbeitungsverhalten ändern, indem sie Flags im Flags-Member von KSPIN_DESCRIPTOR_EX festlegen. Achten Sie besonders auf Kombinationen der sich gegenseitig ausschließenden Flags KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING und KSPIN_FLAG_SOME_FRAMES_REQUIRED_FOR_PROCESSING. Der Minidriver kann auch den Satz von Pins ändern, die Frames erfordern, indem die Routinen KsPinAttachAndGate oder KsPinAttachOrGate verwendet werden.

  • Die Anzahl der Pininstanzen ist gleich oder größer als der InstancesNecessary-Member der KSPIN_DESCRIPTOR_EX-Struktur . Der ClientState-Member der KSPIN-Struktur gibt den bestimmten KSSTATE-Enumerator an, an dem der Pin derzeit festgelegt ist. Nachdem InstancesNecessary erfüllt wurde, verhindern zusätzliche Pins im zustand KSSTATE_STOP die Filterverarbeitung nicht.

  • Die erforderliche Anzahl von Pininstanzen wird erfüllt (wie im InstancesNecessary-Member der KSPIN_DESCRIPTOR_EX-Struktur angegeben.

  • Der Minidriver hat das Prozesssteuerungsgate des Filters mithilfe der KSGATEXxx-Funktionen nicht geschlossen.

In der Rückrufroutine AVStrMiniFilterProcess empfängt der Minidriver einen Zeiger auf ein Array von KSPROCESSPIN_INDEXENTRY Strukturen. AVStream ordnet das Array der KSPROCESSPIN_INDEXENTRY-Strukturen nach Pin-ID an.

Die folgenden Codebeispiele veranschaulichen die Verwendung der Prozess-Pinstrukturen. Der Code stammt aus dem Avssamp-Beispiel (AVStream Filter-Centric Simulated Capture Driver), das veranschaulicht, wie ein filterzentrierter Erfassungstreiber geschrieben wird. Quellcode und eine Beschreibung dieses Beispiels sind im Download der Windows Driver Kit-Beispiele enthalten.

Der Minidriver empfängt ein Array von KSPROCESSPIN_INDEXENTRY Strukturen in seiner Filterprozessverteilung. In diesem Beispiel extrahiert der Minidriver die erste KSPROCESSPIN-Struktur aus der KSPROCESSPIN_INDEXENTRY-Struktur des Index VIDEO_PIN_ID:

NTSTATUS
CCaptureFilter::
Process (
    IN PKSPROCESSPIN_INDEXENTRY ProcessPinsIndex
    )
{
PKSPROCESSPIN VideoPin = NULL;
...
VideoPin = ProcessPinsIndex [VIDEO_PIN_ID].Pins [0];
...
}

Der Minitreiber sollte nicht auf ProcessPinsIndex [n] verweisen. Pins [0], bevor überprüft wurde, ob das Count-Element von ProcessPinsIndex [n] mindestens eins ist oder dass das InstancesNecessary-Element der KSPIN_DESCRIPTOR_EX-Struktur, die in Pins [0] enthalten ist, mindestens eins ist. (Wenn letzteres true ist, ist der Pin garantiert vorhanden.)

Um dann den Pin anzugeben, an dem Frames erfasst werden sollen, übergibt die AVStrMiniFilterProcess-Rückrufroutine einen Zeiger auf eine KSPROCESSPIN-Struktur an CaptureFrame, eine vom Anbieter bereitgestellte Erfassungsroutine:

VidCapPin -> CaptureFrame (VideoPin, m_Tick);

Die Erfassungsroutine kann dann in oder aus dem Data-Member der KSPROCESSPIN-Struktur kopieren. Es können auch die BytesUsed - und Terminate-Member dieser Struktur aktualisiert werden, wie im folgenden Beispiel gezeigt:

RtlCopyMemory ( ProcessPin -> Data,
                m_SynthesisBuffer,
                m_VideoInfoHeader -> bmiHeader.biSizeImage
               );
ProcessPin -> BytesUsed = m_VideoInfoHeader -> bmiHeader.biSizeImage;
ProcessPin -> Terminate = TRUE;

Der Minidriver kann auch auf die Streamheaderstruktur zugreifen, die dem aktuellen Streamzeiger und dem aktuellen Stream-Pin entspricht:

PKSSTREAM_HEADER StreamHeader = ProcessPin -> StreamPointer -> StreamHeader;

Die meisten Minitreiber, die filterzentrierte Verarbeitung verwenden, verwenden den Streamzeiger nur für den Streamheaderzugriff. Im filterzentrierten Modell bearbeitet AVStream den Streamzeiger intern. Daher sollten Minitreiber vorsichtig vorgehen, wenn sie den Streamzeiger in einem filterzentrierten Treiber bearbeiten.