Condividi tramite


MFP asincroni

Questo argomento descrive l'elaborazione asincrona dei dati per le trasformazioni di Media Foundation.This topic describes asynchronous data processing for Media Foundation transforms (MFT).

Nota

Questo argomento si applica a Windows 7 o versione successiva.

 

Informazioni sulle MFP asincrone

Quando le MFP sono state introdotte in Windows Vista, l'API è stata progettata per l'elaborazione dei dati sincrona . In tale modello, MFT è sempre in attesa di ottenere l'input o in attesa di produrre l'output.

Si consideri un decodificatore video tipico. Per ottenere un frame decodificato, il client chiama IMFTransform::P rocessOutput. Se il decodificatore dispone di dati sufficienti per decodificare un frame, ProcessOutput blocca mentre MFT decodifica il frame. In caso contrario, ProcessOutput restituisce MF_E_TRANSFORM_NEED_MORE_INPUT, a indicare che il client deve chiamare IMFTransform::P rocessInput.

Questo modello funziona bene se il decodificatore esegue tutte le operazioni di decodifica su un thread. Si supponga tuttavia che il decodificatore usi diversi thread per decodificare i fotogrammi in parallelo. Per ottenere prestazioni ottimali, il decodificatore deve ricevere un nuovo input ogni volta che un thread di decodifica diventa inattiva. Tuttavia, la frequenza con cui i thread completano le operazioni di decodifica non sarà allineata esattamente alle chiamate del client a ProcessInput e ProcessOutput, con conseguente attesa del lavoro da parte dei thread.

Windows 7 introduce l'elaborazione asincrona guidata dagli eventi per le MFP. In questo modello, ogni volta che MFT necessita di input o ha output, invia un evento al client.

Requisiti generali

In questo argomento viene descritto il modo in cui le MFT asincrone differiscono da MFT sincrone. Tranne dove indicato in questo argomento, i due modelli di elaborazione sono gli stessi. In particolare, la negoziazione del formato è la stessa.

Un MFT asincrono deve implementare le interfacce seguenti:

Eventi

Un MFT asincrono usa gli eventi seguenti per segnalare lo stato di elaborazione dei dati:

Event Descrizione
METransformNeedInput Inviato quando MFT può accettare più input.
METransformHaveOutput Inviato quando MFT ha output.
METransformDrainComplete Inviato al termine di un'operazione di svuotamento. Vedi Svuotamento.
METransformMarker Inviato quando un marcatore è un processo. Vedere Marcatori.

 

Questi eventi vengono inviati fuori banda. È importante comprendere la differenza tra eventi fuori banda e fuori banda nel contesto di un MFT.

La progettazione MFT originale supporta gli eventi in banda . Un evento in banda contiene informazioni sul flusso di dati, ad esempio informazioni su una modifica del formato. Il client invia eventi in banda al MFT chiamando IMFTransform::P rocessEvent. MFT può inviare eventi in banda al client nel metodo ProcessOutput . In particolare, gli eventi vengono trasmessi nel membro pEvents della struttura MFT_OUTPUT_DATA_BUFFER .

Un MFT invia eventi fuori banda tramite l'interfaccia IMFMediaEventGenerator come indicato di seguito:

  1. MFT implementa l'interfaccia IMFMediaEventGenerator , come descritto in Generatori di eventi multimediali.
  2. Il client chiama IUnknown::QueryInterface sull'interfaccia MFT per l'interfaccia IMFMediaEventGenerator . Un MFT asincrono deve esporre questa interfaccia. Le mft sincrone non devono esporre questa interfaccia.
  3. Il client chiama IMFMediaEventGenerator::BeginGetEvent e IMFMediaEventGenerator::EndGetEvent per ricevere eventi fuori banda dal MFT.

ProcessInput

Il metodo IMFTransform::P rocessInput viene modificato nel modo seguente:

  1. All'avvio del flusso, il client invia il messaggio di MFT_MESSAGE_NOTIFY_START_OF_STREAM .
  2. Durante lo streaming, MFT richiede i dati inviando un evento METransformNeedInput . I dati dell'evento sono l'identificatore del flusso.
  3. Per ogni evento METransformNeedInput , il client chiama ProcessInput per il flusso specificato.
  4. Al termine del flusso, il client può chiamare ProcessMessage con il messaggio MFT_MESSAGE_NOTIFY_END_OF_STREAM .

Note sull'implementazione:

ProcessOutput

Il metodo IMFTransform::P rocessOutput viene modificato nel modo seguente:

  1. Ogni volta che MFT ha output, invia un evento METransformHaveOutput .
  2. Per ogni evento METransformHaveOutput , il client chiama ProcessOutput.

Note sull'implementazione:

  • Se il client chiama ProcessOutput in qualsiasi altro momento, il metodo restituisce E_UNEXPECTED.
  • Un MFT asincrono non deve mai restituire MF_E_TRANSFORM_NEED_MORE_INPUT dal metodo ProcessOutput . Se MFT richiede più input, invia un evento METransformNeedInput .

Drenante

Lo svuotamento di un MFT fa sì che il MFT producano l'output possibile da qualsiasi dato di input già inviato. Lo svuotamento di un MFT asincrono funziona come segue:

  1. Il client invia il messaggio di MFT_MESSAGE_COMMAND_DRAIN .
  2. MFT continua a inviare eventi METransformHaveOutput finché non contiene altri dati da elaborare. Non invia eventi METransformNeedInput durante questo periodo.
  3. Dopo che MFT invia l'ultimo evento METransformHaveOutput , invia un evento METransformDrainComplete .

Al termine dello svuotamento, MFT non invia un altro evento METransformNeedInput finché non riceve un messaggio MFT_MESSAGE_NOTIFY_START_OF_STREAM dal client.

Flushing

Il client può scaricare MFT inviando il messaggio di MFT_MESSAGE_COMMAND_FLUSH . MFT elimina tutti gli esempi di input e output che contiene.

MFT non invia un altro evento METransformNeedInput finché non riceve un messaggio MFT_MESSAGE_NOTIFY_START_OF_STREAM dal client.

Marcatori

Il client può contrassegnare un punto nel flusso inviando il messaggio MFT_MESSAGE_COMMAND_MARKER . Il MFT risponde come segue:

  1. MFT genera tutti gli esempi di output possibili dai dati di input esistenti, inviando un evento METransformHaveOutput per ogni esempio di output.
  2. Dopo la generazione di tutti gli output, MFT invia un evento METransformMarker . Questo evento deve essere inviato dopo tutti gli eventi METransformHaveOutput .

Si supponga, ad esempio, che un decodificatore disponga di dati di input sufficienti per produrre quattro esempi di output. Se il client invia il messaggio di MFT_MESSAGE_COMMAND_MARKER , MFT accoderà quattro eventi METransformHaveOutput (uno per ogni esempio di output), seguito da un evento METransformMarker .

Il messaggio del marcatore è simile al messaggio di svuotamento. Tuttavia, un svuotamento viene considerato un'interruzione nel flusso, mentre un marcatore non è. Lo svuotamento e i marcatori presentano le differenze seguenti.

Drenante:

  • Durante lo svuotamento, MFT non invia eventi METransformNeedInput .
  • MFT rimuove tutti i dati di input che non possono essere usati per creare un esempio di output.
  • Alcune MFP producono una "coda" alla fine dei dati. Ad esempio, effetti audio come riverbero o eco producono dati aggiuntivi dopo l'arresto dei dati di input. Un MFT che genera una coda deve farlo alla fine di un'operazione di scarico.
  • Al termine dello svuotamento di MFT, contrassegna l'esempio di output successivo con l'attributo MFSampleExtension_Discontinuity , per indicare una discontinuità nel flusso.

Marcatore:

  • MFT continua a inviare eventi METransformNeedInput prima di inviare l'evento marcatore.
  • MFT non rimuove i dati di input. Se sono presenti dati parziali, l'elaborazione deve essere eseguita dopo il punto del marcatore.
  • MFT non produce una coda in corrispondenza del punto del marcatore.
  • MFT non imposta il flag di discontinuità dopo il punto del marcatore.

Modifiche al formato

Un MFT asincrono deve supportare le modifiche al formato dinamico, come descritto in Gestione delle modifiche del flusso.

Attributi

Un MFT asincrono deve implementare il metodo IMFTransform::GetAttributes per restituire un archivio attributi valido. Gli attributi seguenti si applicano alle MFP asincrone:

Attributo Descrizione
MF_TRANSFORM_ASYNC MFT deve impostare questo attributo su TRUE (1). Il client può eseguire una query su questo attributo per determinare se MFT è asincrono.
MF_TRANSFORM_ASYNC_UNLOCK
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE MFT deve impostare questo attributo su TRUE (1). Il client può presupporre che questo attributo sia impostato.

 

Sblocco di mft asincroni

Le MFP asincrone non sono compatibili con il modello di elaborazione dati MFT originale. Per evitare l'interruzione di applicazioni esistenti asincrone, viene definito il meccanismo seguente:

Il client chiama IMFTransform::GetAttributes su MFT. Il client esegue una query su per questo attributo MF_TRANSFORM_ASYNC . Per un MFT asincrono, il valore di questo attributo è **TRUE**. Per sbloccare MFT, il client deve impostare l'attributo MF_TRANSFORM_ASYNC_UNLOCK su **TRUE**.

Fino a quando il client non sblocca MFT, tutti i metodi IMFTransform devono restituire MF_E_TRANSFORM_ASYNC_LOCKED, con le eccezioni seguenti:

Il codice seguente illustra come sbloccare un MFT asincrono:

HRESULT UnlockAsyncMFT(IMFTransform *pMFT)
{
    IMFAttributes *pAttributes = NULL;

    HRESULT hr = hr = pMFT->GetAttributes(&pAttributes);

    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
        pAttributes->Release();
    }
    
    return hr;
}

Arresto del MFT

Le MFP asincrone devono implementare l'interfaccia IMFShutdown .

  • Shutdown: MFT deve arrestare la coda degli eventi. Se si usa la coda di eventi standard, chiamare IMFMediaEventQueue::Shutdown. Facoltativamente, MFT può rilasciare altre risorse. Il client non deve usare MFT dopo la chiamata a Shutdown.
  • GetShutdownStatus: dopo la chiamata a Shutdown , MFT deve restituire il valore MFSHUTDOWN_COMPLETED nel parametro pStatus . Non deve restituire il valore MFSHUTDOWN_INITIATED.

Registrazione ed enumerazione

Per registrare un MFT asincrono, chiamare la funzione MFTRegister e impostare il flag MFT_ENUM_FLAG_ASYNCMFT nel parametro Flags . In precedenza questo flag era riservato.

Per enumerare le MFTEnumEx asincrone, chiamare la funzione MFTEnumEx e impostare il flag MFT_ENUM_FLAG_ASYNCMFT nel parametro Flags . Per garantire la compatibilità con le versioni precedenti, la funzione MFTEnum non enumera le MFTEnum asincrone. In caso contrario, l'installazione di un MFT asincrono nel computer dell'utente potrebbe interrompere le applicazioni esistenti.

Trasformazioni di Media Foundation