Share via


Mode sans fenêtre VMR

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture in 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 Audio/Video Capture dans Media Foundation au lieu de DirectShow, si 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.]

Le mode sans fenêtre est le moyen préféré pour les applications de restituer la vidéo à l’intérieur d’une fenêtre d’application. En mode sans fenêtre, le convertisseur de mixage vidéo ne charge pas son composant Gestionnaire de fenêtres et ne prend donc pas en charge les interfaces IBasicVideo ou IVideoWindow . Au lieu de cela, l’application fournit la fenêtre de lecture et définit un rectangle de destination dans la zone cliente pour que le VMR dessine la vidéo. VmR utilise un objet clipper DirectDraw pour s’assurer que la vidéo est clippée dans la fenêtre de l’application et qu’elle n’apparaît sur aucune autre fenêtre. Le VMR ne sous-classe pas la fenêtre de l’application ni n’installe aucun hook système/processus.

En mode sans fenêtre, la séquence d’événements pendant la connexion et la transition vers l’état d’exécution est la suivante :

  • Le filtre amont propose un type de média, que le VMR accepte ou rejette.
  • Si le type de média est accepté, le VMR appelle l’allocator-presenter pour obtenir une surface DirectDraw. Si la surface est créée correctement, les broches se connectent et le VMR est prêt à passer à l’état d’exécution.
  • Lorsque le graphique de filtre s’exécute, le décodeur appelle GetBuffer pour obtenir un exemple de média à partir de l’allocateur. Le VMR interroge l’allocator-presenter pour s’assurer que la profondeur des pixels, la taille du rectangle et d’autres paramètres sur sa surface DirectDraw sont compatibles avec la vidéo entrante. S’ils sont compatibles, le VMR renvoie la surface DirectDraw au décodeur. Une fois que le décodeur a été décodé dans la surface, l’unité de synchronisation principale du VMR valide les horodatages. Cette unité bloque l’appel de réception jusqu’à ce que l’heure de présentation arrive. À ce stade, le VMR appelle PresentImage sur l’allocator-presenter, qui présente la surface aux graphiques carte.

L’illustration suivante montre le VMR en mode sans fenêtre avec plusieurs flux d’entrée.

vmr en mode sans fenêtre

Configuration de VMR-7 pour le mode sans fenêtre

Pour configurer vmR-7 en mode sans fenêtre, effectuez toutes les étapes suivantes avant de connecter l’une des broches d’entrée de VMR :

  1. Créez le filtre et ajoutez-le au graphique.

  2. Appelez la méthode IVMRFilterConfig::SetRenderingMode avec l’indicateur VMRMode_Windowless.

  3. Si vous le souhaitez, configurez le VMR pour plusieurs flux d’entrée en appelant IVMRFilterConfig::SetNumberOfStreams. Le VMR crée une broche d’entrée pour chaque flux. Utilisez l’interface IVMRMixerControl pour définir l’ordre Z et d’autres paramètres pour le flux. Pour plus d’informations, consultez VMR avec plusieurs flux (mode mixage).

    Si vous n’appelez pas SetNumberOfStreams, le VMR-7 est défini par défaut sur une broche d’entrée. Une fois les broches d’entrée connectées, le nombre de broches ne peut pas être modifié.

  4. Appelez IVMRWindowlessControl::SetVideoClippingWindow pour spécifier la fenêtre dans laquelle la vidéo rendue apparaîtra.

Une fois ces étapes terminées, vous pouvez connecter les broches d’entrée du filtre VMR. Il existe différentes façons de générer le graphe, telles que la connexion directe de broches, l’utilisation de méthodes Intelligent Connect telles que IGraphBuilder::RenderFile ou l’utilisation de la méthode ICaptureGraphBuilder2::RenderStream du Générateur de graphes Capture. Pour plus d’informations, consultez Général Graph-Building Techniques.

Pour définir la position de la vidéo dans la fenêtre d’application, appelez la méthode IVMRWindowlessControl::SetVideoPosition . La méthode IVMRWindowlessControl::GetNativeVideoSize retourne la taille vidéo native. Pendant la lecture, l’application doit informer le VMR des messages Windows suivants :

Notes

Les applications MFC doivent définir un gestionnaire de messages WM_ERASEBKGND vide, sinon la zone d’affichage vidéo ne se repeint pas correctement.

 

Configuration de VMR-9 pour le mode sans fenêtre

Pour configurer VMR-9 en mode sans fenêtre, suivez les étapes décrites pour vmr-7 pour le mode sans fenêtre, mais utilisez les interfaces IVMRFilterConfig9 et IVMRWindowlessControl9 . La seule différence significative est que le VMR-9 crée quatre broches d’entrée par défaut, au lieu d’une broche d’entrée. Par conséquent, vous devez uniquement appeler SetNumberOfStreams si vous mélangez plus de quatre flux vidéo.

Exemple de code

Le code suivant montre comment créer un filtre VMR-7, l’ajouter au graphique de filtre DirectShow, puis le mettre en mode sans fenêtre. Pour vmr-9, utilisez CLSID_VideoMixingRenderer9 dans CoCreateInstance et les interfaces VMR-9 correspondantes.

HRESULT InitializeWindowlessVMR(
    HWND hwndApp,         // Application window.
    IFilterGraph* pFG,    // Pointer to the Filter Graph Manager.
    IVMRWindowlessControl** ppWc,  // Receives the interface.
    DWORD dwNumStreams,  // Number of streams to use.
    BOOL fBlendAppImage  // Are we alpha-blending a bitmap?
    )
{
    IBaseFilter* pVmr = NULL;
    IVMRWindowlessControl* pWc = NULL;
    *ppWc = NULL;

    // Create the VMR and add it to the filter graph.
    HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL,
       CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
    if (FAILED(hr))
    {
        return hr;
    }
    hr = pFG->AddFilter(pVmr, L"Video Mixing Renderer");
    if (FAILED(hr))
    {
        pVmr->Release();
        return hr;
    }

    // Set the rendering mode and number of streams.  
    IVMRFilterConfig* pConfig;
    hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
    if (SUCCEEDED(hr)) 
    {
        pConfig->SetRenderingMode(VMRMode_Windowless);

        // Set the VMR-7 to mixing mode if you want more than one video
        // stream, or you want to mix a static bitmap over the video.
        // (The VMR-9 defaults to mixing mode with four inputs.)
        if (dwNumStreams > 1 || fBlendAppImage) 
        {
            pConfig->SetNumberOfStreams(dwNumStreams);
        }
        pConfig->Release();

        hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
        if (SUCCEEDED(hr)) 
        {
            pWc->SetVideoClippingWindow(hwndApp);
            *ppWc = pWc;  // The caller must release this interface.
        }
    }
    pVmr->Release();

    // Now the VMR can be connected to other filters.
    return hr;
}

Utilisation du mode sans fenêtre