Jämförelse av MFI och DMO
Media Foundation-transformeringar (MFI) är en utveckling av transformeringsmodellen som först introducerades med DirectX Media Objects (DMOs). I det här avsnittet sammanfattas de huvudsakliga sätten på vilka MFI skiljer sig från DMO:er. Läs det här avsnittet om du redan är bekant med DMO-gränssnitten eller om du vill konvertera en befintlig DMO till en MFT.
Det här avsnittet innehåller följande avsnitt:
- Antal strömmar
- formatera förhandling
- Streaming
- Diverse skillnader
- Flaggor
- felkoder
- Skapa hybrid-DMO/MFT-objekt
- Relaterade ämnen
Antal strömmar
En DMO har ett fast antal strömmar, medan en MFT kan stödja ett dynamiskt antal strömmar. Klienten kan lägga till indataströmmar och MFT kan lägga till nya utdataströmmar under bearbetningen. MMFT krävs dock inte för att stödja dynamiska strömmar. En MFT kan ha ett fast antal strömmar, precis som en DMO.
Följande metoder används för att stödja dynamiska strömmar på en MFT:
- IMFTransform::AddInputStreams
- IMFTransform::D eleteInputStream
- IMFTransform::GetStreamIDs
- IMFTransform::GetStreamLimits
Dessutom definierar metoden IMFTransform::P rocessOutput beteendet för att lägga till eller ta bort utdataströmmar.
Eftersom DMOs har fasta strömmar identifieras strömmarna på en DMO med nollbaserade indexvärden. MMFT använder å andra sidan strömidentifierare som inte nödvändigtvis motsvarar indexvärden. Det beror på att antalet strömmar på en MFT kan ändras. Till exempel kan stream 0 tas bort, vilket lämnar ström 1 som den första strömmen. En MFT med ett fast antal strömmar bör dock observera samma konvention som DMO:er och använda indexvärden för strömidentifierare.
Formatera förhandling
MMFT använder IMFMediaType--gränssnittet för att beskriva medietyper. Annars fungerar formatförhandling med MFI på samma grundläggande principer som med DMO:er. I följande tabell visas formatförhandlingsmetoderna för DMOs och motsvarande metoder för MFI.
Direktuppspelning
Precis som DMO:er bearbetar MMFT:er data via anrop till ProcessInput-- och ProcessOutput- metoder. Här är de största skillnaderna mellan DMO- och MFT-processer när data strömmas.
Allokera resurser
MMFT har inte IMediaObject::AllocateStreamingResources och IMediaObject::FreeStreamingResources metoder som används med DMOs. För att effektivt hantera allokering och frigöra resurser kan en MFT svara på följande meddelanden i metoden IMFTransform::P rocessMessage:
Dessutom kan klienten signalera start och slut på en dataström genom att anropa ProcessMessage med följande meddelanden:
Dessa två meddelanden har ingen exakt DMO-motsvarighet.
Bearbeta data
MMFT använder medieexempel för att lagra indata och utdata. Medieexempel exponerar IMFSample--gränssnittet och innehåller följande data:
- Tidsstämpel och varaktighet.
- Attribut som innehåller information per exempel. En lista över attribut finns i Exempelattribut.
- Noll eller fler mediebuffertar. Varje mediebuffert exponerar IMFMediaBuffer- gränssnitt.
IMFMediaBuffer-gränssnittet liknar DMO IMediaBuffer-gränssnittet. Om du vill komma åt den underliggande minnesbufferten anropar du IMFMediaBuffer::Lås. Den här metoden motsvarar ungefär IMediaBuffer::GetBufferAndLength för DMOs.
För okomprimerade videodata kan en mediebuffert också stödja IMF2DBuffer- gränssnitt. En MFT som bearbetar okomprimerad video (antingen som indata eller utdata) bör vara beredd att använda IMF2DBuffer- gränssnitt om bufferten exponerar den. Mer information finns i okomprimerade videobuffertar.
Media Foundation tillhandahåller vissa standardimplementeringar av IMFMediaBuffer, så det är i allmänhet inte nödvändigt att skriva din egen implementering. Om du vill skapa en DMO-buffert från en Media Foundation-buffert anropar du MFCreateLegacyMediaBufferOnMFMediaBuffer.
Spolning
MMFT:er har ingen Flush-metod. Om du vill tömma en MFT anropar du IMFTransform::P rocessMessage med meddelandet MFT_MESSAGE_COMMAND_FLUSH.
Stream-avbrott
MMFT har ingen Diskontinuitet metod. Ange attributet MFSampleExtension_Discontinuity för indataexemplet för att signalera avbrott i en ström.
Diverse skillnader
Här följer några ytterligare mindre skillnader mellan MFI och DMO: er.
Det finns inga MFT-motsvarigheter för följande DMO-metoder:
MMFT krävs inte för att stödja aggregering.
MMFT stöder en åtgärd som kallas tömning. Syftet med tömning är att bearbeta data som finns kvar i MF, utan att tillhandahålla några fler indata till MFT (till exempel i slutet av dataströmmen). Om du vill tömma en MFT anropar du IMFTransform::P rocessMessage med meddelandet MFT_MESSAGE_COMMAND_DRAIN. Mer information finns i Basic MFT-bearbetningsmodell.
MFI kan ha attribut, inklusive attribut per dataström. Använd följande metoder för att hämta attributen från en MFT:
MMFT kan bearbeta händelser. Om du vill skicka en händelse till en MFT anropar du IMFTransform::P rocessEvent. En MFT kan skicka en händelse till klienten via metoden ProcessOutput. Mer information finns i Basic MFT-bearbetningsmodell.
Flaggor
I följande tabeller visas de olika DMO-flaggorna och deras MFT-motsvarigheter. När en DMO-flagga mappas direkt till en MFT-flagga har båda flaggorna samma numeriska värde. Vissa DMO-flaggor har dock inte exakta MFT-motsvarigheter och vice versa.
ProcessInput-flaggor
DMOs: _DMO_INPUT_DATA_BUFFER_FLAGS uppräkning.
MFI: Ingen motsvarande uppräkning.
DMO-flagga | MFT-flagga |
---|---|
DMO_INPUT_DATA_BUFFERF_SYNCPOINT | Ingen motsvarande flagga. Ange i stället attributet MFSampleExtension_CleanPoint i exemplet. |
DMO_INPUT_DATA_BUFFERF_TIME | Ingen motsvarande flagga. Anropa i stället IMFSample::SetSampleTime i exemplet. |
DMO_INPUT_DATA_BUFFERF_TIMELENGTH | Ingen motsvarande flagga. Anropa i stället IMFSample::SetSampleDuration i exemplet. |
ProcessOutput-flaggor
DMOs: _DMO_PROCESS_OUTPUT_FLAGS uppräkning.
MMFT: _MFT_PROCESS_OUTPUT_FLAGS uppräkning.
DMO-flagga | MFT-flagga |
---|---|
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER | MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER |
DMOs: _DMO_OUTPUT_DATA_BUFFER_FLAGS uppräkning.
MMFT: _MFT_OUTPUT_DATA_BUFFER_FLAGS uppräkning.
DMO-flagga | MFT-flagga |
---|---|
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT | Ingen motsvarande flagga. Leta i stället efter attributet MFSampleExtension_CleanPoint i exemplet. |
DMO_OUTPUT_DATA_BUFFERF_TIME | Ingen motsvarande flagga. Anropa i stället IMFSample::GetSampleTime i exemplet. |
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH | Ingen motsvarande flagga. Anropa i stället IMFSample::GetSampleDuration i exemplet. |
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE | MFT_OUTPUT_DATA_BUFFER_INCOMPLETE |
Ingen motsvarande flagga. | MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE |
Ingen motsvarande flagga. | MFT_OUTPUT_DATA_BUFFER_STREAM_END |
Ingen motsvarande flagga. | MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE |
GetInputStatus-flaggor
DMOs: _DMO_INPUT_STATUS_FLAGS uppräkning.
MMFT: _MFT_INPUT_STATUS_FLAGS uppräkning.
DMO-flagga | MFT-flagga |
---|---|
DMO_INPUT_STATUSF_ACCEPT_DATA | MFT_INPUT_STATUS_ACCEPT_DATA |
GetOutputStatus-flaggor
DMOs: Ingen motsvarande uppräkning.
MFI: _MFT_OUTPUT_STATUS_FLAGS uppräkning.
DMO-flagga | MFT-flagga |
---|---|
Ingen motsvarande flagga. | MFT_OUTPUT_STATUS_SAMPLE_READY |
GetInputStreamInfo-flaggor
DMOs: _DMO_INPUT_STREAM_INFO_FLAGS uppräkning.
MMFT: _MFT_INPUT_STREAM_INFO_FLAGS uppräkning.
DMO-flagga | MFT-flagga |
---|---|
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 |
Ingen motsvarande flagga. | MFT_INPUT_STREAM_DOES_NOT_ADDREF |
Ingen motsvarande flagga. | MFT_INPUT_STREAM_REMOVABLE |
Ingen motsvarande flagga. | MFT_INPUT_STREAM_OPTIONAL |
GetOutputStreamInfo-flaggor
DMOs: _DMO_OUTPUT_STREAM_INFO_FLAGS uppräkning.
MFI: _MFT_OUTPUT_STREAM_INFO_FLAGS uppräkning.
DMO-flagga | MFT-flagga |
---|---|
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 |
Ingen motsvarande flagga. | MFT_OUTPUT_STREAM_PROVIDES_SAMPLES |
Ingen motsvarande flagga. | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES |
Ingen motsvarande flagga. | MFT_OUTPUT_STREAM_LAZY_READ |
Ingen motsvarande flagga. | MFT_OUTPUT_STREAM_REMOVABLE |
SetInputType/SetOutputType-flaggor
DMOs: _DMO_SET_TYPE_FLAGS uppräkning.
MFI: _MFT_SET_TYPE_FLAGS uppräkning.
DMO-flagga | MFT-flagga |
---|---|
DMO_SET_TYPEF_TEST_ONLY | MFT_SET_TYPE_TEST_ONLY |
DMO_SET_TYPEF_CLEAR | Ingen motsvarande flagga. Ställ i stället in medietypen på NULL- för att rensa medietypen. |
Felkoder
I följande tabell visas hur du mappar DMO-felkoder till MFT-felkoder. Ett MFT/DMO-hybridobjekt ska returnera DMO-felkoderna från IMediaObject- metoder och MFT-felkoderna från IMFTransform metoder. DMO-felkoderna definieras i huvudfilen MediaErr.h. MFT-felkoderna definieras i huvudfilen mferror.h.
DMO-felkod | MFT-felkod |
---|---|
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 |
Skapa hybrid-DMO/MFT-objekt
Gränssnittet IMFTransform är löst baserat på IMediaObject, som är det primära gränssnittet för DirectX Media Objects (DMOs). Det är möjligt att skapa objekt som exponerar båda gränssnitten. Detta kan dock leda till namngivningskollisioner, eftersom gränssnitten har vissa metoder som delar samma namn. Du kan lösa det här problemet på något av två sätt:
Lösning 1: Ta med följande rad överst i alla .cpp filer som innehåller MFT-funktioner:
#define MFT_UNIQUE_METHOD_NAMES
Detta ändrar deklarationen av IMFTransform gränssnitt så att de flesta av metodnamnen prefixet med "MFT". Därför blir IMFTransform::P rocessInputIMFTransform::MFTProcessInput, medan IMediaObject::P rocessInput behåller sitt ursprungliga namn. Den här tekniken är mest användbar om du konverterar en befintlig DMO till en hybrid-DMO/MFT. Du kan lägga till de nya MFT-metoderna utan att ändra DMO-metoderna.
Lösning 2: Använd C++-syntax för att skilja namn som ärvs från mer än ett gränssnitt. Deklarera till exempel MFT-versionen av ProcessInput på följande sätt:
CMyHybridObject::IMFTransform::ProcessInput(...)
Deklarera DMO-versionen av ProcessInput så här:
CMyHybridObject::IMediaObject::ProcessInput(...)
Om du gör ett internt anrop till en metod i objektet kan du använda den här syntaxen, men om du gör det åsidosätts metodens virtuella status. Ett bättre sätt att göra anrop inifrån objektet är följande:
hr = ((IMediaObject*)this)->ProcessInput(...)
På så sätt anropas rätt virtuell metod om du härleder en annan klass från CMyHybridObject och åsidosätter metoden CMyHybridObject::IMediaObject::P rocessInput. DMO-gränssnitten dokumenteras i DirectShow SDK-dokumentationen.
Relaterade ämnen