Controlando um grafo de captura
[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.]
A interface IMediaControl do Gerenciador de Grafo de Filtro tem métodos para executar, parar e pausar todo o grafo. No entanto, se o grafo de filtro tiver fluxos de captura e visualização, você provavelmente deseja controlar os dois fluxos de forma independente. Por exemplo, talvez você queira visualizar o vídeo sem capturá-lo. Você pode fazer isso por meio do método ICaptureGraphBuilder2::ControlStream .
Observação
Esse método não funciona ao capturar em um arquivo ASF (Advanced Systems Format).
Controlando o fluxo de captura
O código a seguir define o fluxo de captura de vídeo a ser executado por quatro segundos, iniciando um segundo após a execução do grafo:
// Control the video capture stream.
REFERENCE_TIME rtStart = 10000000, rtStop = 50000000;
const WORD wStartCookie = 1, wStopCookie = 2; // Arbitrary values.
hr = pBuild->ControlStream(
&PIN_CATEGORY_CAPTURE, // Pin category.
&MEDIATYPE_Video, // Media type.
pCap, // Capture filter.
&rtStart, &rtStop, // Start and stop times.
wStartCookie, wStopCookie // Values for the start and stop events.
);
pControl->Run();
O primeiro parâmetro especifica qual fluxo controlar, como um GUID de categoria de pino. O segundo parâmetro fornece o tipo de mídia. O terceiro parâmetro é um ponteiro para o filtro de captura. Para controlar todos os fluxos de captura no grafo, defina o segundo e o terceiro parâmetros como NULL.
Os próximos dois parâmetros definem os horários em que o fluxo será iniciado e interrompido, em relação à hora em que o grafo começa a ser executado. Chame IMediaControl::Run para executar o grafo. Até que você execute o grafo, o método ControlStream não terá efeito. Se o grafo já estiver em execução, as configurações entrarão em vigor imediatamente.
Os dois últimos parâmetros são usados para obter notificações de evento quando o fluxo é iniciado e interrompido. Para cada fluxo que você controla usando esse método, o grafo de filtro envia um par de eventos: EC_STREAM_CONTROL_STARTED quando o fluxo é iniciado e EC_STREAM_CONTROL_STOPPED quando o fluxo é interrompido. Os valores de wStartCookie e wStopCookie são usados como o segundo parâmetro de evento. Assim, lParam2 no evento inicial é igual a wStartCookie e lParam2 no evento stop é igual a wStopCookie. O código a seguir mostra como obter esses eventos:
while (hr = pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0), SUCCEEDED(hr))
{
switch (evCode)
{
case EC_STREAM_CONTROL_STARTED:
// param2 == wStartCookie
break;
case EC_STREAM_CONTROL_STOPPED:
// param2 == wStopCookie
break;
}
pEvent->FreeEventParams(evCode, param1, param2);
}
O método ControlStream define alguns valores especiais para os horários de início e parada.
Valor | Iniciar | Stop |
---|---|---|
MAXLONGLONG | Nunca inicie esse fluxo. | Não pare até que o grafo pare. |
NULL | Comece imediatamente quando o grafo for executado. | Pare imediatamente. |
Por exemplo, o código a seguir interrompe o fluxo de captura imediatamente:
pBuild->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap,
0, 0, // Start and stop times.
wStartCookie, wStopCookie);
Embora você possa interromper o fluxo de captura e reiniciá-lo mais tarde, isso criará uma lacuna nos carimbos de data/hora. Na reprodução, o vídeo aparecerá parado durante a lacuna (dependendo do formato do arquivo).
Controlando o fluxo de visualização
Para controlar o pin de visualização, chame ControlStream , mas defina o primeiro parâmetro como PIN_CATEGORY_PREVIEW. Isso funciona da mesma forma que funciona para PIN_CATEGORY_CAPTURE, exceto que você não pode usar tempos de referência para especificar o início e a parada, pois os quadros de visualização não têm carimbos de data/hora. Portanto, você deve usar NULL ou MAXLONGLONG. Use NULL para iniciar o fluxo de visualização:
pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
NULL, // Start now.
0, // (Don't care.)
wStartCookie, wStopCookie);
Use MAXLONGLONG para interromper o fluxo de visualização:
pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
0, // (Don't care.)
MAXLONGLONG, // Stop now.
wStartCookie, wStopCookie);
Não importa se o fluxo de visualização vem de um pino de visualização no filtro de captura ou do filtro Smart Tee. O método ControlStream funciona de qualquer maneira.
No entanto, para pinos de porta de vídeo, o método falhará. Nesse caso, outra abordagem é ocultar a janela de vídeo. Consulte o grafo para IVideoWindow e use o método IVideoWindow::p ut_Visible para mostrar ou ocultar a janela.
// Hide the video window.
IVideoWindow *pVidWin = 0;
hr = pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVidWin);
if (SUCCEEDED(hr))
{
pVidWin->put_Visible(OAFALSE);
pVidWin->Release();
}
Além disso, se você chamar IVideoWindow::p ut_AutoShow com o valor OAFALSE antes de executar o grafo, o filtro Renderizador de Vídeo ocultará a janela até que você especifique o contrário. Por padrão, o Renderizador de Vídeo mostra a janela quando você executa o grafo.
Comentários sobre o Controle de Fluxo
O comportamento padrão de um pin é fornecer amostras quando o grafo é executado. Por exemplo, suponha que você chame ControlStream com PIN_CATEGORY_CAPTURE mas não com PIN_CATEGORY_PREVIEW. Quando você executar o grafo, o fluxo de visualização será executado imediatamente, enquanto o fluxo de captura será executado em qualquer momento especificado em ControlStream.
Se você estiver capturando mais de um fluxo e enviando-os para um filtro mux , por exemplo, se você estiver capturando áudio e vídeo em um arquivo AVI, deverá controlar ambos os fluxos em conjunto. Caso contrário, o filtro mux pode bloquear a espera de um fluxo, pois ele tenta intercalar os dois fluxos. Defina os mesmos horários de início e parada em todos os fluxos de captura antes de executar o grafo:
pBuild->ControlStream(&PIN_CATEGORY_CAPTURE,
NULL, NULL, // All capture streams.
&rtStart, rtStop,
wStartCookie, wStopCookie);
Internamente, o método ControlStream usa a interface IAMStreamControl , que é exposta nos pinos do filtro de captura, no filtro Smart Tee (se estiver presente) e possivelmente no filtro mux. Você pode usar essa interface diretamente, em vez de chamar ControlStream, embora não haja nenhuma vantagem específica para fazer isso.
Tópicos relacionados