Condividi tramite


Uso del modello di classe DMO

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEnginee Acquisizione audio/video in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente di usare codice nuovo MediaPlayer, IMFMediaEngine e acquisizione audio/video in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

DirectShow include un modello di classe, IMediaObjectImpl, per l'implementazione di DMO. Il modello gestisce molte delle attività di "contabilità", ad esempio la convalida dei parametri di input. Usando il modello, è possibile concentrarsi sulle funzionalità specifiche del tuo DMO. Inoltre, il modello consente di garantire la creazione di un'implementazione affidabile. Il modello viene definito nel file di intestazione Dmoimpl.h, che si trova nella directory Include dell'SDK.

Il template IMediaObjectImpl eredita l'interfaccia IMediaObject. Per creare un oggetto DMO usando il modello, definire una nuova classe che deriva da IMediaObjectImpl. Il modello implementa tutti i metodi di IMediaObject. Nella maggior parte dei casi, il modello chiama un metodo privato corrispondente nella classe derivata. Il modello offre le funzionalità seguenti:

  • Controllo dei parametri di base. I metodi di modello verificano che i parametri obbligatori non siano NULL, che gli indici di flusso siano compresi nell'intervallo e che i flag siano validi.
  • Bloccaggio. I metodi modello chiamano due metodi interni, Lock e Unlock, per serializzare le operazioni sul DMO. Questa Funzionalità garantisce che il DMO sia thread-safe.
  • Tipi di media. Il modello archivia i tipi di media impostati dal client e fornisce metodi di accesso per i tipi di media.
  • Streaming. Il modello impedisce lo streaming fino a quando il client non ha impostato i tipi di supporti per tutti i flussi non facoltativi. Garantisce inoltre che il metodo IMediaObject::AllocateStreamingResources venga chiamato prima dell'inizio del flusso, garantendo l'allocazione delle risorse.

La classe derivata deve implementare l'interfaccia IUnknown; il modello non fornisce questa interfaccia. È possibile usare Active Template Library (ATL) per implementare IUnknownoppure è possibile fornire un'altra implementazione. Il modello non implementa anche il meccanismo di blocco. La classe derivata deve implementare i metodi Lock e Unlock. Se si crea la classe usando ATL, è possibile usare le implementazioni ATL predefinite.

dichiarare la classe derivata

Il modello di classe IMediaObjectImpl viene dichiarato come segue:

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

I tre parametri del modello sono _DERIVED_, NUMBEROFINPUTS e NUMBEROFOUTPUTS. Impostare _DERIVED_ uguale al nome della classe. Gli altri due parametri definiscono il numero di flussi di input e flussi di output nell'operatore DMO. Ad esempio, per creare una classe DMO denominata CMyDmo che supporta un flusso di input e due flussi di output, usare la dichiarazione seguente:

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

Nella parte restante di questa sezione viene descritto come il modello implementa i vari metodi in IMediaObject.

metodi per l'impostazione dei tipi di supporti

I seguenti metodi impostano o recuperano i tipi di media sul DMO.

  • GetInputType, GetOutputType. Questi metodi restituiscono tipi di supporti preferiti, in base al numero di flusso e all'indice di tipo. Il modello chiama InternalGetInputType o InternalGetOutputType nella classe derivata.
  • SetInputType, SetOutputType. Questi metodi impostano il tipo di supporto in un flusso, testano un tipo di supporto o cancellano un tipo di supporto. Per convalidare il tipo di supporto, il modello chiama InternalCheckInputType o InternalCheckOutputType nella classe derivata. La classe derivata restituisce S_OK per accettare il tipo o DMO_E_INVALIDTYPE per rifiutare il tipo. Il modello gestisce l'impostazione o la cancellazione del tipo di supporto.
  • GetInputCurrentType, GetOutputCurrentType. Questi metodi restituiscono il tipo di supporto multimediale corrente per un flusso o DMO_E_TYPE_NOT_SET se non è impostato alcun tipo. Il modello implementa completamente questi metodi.

metodi informativi

I seguenti metodi forniscono informazioni sul DMO.

  • GetInputMaxLatency, SetInputMaxLatency. Questi metodi recuperano o impostano la latenza massima. Il modello chiama InternalGetInputMaxLatency o InternalSetInputMaxLatency nella classe derivata.
  • GetInputSizeInfo, GetOutputSizeInfo. Questi metodi restituiscono i requisiti del buffer DMO per un flusso specificato. Se nel flusso non è stato impostato alcun tipo di supporto, il modello restituisce DMO_E_TYPE_NOT_SET. In caso contrario, chiama InternalGetInputSizeInfo o InternalGetOutputSizeInfo sulla classe derivata.
  • GetInputStreamInfo, GetOutputStreamInfo. Questi metodi restituiscono vari flag che indicano come il client deve formattare i dati. Il modello invoca InternalGetInputStreamInfo oppure InternalGetOutputStreamInfo sulla classe derivata.
  • GetStreamCount. Questo metodo restituisce il numero di flussi di input e output. Il modello implementa questo metodo usando i parametri del modello.

metodi per l'allocazione delle risorse

  • Il metodo AllocateStreamingResources alloca tutte le risorse di cui il DMO ha bisogno prima dell'inizio del flusso. Il metodo FreeStreamingResources rilascia le stesse risorse. Il modello chiama rispettivamente InternalAllocateStreamingResources e InternalFreeStreamingResources.

Il client del DMO non è tenuto a chiamare questi metodi, ma il modello chiama automaticamente AllocateStreamingResources prima dell'inizio dello streaming. Di conseguenza, l'agente DMO può presupporre che le risorse siano state allocate correttamente dal momento in cui viene chiamato ProcessInput. DMO deve chiamare FreeStreamingResources nel distruttore.

Inoltre, quando il modello chiama InternalAllocateStreamingResources, imposta un flag interno, in modo che non chiami di nuovo tale metodo fino a chiamare InternalFreeStreamingResources. In questo modo le risorse non vengono riallocate accidentalmente, causando perdite di memoria.

Metodi per lo streaming

Per trasmettere i dati vengono usati i metodi seguenti:

  • GetInputStatus. Questo metodo indica se DMO può accettare l'input in questo momento. Il modello chiama InternalAcceptingInput nella classe derivata. Se dMO può accettare l'input, la classe derivata restituisce S_OK e il modello imposta il bit DMO_INPUT_STATUSF_ACCEPT_DATA nel parametro dwFlags. In caso contrario, la classe derivata restituisce S_FALSE e il modello imposta dwFlags su zero.
  • ProcessInput. Questo metodo elabora un buffer di input. Il modello chiama AllocateStreamingResources, descritto in precedenza. Chiama quindi InternalAcceptingInput nella classe derivata. Se DMO può accettare un nuovo input, il modello chiama InternalProcessInput.
  • ProcessOutput. Questo metodo elabora un set di buffer di output, un buffer per ogni flusso di output. Il template chiama AllocateStreamingResources e quindi InternalProcessOutput.
  • Discontinuità. Questo metodo segnala una discontinuità in un flusso di input. Il modello chiama InternalAcceptingInput nella classe derivata. Se il metodo restituisce S_OK, il modello chiama InternalDiscontinuity nella classe derivata.
  • Scarica. Questo metodo pulisce il DMO. Il modello chiama InternalFlush nella classe derivata. L'istanza DMO deve eliminare tutti i buffer di input che contiene ancora da processare.

Il modello non fornisce alcun supporto diretto per l'interfacciaIMediaObjectInPlace.

Metodi per il blocco

Il blocco viene usato per proteggere lo stato di DMO in un ambiente multithreading. In un progetto ATL il metodo IMediaObject::Lock causa un conflitto di nomi con il metodo ATL Lock. Per risolvere il conflitto, il modello rinomina il metodo IMediaObject in DMOLock. Quando si compila la classe derivata, definire FIX_LOCK_NAME prima di includere il file header Dmo.h:

#define FIX_LOCK_NAME
#include <dmo.h>

Questa direttiva fa sì che il preprocessore sostituisca DMOLock a Lock nella dichiarazione dell'interfaccia IMediaObject. Le applicazioni possono comunque richiamare il metodo usando il nome Lock, perché l'ordine della tabella virtuale non cambia. Il metodo DMOLock chiama Lock o Unlock nella classe derivata. Se si usa ATL per implementare la classe derivata, questi metodi sono già definiti da ATL, quindi non è necessario alcun codice aggiuntivo. Se non si utilizza ATL, è necessario fornire i metodi Lock e Unlock nella classe derivata.

Il modello blocca automaticamente il DMO in ciascuno dei metodi IMediaObject. La classe derivata potrebbe dover bloccare l'oggetto DMO all'interno di altri metodi pubblici implementati, ad esempio se supporta IMediaObjectInPlace). Il modello di classe fornisce anche una classe helper interna, IMediaObjectImpl::LockIt, utile per bloccare e sbloccare l'oggetto DMO.

Riepilogo

Per i metodi di IMediaObject seguenti, il modello chiama un metodo corrispondente con la stessa firma nella classe derivata. La classe derivata deve implementare ognuno dei metodi illustrati nella seconda colonna.

IMediaObject, metodo Metodo della classe derivata
AllocareRisorseDiStreaming InternalAllocateStreamingResources
Discontinuità DiscontinuitàInterna
scaricamento ScaricoInterno
freeStreamingResources InternalFreeStreamingResources
OttieniLatenzaMassimaInput InternalGetInputMaxLatency
GetInputSizeInfo InternalGetInputSizeInfo
GetInputStreamInfo InternalGetInputStreamInfo
getInputType InternalGetInputType
GetOutputSizeInfo InternalGetOutputSizeInfo
GetOutputStreamInfo InternalGetOutputStreamInfo
GetOutputType InternalGetOutputType
ProcessInput IngressoProcessoInterno
ProcessOutput OutputProcessoInterno
SetInputMaxLatency InternalSetInputMaxLatency

 

Per i rimanenti metodi IMediaObject, non esiste una corrispondenza uno-a-uno tra i metodi del modello e i metodi della classe derivata. Nella tabella seguente vengono riepilogati i metodi completamente implementati dal modello e quali metodi chiamano altri metodi nella classe derivata.

IMediaObject, metodo Metodo della classe derivata
getInputCurrentType Completamente implementato
GetOutputCurrentType Completamente implementato
GetStreamCount Completamente implementato
GetInputStatus InternalAcceptingInput
Blocco (implementato come DMOLock) blocco, sblocca
SetInputType InternalCheckInputType
SetOutputType TipoDiOutputControlloInterno

 

modello di classe IMediaObjectImpl

Come scrivere un DMO