Partager 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, IMFMediaEngineet audio/vidéo capture dans 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 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.]

Le mode sans fenêtre est le moyen préféré pour les applications de restituer la vidéo dans une fenêtre d’application. En mode sans fenêtre, le renderer Video Mixing ne charge pas son composant Window Manager 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 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 n’apparaît pas sur d’autres fenêtres. VmR ne sous-classe pas la fenêtre de l’application ou 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 en amont propose un type de média, que vmR accepte ou rejette.
  • Si le type de média est accepté, vmR appelle l’allocator-présentateur pour obtenir une surface DirectDraw. Si la surface est créée avec succès, les broches se connectent et vmR sont prêtes à 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. VmR interroge l’allocator-présentateur pour s’assurer que la profondeur de 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, vmR retourne l’aire DirectDraw au décodeur. Une fois le décodeur décodé dans la surface, l’unité de synchronisation principale de VMR valide les horodatages. Cette unité bloque l’appel Recevoir jusqu’à ce que l’heure de présentation arrive. À ce stade, vmR appelle PresentImage sur le présentateur de l’allocator, qui présente l’aire à la carte graphique.

L’illustration suivante montre 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 pour le 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 VMR pour plusieurs flux d’entrée en appelant IVMRFilterConfig ::SetNumberOfStreams. 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 du flux. Pour plus d’informations, consultez VMR avec plusieurs flux (mode mixage).

    Si vous n’appelez pas SetNumberOfStreams, 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 s’affiche.

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

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

Note

Les applications MFC doivent définir un gestionnaire de messages WM_ERASEBKGND vide, ou la zone d’affichage vidéo ne sera pas réinitulée correctement.

 

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

Pour configurer VMR-9 pour le mode sans fenêtre, utilisez les étapes décrites pour le mode sans fenêtre VMR-7, mais utilisez les interfaces IVMRFilterConfig9 et IVMRWindowlessControl9. La seule différence significative est que 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 placer vmR 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;
}

à l’aide du mode sans fenêtre