Leeren von Daten

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

Der folgende Pseudocode zeigt, wie die IPin::BeginFlush-Methode implementiert wird:

HRESULT CMyInputPin::BeginFlush()
{
    CAutoLock lock_it(m_pLock);
   
    // First, make sure the Receive method will fail from now on.
    HRESULT hr = CBaseInputPin::BeginFlush();
    
    // Force downstream filters to release samples. If our Receive method
    // is blocked in GetBuffer or Deliver, this will unblock it.
    for (each output pin)
    {
        hr = pOutputPin->DeliverBeginFlush();
    }

    // Unblock our Receive method if it is waiting on an event.
    SetEvent(m_hSomeEventThatReceiveNeedsToWaitOn);

    // At this point, the Receive method can't be blocked. Make sure 
    // it finishes, by taking the streaming lock. (Not necessary if this 
    // is the last step.)
    { 
        CAutoLock lock_2(&m_csReceive);

        /* Now it's safe to do anything that would crash or hang 
           if Receive were executing. */
    }
    return hr;
}

Wenn das Leeren gestartet wird, übernimmt die BeginFlush-Methode die Filtersperre, die die Zustandsänderung serialisiert. Es ist noch nicht sicher, die Streamingsperre zu übernehmen, da das Leeren im Anwendungsthread erfolgt und sich der Streamingthread möglicherweise in der Mitte eines Empfangsaufrufs befindet. Die Pin muss sicherstellen, dass Receive nicht blockiert wird und dass alle nachfolgenden Aufrufe von Receive fehlschlagen. Die CBaseInputPin::BeginFlush-Methode legt das interne Flag CBaseInputPin::m_bFlushing fest. Wenn das Flag TRUE ist, schlägt die Receive-Methode fehl.

Durch die Übermittlung des BeginFlush-Aufrufs nach dem Downstream garantiert der Pin, dass alle Downstreamfilter ihre Proben freigeben und von Empfangsanrufen zurückkehren. Dadurch wird wiederum sichergestellt, dass der Eingabenadel nicht blockiert wird und auf GetBuffer oder Receive wartet. Wenn die Receive-Methode Ihrer Pin jemals auf ein Ereignis wartet (z. B. auf das Abrufen von Ressourcen), sollte die BeginFlush-Methode das Beenden des Wartevorgangs erzwingen, indem das Ereignis festgelegt wird. An diesem Punkt wird die Receive-Methode garantiert zurückgegeben, und das m_bFlushing-Flag verhindert, dass neue Receive-Aufrufe arbeiten.

Für einige Filter ist dies alles, was BeginFlush tun muss. Die EndFlush-Methode signalisiert dem Filter, dass er mit dem Empfang von Beispielen wieder beginnen kann. Andere Filter müssen möglicherweise Variablen oder Ressourcen in BeginFlush verwenden, die auch in Receive verwendet werden. In diesem Fall sollte der Filter zuerst die Streamingsperre enthalten. Stellen Sie sicher, dass Sie dies vor einem der vorherigen Schritte nicht tun, da Sie möglicherweise zu einem Deadlock führen können.

Die EndFlush-Methode enthält die Filtersperre und gibt den Aufruf nach unten weiter:

HRESULT CMyInputPin::EndFlush()
{
    CAutoLock lock_it(m_pLock);
    for (each output pin)
        hr = pOutputPin->DeliverEndFlush();
    return CBaseInputPin::EndFlush();
}

Die CBaseInputPin::EndFlush-Methode setzt das m_bFlushing-Flag auf FALSE zurück, sodass die Receive-Methode mit dem Empfang von Beispielen wieder beginnen kann. Dies sollte der letzte Schritt in EndFlush sein, da der Pin keine Proben empfangen darf, bis das Leeren abgeschlossen ist und alle nachgeschalteten Filter benachrichtigt werden.

Threads und kritische Abschnitte