Condividi tramite


Flussaggio

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEnginee Acquisizione audio/video 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 Acquisizione audio/video in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

Mentre il grafico del filtro è in esecuzione, è possibile spostare quantità arbitrarie di dati nel grafico. Alcune di esse potrebbero trovarsi in code, in attesa di essere recapitate. In alcuni casi il grafico dei filtri deve rimuovere i dati in sospeso il più rapidamente possibile e sostituirli con nuovi dati. Dopo un comando seek, ad esempio, il filtro di origine genera campioni da una nuova posizione nell'origine. Per ridurre al minimo la latenza, i filtri downstream devono eliminare tutti i campioni creati prima del comando seek. Il processo di eliminazione dei campioni viene chiamato pulizia. Consente al grafico di essere più reattivo quando gli eventi modificano il normale flusso di dati.

Il svuotamento viene gestito in modo leggermente diverso dal modello pull rispetto al modello push. Questo articolo inizia descrivendo il modello push; descrive quindi le differenze nel modello pull.

Il flushing avviene in due fasi.

  • Prima di tutto, il filtro di origine chiama IPin::BeginFlush sul pin di input del filtro downstream. Il filtro downstream inizia a rifiutare campioni da upstream. Rimuove anche tutti i campioni che contiene e invia la chiamata BeginFlush a valle al filtro successivo.
  • Quando il filtro di origine è pronto per inviare nuovi dati, chiama IPin::EndFlush sul pin di input. Segnala al filtro downstream che può ricevere nuovi campioni. Il filtro downstream invia la chiamata EndFlush al filtro successivo.

Nel metodo BeginFlush, il pin di input esegue le operazioni seguenti:

  1. Chiama BeginFlush sui pin di input downstream.
  2. Rifiuta qualsiasi altra chiamata che trasmette dati, inclusi Receive e EndOfStream.
  3. Sblocca tutti i filtri upstream bloccati in attesa di un campione dall'allocatore del filtro. Alcuni filtri decommettono i relativi allocatori a questo scopo.
  4. Esce da qualsiasi attesa che blocca lo streaming. Ad esempio, i filtri del renderer si bloccano quando sono in pausa. Bloccano anche quando sono in attesa di effettuare il rendering di un campione al momento corretto nel flusso. Il filtro deve essere sbloccato, in modo che i campioni in coda a monte possano essere consegnati o rifiutati. Questo passaggio garantisce che tutti i filtri upstream si sblocchino.

Nel metodo EndFlush, il pin di input esegue le operazioni seguenti:

  1. Attende che tutti gli esempi in coda vengano eliminati.
  2. Libera tutti i dati memorizzati nel buffer. Questo passaggio può talvolta essere eseguito nel metodo BeginFlush. Tuttavia, BeginFlush non è sincronizzato con il thread di streaming. Il filtro non deve elaborare o memorizzare nel buffer altri dati tra la chiamata a BeginFlush e la chiamata a EndFlush.
  3. Cancella eventuali notifiche di EC_COMPLETE in sospeso.
  4. Chiama EndFlush downstream.

A questo punto, il filtro può accettare di nuovo campioni. Tutti gli esempi sono sicuramente più recenti rispetto allo scaricamento.

Nel modello pull il filtro parser avvia lo scaricamento anziché il filtro di origine. Non solo chiama IPin::BeginFlush e IPin::EndFlush sul filtro downstream, chiama anche IAsyncReader::BeginFlush e IAsyncReader::EndFlush sul pin del filtro di origine. Se il filtro di origine ha richieste di lettura in sospeso, le eliminerà.

Svuotamento dei dati