This document applies to a known issue with the MIPI camera on youyeetoo R1 under the Ubuntu system.
For the firmware R1_UbuntuHdmitocsi_ImageV2V3.img, opening the system's built-in Cheese software shows No device found. For the firmware R1_UbuntuCamera_ImageV2V3.img, opening the system's built-in Cheese software shows There was an error playing video from the webcam. Regardless of which firmware is used, there is an issue where the system's Cheese app fails to display video.
For the R1_UbuntuHdmitocsi_ImageV2V3.img firmware, the kernel itself does not have a camera node added, so it is normal that no device is found. For the R1_UbuntuCamera_ImageV2V3.img firmware, the issue is a compatibility problem with Cheese on the Ubuntu system. The problem with Cheese is that it relies on an idealized, generic camera access workflow. Cheese does not actively specify a format, lock a resolution, or constrain the frame rate. Instead, it relies on GStreamer's caps negotiation mechanism to "guess" what format the camera supports. Since the camera's ISP output may include multiple formats and capabilities, automatic negotiation can easily fail, or it may negotiate a format that Cheese's internal processing pipeline cannot support, which directly causes the pipeline construction to fail.
Instead of using the system's Cheese app, use GStreamer directly, following the steps below.
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
The first run may fail, as shown below
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 ...
Running it again should work
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.
The following script is used to probe which camera device may have video stream output
#!/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."
Regardless of whether the camera is connected to csi0 or csi1, on the first probe right after power-on, typically only /dev/video-camera0 produces output. After that, probing /dev/video22, /dev/video23, and /dev/video-camera0 will all produce output.
To take a photo, you can use the following command, which saves the captured frame to a file named snapshot.jpg in the current directory
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
To record a video, you can use the following command, which saves the video to a file named record.mp4 in the current directory
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