Paso 6: Controlar eventos de grafos
[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.
Este tema es el paso 6 del tutorial Reproducción de audio y vídeo en DirectShow. El código completo se muestra en el tema Ejemplo de reproducción de DirectShow.
Cuando la aplicación crea una nueva instancia de Filter Graph Manager, la aplicación llama a IMediaEventEx::SetNotifyWindow. Este método registra la ventana de la aplicación para recibir eventos del gráfico de filtros.
hr = m_pGraph->QueryInterface(IID_PPV_ARGS(&m_pEvent));
if (FAILED(hr))
{
goto done;
}
// Set up event notification.
hr = m_pEvent->SetNotifyWindow((OAHWND)m_hwnd, WM_GRAPH_EVENT, NULL);
if (FAILED(hr))
{
goto done;
}
El valor WM_GRAPH_EVENT
es un mensaje de ventana privada. Cada vez que la aplicación recibe este mensaje, llama al DShowPlayer::HandleGraphEvent
método .
case WM_GRAPH_EVENT:
g_pPlayer->HandleGraphEvent(OnGraphEvent);
return 0;
El método DShowPlayer::HandleGraphEvent
hace lo siguiente:
- Llama a IMediaEvent::GetEvent en un bucle para obtener todos los eventos en cola.
- Invoca una función de devolución de llamada (pfnOnGraphEvent).
- Llama a IMediaEvent::FreeEventParams para liberar los datos asociados a cada evento.
// Respond to a graph event.
//
// The owning window should call this method when it receives the window
// message that the application specified when it called SetEventWindow.
//
// Caution: Do not tear down the graph from inside the callback.
HRESULT DShowPlayer::HandleGraphEvent(GraphEventFN pfnOnGraphEvent)
{
if (!m_pEvent)
{
return E_UNEXPECTED;
}
long evCode = 0;
LONG_PTR param1 = 0, param2 = 0;
HRESULT hr = S_OK;
// Get the events from the queue.
while (SUCCEEDED(m_pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0)))
{
// Invoke the callback.
pfnOnGraphEvent(m_hwnd, evCode, param1, param2);
// Free the event data.
hr = m_pEvent->FreeEventParams(evCode, param1, param2);
if (FAILED(hr))
{
break;
}
}
return hr;
}
El código siguiente muestra la función de devolución de llamada que se pasa a DShowPlayer::HandleGraphEvent
. La función controla el número mínimo de eventos de grafo (EC_COMPLETE, EC_ERRORABORT y EC_USERABORT); puede expandir la función para controlar eventos adicionales.
void CALLBACK OnGraphEvent(HWND hwnd, long evCode, LONG_PTR param1, LONG_PTR param2)
{
switch (evCode)
{
case EC_COMPLETE:
case EC_USERABORT:
g_pPlayer->Stop();
break;
case EC_ERRORABORT:
NotifyError(hwnd, L"Playback error.");
g_pPlayer->Stop();
break;
}
}
Temas relacionados