Share via


Modo sin ventana de VMR

[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.

El modo sin ventana es la manera preferida de que las aplicaciones represente vídeo dentro de una ventana de la aplicación. En modo sin ventanas, el representador de mezcla de vídeos no carga su componente Administrador de ventanas y, por lo tanto, no admite las interfaces IBasicVideo o IVideoWindow . En su lugar, la aplicación proporciona la ventana de reproducción y establece un rectángulo de destino en el área cliente para que VMR dibuje el vídeo. VMR usa un objeto Clipper de DirectDraw para asegurarse de que el vídeo se recorta en la ventana de la aplicación y no aparece en ninguna otra ventana. VMR no subclase la ventana de la aplicación ni instala ningún enlace de sistema o proceso.

En el modo sin ventanas, la secuencia de eventos durante la conexión y la transición al estado de ejecución es la siguiente:

  • El filtro ascendente propone un tipo de medio, que el VMR acepta o rechaza.
  • Si se acepta el tipo de medio, VMR llama al asignador-moderador para obtener una superficie de DirectDraw. Si la superficie se crea correctamente, los anclajes se conectan y VMR está listo para realizar la transición al estado de ejecución.
  • Cuando se ejecuta el grafo de filtro, el descodificador llama a GetBuffer para obtener un ejemplo multimedia del asignador. VMR consulta al moderador del asignador para asegurarse de que la profundidad del píxel, el tamaño del rectángulo y otros parámetros en su superficie de DirectDraw son compatibles con el vídeo entrante. Si son compatibles, VMR devuelve la superficie de DirectDraw al descodificador. Una vez que el descodificador se ha descodificado en la superficie, la unidad de sincronización principal de VMR valida las marcas de tiempo. Esta unidad bloquea la llamada Receive hasta que llegue la hora de presentación. En ese momento, el VMR llama a PresentImage en el asignador-moderador, que presenta la superficie a la tarjeta gráfica.

En la ilustración siguiente se muestra vmR en modo sin ventanas con varias secuencias de entrada.

vmr en modo sin ventana

Configuración de VMR-7 para el modo sin ventana

Para configurar VMR-7 para el modo sin ventanas, realice todos los pasos siguientes antes de conectar cualquiera de los pines de entrada de VMR:

  1. Cree el filtro y agréguelo al grafo.

  2. Llame al método IVMRFilterConfig::SetRenderingMode con la marca VMRMode_Windowless.

  3. Opcionalmente, configure VMR para varias secuencias de entrada mediante una llamada a IVMRFilterConfig::SetNumberOfStreams. VMR crea un pin de entrada para cada secuencia. Use la interfaz IVMRMixerControl para establecer el orden Z y otros parámetros para la secuencia. Para más información, consulte VMR con varias secuencias (modo de mezcla).

    Si no llama a SetNumberOfStreams, el valor predeterminado de VMR-7 es un pin de entrada. Una vez conectados los pines de entrada, no se puede cambiar el número de patillas.

  4. Llame a IVMRWindowlessControl::SetVideoClippingWindow para especificar la ventana en la que aparecerá el vídeo representado.

Una vez completados estos pasos, puede conectar los pines de entrada del filtro VMR. Hay varias maneras de compilar el grafo, como conectar patillas directamente, mediante métodos intelligent Connect como IGraphBuilder::RenderFile o mediante el método ICaptureGraphBuilder2::RenderStream del Generador de graph de captura. Para obtener más información, vea Técnicas generales de Graph-Building.

Para establecer la posición del vídeo dentro de la ventana de la aplicación, llame al método IVMRWindowlessControl::SetVideoPosition . El método IVMRWindowlessControl::GetNativeVideoSize devuelve el tamaño de vídeo nativo. Durante la reproducción, la aplicación debe notificar a VMR los siguientes mensajes de Windows:

Nota:

Las aplicaciones MFC deben definir un controlador de mensajes WM_ERASEBKGND vacío o el área de visualización de vídeo no se volverá a pintar correctamente.

 

Configuración de VMR-9 para el modo sin ventanas

Para configurar VMR-9 para el modo sin ventana, siga los pasos descritos para VMR-7 para el modo sin ventana, pero use las interfaces IVMRFilterConfig9 e IVMRWindowlessControl9 . La única diferencia significativa es que VMR-9 crea cuatro pines de entrada de forma predeterminada, en lugar de un pin de entrada. Por lo tanto, solo tienes que llamar a SetNumberOfStreams si estás mezclando más de cuatro secuencias de vídeo.

Código de ejemplo

En el código siguiente se muestra cómo crear un filtro VMR-7, agregarlo al gráfico de filtros DirectShow y, a continuación, colocar vmR en modo sin ventanas. Para VMR-9, use CLSID_VideoMixingRenderer9 en CoCreateInstance y las interfaces VMR-9 correspondientes.

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 del modo sin ventanas