Share via


Utilisation du modèle de classe DMO

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture in Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation au lieu de DirectShow, si possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

DirectShow inclut un modèle de classe, IMediaObjectImpl, pour l’implémentation d’objets DMO. Le modèle gère de nombreuses tâches de « comptabilité », telles que la validation des paramètres d’entrée. En utilisant le modèle, vous pouvez vous concentrer sur les fonctionnalités spécifiques à votre DMO. En outre, le modèle permet de s’assurer que vous créez une implémentation robuste. Le modèle est défini dans le fichier d’en-tête Dmoimpl.h, situé dans le répertoire Include du Kit de développement logiciel (SDK).

Le modèle IMediaObjectImpl hérite de l’interface IMediaObject . Pour créer un DMO à l’aide du modèle, définissez une nouvelle classe qui dérive de IMediaObjectImpl. Le modèle implémente toutes les méthodes IMediaObject . Dans la plupart des cas, le modèle appelle une méthode privée correspondante sur la classe dérivée. Le modèle fournit les fonctionnalités suivantes :

  • Vérification des paramètres de base. Les méthodes de modèle vérifient que les paramètres requis ne sont pas NULL, que les index de flux sont dans la plage et que les indicateurs sont valides.
  • Verrouillage. Les méthodes de modèle appellent deux méthodes internes, Lock et Unlock, pour sérialiser les opérations sur le DMO. Cette fonctionnalité garantit que le DMO est thread-safe.
  • Types de médias. Le modèle stocke les types de médias définis par le client et fournit des méthodes d’accesseur pour les types de médias.
  • Streaming. Le modèle empêche la diffusion en continu tant que le client n’a pas défini des types de médias pour tous les flux non facultatifs. Il garantit également que la méthode IMediaObject::AllocateStreamingResources est appelée avant le début de la diffusion en continu, ce qui garantit que les ressources sont allouées.

La classe dérivée doit implémenter l’interface IUnknown ; le modèle ne fournit pas cette interface. Vous pouvez utiliser la bibliothèque ACTIVE Template Library (ATL) pour implémenter IUnknown, ou vous pouvez fournir une autre implémentation. Le modèle n’implémente pas non plus le mécanisme de verrouillage. La classe dérivée doit implémenter les méthodes Lock et Unlock . Si vous créez votre classe à l’aide d’ATL, vous pouvez utiliser les implémentations ATL par défaut.

Déclaration de la classe dérivée

Le modèle de classe IMediaObjectImpl est déclaré comme suit :

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

Les trois paramètres de modèle sont _DERIVED_, NUMBEROFINPUTS et NUMBEROFOUTPUTS. Définissez _DERIVED_ comme nom de votre classe. Les deux autres paramètres définissent le nombre de flux d’entrée et de flux de sortie sur le DMO. Par exemple, pour créer une classe DMO nommée CMyDmo qui prend en charge un flux d’entrée et deux flux de sortie, utilisez la déclaration suivante :

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

Le reste de cette section décrit comment le modèle implémente les différentes méthodes dans IMediaObject.

Méthodes de définition des types de média

Les méthodes suivantes définissent ou récupèrent des types de médias sur le DMO :

  • GetInputType, GetOutputType. Ces méthodes retournent les types de média préférés, par numéro de flux et index de type. Le modèle appelle InternalGetInputType ou InternalGetOutputType sur la classe dérivée.
  • SetInputType, SetOutputType. Ces méthodes définissent le type de média sur un flux, testent un type de média ou effacent un type de média. Pour valider le type de média, le modèle appelle InternalCheckInputType ou InternalCheckOutputType sur la classe dérivée. La classe dérivée retourne S_OK d’accepter le type ou DMO_E_INVALIDTYPE de rejeter le type. Le modèle gère le paramètre ou l’effacement du type de média.
  • GetInputCurrentType, GetOutputCurrentType. Ces méthodes retournent le type de média actuel pour un flux, ou DMO_E_TYPE_NOT_SET si aucun type n’est défini. Le modèle implémente complètement ces méthodes.

Méthodes d’information

Les méthodes suivantes fournissent des informations sur le DMO.

  • GetInputMaxLatency, SetInputMaxLatency. Ces méthodes récupèrent ou définissent la latence maximale. Le modèle appelle InternalGetInputMaxLatency ou InternalSetInputMaxLatency sur la classe dérivée.
  • GetInputsizeInfo, GetOutputsizeInfo. Ces méthodes retournent les exigences de mémoire tampon de DMO pour un flux spécifié. Si aucun type de média n’a été défini sur ce flux, le modèle retourne DMO_E_TYPE_NOT_SET. Sinon, elle appelle InternalGetInputSizeInfo ou InternalGetOutputSizeInfo sur la classe dérivée.
  • GetInputStreamInfo, GetOutputStreamInfo. Ces méthodes retournent différents indicateurs qui indiquent comment le client doit mettre en forme les données. Le modèle appelle InternalGetInputStreamInfo ou InternalGetOutputStreamInfo sur la classe dérivée.
  • GetStreamCount. Cette méthode retourne le nombre de flux d’entrée et de sortie. Le modèle implémente cette méthode à l’aide des paramètres du modèle.

Méthodes d’allocation de ressources

  • La méthode AllocateStreamingResources alloue toutes les ressources dont DMO a besoin avant le début de la diffusion en continu. La méthode FreeStreamingResources libère les mêmes ressources. Le modèle appelle InternalAllocateStreamingResources et InternalFreeStreamingResources, respectivement.

Le client du DMO n’est pas obligé d’appeler ces méthodes, mais le modèle appelle automatiquement AllocateStreamingResources avant le démarrage de la diffusion en continu. Par conséquent, le DMO peut supposer que les ressources ont été allouées correctement au moment où ProcessInput est appelé. Le DMO doit appeler FreeStreamingResources dans son destructeur.

En outre, lorsque le modèle appelle InternalAllocateStreamingResources, il définit un indicateur interne, de sorte qu’il n’appelle pas à nouveau cette méthode avant d’appeler InternalFreeStreamingResources. Cela garantit que les ressources ne sont pas réaffectée accidentellement, ce qui peut entraîner des fuites de mémoire.

Méthodes pour la diffusion en continu

Les méthodes suivantes sont utilisées pour diffuser des données :

  • GetInputStatus. Cette méthode indique si le DMO peut accepter l’entrée pour le moment. Le modèle appelle InternalAcceptingInput sur la classe dérivée. Si le DMO peut accepter l’entrée, la classe dérivée retourne S_OK et le modèle définit le bit DMO_INPUT_STATUSF_ACCEPT_DATA dans le paramètre dwFlags . Sinon, la classe dérivée retourne S_FALSE et le modèle définit dwFlags sur zéro.
  • ProcessInput. Cette méthode traite une mémoire tampon d’entrée. Le modèle appelle AllocateStreamingResources, décrit précédemment. Ensuite, il appelle InternalAcceptingInput sur la classe dérivée. Si le DMO peut accepter de nouvelles entrées, le modèle appelle InternalProcessInput.
  • ProcessOutput. Cette méthode traite un ensemble de mémoires tampons de sortie, une mémoire tampon pour chaque flux de sortie. Le modèle appelle AllocateStreamingResources , puis InternalProcessOutput.
  • Discontinuité. Cette méthode signale une discontinuité dans un flux d’entrée. Le modèle appelle InternalAcceptingInput sur la classe dérivée. Si cette méthode retourne S_OK, le modèle appelle InternalDiscontinuity sur la classe dérivée.
  • Videz. Cette méthode vide le DMO. Le modèle appelle InternalFlush sur la classe dérivée. Le DMO doit ignorer toutes les mémoires tampons d’entrée qu’il contient encore pour être traitées.

Le modèle ne fournit aucune prise en charge directe pour l’interface IMediaObjectInPlace .

Méthodes de verrouillage

Le verrouillage est utilisé pour protéger l’état du DMO dans un environnement multithread. Dans un projet ATL, la méthode IMediaObject::Lock provoque un conflit de noms avec la méthode ATL Lock . Pour résoudre le conflit, le modèle renomme la méthode IMediaObjecten DMOLock. Lorsque vous compilez la classe dérivée, définissez FIX_LOCK_NAME avant d’inclure le fichier d’en-tête Dmo.h :

#define FIX_LOCK_NAME
#include <dmo.h>

Cette directive oblige le préprocesseur à remplacer DMOLock par Lock dans la déclaration de l’interface IMediaObject . Les applications peuvent toujours appeler la méthode à l’aide du nom Lock, car l’ordre de la table virtuelle ne change pas. La méthode DMOLock appelle Lock ou Unlock sur la classe dérivée. Si vous utilisez ATL pour implémenter la classe dérivée, ces méthodes étant déjà définies par ATL, aucun code supplémentaire n’est nécessaire. Si vous n’utilisez pas ATL, vous devez fournir les méthodes Lock et Unlock dans votre classe dérivée.

Le modèle verrouille automatiquement le DMO dans chacune des méthodes IMediaObject . La classe dérivée peut avoir besoin de verrouiller le DMO à l’intérieur d’autres méthodes publiques qu’elle implémente (par exemple, si elle prend en charge IMediaObjectInPlace). Le modèle de classe fournit également une classe d’assistance interne, IMediaObjectImpl::LockIt, qui est utile pour verrouiller et déverrouiller le DMO.

Résumé

Pour les méthodes IMediaObject suivantes, le modèle appelle une méthode correspondante avec la même signature sur la classe dérivée. La classe dérivée doit implémenter chacune des méthodes indiquées dans la deuxième colonne.

IMediaObject, méthode Méthode de classe dérivée
AllocateStreamingResources InternalAllocateStreamingResources
Discontinuité InternalDiscontinuity
Purge InternalFlush
FreeStreamingResources InternalFreeStreamingResources
GetInputMaxLatency InternalGetInputMaxLatency
GetInputSizeInfo InternalGetInputSizeInfo
GetInputStreamInfo InternalGetInputStreamInfo
GetInputType InternalGetInputType
GetOutputSizeInfo InternalGetOutputSizeInfo
GetOutputStreamInfo InternalGetOutputStreamInfo
GetOutputType InternalGetOutputType
ProcessInput InternalProcessInput
ProcessOutput InternalProcessOutput
SetInputMaxLatency InternalSetInputMaxLatency

 

Pour les méthodes IMediaObject restantes, il n’existe pas de correspondance un-à-un entre les méthodes de modèle et les méthodes de classe dérivée. Le tableau suivant récapitule les méthodes entièrement implémentées par le modèle et les méthodes qui appellent d’autres méthodes sur la classe dérivée.

IMediaObject, méthode Méthode de classe dérivée
GetInputCurrentType Entièrement implémenté
GetOutputCurrentType Entièrement implémenté
GetStreamCount Entièrement implémenté
GetInputStatus InternalAcceptingInput
Lock (implémenté en tant que DMOLock) Verrouiller, Déverrouiller
SetInputType InternalCheckInputType
SetOutputType InternalCheckOutputType

 

Modèle de classe IMediaObjectImpl

Écriture d’un DMO