当前USB相机是用sdk访问,日志里显示必须是ttyACM0,我们插了两个会乱,怎么固定USB

问题定位:USB 带宽不足导致 VIDIOC_STREAMON failed: No space left on device

这个错误不是设备节点分配问题,而是USB 带宽不足。RDK X5/X3 的 USB 口通过一个 USB 3.0 Hub 分出,默认情况下第一个摄像头会占满带宽,导致第二个摄像头无法启动。


:white_check_mark: 解决方案:限制 uvcvideo 带宽

步骤1:加载 uvcvideo 模块并限制带宽

# 卸载现有模块
sudo rmmod uvcvideo

# 重新加载并设置 quirks=128(限制带宽)
sudo modprobe uvcvideo quirks=128

参数说明:quirks=128 会限制每个 UVC 设备的带宽占用,允许多设备共享 USB 总线


步骤2:验证模块加载

# 查看模块是否加载成功
lsmod | grep uvcvideo

# 查看模块参数
cat /sys/module/uvcvideo/parameters/quirks

预期输出:128


步骤3:设置开机自动生效(可选)

# 创建模块配置文件
sudo vim /etc/modprobe.d/uvcvideo.conf

写入内容:

options uvcvideo quirks=128

步骤4:降低摄像头分辨率/格式(关键!)

即使设置了 quirks=128,如果两路摄像头总带宽超过 USB 3.0 上限,仍会报错。推荐配置:

分辨率 格式 帧率 单路带宽估算 双路是否可行
640x480 MJPEG 30fps ~15MB/s :white_check_mark: 可行
1280x720 MJPEG 30fps ~30MB/s :white_check_mark: 可行
1920x1080 MJPEG 30fps ~60MB/s :cross_mark: 超限
640x480 YUYV 30fps ~30MB/s :warning: 紧张

测试命令:

# 查看摄像头支持的格式
v4l2-ctl -d /dev/video0 --list-formats-ext

# 设置摄像头为 MJPEG 格式 720p
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=MJPG

步骤5:代码中指定格式和分辨率

import cv2

cap1 = cv2.VideoCapture('/dev/video_CAM1')
cap2 = cv2.VideoCapture('/dev/video_CAM2')

# 强制设置格式和分辨率(关键!)
cap1.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
cap1.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap1.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cap1.set(cv2.CAP_PROP_FPS, 30)

cap2.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
cap2.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap2.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cap2.set(cv2.CAP_PROP_FPS, 30)

# 测试读取
ret1, frame1 = cap1.read()
ret2, frame2 = cap2.read()
print(f"Cam1: {ret1}, Cam2: {ret2}")

步骤6:验证带宽使用情况

# 查看 USB 拓扑和带宽分配
lsusb -t

# 查看内核日志中是否有带宽相关报错
dmesg | grep -i "uvc\|bandwidth\|usb"

:clipboard: 完整操作速查表

步骤 命令 说明
限制带宽 sudo rmmod uvcvideo && sudo modprobe uvcvideo quirks=128 必须执行
验证参数 cat /sys/module/uvcvideo/parameters/quirks 确认值为 128
开机生效 echo "options uvcvideo quirks=128" | sudo tee /etc/modprobe.d/uvcvideo.conf 可选
查看格式 v4l2-ctl -d /dev/video0 --list-formats-ext 确认为 MJPEG
设置格式 v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=MJPG 推荐 720p MJPEG
测试读取 Python OpenCV 代码 同时读取两路

:red_exclamation_mark: 注意事项

  1. 必须使用 MJPEG 格式:YUYV/NV12 等未压缩格式带宽占用太大
  2. 分辨率不要超过 720p:双路 1080p 必超限
  3. USB 口尽量分开:如果有多个 USB 控制器,分散连接
  4. MIPI + USB 组合:如果一个用 MIPI 接口,一个用 USB,不会有带宽冲突

:magnifying_glass_tilted_left: 如果仍然失败

请提供以下信息:

# 1. 当前 uvcvideo 参数
cat /sys/module/uvcvideo/parameters/quirks

# 2. 摄像头支持的格式
v4l2-ctl -d /dev/video0 --list-formats-ext
v4l2-ctl -d /dev/video1 --list-formats-ext

# 3. USB 拓扑
lsusb -t

# 4. 内核日志
dmesg | tail -100

把报错信息和以上输出发出来,我帮你进一步分析!


相关帖子参考: