Delen via


De DMO-klassesjabloon gebruiken

[De functie die is gekoppeld aan deze pagina, DirectShow, is een verouderde functie. Het is vervangen door MediaPlayer, IMFMediaEngineen Audio/Video Capture in Media Foundation. Deze functies zijn geoptimaliseerd voor Windows 10 en Windows 11. Microsoft raadt ten zeerste aan om nieuwe code te gebruiken MediaPlayer, IMFMediaEngine en Audio/Video Capture in Media Foundation in plaats van DirectShow, indien mogelijk. Microsoft stelt voor dat bestaande code die gebruikmaakt van de verouderde API's, indien mogelijk opnieuw worden geschreven om de nieuwe API's te gebruiken.]

DirectShow bevat een klassesjabloon, IMediaObjectImpl, voor het implementeren van DMO's. De sjabloon verwerkt veel van de 'boekhoudtaken', zoals het valideren van invoerparameters. Met behulp van de sjabloon kunt u zich richten op de functionaliteit die specifiek is voor uw DMO. Daarnaast helpt de sjabloon ervoor te zorgen dat u een robuuste implementatie maakt. De sjabloon wordt gedefinieerd in het headerbestand Dmoimpl.h, dat zich in de map Opnemen van de SDK bevindt.

De sjabloon IMediaObjectImpl neemt de IMediaObject interface over. Als u een DMO wilt maken met behulp van de sjabloon, definieert u een nieuwe klasse die is afgeleid van IMediaObjectImpl. De sjabloon implementeert alle IMediaObject-methoden. In de meeste gevallen roept de sjabloon een bijbehorende privémethode aan voor de afgeleide klasse. De sjabloon biedt de volgende functies:

  • Basisparametercontrole. De sjabloonmethoden controleren of vereiste parameters niet NULLzijn, dat streamindexen binnen het bereik vallen en dat vlaggen geldig zijn.
  • Vergrendeling. De sjabloonmethoden roepen twee interne methoden aan, vergrendelen en Ontgrendelen, om bewerkingen op de DMO te serialiseren. Deze functie zorgt ervoor dat de DMO thread-safe is.
  • Mediatypen. De sjabloon slaat de mediatypen op die door de client zijn ingesteld en biedt toegangsmethoden voor de mediatypen.
  • Streaming. De sjabloon voorkomt streaming totdat de client mediatypen heeft ingesteld voor alle niet-optionele streams. Het zorgt er ook voor dat de methode IMediaObject::AllocateStreamingResources wordt aangeroepen voordat streaming wordt gestart, wat garandeert dat resources worden toegewezen.

De afgeleide klasse moet de interface IUnknown implementeren; de sjabloon biedt deze interface niet. U kunt de Active Template Library (ATL) gebruiken om IUnknown-te implementeren of u kunt een andere implementatie bieden. De sjabloon implementeert ook niet het vergrendelingsmechanisme. De afgeleide klasse moet de methoden Lock en Unlock implementeren. Als u uw klas maakt met behulp van ATL, kunt u de standaard-ATL-implementaties gebruiken.

de afgeleide klasse declareren

De IMediaObjectImpl klassesjabloon wordt als volgt gedeclareerd:

template <class _DERIVED_, int NUMBEROFINPUTS, int NUMBEROFOUTPUTS>
class IMediaObjectImpl : public ImediaObject

De drie sjabloonparameters zijn _DERIVED_, NUMBEROFINPUTS en NUMBEROFOUTPUTS. Stel _DERIVED_ in op de naam van uw class. De andere twee parameters definiëren het aantal invoerstromen en uitvoerstromen op de DMO. Als u bijvoorbeeld een DMO-klasse met de naam CMyDmo wilt maken die één invoerstroom en twee uitvoerstromen ondersteunt, gebruikt u de volgende declaratie:

class CMyDmo : public IMediaObjectImpl<CMyDmo, 1, 2>

In de rest van deze sectie wordt beschreven hoe de sjabloon de verschillende methoden in IMediaObjectimplementeert.

methoden voor het instellen van mediatypen

Met de volgende methoden kunt u mediatypen instellen of ophalen op de DMO:

  • GetInputType, GetOutputType. Deze methoden retourneren voorkeursmediatypen, op streamnummer en typeindex. De sjabloon roept InternalGetInputType of InternalGetOutputType aan op de afgeleide klasse.
  • SetInputType, SetOutputType. Met deze methoden wordt het mediatype voor een stream ingesteld, een mediatype getest of een mediatype gewist. Om het mediatype te valideren, roept de sjabloon InternalCheckInputType of InternalCheckOutputType binnen de afgeleide klasse aan. De afgeleide klasse retourneert S_OK om het type te accepteren of DMO_E_INVALIDTYPE om het type te weigeren. De sjabloon verwerkt het instellen of wissen van het mediatype.
  • GetInputCurrentType, GetOutputCurrentType. Deze methoden retourneren het huidige mediatype voor een stream of DMO_E_TYPE_NOT_SET als er geen type is ingesteld. Met de sjabloon worden deze methoden volledig geïmplementeerd.

informatiemethoden

De volgende methoden bieden informatie over de DMO.

  • GetInputMaxLatency, SetInputMaxLatency. Met deze methoden wordt de maximale latentie opgehaald of ingesteld. De sjabloon roept InternalGetInputMaxLatency of InternalSetInputMaxLatency aan op de afgeleide klasse.
  • GetInputSizeInfo, GetOutputSizeInfo. Deze methoden retourneren de buffervereisten van de DMO voor een opgegeven stream. Als er geen mediatype voor die stream is ingesteld, retourneert de sjabloon DMO_E_TYPE_NOT_SET. Anders wordt InternalGetInputSizeInfo of InternalGetOutputSizeInfo in de afgeleide klasse aangeroepen.
  • GetInputStreamInfo, GetOutputStreamInfo. Deze methoden retourneren verschillende vlaggen die aangeven hoe de client de gegevens moet opmaken. Door de sjabloon wordt InternalGetInputStreamInfo of InternalGetOutputStreamInfo aangeroepen op de afgeleide klasse.
  • GetStreamCount. Deze methode retourneert het aantal invoer- en uitvoerstromen. De sjabloon implementeert deze methode met behulp van de sjabloonparameters.

methoden voor resourcetoewijzing

  • De methode AllocateStreamingResources wijst alle resources toe die de DMO nodig heeft voordat streaming begint. De methode FreeStreamingResources brengt dezelfde resources vrij. De sjabloon roept respectievelijk InternalAllocateStreamingResources en InternalFreeStreamingResourcesaan.

De client van de DMO is niet vereist om deze methoden aan te roepen, maar de sjabloon roept automatisch AllocateStreamingResources aan voordat streaming wordt gestart. Daarom kan de DMO ervan uitgaan dat resources correct zijn toegewezen op het moment dat ProcessInput- wordt aangeroepen. De DMO moet FreeStreamingResources aanroepen in zijn destructor.

Wanneer de sjabloon InternalAllocateStreamingResourcesaanroept, wordt ook een interne vlag ingesteld, zodat het die methode niet opnieuw aanroept totdat InternalFreeStreamingResourceswordt aangeroepen. Dit zorgt ervoor dat resources niet per ongeluk opnieuw worden toegewezen, wat kan leiden tot geheugenlekken.

methoden voor streaming

De volgende methoden worden gebruikt om gegevens te streamen:

  • GetInputStatus. Met deze methode wordt aangegeven of de DMO op dit moment invoer kan accepteren. De sjabloon roept InternalAcceptingInput aan op de afgeleide klasse. Als de DMO invoer kan accepteren, retourneert de afgeleide klasse S_OK en stelt de sjabloon de DMO_INPUT_STATUSF_ACCEPT_DATA bit in de dwFlags-parameter. Anders retourneert de afgeleide klasse S_FALSE en stelt de sjabloon dwFlags in op nul.
  • ProcessInput. Met deze methode wordt een invoerbuffer verwerkt. De sjabloon roept AllocateStreamingResources aan, zoals eerder is beschreven. Vervolgens wordt InternalAcceptingInput op de afgeleide klasse aangeroepen. Als de DMO nieuwe invoer kan accepteren, roept de sjabloon InternalProcessInputaan.
  • ProcessOutput-. Deze methode verwerkt een set uitvoerbuffers, één buffer voor elke uitvoerstroom. De sjabloon roept AllocateStreamingResources aan en InternalProcessOutput.
  • discontinuïteit. Deze methode geeft een discontinuïteit aan in een invoerstroom. De sjabloon roept InternalAcceptingInput aan op de afgeleide klasse. Als deze methode S_OK retourneert, roept de sjabloon de methode InternalDiscontinuity- aan op de afgeleide klasse.
  • leegmaken. Met deze methode wordt de DMO leeggemaakt. De sjabloon roept InternalFlush aan op de afgeleide klasse. De DMO moet alle invoerbuffers die het nog in bezit heeft verwijderen voordat ze worden verwerkt.

De sjabloon biedt geen directe ondersteuning voor de interface IMediaObjectInPlace.

Methoden voor het Vergrendelen

Vergrendelen wordt gebruikt om de status van de DMO te beschermen in een omgeving met meerdere threads. In een ATL-project veroorzaakt de methode IMediaObject::Lock een naamconflict met de methode ATL Lock. Om het conflict op te lossen, hernoemt de sjabloon de methode IMediaObject naar DMOLock. Wanneer u de afgeleide klasse compileert, definieert u FIX_LOCK_NAME voordat u het headerbestand Dmo.h invoegt.

#define FIX_LOCK_NAME
#include <dmo.h>

Deze richtlijn zorgt ervoor dat de preprocessor DMOLock- vervangt door Lock- in de declaratie van de IMediaObject interface. Toepassingen kunnen de methode nog steeds aanroepen met de naam Lock, omdat de vtable-volgorde niet verandert. De methode DMOLock roept in de afgeleide klasse Lock of Unlock aan. Als u ATL gebruikt om de afgeleide klasse te implementeren, zijn deze methoden al gedefinieerd door ATL, zodat er geen extra code nodig is. Als u ATL niet gebruikt, moet u in uw afgeleide klasse de methoden Lock en Unlock opgeven.

De sjabloon vergrendelt de DMO automatisch in elk van de IMediaObject methoden. De afgeleide klasse moet mogelijk de DMO vergrendelen binnen andere openbare methoden die deze implementeert (bijvoorbeeld als hij ondersteuning biedt voor IMediaObjectInPlace). De klassesjabloon biedt ook een interne helperklasse, IMediaObjectImpl::LockIt, wat handig is voor het vergrendelen en ontgrendelen van de DMO.

Samenvatting

Voor de volgende IMediaObject methoden roept de sjabloon een bijbehorende methode aan met dezelfde handtekening voor de afgeleide klasse. De afgeleide klasse moet elk van de methoden implementeren die worden weergegeven in de tweede kolom.

Methode IMediaObject Methode Afgeleide klasse
AllocateStreamingResources- InternalAllocateStreamingResources
Discontinuïteit InterneOnderbreking
leegmaken InternalFlush
FreeStreamingResources- InternalFreeStreamingResources-
GetInputMaxLatency- InternalGetInputMaxLatency-
GetInputSizeInfo InternalGetInputSizeInfo
GetInputStreamInfo InternalGetInputStreamInfo
GetInputType- InternalGetInputType
GetOutputSizeInfo InternalGetOutputSizeInfo
GetOutputStreamInfo InternalGetOutputStreamInfo
GetOutputType InternalGetOutputType
ProcessInput- InternalProcessInput
ProcessOutput InternalProcessOutput
SetInputMaxLatency InternalSetInputMaxLatency

 

Voor de resterende IMediaObject methoden is er geen een-op-een-correspondentie tussen sjabloonmethoden en afgeleide-klassemethoden. De volgende tabel bevat een overzicht van welke methoden volledig worden geïmplementeerd door de sjabloon en welke methoden andere methoden aanroepen voor de afgeleide klasse.

Methode IMediaObject Methode van afgeleide klasse
HaalInvoerstroomTypeOp Volledig geïmplementeerd
GetOutputCurrentType Volledig geïmplementeerd
GetStreamCount Volledig geïmplementeerd
GetInputStatus- InternalAcceptingInput
Vergrendelen (geïmplementeerd als DMOLock-) vergrendelen ontgrendelen
SetInputType- InternalCheckInputType
SetOutputType- InternalCheckOutputType

 

Klassesjabloon IMediaObjectImpl

Een DMO schrijven