Livraison d’exemples

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement au nouveau code d’utiliser MediaPlayer, IMFMediaEngine et La capture audio/vidéo dans Media Foundation au lieu de DirectShow, lorsque cela est 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.]

Cet article décrit comment un filtre fournit un exemple. Il décrit à la fois le modèle push, à l’aide des méthodes IMemInputPin , et le modèle pull, à l’aide d’IAsyncReader.

Modèle Push : remise d’un exemple

La broche de sortie fournit un exemple en appelant la méthode IMemInputPin::Receive ou la méthode IMemInputPin::ReceiveMultiple , qui est équivalente mais fournit un tableau d’exemples. La broche d’entrée peut bloquer à l’intérieur de Receive (ou ReceiveMultiple). Si le code pin peut bloquer, sa méthode IMemInputPin::ReceiveCanBlock doit retourner S_OK. Si la broche garantit qu’elle ne se bloque jamais, ReceiveCanBlock doit retourner S_FALSE. La valeur de retour S_OK ne signifie pas que Receive bloque toujours, mais simplement qu’elle peut.

Bien que Réception puisse bloquer pour attendre qu’une ressource soit disponible, elle ne doit pas bloquer pour attendre plus de données du filtre amont. Cela peut entraîner un blocage où le filtre amont attend que le filtre en aval libère l’exemple, ce qui ne se produit jamais parce que le filtre en aval attend le filtre amont. Toutefois, si un filtre a plusieurs broches d’entrée, une broche peut attendre qu’une autre broche reçoive des données. Par exemple, le filtre AVI Mux effectue cette opération afin qu’il puisse entrelacer des données audio et vidéo.

Une broche peut rejeter un exemple pour plusieurs raisons :

  • La broche est en cours de vidage (voir Vidage).
  • La broche n’est pas connectée.
  • Le filtre est arrêté.
  • Une autre erreur s’est produite.

La méthode Receive doit retourner S_FALSE dans le premier cas et un code d’échec dans les autres cas. Le filtre amont doit cesser d’envoyer des exemples lorsque le code de retour est autre que S_OK.

Vous pouvez considérer les trois premiers cas comme des échecs « attendus », dans le sens où le filtre était dans un état incorrect pour recevoir des exemples. Un échec inattendu entraînerait le rejet d’un exemple par la broche, même si la broche est dans un état de réception. Si une erreur de ce type se produit, la broche doit envoyer une notification de fin de flux en aval et envoyer un événement EC_ERRORABORT au Gestionnaire de graphes de filtre.

Dans les classes de base DirectShow, la méthode CBaseInputPin::CheckStreaming recherche les cas d’échec généraux (vidage, arrêt, etc.). La classe dérivée doit case activée pour les défaillances spécifiques au filtre. En cas d’erreur, la méthode CBaseInputPin::Receive envoie la notification de fin de flux et l’événement EC_ERRORABORT.

Modèle d’extraction : demande d’un exemple

Dans l’interface IAsyncReader , la broche d’entrée demande des exemples à partir de la broche de sortie en appelant l’une des méthodes suivantes :

La méthode Request est asynchrone ; la broche d’entrée appelle IAsyncReader::WaitForNext pour attendre que la demande se termine. Les deux autres méthodes sont synchrones.

Quand remettre des données

Un filtre fournit toujours des exemples lorsqu’il est en cours d’exécution. Dans la plupart des cas, un filtre fournit également des exemples en pause. Cela permet au graphe d’indiquer les données afin que la lecture démarre immédiatement lorsque l’exécution est appelée (voir Filtrer les états). Si votre filtre ne fournit pas de données en pause, la méthode IMediaFilter::GetState du filtre doit retourner VFW_S_CANT_CUE dans l’état suspendu. Ce code de retour indique au graphe de filtre de ne pas attendre les données de votre filtre avant de terminer la transition de pause. Sinon, la méthode Pause sera bloquée indéfiniment. Pour obtenir un exemple de code, consultez CBaseFilter::GetState.

Voici quelques exemples de cas où un filtre peut avoir besoin de retourner VFW_S_CANT_CUE :

  • Les sources actives, telles que les filtres de capture, ne doivent pas envoyer de données en pause. Consultez Production de données dans un filtre de capture.
  • Un filtre de fractionnement peut ou non envoyer des données en pause, en fonction de l’implémentation. Si le filtre utilise des threads distincts pour mettre en file d’attente les données sur chaque broche de sortie, il peut envoyer des données en pause. Mais si le filtre utilise un thread unique pour chaque broche de sortie, la première broche peut bloquer le thread lorsqu’il appelle Receive, ce qui empêchera les autres broches d’envoyer des données. Dans ce cas, vous devez retourner VFW_S_CANT_CUE.
  • Un filtre peut fournir des données de manière sporadique. Par exemple, il peut analyser un flux de données personnalisé et filtrer certains paquets lors de la remise d’autres paquets. Dans ce cas, il se peut que le filtre ne soit pas garanti pour fournir des données pendant la pause.

Un filtre source (à l’aide du modèle push) ou un filtre d’analyseur (à l’aide du modèle push/pull) crée un ou plusieurs threads de streaming, qui fournissent des exemples aussi rapidement que possible. Les filtres en aval, tels que les décodeurs et les transformations, envoient généralement des données uniquement lorsque La réception est appelée sur leurs broches d’entrée.

Réception et livraison d’échantillons