Comment les décodeurs utilisent IAMVideoAccelerator
[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.]
L’interface IAMVideoAccelerator active les opérations d’accélération vidéo génériques, notamment l’accélération vidéo DirectX (VA). Pour l’accélération VA non DirectX, le décodeur et le pilote vidéo doivent tous deux respecter un protocole commun.
Cette section décrit l’ordre général des opérations que tout décodeur doit suivre lors de l’utilisation de cette interface. Pour plus d’informations sur les décodeurs basés sur DirectX, consultez Mappage de l’accélération vidéo DirectX à IAMVideoAccelerator.
Notes
Cette interface est disponible dans Windows 2000 et versions ultérieures.
L’interface IAMVideoAccelerator est exposée sur la broche d’entrée du mélangeur de superposition ou du convertisseur de mixage vidéo (VMR). L’interface IAMVideoAcceleratorNotify est exposée sur la broche de sortie du décodeur. La séquence d’événements pour la connexion des broches de filtre est la suivante :
Le Gestionnaire de graphes de filtre appelle IPin::Connect sur la broche de sortie du filtre de décodeur. Un AM_MEDIA_TYPE est un paramètre facultatif.
- AM_MEDIA_TYPE est une structure de données qui décrit un type de média. Il contient un GUID de majortype (qui dans notre cas doit être MEDIATYPE_Video), un GUID de sous-type (qui dans notre cas doit être un GUID d’accélérateur vidéo) et divers autres éléments. L’une de ces choses est un GUID de type format contenant des informations sur le média, y compris dans notre cas la largeur et la hauteur d’une image vidéo non compressée, probablement dans une structure MPEG1VIDEOINFO, VIDEOINFOHEADER, MPEG2VIDEOINFO ou VIDEOINFOHEADER2 .
- Le AM_MEDIA_TYPE structure, le cas échéant, indique au décodeur de fonctionner à l’aide du type de média spécifié, qui peut être « entièrement spécifié » ou « partiellement spécifié ». S’il est « entièrement spécifié », le décodeur tente normalement simplement de fonctionner avec ce type de média. Si « partiellement spécifié », il tente de trouver un mode de fonctionnement compatible « entièrement spécifié » qu’il peut utiliser pour se connecter d’une manière cohérente avec le type de média « partiellement spécifié ».
- La méthode ordinaire pour tenter de trouver un type de média « entièrement spécifié » à utiliser pour une connexion consiste simplement à exécuter une liste de tous les types de médias « entièrement spécifiés » pris en charge par la broche de sortie compatible avec le type multimédia « partiellement spécifié » et à tenter de se connecter à chacun d’eux jusqu’à ce que cela réussisse. Le processus est normalement similaire si aucun AM_MEDIA_TYPE n’est contenu dans l’appel IPin::Connect, mais avec l’épingle de sortie devant case activée tous ses types de médias.
Si le décodeur souhaite case activée si un AM_MEDIA_TYPE spécifique (y compris un GUID d’accélérateur vidéo) est pris en charge par la broche d’entrée en aval, il peut appeler le code IPin::QueryAccept de cette broche (avec le GUID de l’accélérateur vidéo comme sous-type du AM_MEDIA_TYPE) ou il peut simplement tenter de se connecter à cette broche comme décrit à l’élément 5 ci-dessous.
Si le décodeur ne sait pas quels GUID d’accélérateur vidéo sont pris en charge par la broche d’entrée en aval et ne souhaite pas proposer uniquement un GUID d’accélérateur vidéo candidat en appelant l’IPin::QueryAccept de la broche d’entrée en aval, le décodeur peut appeler IAMVideoAccelerator::GetVideoAcceleratorGUIDs pour obtenir une liste des GUID d’accélérateur vidéo pris en charge par la broche.
Pour certains GUID d’accélérateur vidéo particuliers, le décodeur peut appeler iamvideoaccelerator::GetUncompFormatsSupported de la broche d’entrée en aval pour obtenir la liste des formats de pixelS DDPIXELFORMAT qui peuvent être utilisés pour restituer un GUID d’accélérateur vidéo spécifique. La liste retournée doit être considérée comme étant dans l’ordre de préférence décroissant (c’est-à-dire, avec le format le plus préféré répertorié en premier).
Le décodeur appelle l’IPin::ReceiveConnection de la broche d’entrée en aval, en lui passant un AM_MEDIA_TYPE avec le GUID d’accélérateur vidéo approprié comme sous-type du type de média. Cela configure la connexion pour le fonctionnement, y compris la création des surfaces de sortie non compressées (qui sont allouées à l’aide de la largeur et de la hauteur trouvées dans AM_MEDIA_TYPE, du nombre de surfaces à allouer trouvées par un appel décrit ci-dessous, et de toutes les autres informations que l’accélérateur vidéo dispose et souhaite utiliser à cet effet, telles que le GUID de l’accélérateur vidéo lui-même). Si la broche d’entrée en aval rejette le GUID de l’accélérateur vidéo ou un autre aspect de la connexion, cela peut entraîner l’échec de IPin::ReceiveConnection . Si IPin::ReceiveConnection échoue, cela est indiqué dans un HRESULT retourné et le décodeur peut réessayer l’appel, par exemple, avec un nouveau GUID d’accélérateur vidéo dans la structure AM_MEDIA_TYPE .
[!Note]
Il s’agit d’une autre façon (et la façon la plus définitive) pour le décodeur de déterminer ce qui est pris en charge par la broche d’entrée en aval, en appelant simplement IPin::ReceiveConnection et en essayant de se connecter, puis de vérifier si la tentative de connexion a réussi.
Pendant l’IPin::ReceiveConnection, le convertisseur appelle le IAMVideoAcceleratorNotify::GetUncompSurfacesInfo du décodeur, en lui transmettant le GUID de l’accélérateur vidéo et une structure AMVAUncompBufferInfo , afin de déterminer le nombre de surfaces non compressées à allouer. Le décodeur remplit et retourne la structure, qui contient le nombre minimal et maximal de surfaces à allouer du type particulier, ainsi qu’une structure DDPIXELFORMAT décrivant le format de pixels des surfaces à allouer.
[!Note]
Rien n’est en fait passé au décodeur dans l’appel à IAMVideoAcceleratorNotify::GetUncompSurfacesInfo autre que le GUID de l’accélérateur vidéo.
Le convertisseur appelle le décodeur IAMVideoAcceleratorNotify::SetUncompSurfacesInfo du décodeur, en passant au décodeur le nombre réel de surfaces non compressées qui ont été allouées.
Le convertisseur appelle iamvideoacceleratorNotify::GetCreateVideoAcceleratorData du décodeur pour obtenir toutes les données nécessaires à l’initialisation de l’accélérateur vidéo.
Le décodeur appelle IAMVideoAccelerator::GetCompBufferInfo, en lui transmettant un GUID d’accélérateur vidéo, une structure AMVAUncompDataInfo et le nombre de types de mémoire tampon compressées, pour obtenir en retour un ensemble de structures de données AMVACompBufferInfo , une qui correspond à chaque type de mémoire tampon de données compressée utilisée par le GUID de l’accélérateur vidéo.
- La structure AMVAUncompDataInfo contient la largeur et la hauteur des données décodées non compressées (en pixels) et le DDPIXELFORMAT de l’image non compressée.
- Les structures de données AMVACompBufferInfo retournées contiennent chacune :
Nombre de mémoires tampons compressées nécessaires du type spécifique.
Largeur et hauteur de la surface à créer (champs qui peuvent avoir ou non une signification réelle).
Remarque
L’opération d’allocation de surface DirectDraw pour les tampons compressés ne permet pas actuellement que la largeur ou la hauteur de ces surfaces soit supérieure ou égale à 2^15, même si l’appel d’allocation de surface ne peut pas échouer ouvertement si cette limite est violée. Par conséquent, le pilote peut structurer ses demandes de mémoire tampon compressée pour éviter de telles tailles extrêmes. Par exemple, au lieu de demander une mémoire tampon avec width="1 » et height="65536 », le pilote doit demander une mémoire tampon de width="1024 » et height="64 ».
Nombre total d’octets à utiliser par la surface.
Structure de type DDSCAPS2 définissant un objet DirectDrawSurface, décrivant les fonctionnalités permettant de créer des surfaces pour stocker des données compressées.
DDPIXELFORMAT, décrivant le format de pixels utilisé pour créer des surfaces afin de stocker des données compressées (un champ qui peut avoir ou non une signification réelle).
Remarque
Les appels du convertisseur à certaines méthodes d’interface IAMVideoAcceleratorNotify du décodeur peuvent (et normalement) se produire à l’intérieur de l’appel du décodeur à l’IPin::ReceiveConnection du convertisseur. Plus précisément, cela s’applique aux éléments suivants :
Notes
Pour prendre en charge les modifications de format dynamique, le décodeur peut également appeler IPin::ReceiveConnection et d’autres méthodes ci-dessus pendant que les filtres sont connectés et en cours d’exécution. Cette fonctionnalité est fournie pour prendre en charge les changements de format dynamiques (même si ce n’est pas dans le sens H.263, Annexe P, car tous les jeux de données sont redémarrés à partir de zéro et que toutes les informations d’image de référence sont donc perdues).
Voici une description de l’utilisation d’IAMVideoAccelerator pendant l’opération après l’initialisation :
Pour chaque surface non compressée, le décodeur appelle IAMVideoAccelerator::BeginFrame pour commencer le traitement afin de créer l’image de sortie. Dans ce cas, le décodeur envoie une structure AMVABeginFrameInfo .
La structure AMVABeginFrameInfo contient un index pour une mémoire tampon de destination, un pointeur vers certaines données à envoyer en aval et un pointeur vers un emplacement où l’accélérateur peut placer certaines données que le décodeur doit lire.
REMARQUE 1 : L’accélérateur ne reçoit pas réellement l’index de mémoire tampon de destination, car il est traduit par le convertisseur avant d’aller en aval.
REMARQUE 2 : IAMVideoAccelerator::BeginFrame peut être appelé plusieurs fois entre les appels à IAMVideoAccelerator::EndFrame.
REMARQUE 3 : Il n’existe aucune hypothèse dans l’opération d’interface selon laquelle IAMVideoAccelerator::BeginFrame et IAMVideoAccelerator::EndFrame doivent être appelés pour le traitement de chaque image individuelle dans le flux binaire.
Ce que iamVideoAccelerator::BeginFrame fait, en ce qui concerne l’interface, est de créer une association au sein du convertisseur entre un index et une surface non compressée. Il fournit également un moyen d’appeler une fonction spécifique dans un pilote de périphérique (avec prise en charge d’un moyen de transmettre des données arbitraires entre le décodeur et le pilote de périphérique).
(Toutefois, dans l’opération Va DirectX, il est nécessaire que IAMVideoAccelerator::BeginFrame et IAMVideoAccelerator::EndFrame soient appelés pour le traitement de chaque image individuelle dans le flux de bits.)
Pour envoyer des données non compressées à l’accélérateur, le décodeur appelle :
- IAMVideoAccelerator::QueryRenderStatus pour déterminer si une mémoire tampon est sécurisée pour la lecture ou l’écriture.
- IAMVideoAccelerator::GetBuffer pour verrouiller et obtenir l’accès à une mémoire tampon spécifiée (s’il n’a pas déjà appelé ceci pour obtenir cet accès). GetBuffer peut également être utilisé pour obtenir une copie du contenu de la dernière image de sortie non compressée pour laquelle IAMVideoAccelerator::BeginFrame a été appelé, à condition qu’IAMVideoAccelerator::EndFrame n’ait pas été appelé pour cet index de mémoire tampon de destination. Si la DDI retourne une status de rendu de DDERR_WASSTILLDRAWING pour la mémoire tampon demandée, une boucle de veille est exécutée dans GetBuffer jusqu’à ce que cette condition soit effacée. Pour appeler GetBuffer, le décodeur a besoin d’informations à partir d’une structure de données AMVACompBufferInfo obtenue en appelant IAMVideoAccelerator::GetCompBufferInfo.
- IAMVideoAccelerator::Exécuter pour indiquer que les données d’un ensemble de mémoires tampons compressées comme indiqué dans un tableau de structures de données AMVABUFFERINFO doivent être traitées. Un code de fonction dwFunction est passé au pilote dans cet appel. Un pointeur lpPrivateInputData est également transmis à certaines données pour les envoyer en aval, et un pointeur lpPrivateOutputData est passé à un endroit où le processus en aval peut placer des données pour que le décodeur puisse lire.
- IAMVideoAccelerator::ReleaseBuffer pour indiquer que le décodeur a terminé l’utilisation d’une mémoire tampon spécifiée pour le moment et n’a plus besoin d’un accès verrouillé à la mémoire tampon. (Si le décodeur souhaite continuer à utiliser la mémoire tampon, il ne peut tout simplement pas appeler IAMVideoAccelerator::ReleaseBuffer pour le moment, ce qui évite d’avoir besoin d’appeler IAMVideoAccelerator::GetBuffer jusqu’à ce qu’il ait vraiment l’intention de ne plus utiliser la mémoire tampon.) Le décodeur ne doit pas écrire dans la mémoire tampon après l’appel d’Execute tant que QueryRenderStatus n’indique pas que la mémoire tampon est sûre pour l’écriture.
Pour terminer le traitement de sortie d’une mémoire tampon de destination, le décodeur appelle IAMVideoAccelerator::EndFrame. Il peut passer des données arbitraires en aval avec cet appel, et c’est essentiellement tout ce qui se produit à la suite de cet appel. Il n’envoie pas d’index de mémoire tampon de destination dans cet appel. Il ne peut donc pas indiquer précisément à l’accélérateur quelle mémoire tampon de destination est terminée, sauf si cette indication est contenue dans les données arbitraires transmises.
Pour afficher une image, le décodeur appelle IAMVideoAccelerator::D isplayFrame avec l’index du cadre à afficher et une structure IMediaSample contenant des horodatages de début et d’arrêt et des indicateurs pertinents tels que dwTypeSpecificFlags dans la structure AM_SAMPLE2_PROPERTIES et dwInterlaceFlags dans la structure VIDEOINFOHEADER2 . Le décodeur doit vérifier que toutes les opérations de décompression qui affectent le contenu de l’image sont terminées avant d’appeler DisplayFrame.
Enfin, le décodeur doit, une fois le traitement terminé, indiquer l’achèvement de toutes les trames de sortie démarrées restantes en appelant IAMVideoAccelerator::EndFrame et libérer toutes ses mémoires tampons verrouillées en appelant IAMVideoAccelerator::ReleaseBuffer pour chaque mémoire tampon non publié.
Rubriques connexes