Share via


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

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;
}

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:

  1. 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 .
  2. 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);
}

Enumeración de dispositivos de captura de vídeo

Captura de vídeo