Prise en charge de DXVA 2.0 dans Media Foundation
Cette rubrique explique comment prendre en charge DirectX Video Acceleration (DXVA) 2.0 dans une transformation Media Foundation (MFT) à l’aide de Microsoft Direct3D 9 Plus précisément, elle décrit la communication entre le décodeur et le convertisseur vidéo, qui est médiatée par le chargeur de topologie. Cette rubrique ne décrit pas comment implémenter le décodage DXVA.
Dans le reste de cette rubrique, le terme décodeur fait référence au décodeur MFT, qui reçoit la vidéo compressée et génère la vidéo non compressée. Le terme appareil décodeur fait référence à un accélérateur vidéo matériel implémenté par le pilote graphique.
Conseil
Pour plus d’informations sur le décodage vidéo Microsoft Direct3D 11, consultez Prise en charge du décodage vidéo Direct3D 11 dans Media Foundation.
Notes
Les applications du Windows Store doivent utiliser Direct3D 11.
Voici les étapes de base qu’un décodeur doit effectuer pour prendre en charge DXVA 2.0 dans Media Foundation :
- Ouvrez un handle sur l’appareil Direct3D 9.
- Recherchez une configuration de décodeur DXVA.
- Allouez des mémoires tampons non compressées.
- Décodez les trames.
Ces étapes sont décrites plus en détail dans le reste de cette rubrique.
Ouverture d’un handle d’appareil Direct3D
Le MFT utilise le gestionnaire de périphériques Microsoft Direct3D pour obtenir un handle pour l’appareil Direct3D 9. Pour ouvrir le handle d’appareil, procédez comme suit :
- Exposez l’attribut MF_SA_D3D_AWARE avec la valeur TRUE. Le chargeur de topologie interroge cet attribut en appelant IMFTransform::GetAttributes. La définition de l’attribut sur TRUE avertit le chargeur de topologie que le MFT prend en charge DXVA.
- Lorsque la négociation de format commence, le chargeur de topologie appelle IMFTransform::P rocessMessage avec le message MFT_MESSAGE_SET_D3D_MANAGER . Le paramètre ulParam est un pointeur IUnknown vers le gestionnaire de périphériques Direct3D du convertisseur vidéo. Interrogez ce pointeur pour l’interface IDirect3DDeviceManager9 .
- Appelez IDirect3DDeviceManager9::OpenDeviceHandle pour obtenir un handle sur l’appareil Direct3D du convertisseur.
- Appelez IDirect3DDeviceManager9::GetVideoService et passez le handle d’appareil. Cette méthode retourne un pointeur vers l’interface IDirectXVideoDecoderService .
- Mettez en cache les pointeurs et le handle d’appareil.
Recherche d’une configuration de décodeur
Le MFT doit trouver une configuration compatible pour l’appareil décodeur DXVA. Effectuez les étapes suivantes dans la méthode IMFTransform::SetInputType , après avoir validé le type d’entrée :
Appelez IDirectXVideoDecoderService::GetDecoderDeviceGuids. Cette méthode retourne un tableau de GUID d’appareil de décodeur.
Parcourez en boucle le tableau des GUID du décodeur pour rechercher ceux pris en charge par le décodeur. Par exemple, pour un décodeur MPEG-2, vous recherchez DXVA2_ModeMPEG2_MOCOMP, DXVA2_ModeMPEG2_IDCT ou DXVA2_ModeMPEG2_VLD.
Lorsque vous trouvez un GUID d’appareil de décodeur candidat, passez le GUID à la méthode IDirectXVideoDecoderService::GetDecoderRenderTargets . Cette méthode retourne un tableau de formats cibles de rendu, spécifiés en tant que valeurs D3DFORMAT .
Parcourez les formats cibles de rendu et recherchez un format pris en charge par le décodeur.
Appelez IDirectXVideoDecoderService::GetDecoderConfigurations. Transmettez le même GUID de périphérique de décodeur, ainsi qu’une structure de DXVA2_VideoDesc qui décrit le format de sortie proposé. La méthode retourne un tableau de structures DXVA2_ConfigPictureDecode . Chaque structure décrit une configuration possible pour l’appareil décodeur. Recherchez une configuration prise en charge par le décodeur.
Stockez le format et la configuration de la cible de rendu.
Dans la méthode IMFTransform::GetOutputAvailableType , retournez un format vidéo non compressé, en fonction du format cible de rendu proposé.
Dans la méthode IMFTransform::SetOutputType, case activée le type de média par rapport au format cible de rendu.
Secours au décodage logiciel
Si le MFT ne trouve pas de configuration DXVA (par exemple, si le pilote graphique n’a pas les fonctionnalités appropriées), il doit retourner le code d’erreur MF_E_UNSUPPORTED_D3D_TYPE des méthodes SetInputType et SetOutputType . Le chargeur de topologie répond en envoyant le message MFT_MESSAGE_SET_D3D_MANAGER avec la valeur NULL pour le paramètre ulParam . Le MFT doit libérer son pointeur vers l’interface IDirect3DDeviceManager9 . Le chargeur de topologie renégocie ensuite le type de média, et MFT peut utiliser le décodage logiciel.
Allocation de mémoires tampons non compressées
Dans DXVA 2.0, le décodeur est chargé d’allouer des surfaces Direct3D à utiliser comme mémoires tampons vidéo non compressées. Le décodeur doit allouer 3 surfaces pour que l’EVR utilise pour le désinterlacement. Ce nombre est fixe, car Media Foundation ne permet pas à l’EVR de spécifier le nombre de surfaces requises par le pilote graphique pour le désinterlacement. Trois surfaces doivent être suffisantes pour n’importe quel pilote.
Dans la méthode IMFTransform::GetOutputStreamInfo , définissez l’indicateur MFT_OUTPUT_STREAM_PROVIDES_SAMPLES dans la structure MFT_OUTPUT_STREAM_INFO . Cet indicateur informe la session multimédia que le MFT alloue ses propres exemples de sortie.
Pour créer les surfaces, appelez IDirectXVideoAccelerationService::CreateSurface. (L’interface IDirectXVideoDecoderService hérite de cette méthode de IDirectXVideoAccelerationService.) Vous pouvez le faire dans SetInputType, après avoir trouvé le format cible de rendu.
Pour chaque surface, appelez MFCreateVideoSampleFromSurface pour créer un exemple de média pour contenir la surface. La méthode retourne un pointeur vers l’interface IMFSample .
Décodage
Pour créer l’appareil de décodeur, appelez IDirectXVideoDecoderService::CreateVideoDecoder. La méthode retourne un pointeur vers l’interface IDirectXVideoDecoder du périphérique de décodage.
Le décodage doit se produire à l’intérieur de la méthode IMFTransform::P rocessOutput . Sur chaque image, appelez IDirect3DDeviceManager9::TestDevice pour tester le handle d’appareil. Si l’appareil a changé, la méthode retourne DXVA2_E_NEW_VIDEO_DEVICE. Si cela se produit, procédez comme suit :
- Fermez le handle d’appareil en appelant IDirect3DDeviceManager9::CloseDeviceHandle.
- Relâchez les pointeurs IDirectXVideoDecoderService et IDirectXVideoDecoder .
- Ouvrez un nouveau handle d’appareil.
- Négociez une nouvelle configuration de décodeur, comme décrit dans « Recherche d’une configuration de décodeur » plus haut sur cette page.
- Créez un appareil décodeur.
En supposant que le handle d’appareil est valide, le processus de décodage fonctionne comme suit :
- Obtenez une surface disponible qui n’est pas en cours d’utilisation. (Au départ, toutes les surfaces sont disponibles.)
- Interrogez l’exemple de média pour l’interface IMFTrackedSample .
- Appelez IMFTrackedSample::SetAllocator et fournissez un pointeur vers l’interface IMFAsyncCallback , implémentée par le décodeur. Lorsque le convertisseur vidéo libère l’exemple, le rappel du décodeur est appelé.
- Appelez IDirectXVideoDecoder::BeginFrame.
- Effectuez les opérations suivantes une ou plusieurs fois :
- Appelez IDirectXVideoDecoder::GetBuffer pour obtenir une mémoire tampon de décodeur DXVA.
- Remplissez la mémoire tampon.
- Appelez IDirectXVideoDecoder::ReleaseBuffer.
- Appelez IDirectXVideoDecoder::Execute pour effectuer les opérations de décodage sur le frame.
DXVA 2.0 utilise les mêmes structures de données que DXVA 1.0 pour les opérations de décodage. Pour l’ensemble de profils DXVA d’origine (pour H.261, H.263 et MPEG-2), ces structures de données sont décrites dans la spécification DXVA 1.0.
Dans chaque paire d’appels BeginFrame/Execute , vous pouvez appeler GetBuffer plusieurs fois, mais une seule fois pour chaque type de mémoire tampon DXVA. Si vous l’appelez deux fois avec le même type de mémoire tampon, vous remplacerez les données.
Utilisez le rappel de la méthode SetAllocator (étape 3) pour effectuer le suivi des exemples actuellement disponibles et en cours d’utilisation.
Rubriques connexes