Panoramica delle Flusso di dati in DirectShow

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, FMMediaEngine 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, FMMediaEngine e Audio/Video Capture 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.

Questa sezione offre una panoramica generale del funzionamento del flusso di dati in DirectShow. I dettagli sono disponibili in altre sezioni della documentazione.

I dati vengono mantenuti nei buffer, che sono semplicemente matrici di byte. Ogni buffer viene eseguito con wrapping da un oggetto COM denominato esempio multimediale, che implementa l'interfaccia IMediaSample . Gli esempi vengono creati da un altro tipo di oggetto, denominato allocatore, che implementa l'interfaccia IMemAllocator . Un allocatore viene assegnato per ogni connessione pin, anche se due o più connessioni pin potrebbero condividere lo stesso allocatore. L'immagine seguente illustra questo processo.

buffer, esempi e allocatori

Ogni allocatore crea un pool di campioni multimediali e alloca i buffer per ogni esempio. Ogni volta che un filtro deve riempire un buffer con dati, richiede un esempio dall'allocatore chiamando IMemAllocator::GetBuffer. Se l'allocatore include eventuali esempi che non sono attualmente in uso da un altro filtro, il metodo GetBuffer restituisce immediatamente con un puntatore all'esempio. Se tutti gli esempi dell'allocatore sono in uso, il metodo blocca fino a quando non diventa disponibile un esempio. Quando il metodo restituisce un esempio, il filtro inserisce i dati nel buffer, imposta i flag appropriati nell'esempio (in genere incluso un timestamp) e restituisce l'esempio downstream.

Quando un filtro renderer riceve un esempio, controlla il timestamp e rimane nell'esempio finché l'orologio di riferimento del grafo del filtro indica che i dati devono essere sottoposti a rendering. Dopo il rendering dei dati, il filtro rilascia l'esempio. L'esempio non torna al pool di campioni dell'allocatore fino a quando il conteggio dei riferimenti dell'esempio è zero, ovvero ogni filtro ha rilasciato l'esempio. L'immagine seguente illustra questo processo.

decodificatore in attesa di un esempio multimediale gratuito

Il filtro upstream potrebbe essere eseguito prima del renderer, ovvero potrebbe riempire i buffer più velocemente rispetto al renderer li usa. Anche in questo caso, gli esempi non vengono visualizzati in anticipo, perché il renderer contiene ogni volta fino al momento della presentazione. Inoltre, il filtro upstream non sovrascrive accidentalmente i buffer, perché GetSample restituisce solo esempi che non sono altrimenti in uso. La quantità in base alla quale il filtro upstream può essere eseguito in anticipo è determinato dal numero di campioni nel pool dell'allocatore.

Il diagramma precedente mostra solo un allocatore, ma in genere ci sono diversi allocatori per flusso. Pertanto, quando il renderer rilascia un esempio, può avere un effetto a catena. Il diagramma seguente illustra una situazione in cui un decodificatore contiene un frame video compresso mentre attende che il renderer rilasci un esempio. Un filtro parser è anche in attesa che il decodificatore rilasci un esempio.

due filtri in attesa di esempi

Quando il renderer rilascia il relativo esempio, viene restituita la chiamata in sospeso del decodificatore a GetBuffer . Il decodificatore può quindi decodificare il frame video compresso e rilasciare l'esempio che stava tenendo, sbloccando così la chiamata GetBuffer in sospeso del parser.

Flusso di dati nel grafico di filtro