Visualizzare una bitmap fornita dall'app nell'immagine composita

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation invece di DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

Le applicazioni possono usare la modalità di combinazione di VMR per visualizzare i logo dei canali alfa-blend, un'interfaccia utente o annunci parzialmente o completamente all'interno del rettangolo video. Poiché la fusione viene eseguita nell'hardware dal processore di grafica, vi è un impatto minimo sulle prestazioni di riproduzione di Video Stream e non sono presenti elementi di sfarfallio o di strappo rilevabili. Le applicazioni possono modificare l'immagine visualizzata con la frequenza desiderata. Si noti che le modifiche vengono riflesse solo sullo schermo quando il grafico del filtro DirectShow si trova nello stato in esecuzione.

VmR usa il componente mixer per sovrapporre la bitmap all'immagine composita. Con VMR-7, l'applicazione deve forzare il vmr a caricare il suo mixer, anche se è presente un solo flusso video. Questo non è necessario con VMR-9 perché carica il suo mixer per impostazione predefinita.

Per combinare un'immagine bitmap statica con il flusso video, l'applicazione crea la macchina virtuale virtuale e la aggiunge al grafico e quindi chiama IVMRFilterConfig::SetNumberOfStreams. Il valore passato a questa funzione identifica il numero di pin di input che deve essere creato da VMR. Le applicazioni possono specificare qualsiasi valore compreso tra 1 e MAX_MIXER_STREAMS; Specificare un valore pari a 1 è valido se l'applicazione intende solo visualizzare un singolo flusso video. Anche se VMR-7 ha un singolo pin di input per impostazione predefinita, questo metodo deve essere chiamato per forzare il caricamento del componente mixer. VmR-9 carica il suo mixer e configura quattro pin per impostazione predefinita.

Per impostare la bitmap, usare l'interfaccia IVMRMixerBitmap nell'interfaccia VMR-7 o IVMRMixerBitmap9 in VMR-9.

La bitmap può essere specificata da un handle a un contesto di dispositivo GDI (hDC) o da un'interfaccia DirectDraw Surface. Se l'applicazione vuole che l'immagine contenga informazioni alfa incorporate (note anche come per pixel alfa) deve inserire i dati dell'immagine in un'interfaccia di Surface DirectDraw. Ciò è dovuto al fatto che attualmente non è possibile inserire informazioni alfa per pixel con un contesto di dispositivo GDI. La superficie DirectDraw deve essere RGB32 o ARGB32 e deve essere preferibilmente una superficie di memoria di sistema. Non è necessario che le dimensioni della superficie siano una potenza di 2.

VmR consente alle applicazioni di specificare la posizione e un valore complessivo di trasparenza per l'immagine. Il codice seguente illustra come passare i dati dell'immagine alla macchina virtuale per la fusione successiva:

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

I concetti descritti in questo argomento sono illustrati nell'applicazione di esempio VMRPlayer Sample .

Creazione di animazioni semplici con l'immagine bitmap

Per creare un semplice logo bitmap animato, inserire tutte le "cornici" bitmap in una singola immagine, come illustrato nella figura seguente.

strip di immagini vmr

Quando si imposta inizialmente la bitmap usando IVMRMixerBitmap::SetAlphaBitmap, se la bitmap si trova in un HDC, impostare il campo rSrc della struttura VMRALPHABITMAP per specificare le dimensioni dell'intera bitmap all'interno di HDC. I membri superiore e sinistro della struttura sono impostati su 0 e i membri destro e inferiore sono la larghezza e l'altezza della bitmap. Se la bitmap si trova in una superficie DirectDraw, la dimensione della superficie è nota, quindi non è necessario specificare rSrc in questo metodo.

Quando chiami IVMRMixerBitmap::UpdateAlphaBitmapParameters, usa il membro rSrc per le bitmap HDC e DirectDraw, per specificare il frame o il rettangolo specifico all'interno dell'immagine da visualizzare e impostare il flag VMRBITMAP_SRCRECT nel membro dwFlags .

Uso della modalità di combinazione vmr