Gestion de la perte vidéo d’appareil
Cette rubrique explique comment détecter la perte d’appareil lors de l’utilisation d’un appareil de capture vidéo. Il contient les sections suivantes :
- S’inscrire à la notification d’appareil
- Obtenir le lien symbolique de l’appareil
- Gérer WM_DEVICECHANGE
- Désinscrire pour la notification
- Rubriques connexes
S’inscrire à la notification d’appareil
Avant de commencer à capturer à partir de l’appareil, appelez la fonction RegisterDeviceNotification pour vous inscrire aux notifications de l’appareil. Inscrivez-vous à la classe d’appareil KSCATEGORY_CAPTURE , comme indiqué dans le code suivant.
#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;
}
Obtenir le lien symbolique de l’appareil
Énumérez les appareils vidéo sur le système, comme décrit dans Énumération des appareils de capture vidéo. Choisissez un appareil dans la liste, puis interrogez l’objet d’activation pour l’attribut MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK , comme indiqué dans le code suivant.
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
);
}
Gérer WM_DEVICECHANGE
Dans votre boucle de message, écoutez WM_DEVICECHANGE messages. Le paramètre de message lParam est un pointeur vers une structure 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;
Ensuite, comparez le message de notification de l’appareil au lien symbolique de votre appareil, comme suit :
- Vérifiez le membre dbch_devicetype de la structure DEV_BROADCAST_HDR . Si la valeur est DBT_DEVTYP_DEVICEINTERFACE, castez le pointeur de structure vers une structure DEV_BROADCAST_DEVICEINTERFACE .
- Comparez le dbcc_name membre de cette structure au lien symbolique de l’appareil.
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;
}
Désinscrire pour la notification
Avant la fin de l’application, appelez UnregisterDeviceNotification pour annuler l’inscription pour les notifications d’appareil/
void OnClose(HWND /*hwnd*/)
{
if (g_hdevnotify)
{
UnregisterDeviceNotification(g_hdevnotify);
}
PostQuitMessage(0);
}
Rubriques connexes