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、带宽、速度分配。
我正在尝试使用 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、带宽、速度分配。