Sdílet prostřednictvím


Základní model zpracování MFT

Toto téma popisuje, jak klient ke zpracování dat používá transformaci Media Foundation (MFT). Klient je cokoli, co přímo volá metody v MFT. Může se jednat o aplikaci nebo zpracovatelský řetězec Media Foundation.

Pokud jste, přečtěte si toto téma:

  • Psaní aplikace, která provádí přímé volání na jednu nebo více MFT.
  • Píšete vlastní MFT a chcete porozumět očekávanému chování MFT.

Model synchronního zpracování je popsán v tomto tématu . V tomto modelu se všechny metody zpracování dat blokují, dokud nebudou dokončeny. MFT mohou také podporovat asynchronní model, který je popsán v tématu asynchronní MFT.

Základní model zpracování

Vytvořte MFT

Existuje několik způsobů, jak vytvořit MFT:

  • Zavolejte funkci MFTEnum
  • Zavolejte funkci MFTEnumEx
  • Pokud už znáte CLSID MFT, jednoduše zavolejte CoCreateInstance.

Některé MFT můžou poskytovat další možnosti, jako je specializovaná funkce pro vytváření.

Získání identifikátorů streamu

MFT má jeden nebo více proudů . Vstupní datové proudy přijímají vstupní data a výstupní datové proudy generují výstupní data. Datové proudy nejsou reprezentovány jako odlišné objekty. Místo toho různé metody MFT přebírají identifikátory datových proudů jako parametry.

Některé MFT umožňují klientovi přidávat nebo odebírat vstupní streamy. Během streamování může MFT přidávat nebo odebírat výstupní streamy. (Klient nemůže přidat nebo odebrat výstupní streamy.)

  1. (Volitelné.) Zavolejte IMFTransform::GetStreamLimits, abyste získali minimální a maximální počet datových proudů, které MFT může podporovat. Pokud je minimum a maximum stejné, MFT má pevný počet datových proudů.
  2. Volání IMFTransform::GetStreamCount k získání počátečního počtu datových proudů.
  3. Zavolejte IMFTransform::GetStreamIDs pro získání identifikátorů datového proudu. Pokud tato metoda vrátí E_NOTIMPL, znamená to, že MFT má pevný počet datových proudů a identifikátory datových proudů jsou po sobě jdoucí od nuly.
  4. (Volitelné.) Pokud MFT nemá pevný počet datových proudů, zavolejte MMFTransform::AddInputStreams přidat další vstupní proudy, nebo MMFTransform::D eleteInputStream odebrat vstupní proudy. (Výstupní streamy nelze přidat ani odebrat.)

Nastavení typů médií

Aby mohl MFT zpracovávat data, musí klient nastavit typy médií pro každý datový proud MFT. MFT může vyžadovat, aby klient před nastavením výstupních typů nastavil vstupní typy nebo mohl vyžadovat opačné pořadí (napřed typy výstupu). Některé MFT nemají požadavek na objednávku.

MFT může poskytnout seznam upřednostňovaných typů médií pro datový proud. MFT mohou také označit obecné formáty, které podporují, přidáním těchto informací do registru.

Chcete-li nastavit typy médií, postupujte takto:

  1. (Volitelné.) Pro každý vstupní datový proud zavolejte MMFTransform::GetInputAvailableType získat seznam upřednostňovaných typů pro daný datový proud.
    • Pokud tato metoda vrátí MF_E_TRANSFORM_TYPE_NOT_SET, musíte nejprve nastavit výstupní typy; přejděte ke kroku 3.
    • Pokud metoda vrátí E_NOTIMPL, MFT nemá seznam upřednostňovaných typů vstupu; přejděte ke kroku 2.
  2. Pro každý vstupní datový proud volejte IMFTransform::SetInputType pro nastavení typu vstupu. Typ média můžete použít z kroku 1 nebo typ, který popisuje vaše vstupní data. Pokud některý datový proud vrátí MF_E_TRANSFORM_TYPE_NOT_SET, přeskočte ke kroku 3.
  3. (Volitelné.) Pro každý výstupní datový proud zavolejte MMFTransform::GetOutputAvailableType získat seznam upřednostňovaných typů pro daný datový proud.
    • Pokud tato metoda vrátí MF_E_TRANSFORM_TYPE_NOT_SET, musíte nejprve nastavit vstupní typy; vraťte se ke kroku 1.
    • Pokud některý datový proud vrátí E_NOTIMPL, MFT nemá seznam upřednostňovaných typů výstupu; přejděte ke kroku 4.
  4. Pro každý výstupní datový proud zavolejte IMFTransform::SetOutputType k nastavení typu výstupu. Typ média můžete použít z kroku 3 nebo typ, který popisuje požadovaný výstupní formát.
  5. Pokud některé vstupní datové proudy nemají typ média, vraťte se ke kroku 1.

Získání požadavků na vyrovnávací paměť

Jakmile klient nastaví typy médií, měl by získat požadavky na vyrovnávací paměť pro každý datový proud:

Zpracování dat

MFT je navržený tak, aby byl spolehlivým stavovým počítačem. Neprovádí žádná volání zpět klientovi.

  1. Volání IMFTransform::ProcessMessage se zprávou MFT_MESSAGE_NOTIFY_BEGIN_STREAMING. Tato zpráva požádá MFT o přidělení prostředků, které potřebuje během streamování.
  2. Volání MMFTransform::P rocessInput na alespoň jednom vstupním datovém proudu k doručení vstupní ukázky do MFT.
  3. (Volitelné.) Zavolejte IMFTransform::GetOutputStatus pro zjištění, zda MFT může vygenerovat výstupní vzorek. Pokud metoda vrátí S_OK, zkontrolujte pdwFlags parametr. Pokud pdwFlags obsahuje příznak MFT_OUTPUT_STATUS_SAMPLE_READY, přejděte ke kroku 4. Pokud pdwFlags je nula, vraťte se ke kroku 2. Pokud metoda vrátí E_NOTIMPL, přejděte ke kroku 4.
  4. Chcete-li volat IMFTransform::ProcessOutput pro získání výstupních dat.
    • Pokud metoda vrátí MF_E_TRANSFORM_NEED_MORE_INPUT, znamená to, že MFT vyžaduje více vstupních dat; vraťte se ke kroku 2.
    • Pokud metoda vrátí MF_E_TRANSFORM_STREAM_CHANGE, znamená to, že se změnil počet výstupních datových proudů nebo se změnil výstupní formát. Klient může potřebovat zadat dotaz na nové identifikátory datových proudů nebo nastavit nové typy médií. Další informace najdete v dokumentaci pro ProcessOutput.
  5. Pokud se stále zpracovávají vstupní data, přejděte ke kroku 2. Pokud MFT spotřeboval všechna dostupná vstupní data, přejděte ke kroku 6.
  6. Volání ProcessMessage se zprávou MFT_MESSAGE_NOTIFY_END_OF_STREAM.
  7. Volání ProcessMessage se zprávou MFT_MESSAGE_COMMAND_DRAIN.
  8. Pokud chcete získat zbývající výstup, zavolejte ProcessOutput. Tento krok opakujte, dokud metoda nevrátí MF_E_TRANSFORM_NEED_MORE_INPUT. Tato návratová hodnota signalizuje, že veškerý výstup byl vyčerpán z MFT. (Nezacházejte s tím jako s chybovou podmínkou.)

Posloupnost popsaná zde uchovává co nejméně dat v MFT. Po každém volání ProcessInputse klient pokusí získat výstup. K vytvoření jednoho výstupního vzorku může být potřeba několik vstupních vzorků nebo jeden vstupní vzorek může vygenerovat několik výstupních vzorků. Optimální chování klienta je stahovat výstupní vzorky z MFT, dokud MFT nepožaduje více vstupu.

MFT by však měl být schopen zpracovat jiné pořadí volání metod klientem. Klient může například jednoduše přecházet mezi voláními ProcessInput a ProcessOutput. MFT by měl omezit množství vstupu, které získá, vrácením MF_E_NOTACCEPTING z ProcessInput, kdykoli má nějaký výstup k vytvoření.

Pořadí volání metody popsané zde není jedinou platnou posloupností událostí. Například kroky 3 a 4 předpokládají, že klient začíná vstupními typy a pak zkouší výstupní typy. Klient může také obrátit toto pořadí a začít s výstupními typy. V obou případech, pokud MFT vyžaduje opačné pořadí, by měl vrátit kód chyby MF_E_TRANSFORM_TYPE_NOT_SET.

Klient může volat informační metody, například GetInputCurrentType a GetOutputStreamInfo, kdykoli během streamování. Klient se také může kdykoli pokusit změnit typy médií. MFT by měl vrátit kód chyby, pokud se nejedná o platnou operaci. Stručně řečeno, MFT by měly předpokládat velmi málo o pořadí operací, kromě toho, co je zdokumentované v samotných voláních.

Následující diagram znázorňuje vývojový diagram postupů popsaných v tomto tématu.

vývojový diagram, který vede od získání identifikátorů datových proudů přes smyčky, které nastavují vstupní typy, získávají vstupy a zpracovávají výstupy

Rozšíření základního modelu

Volitelně může MFT podporovat některá rozšíření základního modelu streamování.

  • Opožděné datové proudy pro čtení Pokud metoda IMFTransform::GetOutputStreamInfo vrátí příznak MFT_OUTPUT_STREAM_LAZY_READ pro výstupní proud, klient nemusí shromažďovat data z daného výstupního proudu. MFT nadále přijímá vstup a V určitém okamžiku MFT zahodí výstupní data z tohoto datového proudu. Pokud všechny výstupní streamy mají tento příznak, MFT nikdy neodmítne přijetí vstupu. Příkladem může být transformace vizualizace, kde klient získá výstup pouze v případě, že má k vykreslení vizualizace náhradní cykly procesoru.
  • Zahoditelné datové proudy Pokud GetOutputStreamInfo metoda vrátí příznak MFT_OUTPUT_STREAM_DISCARDABLE pro výstupní datový proud, klient může požádat MFT o zahození výstupu, ale MFT nezahodí žádný výstup, pokud není požadován. Když MFT dosáhne maximální vstupní vyrovnávací paměti, klient musí buď shromáždit nějaká výstupní data, nebo požádat MFT, aby zahodil výstup.
  • Volitelné datové proudy. Pokud metoda GetOutputStreamInfo vrátí příznak MFT_OUTPUT_STREAM_OPTIONAL pro výstupní datový proud nebo MMFTransform::GetInputStreamInfo metoda vrátí příznak MFT_INPUT_STREAM_OPTIONAL vstupního datového proudu, je tento datový proud volitelný. Klient nemusí ve streamu nastavovat typ média. Pokud klient nenastaví typ, datový proud se zruší. Nevybraný výstupní datový proud nevytváří vzorky a klient neposkytuje vyrovnávací paměť pro datový proud při volání ProcessOutput. Nevybraný vstupní datový proud nepřijímá vstupní data. MFT může označit všechny vstupní a výstupní streamy jako volitelné. Očekává se však, že aby MFT fungoval, musí být vybrán alespoň jeden vstup a jeden výstup.
  • Asynchronní zpracování. Model asynchronního zpracování byl zaveden ve Windows 7. Je popsáno v tématu Asynchronní MFT.

IMF2DBuffer

Pokud MFT zpracovává nekomprimovaná videodata, měla by k manipulaci s vyrovnávacími pamětmi vzorků použít rozhraní IMF2DBuffer. Chcete-li získat toto rozhraní, zadejte dotaz na rozhraní IMFMediaBuffer na libovolné vstupní nebo výstupní vyrovnávací paměti. Pokud není toto rozhraní použito, když je k dispozici, může vést k dalším kopiím vyrovnávací paměti. Pro správné použití tohoto rozhraní by transformace neměla uzamknout vyrovnávací paměť pomocí rozhraní IMFMediaBuffer, pokud je k dispozici rozhraní IMF2DBuffer.

Další informace o zpracování dat videa naleznete v tématu Nekomprimované vyrovnávací paměti videa.

Vyprázdnění MFT

vyprázdnění MFT způsobí, že MFT zahodí všechna vstupní data. To může způsobit přerušení ve výstupním datovém proudu. Klient by obvykle vyprázdnil MFT před hledáním nového bodu ve vstupním datovém proudu nebo přepnutím na nový vstupní datový proud, když se klient nezajímá o ztrátu dat.

Pokud chcete vyprázdnit MFT, zavolejte IMFTransform::ProcessMessage se zprávou MFT_MESSAGE_COMMAND_FLUSH.

Vyprázdnění MFT

Vyprázdnění MFT způsobí, že MFT vytvoří co nejvíce výstupu z již odeslaných vstupních dat. Pokud MFT nemůže vytvořit kompletní výstupní ukázku z dostupného vstupu, zahodí vstupní data. Klient obvykle vyprázdní MFT, když dosáhne konce zdrojového datového proudu, nebo bezprostředně před změnou formátu ve zdrojovém datovém proudu. Pokud chcete vyprázdnit MFT, postupujte takto:

  1. Zavolejte ProcessMessage se zprávou MFT_MESSAGE_COMMAND_DRAIN. Tato zpráva upozorní MFT, že by měla dodávat co nejvíce výstupních dat ze vstupních dat, která už byla odeslána.
  2. Až metoda ProcessOutput vrátí MF_E_TRANSFORM_NEED_MORE_INPUT, proveďte volání pro získání výstupních dat.

I když se MFT vyprázdní, nepřijme žádné další vstupy.

Ukázkové atributy

Vstupní vzorky můžou mít atributy, které je potřeba zkopírovat do odpovídajících výstupních vzorků.

Pro MFT s jedním vstupem a jedním výstupem můžete použít následující obecné pravidlo:

  • Pokud každá vstupní ukázka vytváří přesně jednu výstupní ukázku, můžete nechat klienta zkopírovat atributy. Vlastnost MFPKEY_EXATTRIBUTE_SUPPORTED nechejte nastavenou.
  • Pokud mezi vstupními vzorky a výstupními vzorky neexistuje shoda 1:1, musí MFT určit správné atributy pro výstupní vzorky. Nastavte vlastnost MFPKEY_EXATTRIBUTE_SUPPORTED na VARIANT_TRUE.

Nespojitosti

Diskontinuita je přerušení ve zvukovém nebo video streamu. Přerušení může být způsobeno vyřazenými pakety v síťovém připojení, poškozenými daty souborů, přepínačem z jednoho zdrojového datového proudu do jiného nebo širokou škálou jiných příčin. Přerušení se signalizují nastavením atributu MFSampleExtension_Discontinuity u první ukázky po přerušení. Ve středu vzorku není možné signalizovat přerušení. Proto by měla být posílána veškerá nesouvislá data v samostatných vzorcích.

Některé transformace, zejména ty, které zpracovávají nekomprimovaná data, jako jsou zvukové a video efekty, by měly ignorovat přerušení při zpracování vstupních dat. Tyto MFT jsou obecně navržené tak, aby zpracovávaly průběžná data a měly by zacházet s daty, která přijímají jako průběžná, i po přerušení.

Pokud MFT ignoruje přerušení vstupních dat, měl by pro výstupní ukázku nastavit příznak přerušení, pokud má výstupní ukázka stejné časové razítko jako vstupní ukázka. Pokud má výstupní ukázka jiné časové razítko, MFT však nemá šířit přerušení. (To by byl případ například v některých zvukových převzorkovačích.) Přerušení na nesprávném místě v datovém proudu je horší než žádné přerušení.

Většina dekodérů nemůže ignorovat přerušení, protože přerušení ovlivňuje interpretaci dalšího vzorku. Každá kódovací technologie, která používá kompresi mezi snímky, jako je MPEG-2, spadá do této kategorie. Některá schémata kódování používají pouze kompresi uvnitř rámce, například DV a MJPEG. Tyto dekodéry mohou bezpečně ignorovat přerušení.

Transformace, které reagují na přerušení, by obecně měly vypisovat tolik dat před přerušením, jak je to možné, a zbytek zahodit. Vstupní vzorek s příznakem přerušení by se měl zpracovat, jako by to byl první vzorek ve streamu. (Toto chování odpovídá zadanému pro zprávu MFT_MESSAGE_COMMAND_DRAIN.) Přesné podrobnosti ale budou záviset na formátu média.

Pokud dekodér nic nezmírní přerušení, měl by zkopírovat příznak přerušení do výstupních dat. Demultiplexery a další MFT, které pracují výhradně s komprimovanými daty, musí kopírovat všechny přerušení do výstupních datových proudů. V opačném případě nemusí podřízené komponenty správně dekódovat komprimovaná data. Obecně platí, že téměř vždy je správné přenést diskontinuity dál, pokud MFT obsahuje explicitní kód pro vyhlazení diskontinuit.

Změny dynamického formátu

Formáty se můžou během streamování měnit. Například poměr stran se může změnit uprostřed streamu videa.

Podrobnosti o tom, jak se změny datových proudů zpracovávají pomocí MFT, najdete v tématu Zpracování změn datových proudů.

Události streamu

Chcete-li odeslat událost do MFT, zavolejte IMFTransform::ProcessEvent. Pokud metoda vrátí MF_S_TRANSFORM_DO_NOT_PROPAGATE_EVENT, MFT vrátí událost volajícímu při následném volání ProcessOutput. Pokud metoda vrátí jakoukoli jinou hodnotu HRESULT, MFT nevrátí událost klientovi v ProcessOutput. V takovém případě je klient zodpovědný za šíření události dále do další komponenty v řetězci, je-li to vhodné. Další informace naleznete v tématu IMFTransform::ProcessOutput.

Media Foundation transformace