Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit onderwerp wordt beschreven hoe een client gebruikmaakt van een Media Foundation-transformatie (MFT) om gegevens te verwerken. De -client is alles wat rechtstreeks methoden aanroept op de MFT. Dit kan de toepassing of de Media Foundation-pijplijn zijn.
Lees dit onderwerp als u:
- Een toepassing schrijven die directe aanroepen naar een of meer MMFT's doet.
- Een aangepaste MFT schrijven en het verwachte gedrag van een MFT willen begrijpen.
In dit onderwerp wordt een synchroon verwerkingsmodel beschreven. In dit model worden alle gegevensverwerkingsmethoden geblokkeerd totdat ze zijn voltooid. MMFT's kunnen ook ondersteuning bieden voor een asynchroon model, dat wordt beschreven in het onderwerp Asynchrone MFT's.
- Basismodel voor Verwerking
- extensies voor het basicmodel
- IMF2DBuffer
- een MFT- leegmaken
- een MFT- leegmaken
- Voorbeeldkenmerken
- Onderbrekingen
- dynamische opmaakwijzigingen
- Stream-gebeurtenissen
- Verwante onderwerpen
Basisverwerkingsmodel
De MFT maken
Er zijn verschillende manieren om een MFT te maken:
- Roep de functie MFTEnum op.
- Roep de functie MFTEnumEx aan.
- Als u de CLSID van de MFT al kent, roept u CoCreateInstanceaan.
Sommige MFT's bieden mogelijk andere opties, zoals een gespecialiseerde creatiefunctie.
Streamidentificatoren ophalen
Een MFT heeft een of meer stromen. Invoerstromen ontvangen invoergegevens en uitvoerstromen genereren uitvoergegevens. Streams worden niet weergegeven als afzonderlijke objecten. In plaats daarvan nemen verschillende MFT-methoden stream-id's als parameters.
Met sommige MFT's kan de client invoerstromen toevoegen of verwijderen. Tijdens het streamen kan een MFT uitvoerstreams toevoegen of verwijderen. (De client kan geen uitvoerstromen toevoegen of verwijderen.)
- (Optioneel.) Bel IMFTransform::GetStreamLimits om het minimum- en maximum aantal streams te verkrijgen dat de MFT kan ondersteunen. Als het minimum en maximum hetzelfde zijn, heeft de MFT een vast aantal streams.
- Roep IMFTransform::GetStreamCount aan om het eerste aantal streams op te halen.
- Roep IMFTransform::GetStreamIDs aan om de stream-id's op te halen. Als deze methode E_NOTIMPL retourneert, betekent dit dat de MFT een vast aantal streams heeft en dat de stream-id's opeenvolgend beginnen vanaf nul.
- (Optioneel.) Als de MFT geen vast aantal streams heeft, roept u IMFTransform::AddInputStreams aan om meer invoerstromen toe te voegen of IMFTransform::D eleteInputStream om invoerstromen te verwijderen. (U kunt geen uitvoerstreams toevoegen of verwijderen.)
Mediatypen instellen
Voordat een MFT gegevens kan verwerken, moet de client een mediatypen instellen voor elk van de stromen van de MFT. Een MFT vereist mogelijk dat de client de invoertypen instelt voordat de uitvoertypen worden ingesteld, of dat de tegenovergestelde volgorde (eerst uitvoertypen) vereist is. Sommige MMFT's hebben geen vereiste voor de bestelling.
Een MFT kan een lijst met voorkeursmediatypen voor een stream opgeven. Ook kunnen MMFT's de algemene indelingen aangeven die ze ondersteunen door deze informatie toe te voegen aan het register.
Ga als volgt te werk om de mediatypen in te stellen:
- (Optioneel.) Roep voor elke invoerstroom IMFTransform::GetInputAvailableType aan om de lijst met voorkeurstypen voor die stream op te halen.
- Als deze methode MF_E_TRANSFORM_TYPE_NOT_SET retourneert, moet u eerst de uitvoertypen instellen; ga verder met stap 3.
- Als de methode E_NOTIMPL retourneert, heeft de MFT geen lijst met voorkeursinvoertypen; ga verder met stap 2.
- Roep voor elke invoerstroom IMFTransform::SetInputType aan om het invoertype in te stellen. U kunt een mediatype uit stap 1 gebruiken of een type dat uw invoergegevens beschrijft. Als een stream MF_E_TRANSFORM_TYPE_NOT_SET retourneert, gaat u verder met stap 3.
- (Optioneel.) Roep voor elke uitvoerstroom IMFTransform::GetOutputAvailableType aan om een lijst met voorkeurstypen voor die stream op te halen.
- Als deze methode MF_E_TRANSFORM_TYPE_NOT_SET retourneert, moet u eerst de invoertypen instellen; ga terug naar stap 1.
- Als een stroom E_NOTIMPL retourneert, heeft de MFT geen lijst met voorkeursuitvoertypen; ga verder met stap 4.
- Roep voor elke uitvoerstroom IMFTransform::SetOutputType aan om het uitvoertype in te stellen. U kunt een mediatype uit stap 3 gebruiken of een type dat de vereiste uitvoerindeling beschrijft.
- Als invoerstromen geen mediatype hebben, gaat u terug naar stap 1.
De buffervereisten ophalen
Nadat de client de mediatypen heeft ingesteld, moeten de buffervereisten voor elke stream worden opgehaald:
- Roep voor elke invoerstroom IMFTransform::GetInputStreamInfoaan.
- Roep voor elke uitvoerstroom IMFTransform::GetOutputStreamInfoaan.
Gegevens verwerken
Een MFT is ontworpen als een betrouwbare statusmachine. Er worden geen aanroepen naar de client uitgevoerd.
- Roep IMFTransform::ProcessMessage aan met het MFT_MESSAGE_NOTIFY_BEGIN_STREAMING bericht. Dit bericht vraagt de MFT om alle resources toe te wijzen die nodig zijn tijdens het streamen.
- Roep IMFTransform::P rocessInput aan op ten minste één invoerstroom om een invoervoorbeeld aan de MFT te leveren.
- (Optioneel.) Roep IMFTransform::GetOutputStatus aan om een query uit te voeren of de MFT een uitvoervoorbeeld kan genereren. Als de methode S_OK retourneert, dient u de parameter pdwFlags te controleren. Als pdwFlags- de vlag MFT_OUTPUT_STATUS_SAMPLE_READY bevat, gaat u naar stap 4. Als pdwFlags nul is, gaat u terug naar stap 2. Als de methode E_NOTIMPL retourneert, gaat u naar stap 4.
- Roep IMFTransform::P rocessOutput aan om uitvoergegevens op te halen.
- Als de methode MF_E_TRANSFORM_NEED_MORE_INPUTretourneert, betekent dit dat de MFT meer invoergegevens vereist; ga terug naar stap 2.
- Als de methode MF_E_TRANSFORM_STREAM_CHANGEretourneert, betekent dit dat het aantal uitvoerstromen is gewijzigd of dat de uitvoerindeling is gewijzigd. De client moet mogelijk een query uitvoeren op nieuwe stream-id's of nieuwe mediatypen instellen. Zie de documentatie voor ProcessOutputvoor meer informatie.
- Als er nog invoergegevens moeten worden verwerkt, gaat u naar stap 2. Als de MFT alle beschikbare invoergegevens heeft verbruikt, gaat u verder met stap 6.
- Roep ProcessMessage aan met het bericht MFT_MESSAGE_NOTIFY_END_OF_STREAM.
- Roep ProcessMessage- aan met het MFT_MESSAGE_COMMAND_DRAIN bericht.
- Roep ProcessOutput- aan om de resterende uitvoer op te halen. Herhaal deze stap totdat de methode MF_E_TRANSFORM_NEED_MORE_INPUTretourneert. Deze retourwaarde geeft aan dat alle uitvoer uit de MFT is verwijderd. (Behandel dit niet als een foutvoorwaarde.)
De hier beschreven reeks bewaart zo weinig mogelijk gegevens in de MFT. Na elke aanroep naar ProcessInput-, probeert de client uitvoer te krijgen. Er kunnen verschillende invoervoorbeelden nodig zijn om één uitvoervoorbeeld te produceren, of één invoervoorbeeld kan verschillende uitvoervoorbeelden genereren. Het optimale gedrag voor de client is het ophalen van uitvoervoorbeelden van de MFT totdat de MFT meer invoer vereist.
De MFT moet echter een andere volgorde van methode-aanroepen door de client kunnen verwerken. De client kan bijvoorbeeld gewoon wisselen tussen aanroepen naar ProcessInput- en ProcessOutput-. De MFT moet de hoeveelheid invoer beperken die het ontvangt door MF_E_NOTACCEPTING te retourneren uit ProcessInput wanneer het uitvoer te produceren heeft.
De volgorde van hier beschreven methode-aanroepen is niet de enige geldige reeks gebeurtenissen. In stap 3 en 4 wordt bijvoorbeeld ervan uitgegaan dat de client begint met de invoertypen en vervolgens de uitvoertypen probeert. De client kan deze volgorde ook omkeren en beginnen met de uitvoertypen. In beide gevallen, als de MFT de tegenovergestelde volgorde vereist, moet de foutcode MF_E_TRANSFORM_TYPE_NOT_SET worden geretourneerd.
De client kan informatieve methoden aanroepen, zoals GetInputCurrentType en GetOutputStreamInfo, op elk gewenst moment tijdens het streamen. De client kan ook op elk gewenst moment proberen de mediatypen te wijzigen. De MFT moet een foutcode retourneren als dit geen geldige bewerking is. Kortom, MMFT's moeten er weinig van uitgaan over de volgorde van bewerkingen, behalve wat wordt beschreven in de aanroepen zelf.
In het volgende diagram ziet u een stroomdiagram van de procedures die in dit onderwerp worden beschreven.
Extensies voor het Basic-model
Een MFT kan desgewenst enkele extensies voor het basisstreamingmodel ondersteunen.
- Lui-lezer streams. Als de methode IMFTransform::GetOutputStreamInfo de MFT_OUTPUT_STREAM_LAZY_READ vlag voor een uitvoerstroom retourneert, hoeft de client geen gegevens van die uitvoerstroom te verzamelen. De MFT blijft invoer accepteren en op een bepaald moment worden de uitvoergegevens van die stroom verwijderd door de MFT. Als alle uitvoerstromen deze vlag hebben, zal de MFT altijd invoer kunnen accepteren. Een voorbeeld hiervan is een visualisatietransformatie, waarbij de client alleen de uitvoer krijgt wanneer deze reserve-CPU-cycli heeft om de visualisatie te tekenen.
- Wegwerpbare streams. Als de methode GetOutputStreamInfo de vlag MFT_OUTPUT_STREAM_DISCARDABLE retourneert voor een uitvoerstroom, kan de client de MFT aanvragen om uitvoer te verwijderen, maar de MFT negeert geen uitvoer, tenzij aangevraagd. Wanneer de MFT de maximale invoerbuffer bereikt, moet de client enkele uitvoergegevens verzamelen of de MFT aanvragen om de uitvoer te verwijderen.
- Optionele streams. Als de methodeGetOutputStreamInfo de MFT_OUTPUT_STREAM_OPTIONAL vlag voor een uitvoerstroom retourneert, of als de methode IMFTransform::GetInputStreamInfo de MFT_INPUT_STREAM_OPTIONAL vlag voor een invoerstroom retourneert, is deze stroom optioneel. De client hoeft geen mediatype op de stream in te stellen. Als de client het type niet instelt, wordt de stream gedeselecteerd. Een gedeselecteerde uitvoerstroom produceert geen voorbeelden en de client biedt geen buffer voor de stream wanneer deze ProcessOutput-aanroept. Een gedeselecteerde invoerstroom accepteert geen invoergegevens. Een MFT kan alle invoer- en uitvoerstromen markeren als optioneel. Er wordt echter verwacht dat ten minste één invoer en één uitvoer moeten worden geselecteerd om de MFT te laten werken.
- Asynchrone verwerking. Het asynchrone verwerkingsmodel is geïntroduceerd in Windows 7. Het wordt beschreven in het onderwerp Asynchrone MMFT's.
IMF2DBuffer
Als een MFT niet-gecomprimeerde videogegevens verwerkt, moet deze de interface IMF2DBuffer gebruiken om de voorbeeldbuffers te bewerken. Als u deze interface wilt ophalen, voert u een query uit op de IMFMediaBuffer interface op elke invoer- of uitvoerbuffer. Als u deze interface niet gebruikt wanneer deze beschikbaar is, kan dit leiden tot extra bufferkopieën. Om deze interface goed te kunnen gebruiken, mag de transformatie de buffer niet vergrendelen met behulp van de IMFMediaBuffer-interface wanneer IMF2DBuffer- beschikbaar is.
Zie Niet-gecomprimeerde videobuffersvoor meer informatie over het verwerken van videogegevens.
Een MFT leegmaken
Flushing een MFT zorgt ervoor dat de MFT alle invoergegevens verwijdert. Dit kan leiden tot een onderbreking in de uitvoerstroom. Wanneer de client zich geen zorgen maakt over gegevensverlies, zou hij doorgaans een MFT leegmaken voordat hij naar een nieuw punt in de invoerstroom zoekt of overschakelt naar een nieuwe invoerstroom.
Als u een MFT wilt leegmaken, belt u IMFTransform::ProcessMessage met het MFT_MESSAGE_COMMAND_FLUSH bericht.
Een MFT leegmaken
Het leegmaken van een MFT zorgt ervoor dat de MFT zoveel mogelijk uitvoer produceert van alle invoergegevens die al zijn verzonden. Als het MFT geen volledig uitvoervoorbeeld van de beschikbare invoer kan produceren, worden de invoergegevens verwijderd. Een client zou doorgaans een MFT leegmaken wanneer deze het einde van de bronstroom heeft bereikt of vlak voor een indelingswijziging in de bronstroom. Ga als volgt te werk om een MFT leeg te maken:
- Roep ProcessMessage aan met het MFT_MESSAGE_COMMAND_DRAIN bericht. In dit bericht wordt aangegeven dat de MFT zoveel uitvoergegevens moet leveren als mogelijk is op basis van de invoergegevens die al zijn verzonden.
- Roep de methode ProcessOutput- aan om uitvoergegevens op te halen totdat de methode MF_E_TRANSFORM_NEED_MORE_INPUTretourneert.
Terwijl de MFT wordt leeggezogen, accepteert deze geen invoer meer.
Voorbeeldkenmerken
De invoervoorbeelden kunnen kenmerken hebben die moeten worden gekopieerd naar de bijbehorende uitvoervoorbeelden.
- Als de MFT VARIANT_TRUE retourneert voor de eigenschap MFPKEY_EXATTRIBUTE_SUPPORTED, moet de MFT de kenmerken kopiëren.
- Als de eigenschap MFPKEY_EXATTRIBUTE_SUPPORTED is VARIANT_FALSE of niet is ingesteld, moet de client de kenmerken kopiëren.
Voor een MFT met één invoer en één uitvoer kunt u de volgende algemene regel gebruiken:
- Als elk invoervoorbeeld precies één uitvoervoorbeeld produceert, kunt u de client de kenmerken laten kopiëren. Laat de eigenschap MFPKEY_EXATTRIBUTE_SUPPORTED uitgeschakeld.
- Als er geen een-op-een-correspondentie is tussen invoervoorbeelden en uitvoervoorbeelden, moet de MFT de juiste kenmerken voor uitvoervoorbeelden bepalen. Stel de eigenschap MFPKEY_EXATTRIBUTE_SUPPORTED in op VARIANT_TRUE.
Onderbrekingen
Een discontinuïteit is een onderbreking in een audio- of videostream. Onderbrekingen kunnen worden veroorzaakt door verwijderde pakketten op een netwerkverbinding, beschadigde bestandsgegevens, een switch van de ene bronstroom naar de andere of een breed scala aan andere oorzaken. De onderbrekingen worden gesignaleerd door het kenmerk MFSampleExtension_Discontinuity in te stellen op het eerste voorbeeld na de discontinuïteit. Het is niet mogelijk om een stopzetting te signaleren in het midden van een steekproef. Daarom moeten alle niet-aaneengeslagen gegevens in afzonderlijke steekproeven worden verzonden.
Sommige transformaties, met name transformaties die niet-gecomprimeerde gegevens verwerken, zoals audio- en video-effecten, moeten de onderbrekingen negeren wanneer ze invoergegevens verwerken. Deze MMFT's zijn over het algemeen ontworpen voor het verwerken van continue gegevens en moeten alle gegevens die ze ontvangen, behandelen als doorlopend, zelfs na een discontinuïteit.
Als een MFT een discontinuïteit in de invoergegevens negeert, moet het nog steeds de discontinuïteitsvlag op het uitvoermonster zetten als het uitvoermonster hetzelfde tijdstempel heeft als het invoermonster. Als het uitvoervoorbeeld echter een ander tijdstempel heeft, mag de MFT de discontinuiteit niet doorgeven. (Dit is bijvoorbeeld het geval bij sommige audio-resamplers.) Een discontinuïteit op de verkeerde plaats in de stroom is erger dan geen discontinuïteit.
De meeste decoders kunnen de discontinuïteit niet negeren, omdat een discontinuïteit van invloed is op de interpretatie van de volgende steekproef. Elke coderingstechnologie die gebruikmaakt van interframecompressie, zoals MPEG-2, valt in deze categorie. Sommige coderingsschema's gebruiken alleen intraframecompressie, zoals DV en MJPEG. Deze decoders kunnen de onderbrekingen veilig negeren.
Transformaties die reageren op discontinuïteiten moeten in het algemeen zoveel mogelijk van de gegevens vóór de discontinuïteit uitvoeren en de rest negeren. Het invoervoorbeeld met de vlag voor stopzetting moet worden verwerkt alsof dit het eerste voorbeeld in de stream was. (Dit gedrag komt overeen met wat is opgegeven voor het MFT_MESSAGE_COMMAND_DRAIN bericht.) De exacte details zijn echter afhankelijk van de media-indeling.
Als een decoder niets doet om een discontinuïteit te beperken, moet deze de vlag voor stopzetting naar de uitvoergegevens kopiëren. Demultiplexers en andere MMFT's die volledig met gecomprimeerde gegevens werken, moeten eventuele onderbrekingen naar hun uitvoerstromen kopiëren. Anders kunnen de downstreamonderdelen de gecomprimeerde gegevens mogelijk niet correct decoderen. Over het algemeen is het bijna altijd juist om de discontinuïteiten downstream door te geven, tenzij de MFT expliciete code bevat om de discontinuïteiten af te vlakken.
Wijzigingen in dynamisch formaat
Indelingen kunnen tijdens het streamen worden gewijzigd. De hoogte-breedteverhouding kan bijvoorbeeld worden gewijzigd in het midden van een videostream.
Voor meer informatie over hoe stroomwijzigingen worden verwerkt door een MFT, zie Handling Stream Changes.
Gebeurtenissen streamen
Als u een gebeurtenis naar een MFT wilt verzenden, roept u IMFTransform::ProcessEvent. Als de methode MF_S_TRANSFORM_DO_NOT_PROPAGATE_EVENTretourneert, retourneert de MFT de gebeurtenis bij een volgende aanroep naar ProcessOutput-. Als de methode een andere HRESULT- waarde retourneert, retourneert de MFT de gebeurtenis niet naar de client in ProcessOutput-. In dat geval is de client verantwoordelijk voor het doorgeven van de gebeurtenis downstream naar het volgende onderdeel in de pijplijn, indien van toepassing. Zie IMFTransform::P rocessOutputvoor meer informatie.
Verwante onderwerpen