Prise en charge du décodage vidéo Direct3D 11 dans Media Foundation
Cette rubrique décrit comment prendre en charge Microsoft Direct3D 11 dans un décodeur de Microsoft Media Foundation. Plus précisément, il décrit la communication entre le décodeur et le convertisseur vidéo. Cette rubrique ne décrit pas comment implémenter les opérations de décodage.
- Vue d'ensemble
- Ouvrir un handle d’appareil
- Rechercher une configuration de décodeur
- Revenir au décodage logiciel
- Allocation de mémoires tampons non compressées
- Décodage
- Rubriques connexes
Vue d’ensemble
Dans le reste de cette rubrique, les termes suivants sont utilisés :
- Décodeur logiciel. Le décodeur logiciel est la Media Foundation transformation (MFT) qui reçoit des échantillons vidéo compressés et génère des trames vidéo non compressées.
- Appareil de décodage. L’appareil décodeur est l’accélérateur vidéo et est implémenté par le pilote Graphics. L’appareil décodeur effectue des opérations de décodage accélérées.
- Pipeline. Le pipeline héberge le décodeur logiciel et fournit des mémoires tampons vers et depuis le décodeur logiciel. Selon l’application, le pipeline peut être la session multimédia, le lecteur sourceou le code d’application qui appelle directement la table MFT.
Pour effectuer le décodage à l’aide de Direct3D 11, le décodeur logiciel doit avoir un pointeur vers un appareil Direct3D 11. L’appareil Direct3D 11 est créé en externe dans le décodeur logiciel. Dans un scénario de session multimédia , le convertisseur vidéo crée l’appareil Direct3D 11. Dans un scénario de lecteur source , l’application crée généralement l’appareil Direct3D 11.
Le Gestionnaire de périphériques DXGI est utilisé pour partager le Direct3D 11 entre les composants. L’Gestionnaire de périphériques DXGI expose l’interface IMFDXGIDeviceManager . Le pipeline définit le pointeur IMFDXGIDeviceManager sur le décodeur logiciel en envoyant le message de l' ensemble de messages MFT du _ _ _ _ Gestionnaire D3D .
Le diagramme suivant montre la relation entre le décodeur logiciel, Direct3D 11 et le pipeline.

Voici les étapes de base qu’un décodeur logiciel doit effectuer pour prendre en charge Direct3D 11 dans Media Foundation :
- Ouvrez un handle vers l’appareil Direct3D 11.
- Rechercher une configuration de décodeur.
- Allouez des tampons non compressés.
- Décodez les frames.
Ces étapes sont décrites plus en détail dans le reste de cette rubrique.
Ouvrir un handle d’appareil
La table MFT du décodeur utilise DXGI Device Manager pour obtenir un descripteur de l’appareil Direct3D 11. Pour ouvrir le descripteur de l’appareil, procédez comme suit :
- La table MFT du décodeur doit exposer l’attribut _ prenant en _ _ charge MF sa d3d11 avec la valeur true.
- Le chargeur de topologie interroge cet attribut en appelant IMFTransform :: GetAttributes. La valeur true indique que la table MFT prend en charge Direct3D 11.
- Le chargeur de topologie appelle IMFTransform ::P rocessmessage avec le message de l' ensemble de messages MFT du _ _ _ _ Gestionnaire D3D . Le paramètre ulParam est un pointeur IUnknown vers le gestionnaire de périphériques DXGI. Interrogez ce pointeur sur l’interface IMFDXGIDeviceManager .
- Appelez IMFDXGIDeviceManager :: OpenDeviceHandle pour obtenir un descripteur de l’appareil Direct3D 11.
- Pour obtenir un pointeur vers l’appareil Direct3D 11, appelez IMFDXGIDeviceManager :: GetVideoService. Transmettez le descripteur de l’appareil et la valeur IID _ ID3D11Device. La méthode retourne un pointeur vers l’interface ID3D11Device .
- Pour obtenir un pointeur vers l’accélérateur vidéo, appelez à nouveau IMFDXGIDeviceManager :: GetVideoService . Cette fois-ci, transmettez le descripteur de l’appareil et la valeur IID _ ID3D11VideoDevice. La méthode retourne un pointeur vers l’interface ID3D11VideoDevice .
- Appelez ID3D11Device :: GetImmediateContext pour accéder à un pointeur ID3D11DeviceContext .
- Appelez QueryInterface sur ID3D11DeviceContext pour accéder à un pointeur ID3D11VideoContext .
- Il est recommandé d’utiliser la protection multithreads sur le contexte de l’appareil pour éviter des problèmes d’interblocage qui peuvent parfois se produire quand vous appelez ID3D11VideoContext :: GetDecoderBuffer ou ID3D11VideoContext :: ReleaseDecoderBuffer. Pour définir la protection multithread, appelez d’abord QueryInterface sur ID3D11Device pour accéder à un pointeur ID3D10Multithread . Appelez ensuite ID3D10Multithread :: SetMultithreadProtected, en passant true pour bMTProtect.
Rechercher une configuration de décodeur
Pour effectuer le décodage, le décodeur logiciel doit trouver une configuration compatible qui est prise en charge par l’appareil décodeur, y compris un format de cible de rendu. Cette étape se produit à l’intérieur de la méthode IMFTransform :: SetInputType , comme suit.
- Validez le type de média d’entrée. Si le type est rejeté, ignorez les étapes restantes et retournez un code d’erreur.
- Appelez ID3D11VideoDevice :: GetVideoDecoderProfileCount pour connaître le nombre de profils pris en charge.
- Appelez ID3D11VideoDevice :: GetVideoDecoderProfile pour énumérer les profils et récupérer les GUID de profil.
- Recherchez un GUID de profil qui correspond au format vidéo et aux fonctionnalités du décodeur logiciel. Par exemple, un décodeur MPEG-2 recherche le profil de _ décodage d3d11 _ _ MPEG2 _ MOCOMP, le profil de _ décodage d3d11 MPEG2 _ _ _ IDCT et le profil de _ décodeur d3d11 _ _ MPEG2 _ VLD.
- Si un GUID de décodeur approprié est trouvé, vérifiez le format de sortie en appelant la méthode ID3D11VideoDevice :: CheckVideoDecoderFormat . Transmettez le GUID du décodeur et une valeur de _ format de dxgi qui spécifie le format de la cible de rendu.
- Recherchez ensuite une configuration appropriée pour le décodeur.
- Appelez ID3D11VideoDevice :: GetVideoDecoderConfigCount pour connaître le nombre de configurations du décodeur. Transmettez le même GUID de périphérique décodeur, ainsi qu’une structure _ _ _ desc décodeur vidéo d3d11 qui décrit le format de cible de rendu proposé.
- Appelez ID3D11VideoDevice :: GetVideoDecoderConfig pour énumérer les configurations du décodeur.
Dans la méthode IMFTransform :: GetOutputAvailableType , retourne un format vidéo non compressé basé sur le format de cible de rendu proposé.
Dans la méthode IMFTransform :: SetOutputType , vérifiez le type de média par rapport au format de la cible de rendu.
Revenir au décodage logiciel
Il se peut que la MFT ne trouve pas de configuration. Par exemple, le pilote Graphics peut ne pas prendre en charge les fonctionnalités appropriées. Dans ce cas, la MFT doit revenir au décodage logiciel, comme suit.
- Les méthodes SetInputType et SetOutputType doivent retourner un _ _ _ _ type D3D non pris en charge MF E.
- En réponse, le chargeur de topologie envoie le message de l' _ ensemble de messages MFT du _ _ _ Gestionnaire D3D avec la valeur null pour le paramètre ulParam .
- La table MFT libère son pointeur vers l’interface IMFDXGIDeviceManager .
- Le chargeur de topologie renégocie le type de média.
À ce stade, la table MFT peut utiliser le décodage logiciel.
Allocation de mémoires tampons non compressées
Le décodeur est chargé d’allouer les textures Direct3D 11 à utiliser comme tampons vidéo non compressés. L’attribut de _ _ nombre minimal d' _ _ échantillons _ de sortie MF sa dans les attributs de flux de sortie (voir IMFTransform :: GetOutputStreamAttributes) est utilisé pour déterminer le nombre de surfaces que le décodeur doit allouer pour le convertisseur vidéo à utiliser pour l’entrelacement. Un décodeur doit utiliser cette valeur pour la limiter à des limites supérieures et inférieures raisonnables, par exemple 3-32. Pour obtenir du contenu progressif, consultez MF _ sa _ minimum _ Output _ Sample _ Count _ progressif.
Dans la méthode IMFTransform :: GetOutputStreamInfo , définissez le flux de sortie MFT fournit l’indicateur _ _ _ _ Samples dans la structure d' informations du _ _ flux _ de sortie MFT . Cet indicateur signale à la session multimédia que la table MFT alloue ses propres exemples de sortie. Pour allouer les exemples de sortie, la table MFT effectue les étapes suivantes :
Créez un tableau de texture 2D en appelant ID3D11Device :: CreateTexture2D. Dans la structure d3d11 _ TEXTURE2D _ desc , définissez arraySize égal au nombre de surfaces dont le décodeur a besoin. notamment :
- Surfaces pour les frames de référence.
- Surfaces pour l’entrelacement (trois surfaces).
- Surfaces dont le décodeur a besoin pour la mise en mémoire tampon.
Les indicateurs de liaison (BindFlags) doivent inclure l’indicateur de _ _ décodeur de liaison d3d11 et tous les indicateurs de liaison définis par le biais de l’attribut _ _ _ BindFlags MF d3d11 dans les attributs de flux de sortie.
Pour chaque surface dans le tableau de texture, appelez ID3D11VideoDevice :: CreateVideoDecoderOutputView pour créer une vue de sortie du décodeur vidéo. Pendant le décodage, ces affichages de sortie sont transmis à la méthode ID3D11VideoContext ::D ecoderbeginframe .
Pour chaque surface dans le tableau de textures, créez un exemple de support comme suit :
- Créez une mémoire tampon de média DXGI en appelant la fonction MFCreateDXGISurfaceBuffer . Transmettez le pointeur ID3D11Texture2D et le décalage pour chaque élément dans le tableau de texture. La fonction retourne un pointeur IMFMediaBuffer .
- Créez un exemple de support vide en appelant la fonction MFCreateVideoSampleFromSurface . Affectez la valeur null au paramètre pUnkSurface . La fonction retourne un pointeur IMFSample .
- Appelez IMFSample :: AddBuffer pour ajouter la mémoire tampon du média à l’exemple.
Vous devez détruire toutes les textures que vous créez en même temps, au lieu de détruire uniquement certains et de continuer à utiliser le rappel.
Décodage
Pour créer l’appareil de décodage, appelez ID3D11VideoDevice :: CreateVideoDecoder. La méthode retourne un pointeur vers l’interface ID3D11VideoDecoder . Le décodage doit se produire à l’intérieur de la méthode IMFTransform ::P rocessoutput . Sur chaque frame, appelez IMFDXGIDeviceManager :: TestDevice pour tester la disponibilité du DXGI. Si l’appareil a changé, le décodeur logiciel doit recréer le périphérique décodeur, comme suit :
- Fermez le handle d’appareil en appelant IMFDXGIDeviceManager :: CloseDeviceHandle.
- Libérer toutes les ressources associées à l’appareil Direct3D 11 précédent, y compris les interfaces ID3D11VideoDecoder, ID3D11VideoContext, ID3D11Texture2Det ID3D11VideoDecoderOutputView .
- Ouvrez un nouveau descripteur d’appareil.
- Négociez une nouvelle configuration de décodeur, comme décrit précédemment dans Rechercher une configuration de décodeur. Cette étape est nécessaire, car les fonctionnalités de l’appareil peuvent avoir changé.
- Créez un appareil de décodage.
En supposant que le descripteur de l’appareil est valide, le processus de décodage fonctionne comme suit :
- Obtient une surface disponible qui n’est pas en cours d’utilisation. Initialement, toutes les surfaces sont disponibles.
- Interrogez l’exemple de support pour l’interface IMFTrackedSample .
- Appelez IMFTrackedSample :: SetAllocator et fournissez un pointeur vers l’interface IMFAsyncCallback . (Le décodeur logiciel doit implémenter cette interface.) Quand le convertisseur vidéo libère l’exemple, le rappel est appelé. Utilisez ce rappel pour suivre les exemples actuellement disponibles et ceux qui sont en cours d’utilisation.
- Appelez ID3D11VideoContext ::D ecoderbeginframe. Transmettez les pointeurs vers l’interface ID3D11VideoDecoder pour l’appareil de décodage et l’interface ID3D11VideoDecoderOutputView pour la vue de sortie.
- Effectuez les opérations suivantes une ou plusieurs fois :
- Appelez ID3D11VideoContext :: GetDecoderBuffer pour obtenir une mémoire tampon.
- Remplir la mémoire tampon.
- Appelez ID3D11VideoContext :: ReleaseDecoderBuffer.
- Appelez ID3D11VideoContext :: SubmitDecoderBuffer. Cette méthode indique à l’appareil décodeur d’effectuer les opérations de décodage sur le frame.
- Appelez ID3D11VideoContext ::D ecoderendframe pour signaler la fin du décodage du frame actuel.
Direct3D 11 utilise les mêmes structures de données que DXVA 2,0 pour les opérations de décodage. Pour l’ensemble initial de profils DXVA (pour H. 261, H. 263 et MPEG-2), ces structures de données sont décrites dans la spécification DXVA 1,0.
Au sein de chaque paire d’appels DecoderBeginFrame et SubmitDecoderBuffer , vous pouvez appeler GetDecoderBuffer plusieurs fois, mais une seule fois pour chaque type de mémoire tampon. Si vous utilisez le même type de mémoire tampon à deux reprises sans appeler SubmitDecoderBuffer, vous allez remplacer les données dans la mémoire tampon.