Canaux et circuits AVStream
Un canal est un ensemble de filtres AVStream qui partagent un allocateur commun.
L’illustration suivante montre un canal composé de trois filtres AVStream : un filtre source, un filtre de transformation inplace et un filtre de convertisseur.
Dans cet exemple, KSProxy (non affiché) a choisi un allocateur, représenté par le bloc Alloc dans le diagramme.
AVStream crée un objet demandeur interne associé au filtre source. Dans le diagramme, le demandeur apparaît sous la forme Req. Le minidriver spécifie dans le membre AllocatorFraming de KSPIN_DESCRIPTOR_EX le type de mémoire et la quantité de mémoire continue à affecter à un frame. En conséquence, le demandeur obtient des trames à partir de l’allocateur et les transmet au composant suivant dans le circuit.
Les données du filtre source sont transmises à un filtre de transformation implémenté par un autre pilote AVStream.
Enfin, les données circulent dans le filtre de renderer implémenté par un troisième filtre AVStream.
Étant donné que toutes les broches de ce graphique sont des broches AVStream, AVStream utilise ses propres interfaces de transport interne au lieu d’envoyer des irps au moyen d’IoCallDriver, ce qui réduit la latence et améliore les performances.
Plus précisément, lorsque l’application entraîne la transition du graphique vers KSSTATE_ACQUIRE (par instance, lorsque l’utilisateur clique sur Lire dans GraphEdit), AVStream connecte directement les files d’attente de filtre comme indiqué ci-dessus.
Par conséquent, les images envoyées en aval retournent au demandeur, où elles peuvent être recyclées une fois le rendu terminé. Ce chemin de données AVStream est un circuit.
Prenons un deuxième exemple, illustré dans l’illustration ci-dessous, dans lequel le filtre de transformation n’est pas un filtre AVStream, mais est toujours un filtre en mode noyau.
Comme dans le premier exemple, cet exemple inclut trois filtres : une source AVStream, une transformation KS (il peut s’agir d’un pilote qui utilise KS directement ou un minidriver sous la classe de flux) et d’un convertisseur AVStream.
Comme dans la première illustration, les broches sont d’abord interconnectées. Toutefois, lorsque le graphique de filtre passe à KSSTATE_ACQUIRE, le filtre Kernel Streaming 1.0 ne prend pas en charge l’interface de transport AVStream. Par conséquent, AVStream ne contourne pas les broches ; au lieu de cela, elle doit utiliser des E/S pour déplacer des données entre des filtres.
Plus précisément, lorsqu’un cadre quitte la file d’attente du filtre source, AVStream appelle IoCallDriver. Dans cet appel, le paramètre Irp contient le frame à passer de la broche de sortie de la source au filtre de transformation.
Lorsque la broche d’entrée du convertisseur reçoit l’IRP, celle-ci place l’IRP dans la file d’attente. Lorsque le pilote de convertisseur termine une image, il retourne le frame à la broche d’entrée du convertisseur, comme indiqué dans le deuxième exemple.
AVStream appelle maintenant IoCompleteRequest pour retourner le frame amont. La broche de sortie du filtre source reçoit une notification d’achèvement. La routine de rappel du processus d’épingle du minidriver peut ensuite appeler KsStreamPointerUnlock et déplacer les images vers le demandeur à recycler dans le circuit.
Prenons un dernier exemple dans lequel la source de frame est en mode utilisateur. (La destination de l’image finale peut également être en mode utilisateur.)
Dans l’illustration ci-dessous, un filtre de transformation non inplace en mode noyau reçoit les trames d’un filtre DirectShow en mode utilisateur et envoie le frame transformé à un renderer AVStream en mode noyau :
Lorsque les images arrivent du mode utilisateur, l’objet pin AVStream les place dans la file d’attente pour la section du canal d’entrée.
Le filtre de transformation non inplace alloue les images transformées en mode noyau, puis utilise le deuxième canal comme circuit pour ces images. Étant donné que le convertisseur est un filtre AVStream, AVStream contourne les broches et utilise l’interface de transport AVStream pour placer les images directement dans la file d’attente du filtre de rendu.
Le minidriver peut injecter des images dans le circuit en appelant KsPinSubmitFrame ou KsPinSubmitFrameMdl. Si le minidriver utilise cette méthode, le demandeur AVStream reçoit des trames à la suite de ces appels, plutôt qu’à partir d’un allocateur en mode noyau.