Usando o modo de janela

[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo na Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use 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.]

Observação

O Filtro do Renderizador de Vídeo herdado sempre usa o modo em janelas. Os filtros VMR-7 e VMR-9 usam o modo em janela por padrão, mas também dão suporte ao modo sem janelas.

 

No modo de janela, o renderizador de vídeo cria sua própria janela onde pinta os quadros de vídeo. A menos que você especifique o contrário, essa janela é uma janela de nível superior com suas próprias bordas e barra de título. Na maioria das vezes, no entanto, você anexará a janela de vídeo a uma janela do aplicativo, para que o vídeo seja integrado à interface do usuário do aplicativo. Isso exige as seguintes etapas:

  1. Consulta para IVideoWindow.
  2. Defina a janela pai.
  3. Defina novos estilos de janela.
  4. Posicione a janela de vídeo dentro da janela do proprietário.
  5. Notifique a janela de vídeo de mensagens de WM_MOVE.

Consulta para IVideoWindow

Antes de iniciar a reprodução, consulte o Gerenciador de Grafo de Filtro para a interface IVideoWindow :

IVideoWindow *pVidWin = NULL;
pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

Definir a janela pai

Para definir a janela pai, chame o método IVideoWindow::p ut_Owner com um identificador para a janela do aplicativo. Esse método usa uma variável do tipo OAHWND, portanto, converta o identificador para esse tipo:

pVidWin->put_Owner((OAHWND)hwnd);

Definir novos estilos de janela

Altere o estilo da janela de vídeo chamando o método IVideoWindow::p ut_WindowStyle :

pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

O sinalizador WS_CHILD define a janela como uma janela filho e o sinalizador WS_CLIPSIBLINGS impede que a janela seja desenhada dentro da área do cliente de outra janela filho.

Posicionar a janela de vídeo

Para definir a posição do vídeo em relação à área de cliente da janela do aplicativo, chame o método IVideoWindow::SetWindowPosition . Esse método usa um retângulo que especifica a borda esquerda, a borda superior, a largura e a altura da janela de vídeo. Por exemplo, o código a seguir estende a janela de vídeo para se ajustar a toda a área do cliente da janela pai:

RECT rc;
GetClientRect(hwnd, &rc);
pVidWin->SetWindowPosition(0, 0, rc.right, rc.bottom);

Para obter o tamanho nativo do vídeo, chame o método IBasicVideo::GetVideoSize no Gerenciador de Grafo de Filtro. Você pode usar essas informações para dimensionar o vídeo e manter a taxa de proporção correta.

Responder a mensagens de WM_MOVE

Para obter o melhor desempenho, você deve notificar o renderizador de vídeo sempre que a janela for movida enquanto o grafo estiver em pausa. Chame o método IVideoWindow::NotifyOwnerMessage para encaminhar a mensagem WM_MOVE:

// (Inside your WindowProc)
case WM_MOVE:
    pVidWin->NotifyOwnerMessage((OAHWND)hWnd, msg, wParam, lParam);
    break;

Se o renderizador estiver usando uma sobreposição de hardware, essa notificação fará com que o renderizador atualize a posição de sobreposição. (A VMR-9 não usa sobreposições, portanto, você não precisa chamar esse método se estiver usando a VMR-9.)

Limpar

Antes que o aplicativo seja encerrado, interrompa o grafo e redefina o proprietário da janela de vídeo como NULL. Caso contrário, as mensagens de janela poderão ser enviadas para a janela errada, o que provavelmente causará erros. Além disso, oculte a janela de vídeo ou então você poderá ver uma cintilação de imagem de vídeo na tela momentaneamente:

pControl->Stop(); 
pVidWin->put_Visible(OAFALSE);
pVidWin->put_Owner(NULL);  

Observação

Se o pai da janela de vídeo for um filho da janela do aplicativo main (em outras palavras, se a janela de vídeo for filho de um filho), você deverá criar a janela de vídeo usando CoCreateInstance e adicioná-la ao grafo, em vez de permitir que o Gerenciador de Grafo de Filtro adicione o renderizador de vídeo durante o Intelligent Connect. Isso garante que a janela de vídeo e a janela filho sejam repintadas ao mesmo tempo. Caso contrário, a janela filho poderá pintar sobre a janela de vídeo.

 

Renderização de vídeo