Condividi tramite


Sink multimediali

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 attraverso la scheda audio o un altro dispositivo audio.

  • Un sink di archiviazione è un sink multimediale che scrive i dati in un file o in un'altra risorsa di archiviazione.

La differenza principale tra di esse è che un sink di archivio 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 IMFMediaSink. 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'interfacciaIMFStreamSink. 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 attivazione .

È consigliabile leggere il resto di questo argomento se si sta scrivendo un sink multimediale personalizzato o se si desidera utilizzare 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 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 IMFMediaSink::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. Viene ordinato l'elenco dei sink di flusso. Per enumerarli in base al valore dell'indice, chiamare il metodoIMFMediaSink::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 del flusso potrebbero avere un significato correlato al contenuto. Ad esempio, un sink di archivio potrebbe scrivere gli identificatori del flusso nell'intestazione del file. In caso contrario, sono arbitrari. Per ottenere un sink di flusso in base al relativo identificatore, chiamare IMFMediaSink::GetStreamSinkById.

Orologio presentazione

La frequenza con cui un sink multimediale utilizza campioni è controllata dal clock di presentazione. La sessione multimediale seleziona l'orologio della presentazione e lo imposta sul sink multimediale chiamando il metodo IMFMediaSink::SetPresentationClock del sink multimediale. L'orologio della presentazione deve essere impostato sul sink multimediale prima di poter iniziare lo streaming. Ogni sink multimediale richiede l'esecuzione di un orologio di presentazione. 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 IMFClockStateSink, che tutti i sink multimediali devono implementare.

  • Per determinare quando deve 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 le ore dell'orologio da un altro oggetto denominato origine ora di presentazione . Le origini temporali di presentazione espongono l'interfacciaIMFPresentationTimeSource. Alcuni sink multimediali hanno accesso a un orologio accurato, quindi espongono questa interfaccia. Ciò significa che un sink multimediale potrebbe pianificare campioni rispetto a un'ora fornita dal proprio orologio. Tuttavia, il sink multimediale non può presupporre che questo 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 frequenze con un clock diverso da quello specifico, il metodogetCharacteristicsrestituisce il flag MEDIASINK_CANNOT_MATCH_CLOCK. Se questo flag è presente e l'orologio della presentazione usa un'origine dell'ora di presentazione diversa, è probabile che il sink multimediale esegua prestazioni scarse. Ad esempio, potrebbe verificarsi un problema durante la riproduzione.

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

Formati di flusso

Prima che il sink multimediale possa ricevere campioni, il client deve impostare il tipo di supporto nei sink del flusso. Per impostare il tipo di supporto, chiamare il metodo IMFStreamSink::GetMediaTypeHandler del sink di flusso. Questo metodo restituisce un puntatore all'interfacciaIMFMediaTypeHandler. Usare questa interfaccia per ottenere l'elenco dei 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à del bit, ma non la larghezza o l'altezza dell'immagine. Un tipo audio parziale può specificare il formato di compressione e la frequenza di campionamento, ma non il numero di canali audio.

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

Per impostare il tipo di supporto, chiamare IMFMediaTypeHandler::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 IMFMediaTypeHandler::IsMediaTypeSupported.

Flusso di dati

I sink multimediali usano un modello di pull , il 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'interfacciaIMFMediaSinkPreroll 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ò evitare interruzioni o interruzioni durante la riproduzione.

Il flusso di dati in un sink multimediale funziona come segue:

  1. Il client imposta i tipi di supporti e l'orologio della presentazione. Il sink multimediale si registra con l'orologio della presentazione per ricevere notifiche sulle modifiche dello stato dell'orologio.
  2. Facoltativamente, le query client per IMFMediaSinkPreroll. 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 MEStreamSinkPrerolled.
  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 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 gli esempi in modo asincrono, quindi i sink di flusso possono 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 gli esempi 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 PlaceMarker e quindi invia un evento MEStreamSinkMarker.

La maggior parte dei sink multimediali mantiene una coda di esempi in sospeso, che elaborano 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 1)
  2. ProcessSample (esempio 2)
  3. PlaceMarker (Marcatore n. 1)
  4. ProcessSample (esempio 3)
  5. PlaceMarker (Marcatore 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 è presente 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 dello 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 del marcatore
OnClockStart Elaborare campioni 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 mentre è in pausa.
Se il sink multimediale accetta campioni durante la pausa, è necessario accodarli fino al riavvio dell'orologio. Non elaborare campioni in coda durante la pausa.
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 marcatore.
OnClockRestart Elaborare tutti gli esempi accodati durante la sospensione e quindi trattare lo stesso valore di OnClockStart. Inviare MEStreamSinkMarker eventi per marcatori in coda (serializzati con l'elaborazione di esempio) e quindi considerarli uguali a OnClockStart.
OnClockStop Eliminare tutti gli esempi in coda. Altre chiamate a ProcessSample possono non riuscire. Inviare eventi marcatori in coda. Nelle chiamate successive a PlaceMarker, inviare immediatamente l'evento del 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. L'impossibilità di chiamare BeginFinalize può generare 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 i conteggi dei 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 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 del sink multimediale

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 Utilizzato 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.
IMFGetService Implementare se il sink multimediale espone eventuali interfacce del servizio. (Facoltativo.
IMFMediaEventGenerator Implementare se il sink multimediale invia eventi. (Facoltativo.
IMFMediaSinkPreroll Implementare se il sink multimediale supporta la preroll. (Facoltativo.
IMFPresentationTimeSource Implementare se il sink multimediale può fornire un'origine ora per l'orologio della presentazione. (Facoltativo.
IMFQualityAdvise 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
IMFRateSupport Segnala l'intervallo di frequenze di riproduzione supportate.

 

Per altre informazioni sulle interfacce del servizio e IMFGetService, vedere Service Interfaces.

Interfacce sink di flusso

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

Interfaccia Descrizione
IMFStreamSink Interfaccia primaria per i sink di flusso. (Obbligatorio).)
IMFMediaEventGenerator Accoda eventi. L'interfacciaIMFStreamSinkeredita 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.

Evento 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 è stato sospeso. (Obbligatorio).)
MEStreamSinkPrerolled 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 pulimento. (Facoltativo.
MEStreamSinkStarted Il sink di flusso è stato avviato. (Obbligatorio).)
MEStreamSinkStopped Il sink del flusso è stato arrestato. (Obbligatorio).)

 

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

pipeline di Media Foundation

architettura di Media Foundation