Distribuzione di esempi
[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stato superato da MediaPlayer, IMFMediaEnginee acquisizione audio/video in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente di usare un nuovo codice 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.
Questo articolo descrive come un filtro fornisce un esempio. Descrive sia il modello push, utilizzando i metodi di IMemInputPin , sia il modello pull, utilizzando IAsyncReader .
Modello Push: distribuzione di un campione
Il pin di output fornisce un esempio chiamando il metodo IMemInputPin::Receive o il metodo IMemInputPin::ReceiveMultiple, che è equivalente ma fornisce una matrice di esempi. Il pin di input può bloccarsi all'interno di Receive (o ReceiveMultiple). Se il pin potrebbe bloccarsi, il metodo IMemInputPin::ReceiveCanBlock deve restituire S_OK. Se il pin garantisce di non bloccare mai, ReceiveCanBlock deve restituire S_FALSE. Il valore restituito S_OK non significa che Receive sempre blocchi, solo che potrebbe.
Anche se Receive può bloccarsi in attesa della disponibilità di una risorsa, non deve bloccarsi in attesa di più dati dal filtro upstream. In questo modo può verificarsi un deadlock in cui il filtro upstream attende che il filtro downstream rilasci il campione, cosa che non accade mai perché il filtro downstream aspetta il filtro upstream. Se un filtro ha più pin di input, tuttavia, un pin può attendere che un altro pin riceva i dati. Ad esempio, il filtro mux AVI fa questo per poter intercalare dati audio e video.
Un pin potrebbe rifiutare un campione per diversi motivi:
- Il pin è in scarico (vedere Flushing).
- Il pin non è connesso.
- Il filtro è fermo.
- Si è verificato un altro errore.
Il metodo Receive deve restituire S_FALSE nel primo caso e un codice di errore negli altri casi. Il filtro upstream deve interrompere l'invio di campioni quando il codice restituito è diverso da S_OK.
È possibile considerare i primi tre casi come errori "previsti", nel senso che il filtro si trovava nello stato errato per ricevere campioni. Un errore imprevisto è uno che fa sì che il pin rifiuti un campione anche se il pin si trova in uno stato di ricezione. Se si verifica un errore di questo tipo, il pin deve inviare una notifica di fine-flusso a valle e inviare un evento EC_ERRORABORT a il Filter Graph Manager.
Nelle classi di base DirectShow il metodo CBaseInputPin::CheckStreaming verifica la presenza di casi di errore generali, ovvero scaricamento, arresto e così via. La classe derivata dovrà verificare la presenza di errori specifici del filtro. In caso di errore, il metodo CBaseInputPin::Receive invia la notifica di fine flusso e l'evento EC_ERRORABORT.
modello pull: richiesta di un di esempio
Nell'interfaccia IAsyncReader, il pin di input richiede esempi dal pin di output chiamando uno dei metodi seguenti:
Il metodo richiesta è asincrono; il pin di input chiama IAsyncReader::WaitForNext per attendere il completamento della richiesta. Gli altri due metodi sono sincroni.
Quando consegnare i dati
Un filtro fornisce sempre campioni mentre è in uno stato operativo. Nella maggior parte dei casi, un filtro fornisce anche campioni durante la pausa. In questo modo, il grafico prepara i dati in modo che la riproduzione inizi immediatamente quando si chiama il comando Esegui (vedere Stati filtro). Se il filtro non recapita i dati durante la pausa, il metodo IMediaFilter::GetState del filtro deve restituire VFW_S_CANT_CUE nello stato sospeso. Questo codice restituito segnala al grafico del filtro di non attendere i dati dal filtro prima di completare la transizione di pausa. In caso contrario, il metodo Pause verrà bloccato per un periodo illimitato. Per un esempio di codice, vedere CBaseFilter::GetState.
Ecco alcuni esempi di quando un filtro potrebbe dover restituire VFW_S_CANT_CUE:
- Le origini live, ad esempio i filtri di acquisizione, non devono inviare dati durante la pausa. Vedere Produzione di dati in un filtro di acquisizione.
- Un filtro di divisione potrebbe o meno inviare dati durante la pausa, a seconda dell'implementazione. Se il filtro usa thread separati per accodare i dati in ogni pin di output, può inviare dati durante la pausa. Tuttavia, se il filtro usa un singolo thread per ogni pin di output, il primo pin potrebbe bloccare il thread quando chiama Receive, che impedirà agli altri pin di inviare dati. In tal caso, è necessario restituire VFW_S_CANT_CUE.
- Un filtro potrebbe recapitare i dati sporadicamente. Ad esempio, potrebbe analizzare un flusso di dati personalizzato e filtrare alcuni pacchetti durante la distribuzione di altri. In tal caso, il filtro potrebbe non garantire di fornire i dati mentre è in pausa.
Un filtro di origine (usando il modello push) o un filtro parser (usando il modello push/pull) crea uno o più thread di streaming, che forniscono campioni il più rapidamente possibile. I filtri downstream, ad esempio decodificatori e trasformazioni, in genere inviano dati solo quando Receive viene chiamato sui pin di input.
Argomenti correlati