Delen via


Asynchrone MMFT's

In dit onderwerp wordt asynchrone gegevensverwerking voor Media Foundation-transformaties (MFT's) beschreven.

Notitie

Dit onderwerp is van toepassing op Windows 7 of hoger.

 

Over Asynchrone MMFT's

Toen MFT's werden geïntroduceerd in Windows Vista, is de API ontworpen voor synchrone gegevensverwerking. In dat model wacht de MFT altijd op invoer of wacht op het produceren van uitvoer.

Overweeg een typische videodecoder. Om een gedecodeerd frame op te halen, roept de client IMFTransform::P rocessOutputaan. Als de decoder voldoende gegevens heeft om een frame te decoderen, ProcessOutput blokken terwijl de MFT het frame ontsleutelt. Anders retourneert ProcessOutputMF_E_TRANSFORM_NEED_MORE_INPUT, waarmee wordt aangegeven dat de client IMFTransform::P rocessInput-moet aanroepen.

Dit model werkt goed als de decoder alle ontsleutelingsbewerkingen op één thread uitvoert. Stel dat de decoder verschillende threads gebruikt om frames parallel te decoderen. Voor de beste prestaties moet de decoder nieuwe invoer ontvangen wanneer een ontsleutelingsthread inactief wordt. Maar de snelheid waarmee threads decoderingsbewerkingen voltooien, komt niet exact overeen met de aanroepen van de client naar ProcessInput- en ProcessOutput-, wat resulteert in threads die wachten op werk.

Windows 7 introduceert gebeurtenisgestuurde, asynchrone verwerking voor MMFT's. In dit model wordt, wanneer de MFT invoer nodig heeft of uitvoer heeft, een gebeurtenis naar de client verzonden.

Algemene vereisten

In dit onderwerp wordt beschreven hoe asynchrone MFT's verschillen van synchrone MFT. Behalve waar vermeld in dit onderwerp, zijn de twee verwerkingsmodellen hetzelfde. (Met name de opmaakonderhandelingen zijn hetzelfde.)

Een asynchrone MFT moet de volgende interfaces implementeren:

Gebeurtenissen

Een asynchrone MFT gebruikt de volgende gebeurtenissen om de status van de gegevensverwerking aan te geven:

Gebeurtenis Beschrijving
METransformNeedInput- Verzonden wanneer de MFT meer invoer kan accepteren.
METransformHaveOutput- Verzonden wanneer de MFT uitvoer heeft.
METransformDrainComplete- Verzonden wanneer een afvoerbewerking is voltooid. Zie leegmaken.
METransformMarker- Verzonden wanneer een markering wordt verwerkt. Zie markeringen.

 

Deze gebeurtenissen worden buiten de band verzonden. Het is belangrijk om inzicht te hebben in het verschil tussen in-band- en out-of-bandgebeurtenissen in de context van een MFT.

Het oorspronkelijke MFT-ontwerp ondersteunt in-band gebeurtenissen. Een in-bandgebeurtenis bevat informatie over de gegevensstroom, zoals informatie over een wijziging in een indeling. De client verzendt in-bandgebeurtenissen naar de MFT door IMFTransform::P rocessEventaan te roepen. De MFT kan in-bandgebeurtenissen terugsturen naar de client in de methode ProcessOutput. (In het bijzonder worden gebeurtenissen overgebracht in de pEvents lid van de MFT_OUTPUT_DATA_BUFFER-structuur.)

Een MFT verzendt out-of-band gebeurtenissen via de IMFMediaEventGenerator interface als volgt:

  1. De MFT implementeert de IMFMediaEventGenerator interface, zoals beschreven in Media Event Generators.
  2. De client roept IUnknown::QueryInterface aan op de MFT voor de IMFMediaEventGenerator interface. Een asynchrone MFT moet deze interface beschikbaar maken. Synchrone MMFT's mogen deze interface niet beschikbaar maken.
  3. De client roept IMFMediaEventGenerator::BeginGetEvent en IMFMediaEventGenerator::EndGetEvent om out-of-band-gebeurtenissen van de MFT te ontvangen.

ProcessInput

De methode IMFTransform::P rocessInput wordt als volgt gewijzigd:

  1. Wanneer streaming wordt gestart, verzendt de client het MFT_MESSAGE_NOTIFY_START_OF_STREAM bericht.
  2. Tijdens het streamen vraagt de MFT gegevens aan door een METransformNeedInput gebeurtenis te verzenden. De gebeurtenisgegevens zijn de stream-id.
  3. Voor elke gebeurtenis METransformNeedInput gebeurtenis roept de client ProcessInput- aan voor de opgegeven stream.
  4. Aan het einde van het streamen kan de client ProcessMessage aanroepen met het MFT_MESSAGE_NOTIFY_END_OF_STREAM bericht.

Opmerkingen bij de implementatie:

ProcessOutput

De methode IMFTransform::P rocessOutput wordt als volgt gewijzigd:

  1. Wanneer de MFT uitvoer heeft, wordt er een METransformHaveOutput-gebeurtenis verzonden.
  2. Voor elke METransformHaveOutput gebeurtenis roept de client ProcessOutput-aan.

Opmerkingen bij de implementatie:

Afvoeren

Het leegmaken van een MFT zorgt ervoor dat de MFT zoveel mogelijk uitvoer produceert van alle invoergegevens die al zijn verzonden. Het leegmaken van een asynchrone MFT werkt als volgt:

  1. De client verzendt het MFT_MESSAGE_COMMAND_DRAIN bericht.
  2. De MFT blijft METransformHaveOutput gebeurtenissen verzenden totdat er geen gegevens meer moeten worden verwerkt. Het verzendt geen METransformNeedInput gebeurtenissen gedurende deze tijd.
  3. Nadat de MFT de laatste METransformHaveOutput gebeurtenis heeft verzonden, wordt er een METransformDrainComplete-gebeurtenis verzonden.

Nadat het leegmaken is voltooid, verzendt de MFT geen andere METransformNeedInput gebeurtenis totdat er een MFT_MESSAGE_NOTIFY_START_OF_STREAM bericht van de client wordt ontvangen.

Vlissingen

De client kan de MFT leegmaken door het MFT_MESSAGE_COMMAND_FLUSH bericht te verzenden. De MFT verwijdert alle invoer- en uitvoervoorbeelden die het vasthoudt.

De MFT verzendt geen andere METransformNeedInput-gebeurtenis totdat er een MFT_MESSAGE_NOTIFY_START_OF_STREAM bericht van de client wordt ontvangen.

Markeringen

De client kan een punt in de stream markeren door het MFT_MESSAGE_COMMAND_MARKER bericht te verzenden. De MFT reageert als volgt:

  1. De MFT genereert zoveel uitvoervoorbeelden als deze kan uit de bestaande invoergegevens, waarmee een METransformHaveOutput gebeurtenis voor elk uitvoervoorbeeld wordt verzonden.
  2. Nadat alle uitvoer is gegenereerd, verzendt de MFT een METransformMarker gebeurtenis. Deze gebeurtenis moet worden verzonden na alle METransformHaveOutput-gebeurtenissen gebeurtenissen.

Stel dat een decoder voldoende invoergegevens heeft om vier uitvoervoorbeelden te produceren. Als de client het MFT_MESSAGE_COMMAND_MARKER bericht verzendt, plaatst de MFT vier METransformHaveOutput gebeurtenissen (één per uitvoervoorbeeld), gevolgd door een METransformMarker-gebeurtenis.

Het markeringsbericht is vergelijkbaar met het afvoerbericht. Een afvoer wordt echter beschouwd als een onderbreking in de stroom, terwijl een markering niet is. Afvoeren en markeringen hebben de volgende verschillen.

Afvoeren:

  • Tijdens het leegmaken verzendt de MFT geen METransformNeedInput gebeurtenissen.
  • De MFT verwijdert invoergegevens die niet kunnen worden gebruikt om een uitvoervoorbeeld te maken.
  • Sommige MFT's produceren een 'staart' aan het einde van de gegevens. Audio-effecten zoals reverb of echo produceren bijvoorbeeld extra gegevens nadat de invoergegevens zijn gestopt. Een MFT die een staart genereert, moet dit doen aan het einde van een afvoerbewerking.
  • Nadat het leegmaken van de MFT is voltooid, wordt het volgende uitvoervoorbeeld gemarkeerd met het kenmerk MFSampleExtension_Discontinuity om een discontinuiteit in de stroom aan te geven.

Marker:

  • De MFT blijft METransformNeedInput gebeurtenissen verzenden voordat de markeringsgebeurtenis wordt verzonden.
  • De MFT negeert geen invoergegevens. Als er gedeeltelijke gegevens zijn, moet deze na het markeringspunt worden verwerkt.
  • De MFT produceert geen staart op het markeringspunt.
  • De MFT stelt de vlag voor stopzetting niet in na het markeringspunt.

Wijzigingen opmaken

Een asynchrone MFT moet dynamische indelingswijzigingen ondersteunen, zoals wordt beschreven in Stroomwijzigingen verwerken.

Kenmerken

Een asynchrone MFT moet de methode IMFTransform::GetAttributes implementeren om een geldig kenmerkarchief te retourneren. De volgende kenmerken zijn van toepassing op asynchrone MFT's:

Attribuut Beschrijving
MF_TRANSFORM_ASYNC De MFT moet dit kenmerk instellen op TRUE (1). De client kan een query uitvoeren op dit kenmerk om te ontdekken of de MFT asynchroon is.
MF_TRANSFORM_ASYNC_UNLOCK
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE De MFT moet dit kenmerk instellen op TRUE (1). De client kan ervan uitgaan dat dit kenmerk is ingesteld.

 

Asynchrone MMFT's ontgrendelen

Asynchrone MMFT's zijn niet compatibel met het oorspronkelijke MFT-gegevensverwerkingsmodel. Om te voorkomen dat asynchrone MMFT's bestaande toepassingen breken, wordt het volgende mechanisme gedefinieerd:

De client roept IMFTransform::GetAttributes aan op de MFT. De client voert een query uit op het kenmerk van dit MF_TRANSFORM_ASYNC. Voor een asynchrone MFT is de waarde van dit kenmerk **TRUE**. Als u de MFT wilt ontgrendelen, moet de client het kenmerk MF_TRANSFORM_ASYNC_UNLOCK instellen op **TRUE**.

Totdat de client de MFT ontgrendelt, moeten alle IMFTransform methoden MF_E_TRANSFORM_ASYNC_LOCKEDretourneren, met de volgende uitzonderingen:

De volgende code laat zien hoe u een asynchrone MFT ontgrendelt:

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;
}

De MFT afsluiten

Asynchrone MFT's moeten de IMFShutdown interface implementeren.

  • afsluiten: de MFT moet de gebeurteniswachtrij afsluiten. Als u de standaardgebeurteniswachtrij gebruikt, belt u IMFMediaEventQueue::Shutdown. Optioneel kan de MFT andere resources vrijgeven. De client mag de MFT niet gebruiken na het aanroepen van Afsluiten.
  • GetShutdownStatus: nadat afsluiten is aangeroepen, moet de MFT de waarde MFSHUTDOWN_COMPLETED in de parameter pStatus retourneren. De waarde mag niet worden geretourneerd MFSHUTDOWN_INITIATED.

Registratie en opsomming

Als u een asynchrone MFT wilt registreren, roept u de functie MFTRegister aan en stelt u de vlag MFT_ENUM_FLAG_ASYNCMFT in de parameter Flags in. (Voorheen was deze vlag gereserveerd.)

Als u asynchrone MFT's wilt inventariseren, roept u de functie MFTEnumEx aan en stelt u de vlag MFT_ENUM_FLAG_ASYNCMFT in de parameter Flags in. Voor compatibiliteit met eerdere versies geeft de MFTEnum--functie geen asynchrone MFTEnum-MFT's op. Anders kan het installeren van een asynchrone MFT op de computer van de gebruiker bestaande toepassingen verbreken.

Media Foundation transformeert