Freigeben über


FENSTERLOSER VMR-Modus

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde durch MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation ersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code nach Möglichkeit MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet. Microsoft schlägt vor, vorhandenen Code, der die Legacy-APIs verwendet, um nach Möglichkeit die neuen APIs zu verwenden.]

Der fensterlose Modus ist die bevorzugte Möglichkeit für Anwendungen, Videos in einem Anwendungsfenster zu rendern. Im fensterlosen Modus lädt der Video Mixing Renderer seine Window Manager-Komponente nicht und unterstützt daher die Schnittstellen IBasicVideo oder IVideoWindow nicht. Stattdessen stellt die Anwendung das Wiedergabefenster bereit und legt ein Zielrechteck im Clientbereich fest, damit die VMR das Video zeichnen kann. Die VMR verwendet ein DirectDraw-Clipperobjekt, um sicherzustellen, dass das Video im Fenster der Anwendung abgeschnitten wird und in keinem anderen Fenster angezeigt wird. Die VMR unterklassiert das Fenster der Anwendung nicht und installiert keine System-/Prozess-Hooks.

Im fensterlosen Modus sieht die Abfolge der Ereignisse während der Verbindung und des Übergangs zum Ausführungszustand wie folgt aus:

  • Der Upstream Filter schlägt einen Medientyp vor, den der VMR entweder akzeptiert oder ablehnt.
  • Wenn der Medientyp akzeptiert wird, ruft der VMR den Zuteilungs-Referenten auf, um eine DirectDraw-Oberfläche zu erhalten. Wenn die Oberfläche erfolgreich erstellt wurde, stellen die Pins eine Verbindung her, und der VMR kann in den Ausführungszustand übergehen.
  • Wenn das Filterdiagramm ausgeführt wird, ruft der Decoder GetBuffer auf, um ein Medienbeispiel vom Zuteilungsgeber abzurufen. Der VMR fragt den Zuweisungs-Referenten ab, um sicherzustellen, dass die Pixeltiefe, die Rechteckgröße und andere Parameter auf der DirectDraw-Oberfläche mit dem eingehenden Video kompatibel sind. Wenn sie kompatibel sind, gibt der VMR die DirectDraw-Oberfläche an den Decoder zurück. Nachdem der Decoder in die Oberfläche decodiert wurde, überprüft die Core Synchronization Unit der VMR die Zeitstempel. Diese Einheit blockiert den Anruf empfangen , bis die Präsentationszeit eintrifft. Zu diesem Zeitpunkt ruft der VMR PresentImage auf dem Zuteilungs-Presenter auf, wodurch die Oberfläche für die Grafik Karte angezeigt wird.

Die folgende Abbildung zeigt die VMR im fensterlosen Modus mit mehreren Eingabedatenströmen.

vmr im fensterlosen Modus

Konfigurieren von VMR-7 für den fensterlosen Modus

Führen Sie zum Konfigurieren von VMR-7 für den fensterlosen Modus alle folgenden Schritte aus, bevor Sie einen der Eingabepins des virtuellen Computers verbinden:

  1. Erstellen Sie den Filter, und fügen Sie ihn dem Diagramm hinzu.

  2. Rufen Sie die IVMRFilterConfig::SetRenderingMode-Methode mit dem flag VMRMode_Windowless auf.

  3. Konfigurieren Sie optional den VMR für mehrere Eingabedatenströme, indem Sie IVMRFilterConfig::SetNumberOfStreams aufrufen. Der VMR erstellt einen Eingabenadel für jeden Stream. Verwenden Sie die IVMRMixerControl-Schnittstelle , um die Z-Reihenfolge und andere Parameter für den Stream festzulegen. Weitere Informationen finden Sie unter VMR mit mehreren Streams (Mischmodus).

    Wenn Sie SetNumberOfStreams nicht aufrufen, wird VMR-7 standardmäßig auf einen Eingabenadel festgelegt. Nachdem die Eingabestifte verbunden wurden, kann die Anzahl der Pins nicht mehr geändert werden.

  4. Rufen Sie IVMRWindowlessControl::SetVideoClippingWindow auf, um das Fenster anzugeben, in dem das gerenderte Video angezeigt wird.

Sobald diese Schritte abgeschlossen sind, können Sie die Eingabepins des VMR-Filters verbinden. Es gibt verschiedene Möglichkeiten, das Diagramm zu erstellen, z. B. das direkte Verbinden von Pins, die Verwendung von Intelligent Connect-Methoden wie IGraphBuilder::RenderFile oder die Verwendung der ICaptureGraphBuilder2::RenderStream-Methode von Capture Graph Builder. Weitere Informationen finden Sie unter Allgemeine Graph-Building-Techniken.

Um die Position des Videos im Anwendungsfenster festzulegen, rufen Sie die IVMRWindowlessControl::SetVideoPosition-Methode auf. Die IVMRWindowlessControl::GetNativeVideoSize-Methode gibt die native Videogröße zurück. Während der Wiedergabe sollte die Anwendung die VMR über die folgenden Windows-Meldungen benachrichtigen:

Hinweis

MFC-Anwendungen müssen einen leeren WM_ERASEBKGND-Nachrichtenhandler definieren, sonst wird der Videoanzeigebereich nicht ordnungsgemäß neu formatiert.

 

Konfigurieren von VMR-9 für den fensterlosen Modus

Führen Sie zum Konfigurieren von VMR-9 für den fensterlosen Modus die schritte aus, die für den VMR-7 für den Fensterlosen Modus beschrieben sind, aber verwenden Sie die Schnittstellen IVMRFilterConfig9 und IVMRWindowlessControl9 . Der einzige signifikante Unterschied besteht darin, dass VMR-9 standardmäßig vier Eingabestifte anstelle eines Eingabestifts erstellt. Daher müssen Sie SetNumberOfStreams nur aufrufen, wenn Sie mehr als vier Videostreams mischen.

Beispielcode

Der folgende Code zeigt, wie Sie einen VMR-7-Filter erstellen, ihn dem DirectShow-Filterdiagramm hinzufügen und dann den VMR in den fensterlosen Modus versetzen. Verwenden Sie für VMR-9 CLSID_VideoMixingRenderer9 in CoCreateInstance und die entsprechenden VMR-9-Schnittstellen.

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;
}

Verwenden des fensterlosen Modus