MFP asincroni
In questo argomento viene descritta 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
- requisiti generali
- eventi
- ProcessInput
- ProcessOutput
- svuotamento
- scaricamento
- indicatori
- modifiche al formato
- attributi
- sblocco di MFP asincrone
- arrestare il MFT
- registrazione ed enumerazione
- argomenti correlati
Informazioni sulle MFP asincrone
Quando le MFP sono state introdotte in Windows Vista, l'API è stata progettata per l'elaborazione sincrona dei dati. In tale modello, MFT è sempre in attesa di ottenere l'input o in attesa di produrre l'output.
Si consideri un tipico decodificatore video. 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, che indica che il client deve chiamare IMFTransform::P rocessInput.
Questo modello funziona correttamente 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 di asincrona basata su 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 come 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:
Avvenimenti
Un MFT asincrono usa gli eventi seguenti per segnalare lo stato di elaborazione dei dati:
Evento | Descrizione |
---|---|
METransformNeedInput | Inviato quando MFT può accettare più input. |
METransformHaveOutput | Inviato quando MFT ha output. |
METransformDrainComplete | Inviato al termine di un'operazione di svuotamento. Vedere svuotamento. |
METransformMarker | Inviato quando viene elaborato un marcatore. 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 eventi di 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 a MFT chiamando IMFTransform::P rocessEvent. L'MFT può inviare eventi in banda al client nel metodo ProcessOutput. In particolare, gli eventi vengono trasmessi nel membro della struttura MFT_OUTPUT_DATA_BUFFER.
Un MFT invia eventi fuori banda tramite l'interfaccia IMFMediaEventGenerator come indicato di seguito:
- MFT implementa l'interfacciaIMFMediaEventGenerator, come descritto in Generatori di eventi multimediali.
- Il client chiama IUnknown::QueryInterface sull'interfaccia MFT per l'interfacciaIMFMediaEventGenerator. Un MFT asincrono deve esporre questa interfaccia. Le MFP sincrone non devono esporre questa interfaccia.
- Il client chiama IMFMediaEventGenerator::BeginGetEvent e IMFMediaEventGenerator::EndGetEvent per ricevere eventi fuori banda da MFT.
ProcessInput
Il metodo IMFTransform::P rocessInput viene modificato come segue:
- All'avvio del flusso, il client invia il messaggio di MFT_MESSAGE_NOTIFY_START_OF_STREAM.
- Durante lo streaming, MFT richiede i dati inviando un evento METransformNeedInput. I dati dell'evento sono l'identificatore del flusso.
- Per ogni evento METransformNeedInput, il client chiama ProcessInput per il flusso specificato.
- Al termine dello streaming, il client può chiamare ProcessMessage con il messaggio di MFT_MESSAGE_NOTIFY_END_OF_STREAM.
Note sull'implementazione:
- MFT non deve inviare alcun evento METransformNeedInput finché non riceve il messaggio di MFT_MESSAGE_NOTIFY_START_OF_STREAM.
- Durante lo streaming, MFT può inviare EVENTI METransformNeedInput in qualsiasi momento.
- MFT deve mantenere un conteggio degli eventi METransformNeedInput in sospeso. Qualsiasi chiamata a ProcessInput che non corrisponde a un evento METransformNeedInput deve restituire MF_E_NOTACCEPTING.
- Quando MFT riceve il messaggio di MFT_MESSAGE_NOTIFY_END_OF_STREAM, reimposta il conteggio degli eventi METransformNeedInput in sospeso su zero.
- MFT non deve inviare eventi METransformNeedInput dopo aver ricevuto il messaggio di MFT_MESSAGE_NOTIFY_END_OF_STREAM.
- Se ProcessInput viene chiamato prima di MFT_MESSAGE_NOTIFY_START_OF_STREAM o dopo MFT_MESSAGE_NOTIFY_END_OF_STREAM, il metodo deve restituire MF_E_NOTACCEPTING.
ProcessOutput
Il metodo IMFTransform::P rocessOutput viene modificato nel modo seguente:
- Ogni volta che MFT ha output, invia un evento METransformHaveOutput.
- 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 metodoProcessOutput. Se MFT richiede più input, invia un evento METransformNeedInput.
Scolatura
Lo svuotamento di un MFT fa sì che il MFT producano il maggior numero di output possibile da qualsiasi dato di input già inviato. Lo svuotamento di un MFT asincrono funziona come segue:
- Il client invia il messaggio di MFT_MESSAGE_COMMAND_DRAIN.
- MFT continua a inviare eventi METransformHaveOutput fino a quando non ha più dati da elaborare. Non invia eventi METransformNeedInput durante questo periodo.
- 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.
Flussaggio
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:
- MFT genera tutti gli esempi di output che possono essere generati dai dati di input esistenti, inviando un evento METransformHaveOutput per ogni esempio di output.
- Dopo aver generato tutto l'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 dell'indicatore è simile al messaggio di svuotamento. Tuttavia, uno scarico viene considerato un'interruzione nel flusso, mentre un marcatore non è. Lo svuotamento e i marcatori presentano le differenze seguenti.
Scolatura:
- Durante lo svuotamento, MFT non invia eventi METransformNeedInput.
- MFT elimina 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 svuotamento.
- Al termine dell'svuotamento 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 del marcatore.
- MFT non rimuove alcun dato di input. Se sono presenti dati parziali, è necessario elaborarli dopo il punto dell'indicatore.
- L'MFT non produce una coda in corrispondenza del punto del marcatore.
- MFT non imposta il flag di discontinuità dopo il punto dell'indicatore.
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 mft 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:
- IMFTransform::GetAttributes (tutte le MFP asincrone)
- IMFTransform::GetInputAvailableType (tutte le MMF asincrone)
- IMFTransform::GetOutputCurrentType (solo codificatori)
- IMFTransform::SetOutputType (solo codificatori)
- IMFTransform::GetStreamCount (tutte le MFP asincrone)
- IMFTransform::GetStreamIDs (tutte le MMF asincrone)
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'interfacciaIMFShutdown.
- Shutdown: L'MFT deve arrestare la coda di 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 aver chiamato Shutdown.
- GetShutdownStatus: dopo aver chiamato Shutdown, MFT restituirà il valore MFSHUTDOWN_COMPLETED nel parametro pStatus. Non deve restituire il valore MFSHUTDOWN_INITIATED.
Registrazione ed enumerazione
Per registrare un MFT asincrono, chiamare la funzioneMFTRegistere impostare il flag MFT_ENUM_FLAG_ASYNCMFT nel parametro flag. In precedenza questo flag era riservato.
Per enumerare le funzioni a più fattori asincrone, chiamare la funzioneMFTEnumExe impostare il flag MFT_ENUM_FLAG_ASYNCMFT nel parametro Flag. Per garantire la compatibilità con le versioni precedenti, la funzioneMFTEnumnon enumera le MFTEnum asincrone. In caso contrario, l'installazione di un MFT asincrono nel computer dell'utente potrebbe interrompere le applicazioni esistenti.
Argomenti correlati