Raspberry Pi 上视频捕获的带宽限制以及如何克服这些限制

Bandwidth limitations for video capturing on a Raspberry Pi and how to overcome them

我正在尝试使用 USB 摄像头直接在 Raspberry Pi 4 上捕获和保存两个视频流。摄像头在 /dev 中显示为 /dev/video0/dev/video2并且两者都经过独立测试,可以在 30 fps 的帧速率下工作。

我使用命令同时启动了两个流

sh -c 'ffmpeg -f v4l2 -r 25 -s 640x480 -i /dev/video2 left.avi & ffmpeg -f v4l2 -r 25 -s 640x48
0 -i /dev/video0 right.avi & wait'

我遇到一个摄像头的帧率是~25fps而另一个显示如下输出

frame=1 fps=0.2 q=2.9 size=6kB time=00:00:00.04 bitrate=1135.6kbits/s speed=0.00983x

一个视频按预期播放,另一个视频只存储了几帧。当我尝试使用 OpenCV 的 VideoCapture() class.

捕获视频时出现了同样的问题

我已经看到 问题并在 ffmpeg 中将帧速率降低到 15,就像这样

sh -c 'ffmpeg -f v4l2 -r 15 -s 640x480 -i /dev/video2 left.avi & ffmpeg -f v4l2 -r 15 -s 640x480 -i /dev/video0 right.avi & wait'

这并没有改变问题,只是通过查看两个捕获文件的文件大小,我们发现它们差异极大

ubuntu@ubuntu:~/code-py$ ls -l
total 520
-rw-rw-r-- 1 ubuntu ubuntu 490368 Mar 18 14:05 left.avi
-rw-rw-r-- 1 ubuntu ubuntu   5686 Mar 18 14:05 right.avi

使用 OpenCV 的 capture.set(cv2.CAP_PROP_FPS, 15).

本质上是一样的

在第三步中,我像这样将视频大小减半

sh -c 'ffmpeg -f v4l2 -r 30 -s 320x240 -i /dev/video2 left.avi & ffmpeg -f v4l2 -r 30 -s 320x240 -i /dev/video0 right.avi & wait'

成功了!显然 Raspberry 中的某些东西被流入的字节数淹没了,但我如何弄清楚它是什么?总而言之,320x240 是一个非常糟糕的分辨率,我想知道是否有可能找到限制因素并提高它。

编辑:

这是 lsusb -t 的输出,相机插入 USB 3 端口:

/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 3, If 0, Class=Video, Driver=uvcvideo, 480M
        |__ Port 1: Dev 3, If 1, Class=Video, Driver=uvcvideo, 480M
        |__ Port 1: Dev 3, If 2, Class=Audio, Driver=snd-usb-audio, 480M
        |__ Port 1: Dev 3, If 3, Class=Audio, Driver=snd-usb-audio, 480M
        |__ Port 2: Dev 4, If 0, Class=Video, Driver=uvcvideo, 480M
        |__ Port 2: Dev 4, If 3, Class=Audio, Driver=snd-usb-audio, 480M
        |__ Port 2: Dev 4, If 1, Class=Video, Driver=uvcvideo, 480M
        |__ Port 2: Dev 4, If 2, Class=Audio, Driver=snd-usb-audio, 480M

30fps 的 640x480 数据的 RGB888 流占用以下带宽:

640 * 480 * 3 * 30 * 8    i.e. about 220 Mbits/s

这几乎是 480 Mbits/s USB 2 带宽的一半,因此您实际上无法 运行 2 个这样的流流畅地传输。

您可以使用 lsusb -t 命令检查 USB 带宽。这是插入 USB 2 端口的记忆棒 - 您可以看到它分配了 480 Mbits/s:

lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 3: Dev 3, If 0, Class=Mass Storage, Driver=usb-storage, 480M   <--- HERE

这是插入靠近以太网的蓝色 USB 3 端口的设备 - 分配 5Gbits/s:

lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
    |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M  <--- HERE
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M

关键字:USB 2、USB 3、带宽、速度分配。