Condividi tramite


Sink multimediali

I sink multimediali sono gli oggetti pipeline che ricevono dati multimediali. Un sink multimediale è la destinazione per uno o più flussi multimediali. I sink multimediali rientrano in due categorie generali:

  • Un renderer è un sink multimediale che presenta i dati per la riproduzione. Il renderer video avanzato (EVR) visualizza i fotogrammi video e il renderer audio riproduce flussi audio tramite la scheda audio o altri dispositivi audio.

  • Un sink di archiviazione è un sink multimediale che scrive i dati in un file o in un altro archivio.

La differenza principale tra di esse è che un sink di archiviazione non utilizza i dati a una velocità di riproduzione fissa. Scrive invece i dati ricevuti il più rapidamente possibile.

I sink multimediali espongono l'interfaccia FMMediaSink . Ogni sink multimediale contiene uno o più sink di flusso. Ogni sink di flusso riceve i dati da un flusso. I sink di flusso espongono l'interfaccia FMStreamSink . In genere un'applicazione non crea direttamente sink multimediali. L'applicazione crea invece uno o più oggetti di attivazione che la sessione multimediale usa per creare il sink. Tutte le altre operazioni sul sink vengono gestite dalla sessione multimediale e l'applicazione non chiama alcun metodo nel sink multimediale o in uno dei sink di flusso. Per altre informazioni sugli oggetti di attivazione, vedere Oggetti di attivazione.

È consigliabile leggere il resto di questo argomento se si scrive un sink multimediale personalizzato o se si vuole usare un sink multimediale direttamente senza la sessione multimediale.

Sink di flusso

Un sink multimediale può avere un numero fisso di sink di flusso oppure può supportare l'aggiunta e la rimozione di sink di flusso. Se ha un numero fisso di sink di flusso, il metodo IMFMediaSink::GetCharacteristics restituisce il flag di MEDIASINK_FIXED_STREAMS. In caso contrario, è possibile aggiungere e rimuovere sink di flusso. Per aggiungere un nuovo sink di flusso, chiamare IMFMediaSink::AddStreamSink. Per rimuovere un sink di flusso, chiamare FMMediaSink::RemoveStreamSink. Il flag MEDIASINK_FIXED_STREAMS indica che il sink multimediale non supporta questi due metodi. Potrebbe supportare un altro modo per configurare il numero di flussi, ad esempio impostando i parametri di inizializzazione al momento della creazione del sink. L'elenco dei sink di flusso è ordinato. Per enumerarli in base al valore dell'indice, chiamare il metodo IMFMediaSink::GetStreamSinkByIndex .

I sink di flusso hanno anche identificatori. Gli identificatori di flusso sono univoci all'interno del sink multimediale, ma non devono essere consecutivi. A seconda del sink multimediale, gli identificatori di flusso potrebbero avere un significato correlato al contenuto. Ad esempio, un sink di archivio potrebbe scrivere gli identificatori di flusso nell'intestazione del file. In caso contrario, sono arbitrari. Per ottenere un sink di flusso in base all'identificatore, chiamare FMMediaSink::GetStreamSinkById.

Orologio presentazione

La frequenza in cui un sink multimediale utilizza campioni è controllata dall'orologio della presentazione. La sessione multimediale seleziona l'orologio della presentazione e lo imposta sul sink multimediale chiamando il metodo FMMediaSink::SetPresentationClock del sink multimediale. L'orologio della presentazione deve essere impostato sul sink multimediale prima che lo streaming possa iniziare. Ogni sink multimediale richiede un orologio di presentazione da eseguire. Il sink multimediale usa l'orologio della presentazione per due scopi:

  • Per ricevere notifiche all'avvio o all'arresto dello streaming. Il sink multimediale riceve queste notifiche tramite l'interfaccia FMClockStateSink , che tutti i sink multimediali devono implementare.

  • Per determinare quando eseguire il rendering degli esempi. Quando il sink multimediale riceve un nuovo esempio, ottiene il timestamp dall'esempio e tenta di eseguire il rendering dell'esempio in quel momento della presentazione.

L'orologio della presentazione deriva i tempi dell'orologio da un altro oggetto denominato origine dell'ora della presentazione. Le origini temporali di presentazione espongono l'interfaccia FMPresentationTimeSource . Alcuni sink multimediali hanno accesso a un orologio accurato, quindi espongono questa interfaccia. Ciò significa che un sink multimediale potrebbe pianificare gli esempi rispetto a un'ora fornita dal proprio orologio. Tuttavia, il sink multimediale non può presupporre che sia il caso. Deve sempre usare l'ora dall'orologio della presentazione, indipendentemente dal fatto che l'orologio della presentazione sia guidato dal sink multimediale stesso o da un altro orologio.

Se un sink multimediale non può corrispondere alle tariffe con un orologio diverso dal proprio, il metodo GetCharacteristics restituisce il flag di MEDIASINK_CANNOT_MATCH_CLOCK. Se questo flag è presente e l'orologio della presentazione usa un'origine temporale di presentazione diversa, il sink multimediale è probabile che venga eseguito male. Ad esempio, potrebbe verificarsi un problema durante la riproduzione.

Un sink senza frequenza è un sink multimediale che ignora i timestamp sugli esempi e utilizza i dati non appena arriva ogni esempio. Un sink multimediale senza frequenza restituisce il flag di MEDIASINK_RATELESS dal metodo GetCharacteristics . In genere questo flag si applica ai sink di archiviazione. Se ogni sink multimediale nella pipeline è senza frequenza, la sessione multimediale usa un orologio di presentazione senza frequenza speciale. Questo orologio viene eseguito rapidamente quando i sink usano esempi.

Formati di flusso

Prima che il sink multimediale possa ricevere esempi, il client deve impostare il tipo di supporto nei sink di flusso. Per impostare il tipo di supporto, chiamare il metodo FMStreamSink::GetMediaTypeHandler del sink di flusso. Questo metodo restituisce un puntatore all'interfaccia IMFMediaTypeHandler . Usare questa interfaccia per ottenere l'elenco di tipi di supporti preferiti, ottenere il tipo di supporto corrente e impostare il tipo di supporto.

Per ottenere l'elenco dei tipi di supporti preferiti, chiamare IMFMediaTypeHandler::GetMediaTypeByIndex. I tipi preferiti devono essere presi come hint per il client. L'elenco potrebbe essere incompleto o includere tipi di supporti parziali. Un tipo di supporto parziale è uno che non dispone di tutti gli attributi necessari per descrivere un formato valido. Ad esempio, un tipo di video parziale potrebbe specificare lo spazio dei colori e la profondità di bit, ma non la larghezza o l'altezza dell'immagine. Un tipo audio parziale potrebbe specificare il formato di compressione e la frequenza di esempio, ma non il numero di canali audio.

Per ottenere il tipo di supporto corrente del sink di flusso, chiamare FMMediaTypeHandler::GetCurrentMediaTypeType. Quando viene creato per la prima volta un sink di flusso, potrebbe avere un tipo di supporto predefinito già impostato oppure potrebbe non avere alcun tipo di supporto fino a quando il client ne imposta uno.

Per impostare il tipo di supporto, chiamare FMMediaTypeHandler::SetCurrentMediaType. Alcuni sink di flusso potrebbero non supportare la modifica del tipo dopo che è stato impostato. Pertanto, è utile testare i tipi di supporti prima di impostarli. Per verificare se il sink multimediale accetterà un tipo di supporto( senza impostare il tipo), chiamare FMMediaTypeHandler::IsMediaTypeSupported.

Flusso di dati

I sink multimediali usano un modello pull, che significa che i sink di flusso richiedono i dati in base alle esigenze. Il client deve rispondere in modo tempestivo per evitare eventuali errori.

Alcuni sink multimediali supportano la prerolling. La prerolling è il processo di assegnazione dei dati al sink multimediale prima dell'avvio dell'orologio della presentazione. Se un sink multimediale supporta la prerolling, il sink multimediale espone l'interfaccia FMMediaSinkPreroll e il metodo GetCharacteristics restituisce il flag di MEDIASINK_CAN_PREROLL. La prerolling garantisce che il sink multimediale sia pronto per presentare il primo esempio all'avvio dell'orologio della presentazione. È consigliabile che il client preroll sempre se il sink multimediale lo supporta, perché può impedire l'interruzione o le lacune durante la riproduzione.

Il flusso di dati in un sink multimediale funziona come indicato di seguito:

  1. Il client imposta i tipi di supporti e l'orologio della presentazione. Il sink multimediale registra se stesso con l'orologio della presentazione per ricevere notifiche relative alle modifiche dello stato dell'orologio.
  2. Facoltativamente, le query client per FMMediaSinkPreroll. Se il sink multimediale espone questa interfaccia, il client chiama IMFMediaSinkPreroll::NotifyPreroll. In caso contrario, il client passa al passaggio 5.
  3. Ogni sink di flusso invia uno o più eventi MEStreamSinkRequestSample . In risposta a ognuno di questi eventi, il client ottiene il successivo campione di dati per tale flusso e chiama IMFStreamSink::P rocessSample.
  4. Quando ogni sink di flusso riceve dati di preroll sufficienti, invia un evento MEStreamSinkPre roll .
  5. Il client chiama IMFPresentationClock::Start per avviare l'orologio della presentazione.
  6. L'orologio della presentazione notifica al sink multimediale che l'orologio sta iniziando chiamando IMFClockStateSink::OnClockStart.
  7. Per ottenere più dati, ogni sink di flusso invia gli eventi MEStreamSinkRequestSample . In risposta a ognuno di questi eventi, il client ottiene l'esempio successivo e chiama ProcessSample. Questo passaggio viene ripetuto fino al termine della presentazione.

La maggior parte dei sink multimediali elabora i campioni in modo asincrono, in modo che i sink di flusso possano inviare più di una richiesta di esempio alla volta.

Durante lo streaming, il client può chiamare IMFStreamSink::P laceMarker e IMFStreamSink::Flush in qualsiasi momento. I marcatori sono descritti nella sezione successiva. Lo scaricamento causa l'eliminazione del sink di flusso di tutti i campioni accodati ma non ancora sottoposti a rendering.

Marcatori

I marcatori consentono al client di indicare punti specifici nel flusso. Un marcatore è costituito dalle informazioni seguenti:

  • Tipo di marcatore, definito come membro dell'enumerazione MFSTREAMSINK_MARKER_TYPE .
  • Dati associati al marcatore. Il significato dei dati dipende dal tipo di marcatore. Alcuni tipi di marcatori non dispongono di dati.
  • Dati facoltativi per l'uso del client.

Per posizionare un marcatore, il client chiama IMFStreamSink::P laceMarker. Il sink di flusso termina l'elaborazione di tutti gli esempi ricevuti prima della chiamata a PlaceMarker e quindi invia un evento MEStreamSinkMarker .

La maggior parte dei sink multimediali mantiene una coda di esempi in sospeso, che vengono elaborati in modo asincrono. Gli eventi marcatori devono essere serializzati con l'elaborazione del campione, quindi il sink multimediale deve posizionare gli indicatori nella stessa coda. Si supponga, ad esempio, che il client effettui le chiamate al metodo seguenti:

  1. ProcessSample (esempio n. 1)
  2. ProcessSample (esempio n. 2)
  3. PlaceMarker (marcatore n. 1)
  4. ProcessSample (esempio n. 3)
  5. PlaceMarker (marcatore n. 2)

In questo esempio, il sink di flusso deve inviare l'evento MEStreamSinkMarker per il marcatore #1 dopo l'elaborazione del campione n. 2 e l'evento per il marcatore #2 dopo l'elaborazione del campione n. 3.

Se il client scarica un sink di flusso, il sink del flusso elabora immediatamente tutti i marcatori presenti nella coda. Imposta il codice di stato su E_ABORT su questi eventi.

Alcuni marcatori contengono informazioni rilevanti per il sink multimediale:

  • MFSTREAMSINK_MARKER_TICK: indica che esiste un gap nel flusso. L'esempio successivo sarà una discontinuità.
  • MFSTREAMSINK_MARKER_ENDOFSEGMENT: indica la fine di un segmento o la fine di un flusso. L'esempio successivo (se presente) potrebbe essere una discontinuità.
  • MFSTREAMSINK_MARKER_EVENT: contiene un evento. A seconda del tipo di evento e dell'implementazione del sink multimediale, il sink multimediale potrebbe gestire l'evento o ignorarlo.

Modifiche di stato

Un sink multimediale riceve una notifica delle modifiche di stato nell'orologio della presentazione tramite l'interfaccia IMFClockStateSink del sink multimediale. Quando il client imposta l'orologio della presentazione, il sink multimediale chiama IMFPresentationClock::AddClockStateSink per registrarsi per le notifiche dall'orologio. Nella tabella seguente viene riepilogato il comportamento di un sink multimediale in risposta alle modifiche dello stato di clock.

Modifica dello stato dell'orologio Elaborazione di esempio Elaborazione dei marcatori
OnClockStart Elaborare esempi il cui timestamp è uguale o successivo all'ora di inizio dell'orologio. Inviare l'evento MEStreamSinkMarker quando tutti i campioni ricevuti prima dell'elaborazione del marcatore.
OnClockPause Il sink multimediale può non riuscire ProcessSample durante la sospensione.
Se il sink multimediale accetta campioni durante la sospensione, deve accodarli fino al riavvio dell'orologio. Non elaborare esempi in coda durante la sospensione.
Se sono presenti campioni in coda, inserire i marcatori nella stessa coda. Inviare l'evento marcatore al riavvio dell'orologio.
In caso contrario, inviare immediatamente l'evento del marcatore.
OnClockRestart Elaborare tutti gli esempi accodati durante la sospensione e quindi trattare lo stesso valore di OnClockStart. Inviare gli eventi MEStreamSinkMarker per i marcatori in coda (serializzati con l'elaborazione di esempio) e quindi considerare lo stesso valore di OnClockStart.
OnClockStop Eliminare tutti gli esempi in coda. Altre chiamate a ProcessSample possono avere esito negativo. Inviare eventi di marcatore in coda. Nelle chiamate successive a PlaceMarker inviare immediatamente l'evento marcatore.

 

Inoltre, i sink di flusso devono inviare gli eventi seguenti quando hanno completato le transizioni di stato:

Finalizzazione

Alcuni sink multimediali richiedono un passaggio di elaborazione aggiuntivo dopo il recapito dell'ultimo esempio. In genere, questo requisito si applica ai sink di archiviazione, che devono scrivere intestazioni o indici nel file. Se un sink multimediale richiede un'elaborazione finale, espone l'interfaccia IMFFinalizableMediaSink .

Dopo che il client ha recapitato l'ultimo esempio, il client esegue una query per questa interfaccia. Se il sink multimediale supporta l'interfaccia, il client chiama IMFFinalizableMediaSink::BeginFinalize per eseguire l'elaborazione finale in modo asincrono. Questo metodo segue il modello asincrono standard di Media Foundation, descritto in Metodi di callback asincroni. Il sink multimediale può presupporre che il client chiamerà BeginFinalize. La mancata chiamata a BeginFinalize può comportare un file creato in modo non corretto.

Arresto

Quando il client viene eseguito usando il sink multimediale, il client chiama IMFMediaSink::Shutdown. All'interno di questo metodo, il sink multimediale deve interrompere qualsiasi conteggio di riferimenti circolari. In genere, saranno presenti riferimenti circolari tra il sink multimediale e i sink del flusso.

Se si usa l'oggetto helper della coda di eventi per implementare IMFMediaEventGenerator, chiamare IMFMediaEventQueue::Shutdown nella coda di eventi. Questo metodo arresta la coda di eventi e segnala qualsiasi chiamante in attesa di un evento.

Dopo l'arresto, tutti i metodi nel sink multimediale restituiscono MF_E_SHUTDOWN, ad eccezione dei metodi IUnknown .

Interfacce sink multimediali

Nella tabella seguente sono elencate le interfacce standard che i sink multimediali possono esporre tramite QueryInterface. I sink multimediali possono anche esporre interfacce personalizzate.

Interfaccia Descrizione
IMFMediaSink Interfaccia primaria per i sink multimediali. Obbligatorio.
IMFClockStateSink Usato per notificare al sink multimediale quando l'orologio della presentazione cambia stato. Obbligatorio.
IMFFinalizableMediaSink Implementare se il sink multimediale deve eseguire un passaggio di elaborazione finale. Facoltativo.
FMGetService Implementare se il sink multimediale espone qualsiasi interfaccia del servizio. Facoltativo.
FMMediaEventGenerator Implementare se il sink multimediale invia eventuali eventi. Facoltativo.
FMMediaSinkPreroll Implementare se il sink multimediale supporta la preroll. Facoltativo.
FMPresentationTimeSource Implementare se il sink multimediale può fornire un'origine temporale per l'orologio della presentazione. Facoltativo.
FMQualityAdvise Implementare se il sink multimediale può regolare la qualità della riproduzione. Facoltativo.

 

Facoltativamente, un sink multimediale può implementare l'interfaccia seguente come servizio.

Interfaccia del servizio Descrizione
FMRateSupport Segnala l'intervallo di frequenze di riproduzione supportate.

 

Per altre informazioni sulle interfacce di servizio e FMGetService, vedere Interfacce di servizio.

Interfacce sink di flusso

I sink di flusso devono esporre le interfacce seguenti tramite QueryInterface.

Interfaccia Descrizione
FMStreamSink Interfaccia primaria per i sink di flusso. Obbligatorio.
FMMediaEventGenerator Eventi code. L'interfaccia IMFStreamSink eredita questa interfaccia. Obbligatorio.

 

Attualmente non sono definite interfacce di servizio per i sink di flusso.

Eventi sink di flusso

Nella tabella seguente sono elencati gli eventi definiti per i sink di flusso generici. I sink di flusso possono anche inviare eventi personalizzati non elencati qui.

Event Descrizione
MEStreamSinkFormatChanged Il tipo di supporto del sink di flusso non è più valido. Facoltativo.
MEStreamSinkMarker È stato elaborato un marcatore. Obbligatorio.
MEStreamSinkPaused Il sink di flusso è sospeso. Obbligatorio.
MEStreamSinkPre roll La registrazione preliminare è stata completata. Facoltativo.
MEStreamSinkRateChanged Il sink di flusso ha modificato la frequenza di riproduzione. Facoltativo.
MEStreamSinkRequestSample Viene richiesto un nuovo esempio. Obbligatorio.
MEStreamSinkScrubSampleComplete È stata completata una richiesta di pulizia. Facoltativo.
MEStreamSinkStarted Il sink di flusso è stato avviato. Obbligatorio.
MEStreamSinkStopped Il sink di flusso è stato arrestato. Obbligatorio.

 

Attualmente non vengono definiti eventi per utilizzo generico per i sink multimediali. Alcuni sink multimediali potrebbero inviare eventi personalizzati.

Media Foundation Pipeline

Architettura di Media Foundation