Anzeigen einer von der App bereitgestellten Bitmap auf dem zusammengesetzten Bild

[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.]

Anwendungen können den Mischmodus der VMR verwenden, um Alpha-gemischte Kanallogos, eine Benutzeroberfläche oder Werbung entweder teilweise oder vollständig innerhalb des Videorechtecks anzuzeigen. Da das Mischen in der Hardware vom Grafikprozessor ausgeführt wird, hat dies minimale Auswirkungen auf die Wiedergabeleistung des Videostreams, und es gibt keine erkennbaren Flacker- oder Reißartefakte. Anwendungen können das angezeigte Bild beliebig oft ändern. Beachten Sie, dass Änderungen nur dann auf dem Bildschirm widergespiegelt werden, wenn sich das DirectShow-Filterdiagramm im Ausführungszustand befindet.

Der VMR verwendet seine Mixerkomponente, um die Bitmap mit dem zusammengesetzten Bild zu überlagern. Bei VMR-7 muss die Anwendung den VMR erzwingen, seinen Mixer zu laden, auch wenn nur ein einzelner Videostream vorhanden ist. Dies ist bei VMR-9 nicht erforderlich, da der Mixer standardmäßig geladen wird.

Um ein statisches Bitmapbild mit dem Videostream zu mischen, erstellt die Anwendung die VMR, fügt sie dem Graphen hinzu und ruft dann IVMRFilterConfig::SetNumberOfStreams auf. Der an diese Funktion übergebene Wert gibt die Anzahl der Eingabenadeln an, die der VMR erstellen soll. Anwendungen können einen beliebigen Wert zwischen 1 und MAX_MIXER_STREAMS angeben. Das Angeben des Werts 1 ist gültig, wenn die Anwendung nur einen einzelnen Videostream anzeigen möchte. Obwohl die VMR-7 standardmäßig über einen einzelnen Eingabestift verfügt, muss diese Methode aufgerufen werden, um das Laden der Mixerkomponente zu erzwingen. (Der VMR-9 lädt seinen Mixer und richtet standardmäßig vier Pins ein.)

Um die Bitmap festzulegen, verwenden Sie die IVMRMixerBitmap-Schnittstelle auf der VMR-7 oder die IVMRMixerBitmap9-Schnittstelle auf der VMR-9.

Die Bitmap kann entweder durch ein Handle für einen GDI Device Context (hDC) oder durch eine DirectDraw Surface-Schnittstelle angegeben werden. Wenn die Anwendung möchte, dass das Bild eingebettete Alphainformationen enthält (auch als pro Pixel alpha bezeichnet), müssen die Bilddaten in einer DirectDraw Surface-Schnittstelle platziert werden. Dies liegt daran, dass es derzeit nicht möglich ist, Alphainformationen pro Pixel mit einem GDI-Gerätekontext zu platzieren. Die DirectDraw-Oberfläche muss entweder RGB32 oder ARGB32 sein und sollte vorzugsweise eine Systemspeicheroberfläche sein. Es ist nicht erforderlich, dass die Oberflächendimensionen eine Leistung von 2 aufweisen.

Mit der VMR können Anwendungen den Speicherort und einen Gesamttransparenzwert für das Image angeben. Der folgende Code zeigt, wie Bilddaten für die nachfolgende Mischung an den VMR übergeben werden:

HRESULT BlendApplicationImage( 
  HWND hwndApp,
  IVMRWindowlessControl* pWc,
  HBITMAP hbm
)
{
    LONG cx, cy;
    HRESULT hr;
    hr = pWc->GetNativeVideoSize(&cx, &cy, NULL, NULL);
    if (FAILED(hr))
        return hr;
    
    HDC hdc = GetDC(hwndApp);
    if (hdc == NULL)
    {
        return E_FAIL;
    }
    
    HDC hdcBmp = CreateCompatibleDC(hdc);
    ReleaseDC(hwndApp, hdc);
    
    if (hdcBmp == NULL)
    {
        return E_FAIL;
    }
    
    BITMAP bm;
    if (0 == GetObject(hbm, sizeof(bm), &bm))
    {
        DeleteDC(hdcBmp);
        return E_FAIL;
    }
    
    HBITMAP hbmOld = (HBITMAP)SelectObject(hdcBmp, hbm);
    if (hbmOld == 0)
    {
        DeleteDC(hdcBmp);
        return E_FAIL;
    }
    
    VMRALPHABITMAP bmpInfo;
    ZeroMemory(&bmpInfo, sizeof(bmpInfo) );
    bmpInfo.dwFlags = VMRBITMAP_HDC;
    bmpInfo.hdc = hdcBmp;
    
    // Show the entire bitmap in the top-left corner of the video image.
    SetRect(&bmpInfo.rSrc, 0, 0, bm.bmWidth, bm.bmHeight);
    bmpInfo.rDest.left = 0.f;
    bmpInfo.rDest.top = 0.f;
    bmpInfo.rDest.right = (float)bm.bmWidth / (float)cx;
    bmpInfo.rDest.bottom = (float)bm.bmHeight / (float)cy;
    
    // Set the transparency value (1.0 is opaque, 0.0 is transparent).
    bmpInfo.fAlpha = 0.2f;
    
    IVMRMixerBitmap* pBmp;
    hr = pWc->QueryInterface(IID_IVMRMixerBitmap, (LPVOID *)&pBmp);
    if (SUCCEEDED(hr)) 
    {
        pBmp->SetAlphaBitmap(&bmpInfo);
        pBmp->Release();
    }
    
    DeleteObject(SelectObject(hdcBmp, hbmOld));
    DeleteDC(hdcBmp);
    return hr;
}

Die in diesem Thema erläuterten Konzepte werden in der Beispielanwendung VMRPlayer-Beispiel veranschaulicht.

Erstellen einfacher Animationen mit dem Bitmapbild

Um ein einfaches animiertes Bitmaplogo zu erstellen, fügen Sie alle Bitmap "Frames" in ein einzelnes Bild ein, wie in der folgenden Abbildung gezeigt.

vmr-Imagestreifen

Wenn Sie die Bitmap zunächst mithilfe von IVMRMixerBitmap::SetAlphaBitmap festlegen, legen Sie das Feld rSrc der VMRALPHABITMAP-Struktur fest, um die Größe der gesamten Bitmap innerhalb des HDC anzugeben. Die oberen und linken Elemente der Struktur sind auf 0 festgelegt, und die rechten und unteren Elemente sind die Breite und Höhe der Bitmap. Wenn sich die Bitmap in einer DirectDraw-Oberfläche befindet, ist die Größe der Oberfläche bekannt, sodass es nicht erforderlich ist, rSrc in dieser Methode anzugeben.

Wenn Sie IVMRMixerBitmap::UpdateAlphaBitmapParameters aufrufen, verwenden Sie den rSrc-Member sowohl für HDC- als auch für DirectDraw-Bitmaps, um den bestimmten Frame oder rechteck innerhalb des anzuzeigenden Bilds anzugeben, und legen Sie das VMRBITMAP_SRCRECT-Flag im dwFlags-Element fest.

Verwenden des VMR-Mischmodus