Condividi tramite


Uso del modello di classe DMO

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, FMMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, FMMediaEngine e Audio/Video Capture 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à "bookkeeping", ad esempio la convalida dei parametri di input. Usando il modello, è possibile concentrarsi sulle funzionalità specifiche dell'oggetto DMO. Inoltre, il modello consente di garantire la creazione di un'implementazione affidabile. Il modello è definito nel file di intestazione Dmoimpl.h, situato nella directory Include dell'SDK.

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

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

La classe derivata deve implementare l'interfaccia IUnknown ; il modello non fornisce questa interfaccia. È possibile usare Active Template Library (ATL) per implementare IUnknown oppure è 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.

Dichiarazione della 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 nel 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>

La parte restante di questa sezione descrive come il modello implementa i vari metodi in IMediaObject.

Metodi per l'impostazione dei tipi di supporti

I metodi seguenti impostano o recuperano tipi di supporti nella 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 cancella il tipo di supporto.
  • GetInputCurrentType, GetOutputCurrentType. Questi metodi restituiscono il tipo di supporto corrente per un flusso o DMO_E_TYPE_NOT_SET se non è impostato alcun tipo. Il modello implementa completamente questi metodi.

Metodi informativi

I metodi seguenti forniscono informazioni sull'oggetto 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 non è stato impostato alcun tipo di supporto nel flusso, il modello restituisce DMO_E_TYPE_NOT_SET. In caso contrario, chiama InternalGetInputSizeInfo o InternalGetOutputSizeInfo nella classe derivata.
  • GetInputStreamInfo, GetOutputStreamInfo. Questi metodi restituiscono vari flag che indicano come il client deve formattare i dati. Il modello chiama InternalGetInputStreamInfo o InternalGetOutputStreamInfo nella 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 necessarie prima dell'inizio del flusso. Il metodo FreeStreamingResources rilascia le stesse risorse. Il modello chiama rispettivamente InternalAllocateStreamingResources e InternalFreeStreamingResources.

Il client di DMO non è necessario chiamare questi metodi, ma il modello chiama automaticamente AllocateStreamingResources prima dell'avvio del flusso. Pertanto, il DMO può presupporre che le risorse siano state allocate correttamente dal momento in cui viene chiamato ProcessInput . DMO deve chiamare FreeStreamingResources nel relativo distruttore.

Inoltre, quando il modello chiama InternalAllocateStreamingResources, imposta un flag interno, in modo che non chiami nuovamente tale metodo finché non chiama InternalFreeStreamingResources. Ciò garantisce che le risorse non vengano riallocate accidentalmente, che potrebbero causare perdite di memoria.

Metodi per lo streaming

I metodi seguenti vengono usati per trasmettere i dati:

  • GetInputStatus. Questo metodo indica se il DMO può accettare l'input in questo momento. Il modello chiama InternalAcceptingInput nella classe derivata. Se il DMO può accettare l'input, la classe derivata restituisce S_OK e il modello imposta il bit DMO_INPUT_STATUSF_ACCEPT_DATA bit 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 modello 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 scarica l'oggetto DMO. Il modello chiama InternalFlush nella classe derivata. DMO deve eliminare tutti i buffer di input che contiene ancora da elaborare.

Il modello non fornisce alcun supporto diretto per l'interfaccia IMediaObjectInPlace .

Metodi per il blocco

Il blocco viene usato per proteggere lo stato di DMO in un ambiente multithreaded. 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 di intestazione Dmo.h:

#define FIX_LOCK_NAME
#include <dmo.h>

Questa direttiva fa sì che il preprocessore sostituisca DMOLock per 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 usa ATL, è necessario fornire metodi Lock e Unlock nella classe derivata.

Il modello blocca automaticamente l'oggetto DMO in ognuno dei metodi IMediaObject. La classe derivata potrebbe dover bloccare il 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 il DMO.

Summary

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

Metodo IMediaObject Metodo classe derivata
AllocateStreamingResources InternalAllocateStreamingResources
Discontinuità InternalDiscontinuity
Svuotamento InternalFlush
FreeStreamingResources InternalFreeStreamingResources
GetInputMaxLatency InternalGetInputMaxLatency
GetInputSizeInfo InternalGetInputSizeInfo
GetInputStreamInfo InternalGetInputStreamInfo
GetInputType InternalGetInputType
GetOutputSizeInfo InternalGetOutputSizeInfo
GetOutputStreamInfo InternalGetOutputStreamInfo
GetOutputType InternalGetOutputType
ProcessInput InternalProcessInput
ProcessOutput InternalProcessOutput
SetInputMaxLatency InternalSetInputMaxLatency

 

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

Metodo IMediaObject Metodo classe derivata
GetInputCurrentType Completamente implementato
GetOutputCurrentType Completamente implementato
GetStreamCount Completamente implementato
GetInputStatus InternalAcceptingInput
Blocco (implementato come DMOLock) Blocco, Sblocco
SetInputType InternalCheckInputType
SetOutputType InternalCheckOutputType

 

Modello di classe IMediaObjectImpl

Scrittura di un DMO