Ubuntu下v4l2-ctl设备断开后无响应的原因排查
V4L2-ctl在Ubuntu下断开摄像头后无响应的问题分析
问题背景
可正常执行以下视频采集命令:
v4l2-ctl -d 0 --set-fmt-video=width=1280,height=720,pixelformat=MJPG --stream-mmap --set-parm 25 --stream-to=video.yuvj422p --stream-count=1000
采集过程中断开摄像头后,出现两种不同行为:
- Ubuntu系统(版本为
linux 6.2.0-26-generic #26~22.04.1-Ubuntu)中的v4l2-ctl进程持续无响应(已等待约10分钟) - Buildroot(内核4.19.269)环境下的同版本v4l2-ctl会终止并提示:
VIDIOC_DQBUF: failed: No such device
期望v4l2-ctl输出v4l2-ctl-streaming.cpp第1486行对应的提示,询问Ubuntu下v4l2-ctl无响应的原因。
环境信息
两台设备的v4l2-ctl版本均为1.22.1:
v4l2-ctl --version v4l2-ctl 1.22.1
问题根源分析
这种差异主要源于内核版本对设备热插拔事件的处理逻辑差异,以及V4L2子系统错误路径的行为变化:
内核版本差异导致阻塞行为
- 内核4.19(Buildroot所用)在USB摄像头断开后,会立即向等待
VIDIOC_DQBUF调用的用户空间进程返回ENODEV(No such device)错误,让v4l2-ctl能捕获错误并终止流程。 - 内核6.2(Ubuntu所用)的V4L2子系统或USB核心层在设备移除时,可能将
VIDIOC_DQBUF调用置于无限阻塞状态而非返回错误。这是因为新内核在处理设备移除时,缓冲队列的清理逻辑发生变化,未及时唤醒等待队列中的用户进程。
- 内核4.19(Buildroot所用)在USB摄像头断开后,会立即向等待
v4l2-ctl错误处理依赖内核反馈
v4l2-ctl-streaming.cpp第1486行的提示需要内核返回明确错误码才能触发。如果内核不返回错误而是持续阻塞,v4l2-ctl会一直停留在等待缓冲数据的循环中,无法进入错误处理分支。内核配置差异影响行为
Ubuntu的内核可能启用了USB autosuspend、V4L2高级缓冲管理等配置选项,这些选项改变了设备移除时的处理逻辑;而Buildroot的内核配置更精简,没有此类选项,因此错误反馈更直接。
验证与解决方向
- 用
strace v4l2-ctl [你的采集命令]跟踪系统调用,确认Ubuntu下VIDIOC_DQBUF是否确实处于阻塞状态。 - 尝试升级v4l-utils版本(后续版本可能针对新内核调整了超时逻辑),或在内核层面调整V4L2的错误处理参数。
- 对比Ubuntu与Buildroot的内核
CONFIG_USB、CONFIG_VIDEO_V4L2相关配置,找出行为差异的具体配置项。
内容的提问来源于stack exchange,提问作者Andrei Cherniaev
相关产品推荐
相关产品推荐

