VMR-Fensterloser Modus
[Das dieser Seite zugeordnete Feature DirectShow-ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngineund Audio/Video Capture in Media Foundationersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code MediaPlayer-, IMFMediaEngine und Audio-/Videoaufnahme in Media Foundation anstelle von DirectShow-verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, um die neuen APIs zu verwenden, falls möglich umgeschrieben werden.]
Der Fensterlose Modus ist die bevorzugte Methode für Anwendungen zum Rendern von Videos in einem Anwendungsfenster. Im Fensterlosen Modus lädt der Video mixing Renderer seine Window Manager-Komponente nicht und unterstützt daher die IBasicVideo- oder IVideoWindow Schnittstellen nicht. Stattdessen stellt die Anwendung das Wiedergabefenster bereit und legt ein Zielrechteck im Clientbereich fest, damit der VMR das Video zeichnen kann. Der VMR verwendet ein DirectDraw-Clipper-Objekt, um sicherzustellen, dass das Video in das Fenster der Anwendung abgeschnitten wird und nicht in anderen Fenstern angezeigt wird. Der VMR unterklassig das Fenster der Anwendung oder installiert keine System-/Prozess-Hooks.
Im Fensterlosen Modus sieht die Abfolge von Ereignissen während der Verbindung und beim Übergang zum Ausführungszustand wie folgt aus:
- Der Upstreamfilter schlägt einen Medientyp vor, den der VIRTUELLE Computer entweder akzeptiert oder ablehnt.
- Wenn der Medientyp akzeptiert wird, ruft der VMR den Allocator-Presenter auf, um eine DirectDraw-Oberfläche abzurufen. Wenn die Oberfläche erfolgreich erstellt wird, stellen die Pins eine Verbindung her, und der VMR ist bereit, in den Ausführungszustand zu wechseln.
- Wenn das Filterdiagramm ausgeführt wird, ruft der Decoder GetBuffer- auf, um ein Medienbeispiel aus dem Allocator abzurufen. Der VMR fragt den Allocator-Presenter 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 auf der Oberfläche decodiert wurde, überprüft die Kernsynchronisierungseinheit des virtuellen Computers die Zeitstempel. Diese Einheit blockiert die Empfangen Anrufs, bis die Präsentationszeit eingeht. Zu diesem Zeitpunkt ruft der VMR PresentImage- auf dem Allocator-Presenter auf, der die Oberfläche auf der Grafikkarte darstellt.
Die folgende Abbildung zeigt den virtuellen Computer im Fensterlosen Modus mit mehreren Eingabedatenströmen.
Konfigurieren des VMR-7 für den fensterlosen Modus
Führen Sie zum Konfigurieren des VMR-7 für den fensterlosen Modus alle folgenden Schritte aus, bevor Sie eine der Eingabe-Pins des virtuellen Computers verbinden:
Erstellen Sie den Filter, und fügen Sie ihn dem Diagramm hinzu.
Rufen Sie die IVMRFilterConfig::SetRenderingMode--Methode mit dem VMRMode_Windowless-Flag auf.
Konfigurieren Sie optional den VMR für mehrere Eingabedatenströme, indem Sie IVMRFilterConfig::SetNumberOfStreamsaufrufen. Der VMR erstellt einen Eingabenadel für jeden Datenstrom. Verwenden Sie die IVMRMixerControl Schnittstelle, um die Z-Reihenfolge und andere Parameter für den Datenstrom festzulegen. Weitere Informationen finden Sie unter VMR mit mehreren Streams (Mischmodus).
Wenn Sie SetNumberOfStreams-nicht aufrufen, wird der VMR-7 standardmäßig auf einen Eingabenadel festgelegt. Nachdem die Eingabenadel verbunden sind, kann die Anzahl der Pins nicht mehr geändert werden.
Rufen Sie IVMRWindowlessControl::SetVideoClippingWindow auf, um das Fenster anzugeben, in dem das gerenderte Video angezeigt wird.
Nach Abschluss dieser Schritte können Sie die Eingabe-Pins des VMR-Filters verbinden. Es gibt verschiedene Möglichkeiten zum Erstellen des Diagramms, z. B. das direkte Verbinden von Pins, mithilfe von Intelligent Connect-Methoden wie IGraphBuilder::RenderFileoder mithilfe der ICaptureGraphBuilder2::RenderStream-Methode des Capture Graph Builders. Weitere Informationen finden Sie unter Allgemeine Graph-Building Techniken.
Rufen Sie zum Festlegen der Position des Videos im Anwendungsfenster die IVMRWindowlessControl::SetVideoPosition-Methode auf. Die IVMRWindowlessControl::GetNativeVideoSize Methode gibt die systemeigene Videogröße zurück. Während der Wiedergabe sollte die Anwendung den VMR über die folgenden Windows-Meldungen benachrichtigen:
- WM_PAINT: Rufen Sie IVMRWindowlessControl::RepaintVideo auf, um das Bild neu zu erstellen.
- WM_DISPLAYCHANGE: Rufen Sie IVMRWindowlessControl::D isplayModeChangedauf. Der VMR führt alle Aktionen aus, die erforderlich sind, um das Video in der neuen Auflösung oder Farbtiefe anzuzeigen.
- WM_SIZE: Berechnen Sie die Position des Videos neu, und rufen Sie SetVideoPosition bei Bedarf erneut an.
Anmerkung
MFC-Anwendungen müssen einen leeren WM_ERASEBKGND Nachrichtenhandler definieren, oder der Videoanzeigebereich wird nicht ordnungsgemäß neu zuordnen.
Konfigurieren des VMR-9 für den Fensterlosen Modus
Um den VMR-9 für den Fensterlosen Modus zu konfigurieren, führen Sie die schritte aus, die für den VMR-7 für den Fensterlosen Modus beschrieben sind, verwenden aber die IVMRFilterConfig9 und IVMRWindowlessControl9 Schnittstellen. Der einzige wesentliche Unterschied besteht darin, dass der VMR-9 standardmäßig vier Eingabe-Pins anstelle eines Eingabenadels erstellt. Daher müssen Sie nur SetNumberOfStreams- aufrufen, wenn Sie mehr als vier Videostreams mischen.
Beispielcode-
Der folgende Code zeigt, wie Sie einen VMR-7-Filter erstellen, 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 den 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;
}
Verwandte Themen