Asynchronní MFT
Toto téma popisuje asynchronní zpracování dat pro transformace Media Foundation (MFT).
Poznámka
Toto téma se týká Windows 7 nebo novějšího.
- o asynchronních MFT
- obecné požadavky
- událostí
- ProcessInput
- ProcessOutput
- vyprázdnění
- vyprazdňování
- značky
- změny formátu
- atributů
- odemknutí asynchronních MFT
- vypnutí MFT
- registrace a výčtu
- související témata
Asynchronní MFT
Když byly v systému Windows Vista zavedeny MFT, rozhraní API bylo navrženo pro synchronní zpracování dat. V daném modelu MFT vždy čeká na vstup nebo čeká na vytvoření výstupu.
Zvažte typický dekodér videa. Chcete-li získat dekódovaný rámec, klient volá MMFTransform::P rocessOutput. Pokud má dekodér dostatek dat k dekódování rámce, ProcessOutput bloky, zatímco MFT dekóduje rámec. V opačném případě ProcessOutput vrátí MF_E_TRANSFORM_NEED_MORE_INPUT, což znamená, že klient by měl volat MMFTransform::P rocessInput.
Tento model funguje dobře, pokud dekodér provádí všechny své dekódovací operace na jednom vlákně. Předpokládejme ale, že dekodér používá k dekódování rámců paralelně několik vláken. Pro nejlepší výkon by dekodér měl přijímat nový vstup pokaždé, když se dekódovací vlákno stane nečinné. Rychlost, s jakou vlákna dokončí dekódovací operace, ale nebudou přesně odpovídat volání klienta ProcessInput a ProcessOutput, což vede k tomu, že vlákna čekají na práci.
Systém Windows 7 zavádí asynchronní zpracování asynchronní pro MFT. V tomto modelu, kdykoli MFT potřebuje vstup nebo má výstup, odešle událost klientovi.
Obecné požadavky
Toto téma popisuje, jak se asynchronní MFT liší od synchronního MFT. S výjimkou případů, kdy jsou uvedené v tomto tématu, jsou dva modely zpracování stejné. (Zejména vyjednávání formátu je stejné.)
Asynchronní MFT musí implementovat následující rozhraní:
Dění
Asynchronní MFT používá k signalizaci stavu zpracování dat následující události:
Událost | Popis |
---|---|
METransformNeedInput | Odesláno, když MFT může přijmout další vstup. |
METransformHaveOutput | Odesláno, když má MFT výstup. |
METransformDrainComplete | Odesláno po dokončení operace vyprázdnění. Viz vyprázdnění. |
METransformMarker | Odesláno při procesu značky. Viz značky. |
Tyto události se odesílají mimo pásmo. Je důležité pochopit rozdíl mezi událostmi v pásmu a mimo pásmo v kontextu MFT.
Původní návrh MFT podporuje událostí v pásmu. Událost v pásmu obsahuje informace o datovém streamu, například informace o změně formátu. Klient odesílá do MFT události v pásmu voláním MMFTransform::P rocessEvent. MFT může odesílat události v pásmu zpět klientovi v metodě ProcessOutput. (Konkrétně se události předávají v pEvents člen struktury MFT_OUTPUT_DATA_BUFFER.)
MFT odesílá vzdálené události prostřednictvím rozhraní MMFMediaEventGenerator následujícím způsobem:
- MFT implementuje MMFMediaEventGenerator rozhraní, jak je popsáno v Media Event Generators.
- Klient volá IUnknown::QueryInterface na MFT pro rozhraní MMFMediaEventGenerator. Asynchronní MFT musí toto rozhraní zveřejnit. Synchronní MFT by toto rozhraní neměly zveřejnit.
- Klient volá MMFMediaEventGenerator::BeginGetEvent a MMFMediaEventGenerator::EndGetEvent pro příjem nesměrných událostí z MFT.
ProcessInput
Metoda MMFTransform::P rocessInput metoda je upravena následujícím způsobem:
- Při spuštění streamování klient odešle zprávu MFT_MESSAGE_NOTIFY_START_OF_STREAM.
- Během streamování MFT požaduje data odesláním události METransformNeedInput. Data události jsou identifikátorem datového proudu.
- Pro každou událost METransformNeedInput klient volá ProcessInput pro zadaný datový proud.
- Na konci streamování může klient volat ProcessMessage se zprávou MFT_MESSAGE_NOTIFY_END_OF_STREAM.
Poznámky k implementaci:
- MFT nesmí odesílat žádné události METransformNeedInput, dokud neobdrží zprávu MFT_MESSAGE_NOTIFY_START_OF_STREAM.
- Během streamování může MFT kdykoli odesílat události METransformNeedInput.
- MFT by měl udržovat počet čekajících METransformNeedInput událostí. Jakékoli volání ProcessInput, která neodpovídá události METransformNeedInput, musí vrátit MF_E_NOTACCEPTING.
- Když MFT obdrží MFT_MESSAGE_NOTIFY_END_OF_STREAM zprávu, resetuje počet čekajících METransformNeedInput události na nulu.
- Po přijetí zprávy MFT_MESSAGE_NOTIFY_END_OF_STREAM nesmí MFT odesílat žádné události METransformNeedInput.
- Je-li ProcessInput volána před MFT_MESSAGE_NOTIFY_START_OF_STREAM nebo po MFT_MESSAGE_NOTIFY_END_OF_STREAM, metoda musí vrátit MF_E_NOTACCEPTING.
ProcessOutput
Metoda MMFTransform::P rocessOutput metoda je upravena následujícím způsobem:
- Kdykoli má MFT výstup, odešle METransformHaveOutput událost.
- Pro každou událost METransformHaveOutput klient volá ProcessOutput.
Poznámky k implementaci:
- Pokud klient volá ProcessOutput kdykoli jindy, vrátí metoda E_UNEXPECTED.
- Asynchronní MFT by nikdy neměl vracet MF_E_TRANSFORM_NEED_MORE_INPUT z metody ProcessOutput. Pokud MFT vyžaduje více vstupu, odešle METransformNeedInput událost.
Vypouštění
Vyprázdnění MFT způsobí, že MFT vytvoří co nejvíce výstupu ze vstupních dat, která už byla odeslána. Vyprazdňování asynchronního MFT funguje takto:
- Klient odešle zprávu MFT_MESSAGE_COMMAND_DRAIN.
- MFT nadále odesílá METransformHaveOutput událostí, dokud nebude zpracovávat žádná další data. Během této doby neodesílá události METransformNeedInput.
- Jakmile MFT odešle poslední událost METransformHaveOutput, odešle událost METransformDrainComplete.
Po dokončení vyprázdnění MFT neodesílá další METransformNeedInput událost, dokud neobdrží zprávu MFT_MESSAGE_NOTIFY_START_OF_STREAM od klienta.
Zaplavování
Klient může Vyprázdnit MFT odesláním MFT_MESSAGE_COMMAND_FLUSH zprávy. MFT zahodí všechny vstupní a výstupní vzorky, které drží.
MFT neodesílá další METransformNeedInput událost, dokud neobdrží MFT_MESSAGE_NOTIFY_START_OF_STREAM zprávu od klienta.
Záložky
Klient může označit bod v datovém proudu odesláním MFT_MESSAGE_COMMAND_MARKER zprávy. MFT reaguje takto:
- MFT generuje tolik výstupních ukázek, kolik může z existujících vstupních dat odesílat METransformHaveOutput událost pro každou ukázku výstupu.
- Po vygenerování veškerého výstupu odešle MFT událost METransformMarker. Tato událost musí být odeslána po všech událostech METransformHaveOutput.
Předpokládejme například, že dekodér má dostatek vstupních dat pro vytvoření čtyř výstupních vzorků. Pokud klient odešle zprávu MFT_MESSAGE_COMMAND_MARKER, MFT zařadí čtyři METransformHaveOutput události (jedna na ukázku výstupu), následované událostí METransformMarker.
Zpráva značky je podobná zprávě o odtoku. Nicméně, odtok je považován za přerušení v toku, zatímco značka není. Vyprazdňování a značky mají následující rozdíly.
Vypouštění:
- Při vyprázdnění MFT neodesílá události METransformNeedInput.
- MFT zahodí všechna vstupní data, která nelze použít k vytvoření výstupní ukázky.
- Některé MFT vytvoří na konci dat "ocas". Například zvukové efekty, jako je reverb nebo ozvěna, po zastavení vstupních dat vytvářejí další data. MFT, který vygeneruje ocas, by to měl provést na konci operace vyprázdnění.
- Po dokončení vyprázdnění MFT označí další výstupní ukázku s atributem MFSampleExtension_Discontinuity, který označuje přerušení datového proudu.
Značkovač:
- MFT nadále odesílá METransformNeedInput události před odesláním události značky.
- MFT nezahodí žádná vstupní data. Pokud existují částečná data, měla by se zpracovat za bodem značky.
- MFT nevytvoří ocas v bodě značky.
- MFT nenastaví příznak přerušení za bodem značky.
Formátování změn
Asynchronní MFT musí podporovat změny dynamického formátu, jak je popsáno v tématu Zpracování změn datových proudů.
Atributy
Asynchronní MFT musí implementovat MMFTransform::GetAttributes metoda pro vrácení platného úložiště atributů. Následující atributy platí pro asynchronní MFT:
Atribut | Popis |
---|---|
MF_TRANSFORM_ASYNC | MFT musí tento atribut nastavit na TRUE (1). Klient se může dotazovat na tento atribut a zjistit, jestli je MFT asynchronní. |
MF_TRANSFORM_ASYNC_UNLOCK | |
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE | MFT musí tento atribut nastavit na TRUE (1). Klient může předpokládat, že je tento atribut nastavený. |
Odemknutí asynchronních MFT
Asynchronní MFT nejsou kompatibilní s původním modelem zpracování dat MFT. Aby se zabránilo přerušení existujících aplikací asynchronním MFT, definuje se následující mechanismus:
- Klient volá MMFTransform::GetAttributes v MFT.
Klient se dotazuje na tento atribut MF_TRANSFORM_ASYNC. U asynchronního MFT je hodnota tohoto atributu **TRUE**.
Aby klient odemkl MFT, musí nastavit atribut MF_TRANSFORM_ASYNC_UNLOCK na **TRUE**.
Dokud klient odemkne MFT, všechny MMFTransform metody by měly vrátit MF_E_TRANSFORM_ASYNC_LOCKED, s následujícími výjimkami:
- MMFTransform::GetAttributes (všechny asynchronní MFT)
- MMFTransform::GetInputAvailableType (všechny asynchronní MFT)
- MMFTransform::GetOutputCurrentType (pouze kodéry)
- MMFTransform::SetOutputType (pouze kodéry)
- MMFTransform::GetStreamCount (všechny asynchronní MFT)
- MMFTransform::GetStreamIDs (všechny asynchronní MFT)
Následující kód ukazuje, jak odemknout asynchronní MFT:
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;
}
Vypnutí MFT
Asynchronní MFT musí implementovat rozhraní MMFShutdown.
- Vypnutí: MFT musí vypnout frontu událostí. Pokud používáte standardní frontu událostí, zavolejte MMFMediaEventQueue::Shutdown. Volitelně může MFT uvolnit další prostředky. Klient nesmí používat MFT po volání Vypnout.
- GetShutdownStatus: Po zavolání vypnutí by měl MFT vrátit hodnotu MFSHUTDOWN_COMPLETED v parametru pStatus. Neměl by vracet hodnotu MFSHUTDOWN_INITIATED.
Registrace a výčet
Pokud chcete zaregistrovat asynchronní MFT, zavolejte funkci MFTRegister a nastavte příznak MFT_ENUM_FLAG_ASYNCMFT v parametru Flags. (Dříve byl tento příznak rezervován.)
Pokud chcete vytvořit výčet asynchronních MFT, zavolejte funkci MFTEnumEx a nastavte příznak MFT_ENUM_FLAG_ASYNCMFT v parametru Flags. Z důvodu zpětné kompatibility funkce MFTEnum nevypisuje asynchronní MFT. Jinak by instalace asynchronního MFT na počítač uživatele mohla narušit stávající aplikace.
Související témata