Controlar la pérdida de dispositivos de vídeo
En este tema se describe cómo detectar la pérdida de dispositivos al usar un dispositivo de captura de vídeo. Contiene las secciones siguientes:
- Registrarse para la notificación del dispositivo
- Obtener el vínculo simbólico del dispositivo
- Controlar WM_DEVICECHANGE
- Anular el registro de la notificación
- Temas relacionados
Registrarse para la notificación del dispositivo
Antes de empezar a capturar desde el dispositivo, llame a la función RegisterDeviceNotification para registrarse para las notificaciones del dispositivo. Regístrese para la clase de dispositivo KSCATEGORY_CAPTURE , como se muestra en el código siguiente.
#include <Dbt.h>
#include <ks.h>
#include <ksmedia.h>
HDEVNOTIFY g_hdevnotify = NULL;
BOOL RegisterForDeviceNotification(HWND hwnd)
{
DEV_BROADCAST_DEVICEINTERFACE di = { 0 };
di.dbcc_size = sizeof(di);
di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
di.dbcc_classguid = KSCATEGORY_CAPTURE;
g_hdevnotify = RegisterDeviceNotification(
hwnd,
&di,
DEVICE_NOTIFY_WINDOW_HANDLE
);
if (g_hdevnotify == NULL)
{
return FALSE;
}
return TRUE;
}
Obtener el vínculo simbólico del dispositivo
Enumere los dispositivos de vídeo en el sistema, tal y como se describe en Enumeración de dispositivos de captura de vídeo. Elija un dispositivo de la lista y, a continuación, consulte el objeto de activación para el atributo MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK , como se muestra en el código siguiente.
WCHAR *g_pwszSymbolicLink = NULL;
UINT32 g_cchSymbolicLink = 0;
HRESULT GetSymbolicLink(IMFActivate *pActivate)
{
return pActivate->GetAllocatedString(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
&g_pwszSymbolicLink,
&g_cchSymbolicLink
);
}
Controlar WM_DEVICECHANGE
En el bucle de mensajes, escuche WM_DEVICECHANGE mensajes. El parámetro de mensaje lParam es un puntero a una estructura de DEV_BROADCAST_HDR .
case WM_DEVICECHANGE:
if (lParam != 0)
{
HRESULT hr = S_OK;
BOOL bDeviceLost = FALSE;
hr = CheckDeviceLost((PDEV_BROADCAST_HDR)lParam, &bDeviceLost);
if (FAILED(hr) || bDeviceLost)
{
CloseDevice();
MessageBox(hwnd, L"Lost the capture device.", NULL, MB_OK);
}
}
return TRUE;
A continuación, compare el mensaje de notificación del dispositivo con el vínculo simbólico del dispositivo, como se indica a continuación:
- Compruebe el miembro dbch_devicetype de la estructura de DEV_BROADCAST_HDR . Si el valor es DBT_DEVTYP_DEVICEINTERFACE, convierta el puntero de estructura en una estructura DEV_BROADCAST_DEVICEINTERFACE .
- Compare el miembro dbcc_name de esta estructura con el vínculo simbólico del dispositivo.
HRESULT CheckDeviceLost(DEV_BROADCAST_HDR *pHdr, BOOL *pbDeviceLost)
{
DEV_BROADCAST_DEVICEINTERFACE *pDi = NULL;
if (pbDeviceLost == NULL)
{
return E_POINTER;
}
*pbDeviceLost = FALSE;
if (g_pSource == NULL)
{
return S_OK;
}
if (pHdr == NULL)
{
return S_OK;
}
if (pHdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
{
return S_OK;
}
// Compare the device name with the symbolic link.
pDi = (DEV_BROADCAST_DEVICEINTERFACE*)pHdr;
if (g_pwszSymbolicLink)
{
if (_wcsicmp(g_pwszSymbolicLink, pDi->dbcc_name) == 0)
{
*pbDeviceLost = TRUE;
}
}
return S_OK;
}
Anular el registro de la notificación
Antes de que se cierre la aplicación, llame a UnregisterDeviceNotification para anular el registro de las notificaciones del dispositivo/
void OnClose(HWND /*hwnd*/)
{
if (g_hdevnotify)
{
UnregisterDeviceNotification(g_hdevnotify);
}
PostQuitMessage(0);
}
Temas relacionados