Freigeben über


Verwenden der DMO-Klassenvorlage

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde durch MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation ersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code nach Möglichkeit MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet. Microsoft schlägt vor, vorhandenen Code, der die Legacy-APIs verwendet, um nach Möglichkeit die neuen APIs zu verwenden.]

DirectShow enthält eine Klassenvorlage, IMediaObjectImpl, für die Implementierung von DMOs. Die Vorlage verarbeitet viele der "Buchhaltungsaufgaben", z. B. das Überprüfen von Eingabeparametern. Mithilfe der Vorlage können Sie sich auf die Funktionalität konzentrieren, die für Ihre DMO spezifisch ist. Darüber hinaus trägt die Vorlage dazu bei, sicherzustellen, dass Sie eine robuste Implementierung erstellen. Die Vorlage wird in der Headerdatei Dmoimpl.h definiert, die sich im Verzeichnis Include des SDK befindet.

Die IMediaObjectImpl-Vorlage erbt die IMediaObject-Schnittstelle . Um eine DMO mithilfe der Vorlage zu erstellen, definieren Sie eine neue Klasse, die von IMediaObjectImpl abgeleitet ist. Die Vorlage implementiert alle IMediaObject-Methoden . In den meisten Fällen ruft die Vorlage eine entsprechende private Methode für die abgeleitete Klasse auf. Die Vorlage bietet die folgenden Features:

  • Grundlegende Parameterüberprüfung. Die Vorlagenmethoden überprüfen, ob die erforderlichen Parameter nicht NULL sind, dass sich Streamindizes innerhalb des Bereichs befinden und dass Flags gültig sind.
  • Sperren. Die Vorlagenmethoden rufen zwei interne Methoden auf, Lock und Unlock, um Vorgänge für die DMO zu serialisieren. Dieses Feature stellt sicher, dass die DMO threadsicher ist.
  • Medientypen. Die Vorlage speichert die vom Client festgelegten Medientypen und stellt Accessormethoden für die Medientypen bereit.
  • Streaming. Die Vorlage verhindert das Streaming, bis der Client Medientypen für alle nicht optionalen Streams festgelegt hat. Außerdem wird sichergestellt, dass die IMediaObject::AllocateStreamingResources-Methode aufgerufen wird, bevor das Streaming beginnt, was garantiert, dass Ressourcen zugeordnet werden.

Die abgeleitete Klasse muss die IUnknown-Schnittstelle implementieren. Die Vorlage stellt diese Schnittstelle nicht bereit. Sie können die Active Template Library (ATL) verwenden, um IUnknown zu implementieren, oder Sie können eine andere Implementierung bereitstellen. Die Vorlage implementiert auch nicht den Sperrmechanismus. Die abgeleitete Klasse muss die Lock - und Unlock-Methoden implementieren. Wenn Sie Ihre Klasse mit ATL erstellen, können Sie die standardmäßigen ATL-Implementierungen verwenden.

Deklarieren der abgeleiteten Klasse

Die IMediaObjectImpl-Klassenvorlage wird wie folgt deklariert:

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

Die drei Vorlagenparameter sind _DERIVED_, NUMBEROFINPUTS und NUMBEROFOUTPUTS. Legen Sie _DERIVED_ gleich dem Namen Ihrer Klasse fest. Die beiden anderen Parameter definieren die Anzahl der Eingabe- und Ausgabedatenströme auf dem DMO. Verwenden Sie beispielsweise die folgende Deklaration, um eine DMO-Klasse namens CMyDmo zu erstellen, die einen Eingabe- und zwei Ausgabedatenströme unterstützt:

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

Im rest dieses Abschnitts wird beschrieben, wie die Vorlage die verschiedenen Methoden in IMediaObject implementiert.

Methoden zum Festlegen von Medientypen

Mit den folgenden Methoden werden Medientypen für die DMO festgelegt oder abgerufen:

  • GetInputType, GetOutputType. Diese Methoden geben bevorzugte Medientypen nach Streamnummer und Typindex zurück. Die Vorlage ruft InternalGetInputType oder InternalGetOutputType für die abgeleitete Klasse auf.
  • SetInputType, SetOutputType. Mit diesen Methoden wird der Medientyp für einen Stream festgelegt, ein Medientyp getestet oder ein Medientyp gelöscht. Um den Medientyp zu überprüfen, ruft die Vorlage InternalCheckInputType oder InternalCheckOutputType für die abgeleitete Klasse auf. Die abgeleitete Klasse gibt S_OK zurück, um den Typ oder DMO_E_INVALIDTYPE zu akzeptieren, um den Typ abzulehnen. Die Vorlage verarbeitet das Festlegen oder Löschen des Medientyps.
  • GetInputCurrentType, GetOutputCurrentType. Diese Methoden geben den aktuellen Medientyp für einen Stream zurück oder DMO_E_TYPE_NOT_SET, wenn kein Typ festgelegt ist. Die Vorlage implementiert diese Methoden vollständig.

Informationsmethoden

Die folgenden Methoden stellen Informationen zum DMO bereit.

  • GetInputMaxLatency, SetInputMaxLatency. Diese Methoden rufen die maximale Latenz ab oder legen sie fest. Die Vorlage ruft InternalGetInputMaxLatency oder InternalSetInputMaxLatency für die abgeleitete Klasse auf.
  • GetInputSizeInfo, GetOutputSizeInfo. Diese Methoden geben die Pufferanforderungen des DMO für einen angegebenen Stream zurück. Wenn kein Medientyp für diesen Stream festgelegt wurde, gibt die Vorlage DMO_E_TYPE_NOT_SET zurück. Andernfalls wird InternalGetInputSizeInfo oder InternalGetOutputSizeInfo für die abgeleitete Klasse aufgerufen.
  • GetInputStreamInfo, GetOutputStreamInfo. Diese Methoden geben verschiedene Flags zurück, die angeben, wie der Client die Daten formatieren soll. Die Vorlage ruft InternalGetInputStreamInfo oder InternalGetOutputStreamInfo für die abgeleitete Klasse auf.
  • GetStreamCount. Diese Methode gibt die Anzahl der Eingabe- und Ausgabestreams zurück. Die Vorlage implementiert diese Methode mithilfe der Vorlagenparameter.

Methoden für die Ressourcenzuordnung

  • Die AllocateStreamingResources-Methode weist alle Ressourcen zu, die der DMO benötigt, bevor das Streaming beginnt. Die FreeStreamingResources-Methode gibt dieselben Ressourcen frei. Die Vorlage ruft InternalAllocateStreamingResources bzw . InternalFreeStreamingResources auf.

Der Client des DMO ist nicht erforderlich, um diese Methoden aufzurufen, aber die Vorlage ruft automatisch AllocateStreamingResources auf, bevor das Streaming gestartet wird. Daher kann die DMO davon ausgehen, dass Ressourcen zum Zeitpunkt des Aufrufs von ProcessInput ordnungsgemäß zugeordnet wurden. Die DMO sollte FreeStreamingResources in seinem Destruktor aufrufen.

Wenn die Vorlage InternalAllocateStreamingResources aufruft, legt sie außerdem ein internes Flag fest, sodass diese Methode erst wieder aufgerufen wird, wenn InternalFreeStreamingResources aufgerufen wird. Dadurch wird sichergestellt, dass Ressourcen nicht versehentlich neu zugewiesen werden, was zu Speicherverlusten führen kann.

Methoden für Streaming

Zum Streamen von Daten werden die folgenden Methoden verwendet:

  • GetInputStatus. Diese Methode gibt an, ob die DMO zu diesem Zeitpunkt Eingaben akzeptieren kann. Die Vorlage ruft InternalAcceptingInput für die abgeleitete Klasse auf. Wenn die DMO Eingaben akzeptieren kann, gibt die abgeleitete Klasse S_OK zurück, und die Vorlage legt das DMO_INPUT_STATUSF_ACCEPT_DATA Bit im dwFlags-Parameter fest. Andernfalls gibt die abgeleitete Klasse S_FALSE zurück, und die Vorlage legt dwFlags auf Null fest.
  • ProcessInput. Diese Methode verarbeitet einen Eingabepuffer. Die Vorlage ruft AllocateStreamingResources auf, die zuvor beschrieben wurde. Anschließend wird InternalAcceptingInput für die abgeleitete Klasse aufgerufen. Wenn die DMO neue Eingaben akzeptieren kann, ruft die Vorlage InternalProcessInput auf.
  • ProcessOutput. Diese Methode verarbeitet einen Satz von Ausgabepuffern, einen Puffer für jeden Ausgabedatenstrom. Die Vorlage ruft AllocateStreamingResources und dann InternalProcessOutput auf.
  • Diskontinuität. Diese Methode signalisiert eine Diskontinuität in einem Eingabedatenstrom. Die Vorlage ruft InternalAcceptingInput für die abgeleitete Klasse auf. Wenn diese Methode S_OK zurückgibt, ruft die Vorlage InternalDiscontinuity für die abgeleitete Klasse auf.
  • Leer. Diese Methode löscht die DMO. Die Vorlage ruft InternalFlush für die abgeleitete Klasse auf. Die DMO sollte alle Eingabepuffer verwerfen, die noch zur Verarbeitung vorhanden sind.

Die Vorlage bietet keine direkte Unterstützung für die IMediaObjectInPlace-Schnittstelle .

Methoden zum Sperren

Sperren werden verwendet, um den DMO-Zustand in einer Multithreadumgebung zu schützen. In einem ATL-Projekt verursacht die IMediaObject::Lock-Methode einen Namenskonflikt mit der ATL Lock-Methode . Um den Konflikt zu beheben, benennt die Vorlage die IMediaObject-Methode in DMOLock um. Wenn Sie die abgeleitete Klasse kompilieren, definieren Sie FIX_LOCK_NAME, bevor Sie die Headerdatei Dmo.h einschließen:

#define FIX_LOCK_NAME
#include <dmo.h>

Diese Direktive bewirkt, dass der Präprozessor in der Deklaration der IMediaObject-SchnittstelleDMOLock durch Lock ersetzt. Anwendungen können die -Methode weiterhin mit dem Namen Lock aufrufen, da sich die vtable-Reihenfolge nicht ändert. Die DMOLock-Methode ruft Lock oder Unlock für die abgeleitete Klasse auf. Wenn Sie ATL zum Implementieren der abgeleiteten Klasse verwenden, sind diese Methoden bereits von ATL definiert, sodass kein zusätzlicher Code erforderlich ist. Wenn Sie ATL nicht verwenden, müssen Sie die Lock - und Unlock-Methoden in Ihrer abgeleiteten Klasse angeben.

Die Vorlage sperrt den DMO in jeder der IMediaObject-Methoden automatisch. Die abgeleitete Klasse muss den DMO möglicherweise in anderen öffentlichen Methoden sperren, die sie implementiert (z. B. wenn sie IMediaObjectInPlace unterstützt). Die Klassenvorlage bietet auch eine interne Hilfsklasse, IMediaObjectImpl::LockIt, die zum Sperren und Entsperren der DMO nützlich ist.

Zusammenfassung

Für die folgenden IMediaObject-Methoden ruft die Vorlage eine entsprechende Methode mit derselben Signatur für die abgeleitete Klasse auf. Die abgeleitete Klasse muss jede der methoden implementieren, die in der zweiten Spalte angezeigt werden.

IMediaObject-Methode Abgeleitete Klassenmethode
AllocateStreamingResources InternalAllocateStreamingResources
Diskontinuität InternalDiscontinuity
Leerung InternalFlush
FreeStreamingResources InternalFreeStreamingResources
GetInputMaxLatency InternalGetInputMaxLatency
GetInputSizeInfo InternalGetInputSizeInfo
GetInputStreamInfo InternalGetInputStreamInfo
GetInputType InternalGetInputType
GetOutputSizeInfo InternalGetOutputSizeInfo
GetOutputStreamInfo InternalGetOutputStreamInfo
GetOutputType InternalGetOutputType
ProcessInput InternalProcessInput
ProcessOutput InternalProcessOutput
SetInputMaxLatency InternalSetInputMaxLatency

 

Für die verbleibenden IMediaObject-Methoden besteht keine 1:1-Korrespondenz zwischen Vorlagenmethoden und abgeleiteten Klassenmethoden. In der folgenden Tabelle wird zusammengefasst, welche Methoden vollständig von der Vorlage implementiert werden und welche Methoden andere Methoden für die abgeleitete Klasse aufrufen.

IMediaObject-Methode Abgeleitete Klassenmethode
GetInputCurrentType Vollständig implementiert
GetOutputCurrentType Vollständig implementiert
GetStreamCount Vollständig implementiert
GetInputStatus InternalAcceptingInput
Sperre (implementiert als DMOLock) Sperren, Entsperren
SetInputType InternalCheckInputType
SetOutputType InternalCheckOutputType

 

IMediaObjectImpl-Klassenvorlage

Schreiben einer DMO