비디오 디바이스 손실 처리
이 항목에서는 비디오 캡처 디바이스를 사용할 때 디바이스 손실을 감지하는 방법을 설명합니다. 여기에는 다음 단원이 포함되어 있습니다.
디바이스 알림 등록
디바이스에서 캡처를 시작하기 전에 RegisterDeviceNotification 함수를 호출하여 디바이스 알림에 등록합니다. 다음 코드와 같이 KSCATEGORY_CAPTURE 디바이스 클래스에 등록합니다.
#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;
}
디바이스의 기호 링크 가져오기
비디오 캡처 디바이스 열거에 설명된 대로 시스템의 비디오 디바이스를 열거합니다. 목록에서 디바이스를 선택한 다음, 다음 코드와 같이 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 특성에 대한 활성화 개체를 쿼리합니다.
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
);
}
WM_DEVICECHANGE 처리
메시지 루프에서 WM_DEVICECHANGE 메시지를 수신 대기합니다. lParam 메시지 매개 변수는 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;
다음으로, 다음과 같이 디바이스 알림 메시지를 디바이스의 기호 링크와 비교합니다.
- DEV_BROADCAST_HDR 구조체의 dbch_devicetype 멤버를 확인합니다. 값이 DBT_DEVTYP_DEVICEINTERFACE 경우 구조체 포인터를 DEV_BROADCAST_DEVICEINTERFACE 구조체로 캐스팅합니다.
- 이 구조체의 dbcc_name 멤버를 디바이스의 기호 링크와 비교합니다.
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;
}
알림 등록 취소
애플리케이션이 종료되기 전에 UnregisterDeviceNotification을 호출하여 디바이스 알림 등록을 취소합니다.
void OnClose(HWND /*hwnd*/)
{
if (g_hdevnotify)
{
UnregisterDeviceNotification(g_hdevnotify);
}
PostQuitMessage(0);
}
관련 항목