Scaricamento dei dati

[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.

Lo pseudocodice seguente illustra come implementare il metodo IPin::BeginFlush :

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;
}

All'avvio dello scaricamento, il metodo BeginFlush accetta il blocco del filtro, che serializza la modifica dello stato. Non è ancora sicuro eseguire il blocco di streaming, perché lo scaricamento avviene nel thread dell'applicazione e il thread di streaming potrebbe trovarsi al centro di una chiamata di ricezione . Il pin deve garantire che Receive non sia bloccato e che le chiamate successive a Receive avranno esito negativo. Il metodo CBaseInputPin::BeginFlush imposta un flag interno, CBaseInputPin::m_bFlushing. Quando il flag è TRUE, il metodo Receive ha esito negativo.

Recapitando la chiamata downstream di BeginFlush , il pin garantisce che tutti i filtri downstream rilascino i campioni e restituiscono dalle chiamate di ricezione . Ciò garantisce a sua volta che il pin di input non sia bloccato in attesa di GetBuffer o Receive. Se il metodo Receive del pin attende un evento ,ad esempio per ottenere risorse, il metodo BeginFlush deve forzare l'attesa per terminare impostando l'evento. A questo punto, il metodo Receive viene restituito e il flag m_bFlushing impedisce alle nuove chiamate di ricezione di eseguire qualsiasi operazione.

Per alcuni filtri, è necessario eseguire tutte le operazioni di BeginFlush . Il metodo EndFlush segnalerà al filtro che può iniziare a ricevere nuovamente campioni. Altri filtri potrebbero dover usare variabili o risorse in BeginFlush che vengono usati anche in Receive. In tal caso, il filtro deve contenere prima il blocco di streaming. Assicurarsi di non eseguire questa operazione prima di uno dei passaggi precedenti, perché è possibile che si verifichi un deadlock.

Il metodo EndFlush contiene il blocco del filtro e propaga la chiamata downstream:

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

Il metodo CBaseInputPin::EndFlush reimposta il flag m_bFlushing su FALSE, che consente al metodo Receive di avviare nuovamente la ricezione di campioni. Questo dovrebbe essere l'ultimo passaggio in EndFlush, perché il pin non deve ricevere campioni fino al completamento dello scaricamento e tutti i filtri downstream vengono informati.

Thread e sezioni critiche