Condividi tramite


Modalità senza finestra di VMR

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, FMMediaEngine 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, FMMediaEngine e Audio/Video Capture in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

La modalità senza finestra è il modo preferito per le applicazioni di eseguire il rendering di video all'interno di una finestra dell'applicazione. In modalità senza finestra, il renderer di mix video non carica il componente Window Manager e pertanto non supporta le interfacce IBasicVideo o IVideoWindow . L'applicazione fornisce invece la finestra di riproduzione e imposta un rettangolo di destinazione nell'area client per la macchina virtuale per disegnare il video. VmR usa un oggetto Clipper DirectDraw per assicurarsi che il video venga ritagliato nella finestra dell'applicazione e non venga visualizzato in nessun'altra finestra. VmR non sottoclasse la finestra dell'applicazione o installare eventuali hook di sistema/elaborazione.

In modalità senza finestra, la sequenza di eventi durante la connessione e la transizione allo stato di esecuzione è la seguente:

  • Il filtro upstream propone un tipo di supporto, che la vmR accetta o rifiuta.
  • Se il tipo di supporto viene accettato, vmR chiama l'allocatore-relatore per ottenere una superficie DirectDraw. Se la superficie viene creata correttamente, i pin si connettono e vmR è pronto per la transizione nello stato di esecuzione.
  • Quando viene eseguito il grafico del filtro, il decodificatore chiama GetBuffer per ottenere un esempio multimediale dall'allocatore. VmR esegue una query sul relatore allocatore per garantire che la profondità dei pixel, le dimensioni del rettangolo e altri parametri nella superficie DirectDraw siano compatibili con il video in ingresso. Se sono compatibili, vmR restituisce la superficie DirectDraw al decodificatore. Dopo che il decodificatore è stato decodificato nella superficie, l'unità di sincronizzazione core di VMR convalida i timestamp. Questa unità blocca la chiamata di ricezione fino all'arrivo dell'ora di presentazione. A quel punto, vmR chiama PresentImage nel relatore allocatore, che presenta la superficie alla scheda grafica.

Nella figura seguente viene illustrata la macchina virtuale in modalità senza finestre con più flussi di input.

vmr in modalità senza finestra

Configurazione della vmR-7 per la modalità senza finestra

Per configurare vmR-7 per la modalità senza finestra, eseguire tutti i passaggi seguenti prima di connettere uno dei pin di input di VMR:

  1. Creare il filtro e aggiungerlo al grafico.

  2. Chiamare il metodo IVMRFilterConfig::SetRenderingMode con il flag di VMRMode_Windowless.

  3. Facoltativamente, configurare vmR per più flussi di input chiamando IVMRFilterConfig::SetNumberOfStreams. VmR crea un pin di input per ogni flusso. Usare l'interfaccia IVMRMixerControl per impostare l'ordine Z e altri parametri per il flusso. Per altre informazioni, vedere VMR con più flussi (modalità di combinazione).

    Se non si chiama SetNumberOfStreams, l'impostazione predefinita VMR-7 viene impostata su un pin di input. Dopo la connessione dei pin di input, non è possibile modificare il numero di pin.

  4. Chiamare IVMRWindowlessControl::SetVideoClippingWindow per specificare la finestra in cui verrà visualizzato il video di rendering.

Al termine di questi passaggi, è possibile connettere i pin di input del filtro VMR. Esistono diversi modi per compilare il grafico, ad esempio connettersi direttamente ai pin, usando metodi Intelligent Connect, ad esempio IGraphBuilder::RenderFile o usando il metodo ICaptureGraphBuilder2::RenderStream di Capture Graph Builder. Per altre informazioni, vedere Generale Graph-Building Tecniche.

Per impostare la posizione del video nella finestra dell'applicazione, chiamare il metodo IVMRWindowlessControl::SetVideoPosition . Il metodo IVMRWindowlessControl::GetNativeVideoSize restituisce le dimensioni del video nativo. Durante la riproduzione, l'applicazione deve inviare una notifica a VMR dei messaggi di Windows seguenti:

Nota

Le applicazioni MFC devono definire un gestore di messaggi WM_ERASEBKGND vuoto oppure l'area di visualizzazione video non eseguirà correttamente il repository.

 

Configurazione della vmR-9 per la modalità senza finestra

Per configurare vmR-9 per la modalità senza finestra, usare i passaggi descritti per la modalità VMR-7 per la modalità senza finestra, ma usare le interfacce IVMRFilterConfig9 e IVMRWindowlessControl9 . L'unica differenza significativa è che vmR-9 crea quattro pin di input per impostazione predefinita, anziché un pin di input. Pertanto, è necessario chiamare SetNumberOfStreams solo se si combinano più di quattro flussi video.

Codice di esempio

Il codice seguente illustra come creare un filtro VMR-7, aggiungerlo al grafico del filtro DirectShow e quindi inserire vmR in modalità senza finestra. Per VMR-9, usare CLSID_VideoMixingRenderer9 in CoCreateInstance e nelle interfacce VMR-9 corrispondenti.

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

Uso della modalità senza finestra