【MediaFoundation】设备丢失处理

编程入门 行业动态 更新时间:2024-10-27 22:26:58

【MediaFoundation】<a href=https://www.elefans.com/category/jswz/34/1769313.html style=设备丢失处理"/>

【MediaFoundation】设备丢失处理

处理视频设备丢失

这个主题描述了在使用视频捕获设备时如何检测设备丢失。它包括以下几个部分:

  • 注册设备通知
  • 获取设备的符号链接
  • 处理WM_DEVICECHANGE消息
  • 取消注册通知

注册设备通知

在开始从设备捕获数据之前,请调用RegisterDeviceNotification函数来注册设备通知。请按下面的代码示例注册KSCATEGORY_CAPTURE设备类:

#pragma once
#include <dbt.h>
#include <ks.h>
#include <ksmedia.h>HDEVNOTIFY  g_hdevnotify = NULL;// HWND hwnd: 窗口句柄
// HWND 的作用是:当设备丢失时,系统会向这个窗口发送WM_DEVICECHANGE消息
// 返回值:如果函数调用成功,则返回值为非零值。如果函数调用失败,则返回值为零。
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 结构的指针。
Note: Windows 消息循环

简要概括 windows 消息循环

  1. 消息
    Windows 使用消息进行通讯。每个Windows 消息共有两个参数,wParamlParam。 在win32中,这两个参数都是32位的。
  • wParam 包含两个值
    • HIWORD(wParam) 是通知消息(如果可用)
    • LOWORD(wParam) 是发送消息的空间或菜单ID。
  • IParam 是发送消息的控件的 HWND (窗口句柄), 如果为NULL,表示消息不是由控件发送的。
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;
wchar_t* ExtractDeviceId(const wchar_t* devicePath)
{const wchar_t* start = wcschr(devicePath, L'#');if (start == NULL){return NULL;}start += 1;const wchar_t* end = wcschr(start, L'#');const wchar_t* next = end;while (next != NULL){end = next;next += 1;next = wcschr(next, L'#');}if (end == NULL){return NULL;}size_t length = end - start;wchar_t* deviceId = (wchar_t*)malloc((length + 1) * sizeof(wchar_t));wcsncpy_s(deviceId, length + 1, start, length);deviceId[length] = L'\0';return deviceId;
}//-------------------------------------------------------------------
//  CheckDeviceLost
//  Checks whether the video capture device was removed.
//
//  The application calls this method when is receives a 
//  WM_DEVICECHANGE message.
//-------------------------------------------------------------------HRESULT CPreview::CheckDeviceLost(DEV_BROADCAST_HDR *pHdr, BOOL *pbDeviceLost)
{DEV_BROADCAST_DEVICEINTERFACE *pDi = NULL;if (pbDeviceLost == NULL){return E_POINTER;}*pbDeviceLost = FALSE;if (m_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 (m_pwszSymbolicLink){_locale_t locale = _create_locale(LC_ALL, "en-US");if (_wcsicmp_l(ExtractDeviceId(m_pwszSymbolicLink), ExtractDeviceId(pDi->dbcc_name), locale) == 0){*pbDeviceLost = TRUE;}}return S_OK;
}

完整Demo 查看官方github 代码

更多推荐

【MediaFoundation】设备丢失处理

本文发布于:2023-11-16 00:05:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1610272.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:设备   MediaFoundation

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!