本文档适于youyeetoo R1在Ubuntu系统下的MIPI摄像头的已知问题。
对于固件R1_UbuntuHdmitocsi_ImageV2V3.img,打开系统的自带的软件Cheese,显示No device found,对于固件R1_UbuntuCamera_ImageV2V3.img,打开系统的自带的软件Cheese,显示There was an error playing video from the webcam,无论是哪个固件都存在使用系统的Cheese,存在不显示的问题。
对于R1_UbuntuHdmitocsi_ImageV2V3.img固件,其内核本身没有添加摄像头节点,所以没有找到设备是正常现象,而对于R1_UbuntuCamera_ImageV2V3.img固件,则是Ubuntu系统Cheese的兼容性问题,Cheese的问题在于它依赖一套理想化的、通用的摄像头访问流程,Cheese不会主动去指定格式、锁定分辨率或约束帧率,它依赖GStreamer的caps negotiation(能力协商)机制来“猜”摄像头支持什么格式,摄像头的ISP输出可能包含多种格式和能力,自动协商很可能失败,或者协商出一个Cheese内部处理管道无法兼容的格式,直接导致管道构建失败。
不使用系统的Cheese,改为使用GStreamer,具体按照下面的方式
sudo apt update
sudo apt install libv4l-0
gst-launch-1.0 v4l2src device=/dev/video22 ! video/x-raw, format=NV12, width=1280, height=720, framerate=30/1 ! autovideosink
第一次执行会有失败的情况,如下
youyeetoo@R1:~$ gst-launch-1.0 v4l2src device=/dev/video22 ! video/x-raw, format=NV12, width=1280, height=720, framerate=30/1 ! autovideosink
Setting pipeline to PAUSED ...
libEGL warning: DRI2: failed to authenticate
Using mplane plugin for capture
Pipeline is live and does not need PREROLL ...
Got context from element 'autovideosink0': gst.gl.GLDisplay=context, gst.gl.GLDisplay=(GstGLDisplay)"\(GstGLDisplayX11\)\ gldisplayx11-0";
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Failed to allocate required memory.
Additional debug info:
../sys/v4l2/gstv4l2src.c(759): gst_v4l2src_decide_allocation (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
Buffer pool activation failed
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
Additional debug info:
../libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming stopped, reason not-negotiated (-4)
Execution ended after 0:00:00.008641730
Setting pipeline to NULL ...
Freeing pipeline ...
重新执行即可
youyeetoo@R1:~$ gst-launch-1.0 v4l2src device=/dev/video22 ! video/x-raw, format=NV12, width=1280, height=720, framerate=30/1 ! autovideosink
Setting pipeline to PAUSED ...
libEGL warning: DRI2: failed to authenticate
Using mplane plugin for capture
libv4l2: error getting pixformat: Invalid argument
Pipeline is live and does not need PREROLL ...
Got context from element 'autovideosink0': gst.gl.GLDisplay=context, gst.gl.GLDisplay=(GstGLDisplay)"\(GstGLDisplayX11\)\ gldisplayx11-0";
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Redistribute latency...
0:00:06.9 / 99:99:99.
以下脚本用于探测哪个摄像头有可能有视频流输出
#!/bin/bash
# enumerate_video_devices.sh
# Enumerate /dev/videoX one by one and test NV12 @ 1280x720 with GStreamer
TIMEOUT=8 # Max seconds to test each device
echo "Starting video device enumeration (max ${TIMEOUT} seconds per device)"
echo "=================================================="
echo "Available devices:"
ls /dev/video* 2>/dev/null | tr '\n' ' '
echo
echo "=================================================="
for dev in /dev/video*; do
[ -e "$dev" ] || continue
echo
echo ">>> Testing device: $dev"
echo "--------------------------------------------------"
timeout "$TIMEOUT" gst-launch-1.0 v4l2src device="$dev" ! \
video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! \
autovideosink
rc=$?
echo "--------------------------------------------------"
case $rc in
0)
echo "OK: $dev test ended (exit code 0, may have ended normally)"
;;
124)
echo "OK: $dev test timed out (${TIMEOUT}s), likely streaming successfully!"
;;
130)
echo "STOPPED: $dev interrupted by Ctrl+C"
;;
*)
echo "FAIL: $dev failed (exit code $rc)"
;;
esac
read -r -p "Press Enter to continue to the next device (type q to quit)..." key
if [[ "$key" == "q" ]]; then
echo "User quit."
exit 0
fi
done
echo
echo "Enumeration complete."
不论摄像头是接在csi0还是csi1在上电开机的第一次探测的结果大概是,只有/dev/video-camera0有输出,之后的探测/dev/video22,/dev/video23,/dev/video-camera0这三个都会有输出
拍照可以使用以下命令,将摄像头捕获到的画面保存到当前目录下的snapshot.jpg文件中
gst-launch-1.0 v4l2src device=/dev/video22 num-buffers=1 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! videoconvert ! jpegenc ! filesink location=snapshot.jpg
录制视频可以使用以下命令,视频会保存在当前目录下的record.mp4文件中
gst-launch-1.0 -e v4l2src device=/dev/video22 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! videoconvert ! x264enc tune=zerolatency speed-preset=ultrafast ! h264parse ! qtmux ! filesink location=record.mp4