Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEnginee Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda vivamente que o novo código utilize MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]
O modo sem janela é a maneira preferida para os aplicativos renderizarem vídeo dentro de uma janela do aplicativo. No modo sem janelas, o renderizador de mistura de vídeo não carrega seu componente Gerenciador de janelas e, portanto, não suporta o IBasicVideo ou interfaces de IVideoWindow. Em vez disso, o aplicativo fornece a janela de reprodução e define um retângulo de destino na área do cliente para o VMR desenhar o vídeo. O VMR usa um objeto de clipper DirectDraw para garantir que o vídeo seja cortado na janela do aplicativo e não apareça em nenhuma outra janela. O VMR não subclassifica a janela do aplicativo nem instala nenhum gancho de sistema/processo.
No modo sem janelas, a sequência de eventos durante a conexão e a transição para o estado de execução é a seguinte:
- O filtro upstream propõe um tipo de mídia, que o VMR aceita ou rejeita.
- Se o tipo de mídia for aceito, o VMR chamará o alocador-apresentador para obter uma superfície DirectDraw. Se a superfície for criada com êxito, os pinos se conectam e o VMR está pronto para fazer a transição para o estado de execução.
- Quando o gráfico de filtro é executado, o decodificador chama GetBuffer para obter uma amostra de mídia do alocador. O VMR consulta o alocador-apresentador para garantir que a profundidade do pixel, o tamanho do retângulo e outros parâmetros em sua superfície DirectDraw sejam compatíveis com o vídeo recebido. Se forem compatíveis, o VMR devolve a superfície DirectDraw ao descodificador. Depois que o decodificador for decodificado na superfície, a Unidade de Sincronização Principal do VMR validará os carimbos de data/hora. Esta unidade bloqueia a chamada Receber até chegar a hora da apresentação. Nesse ponto, o VMR chama PresentImage no alocador-apresentador, que apresenta a superfície para a placa gráfica.
A ilustração a seguir mostra o VMR no modo sem janelas com vários fluxos de entrada.
Configurando o VMR-7 para o modo sem janela
Para configurar o VMR-7 para o modo sem janelas, execute todas as seguintes etapas antes de conectar qualquer um dos pinos de entrada do VMR:
Crie o filtro e adicione-o ao gráfico.
Chame o IVMRFilterConfig::SetRenderingMode método com o sinalizador VMRMode_Windowless.
Opcionalmente, configure o VMR para vários fluxos de entrada chamando IVMRFilterConfig::SetNumberOfStreams. O VMR cria um pino de entrada para cada fluxo. Use o interface de IVMRMixerControl para definir a ordem Z e outros parâmetros para o fluxo. Para obter mais informações, consulte VMR com vários fluxos (modo de mistura).
Se você não chamar SetNumberOfStreams, o VMR-7 assume como padrão um pino de entrada. Depois que os pinos de entrada são conectados, o número de pinos não pode ser alterado.
Chame IVMRWindowlessControl::SetVideoClippingWindow para especificar a janela na qual o vídeo renderizado aparecerá.
Quando essas etapas forem concluídas, você poderá conectar os pinos de entrada do filtro VMR. Há várias maneiras de criar o gráfico, como conectar pinos diretamente, usando métodos Intelligent Connect, como IGraphBuilder::RenderFile, ou usando o métodoICaptureGraphBuilder2::RenderStream do Capture Graph Builder. Para obter mais informações, consulte Técnicas gerais Graph-Building .
Para definir a posição do vídeo dentro da janela do aplicativo, chame o IVMRWindowlessControl::SetVideoPosition método. O IVMRWindowlessControl::GetNativeVideoSize método retorna o tamanho de vídeo nativo. Durante a reprodução, o aplicativo deve notificar o VMR das seguintes mensagens do Windows:
- WM_PAINT: Chame IVMRWindowlessControl::RepaintVideo para repintar a imagem.
- WM_DISPLAYCHANGE: Ligue IVMRWindowlessControl::D isplayModeChanged. O VMR executa todas as ações necessárias para exibir o vídeo na nova resolução ou profundidade de cor.
- WM_SIZE: Recalcule a posição do vídeo e chame SetVideoPosition novamente, se necessário.
Observação
Os aplicativos MFC devem definir um manipulador de mensagens WM_ERASEBKGND vazio ou a área de exibição de vídeo não será repintada corretamente.
Configurando o VMR-9 para o modo sem janela
Para configurar o VMR-9 para o modo sem janelas, use as etapas descritas para o VMR-7 para o modo sem janelas, mas use o IVMRFilterConfig9 e interfaces de IVMRWindowlessControl9. A única diferença significativa é que o VMR-9 cria quatro pinos de entrada por padrão, em vez de um pino de entrada. Portanto, você só precisa chamar SetNumberOfStreams se estiver misturando mais de quatro fluxos de vídeo.
Exemplo de código
O código a seguir mostra como criar um filtro VMR-7, adicioná-lo ao gráfico de filtro DirectShow e, em seguida, colocar o VMR no modo sem janelas. Para o VMR-9, use CLSID_VideoMixingRenderer9 em CoCreateInstance e as interfaces VMR-9 correspondentes.
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;
}
Tópicos relacionados