Sdílet prostřednictvím


Porovnání MFT a DMO

Transformace Media Foundation (MFT) jsou vývojem transformačního modelu, který byl poprvé představen s objekty DMO (DirectX Media Objects). Toto téma shrnuje hlavní způsoby, kterými se MFT liší od objektů dynamické správy. Toto téma si přečtěte, pokud už znáte rozhraní DMO nebo pokud chcete převést existující objekt DMO na MFT.

Toto téma obsahuje následující části:

Počet streamů

DMO má pevný počet datových proudů, zatímco MFT může podporovat dynamický počet datových proudů. Klient může přidat vstupní datové proudy a MFT může během zpracování přidávat nové výstupní streamy. Pro podporu dynamických datových proudů se však nevyžadují MFT. MFT může mít pevný počet datových proudů, stejně jako DMO.

K podpoře dynamických datových proudů v MFT se používají následující metody:

Kromě toho MMFTransform::P rocessOutput metoda definuje chování pro přidání nebo odebrání výstupních datových proudů.

Vzhledem k tomu, že objekty dynamické správy mají pevné datové proudy, jsou datové proudy v objektu DMO identifikovány pomocí hodnot indexu založených na nule. MFT naopak používají identifikátory datových proudů, které nemusí nutně odpovídat hodnotám indexu. Důvodem je, že se může změnit počet datových proudů v MFT. Například stream 0 může být odebrán, takže stream 1 ponechá jako první datový proud. MFT s pevným počtem datových proudů by však měl dodržovat stejnou konvenci jako objekty dynamické správy a používat hodnoty indexu pro identifikátory datových proudů.

Formátování vyjednávání

MFT používají k popisu typů médií rozhraní MMFMediaType. V opačném případě formátování vyjednávání s MFT funguje na stejných základních principech jako u dmO. Následující tabulka uvádí metody vyjednávání formátu pro objekty dynamické správy a odpovídající metody pro MFT.

Metoda DMO Metoda MFT
IMediaObject::GetInputCurrentType MMFTransform::GetInputCurrentType
IMediaObject::GetInputMaxLatency MMFTransform::GetInputStreamInfo
IMediaObject::GetInputSizeInfo MMFTransform::GetInputStreamInfo
IMediaObject::GetInputType MMFTransform::GetInputAvailableType
IMediaObject::GetOutputCurrentType MMFTransform::GetOutputCurrentType
IMediaObject::GetOutputSizeInfo MMFTransform::GetOutputStreamInfo
IMediaObject::GetOutputType MMFTransform::GetOutputAvailableType

 

Proudem

Podobně jako dmos zpracovávají MFT data prostřednictvím volání ProcessInput a ProcessOutput metod. Tady jsou hlavní rozdíly mezi procesy DMO a MFT při streamování dat.

Přidělování prostředků

MFT nemají IMediaObject::AllocateStreamingResources a IMediaObject::FreeStreamingResources metody používané s objekty DMO. Za účelem efektivního zpracování přidělování a uvolnění prostředků může MFT reagovat na následující zprávy v MMFTransform::P rocessMessage metoda:

Klient navíc může signalizovat začátek a konec datového proudu voláním ProcessMessage s následujícími zprávami:

Tyto dvě zprávy nemají žádný přesný ekvivalent DMO.

Zpracování dat

MFT používají ukázky médií k uložení vstupních a výstupních dat. Ukázky médií zveřejňují rozhraní MMFSample a obsahují následující data:

  • Časové razítko a doba trvání
  • Atributy, které obsahují informace pro jednotlivé vzorky. Seznam atributů najdete v tématu Ukázkové atributy.
  • Nulové nebo více vyrovnávacích pamětí médií. Každá vyrovnávací paměť médií zveřejňuje rozhraní MMFMediaBuffer.

Rozhraní MMFMediaBuffer je podobné rozhraní DMO IMediaBuffer. Chcete-li získat přístup k podkladové vyrovnávací paměti, zavolejte MMFMediaBuffer::Lock. Tato metoda je přibližně ekvivalentní IMediaBuffer::GetBufferAndLength pro DMO.

U nekomprimovaných dat videa může vyrovnávací paměť médií podporovat také MMF2DBuffer rozhraní. MFT, který zpracovává nekomprimované video (buď jako vstup nebo výstup), by měl být připraven použít MMF2DBuffer rozhraní, pokud ji vyrovnávací paměť zveřejňuje. Další informace naleznete v tématu Nekomprimované vyrovnávací paměti videa.

Media Foundation poskytuje některé standardní implementace MMFMediaBuffer, takže obecně není nutné psát vlastní implementaci. Chcete-li vytvořit vyrovnávací paměť DMO z vyrovnávací paměti Media Foundation, volání MFCreateLegacyMediaBufferOnMFMediaBuffer.

Zaplavování

MFT nemají metodu Flush. Pokud chcete vyprázdnit MFT, zavolejte MMFTransform::P rocessMessage se zprávou MFT_MESSAGE_COMMAND_FLUSH.

Přerušení datového proudu

MFT nemají metodu Discontinuity. Chcete-li signalizovat přerušení datového proudu, nastavte atribut MFSampleExtension_Discontinuity u vstupní ukázky.

Různé rozdíly

Tady jsou některé další menší rozdíly mezi MFT a DMO.

Vlajky

Následující tabulky uvádějí různé příznaky DMO a jejich ekvivalenty MFT. Pokaždé, když se příznak DMO mapuje přímo na příznak MFT, mají oba příznaky stejnou číselnou hodnotu. Některé příznaky DMO ale nemají přesné ekvivalenty MFT a naopak.

Příznaky ProcessInput

DmO: _DMO_INPUT_DATA_BUFFER_FLAGS výčtu.

MFT: Žádný ekvivalentní výčet.

Příznak DMO Příznak MFT
DMO_INPUT_DATA_BUFFERF_SYNCPOINT Žádný ekvivalentní příznak. Místo toho nastavte atribut MFSampleExtension_CleanPoint v ukázce.
DMO_INPUT_DATA_BUFFERF_TIME Žádný ekvivalentní příznak. Místo toho volejte MMFSample::SetSampleTime ukázky.
DMO_INPUT_DATA_BUFFERF_TIMELENGTH Žádný ekvivalentní příznak. Místo toho volejte MMFSample::SetSampleDuration ukázky.

 

Příznaky ProcessOutput

DMO: _DMO_PROCESS_OUTPUT_FLAGS výčtu.

MFT: _MFT_PROCESS_OUTPUT_FLAGS výčtu.

Příznak DMO Příznak MFT
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

Zobrazení dynamické správy: _DMO_OUTPUT_DATA_BUFFER_FLAGS výčtu.

MFT: _MFT_OUTPUT_DATA_BUFFER_FLAGS výčtu.

Příznak DMO Příznak MFT
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT Žádný ekvivalentní příznak. Místo toho zkontrolujte atribut MFSampleExtension_CleanPoint ukázky.
DMO_OUTPUT_DATA_BUFFERF_TIME Žádný ekvivalentní příznak. Místo toho volejte MMFSample::GetSampleTime ukázky.
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH Žádný ekvivalentní příznak. Místo toho volejte MMFSample::GetSampleDuration ukázky.
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
Žádný ekvivalentní příznak. MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
Žádný ekvivalentní příznak. MFT_OUTPUT_DATA_BUFFER_STREAM_END
Žádný ekvivalentní příznak. MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE

 

Příznaky GetInputStatus

DMO: _DMO_INPUT_STATUS_FLAGS výčtu.

MFT: _MFT_INPUT_STATUS_FLAGS výčtu.

Příznak DMO Příznak MFT
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

Příznaky GetOutputStatus

Zobrazení dynamické správy: Žádný ekvivalentní výčet.

MFT: _MFT_OUTPUT_STATUS_FLAGS výčtu.

Příznak DMO Příznak MFT
Žádný ekvivalentní příznak. MFT_OUTPUT_STATUS_SAMPLE_READY

 

Příznaky GetInputStreamInfo

DMO: _DMO_INPUT_STREAM_INFO_FLAGS výčtu.

MFT: _MFT_INPUT_STREAM_INFO_FLAGS výčtu.

Příznak DMO Příznak MFT
DMO_INPUT_STREAMF_WHOLE_SAMPLES MFT_INPUT_STREAM_WHOLE_SAMPLES
DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_INPUT_STREAMF_HOLDS_BUFFERS MFT_INPUT_STREAM_HOLDS_BUFFERS
Žádný ekvivalentní příznak. MFT_INPUT_STREAM_DOES_NOT_ADDREF
Žádný ekvivalentní příznak. MFT_INPUT_STREAM_REMOVABLE
Žádný ekvivalentní příznak. MFT_INPUT_STREAM_OPTIONAL

 

Příznaky GetOutputStreamInfo

DmO: _DMO_OUTPUT_STREAM_INFO_FLAGS výčtu.

MFT: _MFT_OUTPUT_STREAM_INFO_FLAGS výčtu.

Příznak DMO Příznak MFT
DMO_OUTPUT_STREAMF_WHOLE_SAMPLES MFT_OUTPUT_STREAM_WHOLE_SAMPLES
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_OUTPUT_STREAMF_DISCARDABLE MFT_OUTPUT_STREAM_DISCARDABLE
DMO_OUTPUT_STREAMF_OPTIONAL MFT_OUTPUT_STREAM_OPTIONAL
Žádný ekvivalentní příznak. MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
Žádný ekvivalentní příznak. MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
Žádný ekvivalentní příznak. MFT_OUTPUT_STREAM_LAZY_READ
Žádný ekvivalentní příznak. MFT_OUTPUT_STREAM_REMOVABLE

 

Příznaky SetInputType/SetOutputType

DmOs: _DMO_SET_TYPE_FLAGS výčtu.

MFT: _MFT_SET_TYPE_FLAGS výčtu.

Příznak DMO Příznak MFT
DMO_SET_TYPEF_TEST_ONLY MFT_SET_TYPE_TEST_ONLY
DMO_SET_TYPEF_CLEAR Žádný ekvivalentní příznak. Místo toho nastavte typ média tak, aby NULL vymazat typ média.

 

Kódy chyb

Následující tabulka ukazuje, jak mapovat kódy chyb DMO na kódy chyb MFT. Hybridní objekt MFT/DMO by měl vrátit kódy chyb DMO z IMediaObject metod a kódy chyb MFT z MMFTransform metod. Kódy chyb DMO jsou definovány v souboru hlaviček MediaErr.h. Kódy chyb MFT jsou definovány v souboru hlavičky mferror.h.

Kód chyby DMO Kód chyby MFT
DMO_E_INVALIDTYPE MF_E_INVALIDTYPE
DMO_E_INVALIDSTREAMINDEX MF_E_INVALIDSTREAMNUMBER
DMO_E_NOTACCEPTING MF_E_NOTACCEPTING
DMO_E_NO_MORE_ITEMS MF_E_NO_MORE_TYPES
DMO_E_TYPE_NOT_ACCEPTED MF_E_INVALIDMEDIATYPE
DMO_E_TYPE_NOT_SET MF_E_TRANSFORM_TYPE_NOT_SET

 

Vytváření hybridních objektů DMO/MFT

Rozhraní MMFTransform je volně založené na IMediaObject, což je primární rozhraní pro objekty DIRECTX Media Objects (DMO). Je možné vytvořit objekty, které zpřístupňují obě rozhraní. To ale může vést ke kolizím názvů, protože rozhraní mají některé metody, které sdílejí stejný název. Tento problém můžete vyřešit jedním ze dvou způsobů:

Řešení 1: Do horní části libovolného souboru .cpp, který obsahuje funkce MFT, zahrňte následující řádek:

#define MFT_UNIQUE_METHOD_NAMES

Tím se změní deklarace MMFTransform rozhraní tak, aby většina názvů metod byla předpona "MFT". Proto MMFTransform::P rocessInput se stane MMFTransform::MFTProcessInput, zatímco IMediaObject::P rocessInput zachová původní název. Tato technika je nejužitečnější, pokud převádíte existující objekt DMO na hybridní DMO/MFT. Nové metody MFT můžete přidat beze změny metod DMO.

Řešení 2: Použití syntaxe jazyka C++ k nejednoznačnosti názvů, které jsou zděděné z více než jednoho rozhraní. Deklarujte například verzi ProcessInput MFT následujícím způsobem:

CMyHybridObject::IMFTransform::ProcessInput(...)

Deklarujte verzi DMO ProcessInput takto:

CMyHybridObject::IMediaObject::ProcessInput(...)

Pokud provedete interní volání metody v rámci objektu, můžete použít tuto syntaxi, ale tím se přepíše virtuální stav metody. Lepší způsob volání z objektu je následující:

hr = ((IMediaObject*)this)->ProcessInput(...)

Pokud tak odvozíte jinou třídu z CMyHybridObject a přepíšete CMyHybridObject::IMediaObject::P rocessInput metoda, je volána správná virtuální metoda. Rozhraní DMO jsou zdokumentovaná v dokumentaci k sadě DirectShow SDK.

transformace Media Foundation