UVC取流(bulk传输)——设备资源安全释放机制
(一)、问题现象
在UVC设备取流的开发中,资源的彻底释放是确保设备能够被稳定重复打开使用的关键环节。
若释放不彻底,会导致后续重新打开设备时出现获取不到数据、设备无响应等异常情况。例如uvc_start_streaming并不会返回失败,但迟迟接收不到流,像卡住了一样。
(二)、核心问题分析
UVC流停止后,若USBinterface与endpoint状态未完全复位,设备固件可能仍维持着上一次的流状态或数据缓冲区的残留。这会在物理层面阻塞新的会话建立,导致主机端再次枚举或初始化时,设备无法进入预期的空闲初始状态。
(三)、建议的设备释放原则
清理流程应遵循分层释放原则,从数据流、到设备句柄、再到上下文,逐级清理。
很多示例代码往往是一个uvc_close->uvc_unref_device->uvc_exit就了结了,但在bulk传输下,就会带来(一)中出现的问题。
经笔者尝试,首先停止流传输是基础操作,然后关键的是USB接口、端点的清理。
- 明确设备的具体视频流(video stream)接口编号,通常是接口1, 可以用UsbTreeView帮助确定。
- 执行接口释放、重置备用设置、重新声明的操作序列,将接口恢复到初始状态。
- 必须清除输入端点上的挂起状态,清除OUT端点和IN端点的数据残留。
最后,设备句柄关闭后,置空指针。
上下文清理前建议添加短暂延时,确保所有异步操作完成。最后清空上下文指针,完成整个释放链条。
(四)、参考代码
4.1 停止数据流
uvc_stop_streaming(g_devh);
4.2 复位USB接口
- 释放视频流接口
- 重置备用设置到默认值
- 重新声明接口所有权
- 清除输入端点挂起状态
- 清除输出端点挂起状态
int vs_interface = 1;
libusb_release_interface(g_devh->usb_devh, vs_interface);
libusb_set_interface_alt_setting(g_devh->usb_devh, vs_interface, 0);
libusb_claim_interface(g_devh->usb_devh, vs_interface);
libusb_clear_halt(g_devh->usb_devh, endpoint_vc);
libusb_clear_halt(g_devh->usb_devh, endpoint_vs);
4.3 关闭设备句柄
- 关闭UVC设备连接
- 置空设备句柄指针
uvc_close(g_devh);
g_devh = NULL;
4.4 释放设备引用
- 减少设备引用计数
- 置空设备指针
uvc_unref_device(g_dev);
g_dev = NULL;
4.5 清理上下文
- 等待异步操作完成
- 退出UVC上下文
- 置空上下文指针
Sleep(50); // 或适当延时
uvc_exit(g_ctx);
g_ctx = NULL;
4605

被折叠的 条评论
为什么被折叠?



