États du filtre
[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngineet audio/vidéo capture dans 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 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.]
Les filtres ont trois états possibles : arrêté, suspendu et en cours d’exécution. L’objectif de l’état suspendu est d’indiquer les données dans le graphique, afin qu’une commande d’exécution réponde immédiatement. Le Gestionnaire de graphes de filtre contrôle toutes les transitions d’état. Lorsqu’une application appelle IMediaControl ::Run, IMediaControl ::P auseou IMediaControl ::Stop, le Gestionnaire de graphes de filtre appelle la méthode IMediaFilter correspondante sur tous les filtres. Les transitions entre arrêtés et en cours d’exécution passent toujours par l’état suspendu. Par conséquent, si l’application appelle Exécuter sur un graphique arrêté, le Gestionnaire de graphes de filtre interrompt le graphique avant de l’exécuter.
Pour la plupart des filtres, les états en cours d’exécution et suspendus sont identiques. Considérez le graphique de filtre suivant :
Convertisseur de transformation > source >
Supposons que pour l’instant, le filtre source n’est pas une source de capture dynamique. Lorsque le filtre source s’interrompt, il crée un thread qui génère de nouvelles données et les écrit dans des exemples multimédias le plus rapidement possible. Le thread « envoie (push) » les exemples en aval en appelant IMemInputPin ::Receive sur la broche d’entrée du filtre de transformation. Le filtre de transformation reçoit les exemples sur le thread du filtre source. Il peut utiliser un thread de travail pour remettre les exemples au renderer, mais il les remet généralement sur le même thread. Pendant que le renderer est suspendu, il attend de recevoir un exemple. Une fois qu’il en reçoit un, il bloque et contient cet exemple indéfiniment. S’il s’agit d’un renderer vidéo, il affiche l’exemple sous forme d’image d’affiche, repeint l’image si nécessaire.
À ce stade, le flux est entièrement cued et prêt pour le rendu. Si le graphe reste suspendu, les exemples sont « empilés » dans le graphe derrière le premier échantillon, jusqu’à ce que chaque filtre soit bloqué dans Recevoir ou IMemAllocator ::GetBuffer. Toutefois, aucune donnée n’est perdue. Une fois le thread source déblocé, il reprend simplement à partir du point où il a bloqué.
Le filtre source et le filtre de transformation ignorent la transition entre pause et exécution, ils continuent simplement à traiter les données aussi rapidement que possible. Toutefois, lorsque le renderer s’exécute, il démarre le rendu des exemples. Tout d’abord, il restitue l’exemple qu’il a conservé pendant qu’il a été suspendu. Ensuite, chaque fois qu’il reçoit un nouvel exemple, il calcule l’heure de présentation de l’exemple. (Pour plus d’informations, consultez heure et horloges dans DirectShow.) Le renderer contient chaque échantillon jusqu’au moment de la présentation, à quel moment il restitue l’exemple. Pendant qu’il attend le temps de présentation, il bloque dans la méthode Receive, ou reçoit de nouveaux exemples sur un thread de travail avec une file d’attente. Les filtres en amont à partir du renderer ne sont pas impliqués dans la planification.
Les sources actives, telles que les appareils de capture, sont une exception à cette architecture générale. Avec une source dynamique, il n’est pas approprié de mettre en avant les données. L’application peut suspendre le graphique, puis attendre longtemps avant de l’exécuter. Le graphique ne doit pas afficher les exemples « obsolètes ». Par conséquent, une source dynamique ne produit aucun échantillon en pause, uniquement lors de l’exécution. Pour signaler ce fait au Gestionnaire de graphes de filtre, la méthode IMediaFilter ::GetState du filtre source retourne VFW_S_CANT_CUE. Ce code de retour indique que le filtre a basculé vers l’état suspendu, même si le renderer n’a pas reçu de données.
Lorsqu’un filtre s’arrête, il rejette d’autres échantillons remis à celui-ci. Les filtres sources arrêtent leurs threads de diffusion en continu, et d’autres filtres arrêtent les threads de travail qu’ils peuvent avoir créés. Épingles décommit leurs allocateurs.
Transitions d’état
Le Gestionnaire de graphiques de filtre effectue toutes les transitions d’état dans l’ordre en amont, en commençant par le renderer et en descendant vers le filtre source. Cet ordre est nécessaire pour empêcher l’abandon des échantillons et empêcher le graphique d’interblocage. Les transitions d’état les plus cruciales sont entre suspendues et arrêtées :
- Arrêté de suspendre : à mesure que chaque filtre s’interrompt, il est prêt à recevoir des échantillons à partir du filtre suivant. Le filtre source est le dernier à suspendre. Il crée le thread de diffusion en continu et commence à distribuer des exemples. Étant donné que tous les filtres en aval sont suspendus, aucun filtre ne rejette les échantillons. Le Gestionnaire de graphiques de filtre n’effectue pas la transition tant que chaque renderer du graphique n’a pas reçu un exemple (à l’exception des sources actives, comme décrit précédemment).
- Suspendu pour s’arrêter : lorsqu’un filtre s’arrête, il libère tous les échantillons qu’il contient, ce qui débloque tous les filtres en amont en attente dans GetBuffer. Si le filtre attend une ressource à l’intérieur de la méthode Receive, il cesse d’attendre et de retourner de Recevoir, ce qui débloque le filtre appelant. Par conséquent, lorsque le Gestionnaire de graphes de filtre arrête le filtre en amont suivant, ce filtre n’est pas bloqué dans GetBuffer ou Recevoir, et peut répondre à la commande d’arrêt. Le filtre en amont peut fournir quelques exemples supplémentaires avant d’obtenir la commande d’arrêt, mais le filtre en aval les rejette simplement, car il s’est déjà arrêté.
Rubriques connexes
-
flux de données dans le du graphique de filtre