しゅれログ

備忘録です。

libcameraのv4l2 compatibleを通してraw streamを取得

環境: Raspi Zero 2 W / RaspiOS Bullseye / disable legacy mode

v4l2-ctlで使えるフォーマット一覧を出すとずらっと出るが、すべて使えるわけではない。

~/cameracheck $ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture

        [0]: 'YUYV' (YUYV 4:2:2)
                Size: Stepwise 16x16 - 16376x16376 with step 1/1
        [1]: 'UYVY' (UYVY 4:2:2)
        ....
        [43]: 'Y12 ' (12-bit Greyscale)
                Size: Stepwise 16x16 - 16376x16376 with step 1/1
        [44]: 'Y14P' (14-bit Greyscale (MIPI Packed))
                Size: Stepwise 16x16 - 16376x16376 with step 1/1
        [45]: 'Y14 ' (14-bit Greyscale)
                Size: Stepwise 16x16 - 16376x16376 with step 1/1

libcameraにv4l2 compatibleの機能があり、そこを通すと下記のようにうまいことやってくれるっぽい

Documentation — libcamera

使うにはLD_PRELOADを使う

export LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/v4l2-compat.so

絞られる

~/cameracheck $  v4l2-ctl -d /dev/video0 --list-formats
[1:38:27.462853673] [6401]  INFO Camera camera_manager.cpp:293 libcamera v0.0.0+3777-69ae75b0
[1:38:27.500574932] [6402]  WARN RPI raspberrypi.cpp:1252 Mismatch between Unicam and CamHelper for embedded data usage!
[1:38:27.501922072] [6402]  INFO RPI raspberrypi.cpp:1368 Registered camera /base/soc/i2c0mux/i2c@1/imx219@10 to Unicam device /dev/media3 and ISP device /dev/media0
ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture

        [0]: 'NV21' (Y/CrCb 4:2:0)
        [1]: 'YU12' (Planar YUV 4:2:0)
        [2]: 'NV12' (Y/CbCr 4:2:0)
        [3]: 'YV12' (Planar YVU 4:2:0)
        [4]: 'XB24' (32-bit RGBX 8-8-8-8)
        [5]: 'RGB3' (24-bit RGB 8-8-8)
        [6]: 'BGR3' (24-bit BGR 8-8-8)
        [7]: 'XR24' (32-bit BGRX 8-8-8-8)
        [8]: 'RGBP' (16-bit RGB 5-6-5)
        [9]: 'YVYU' (YVYU 4:2:2)
        [10]: 'YUYV' (YUYV 4:2:2)
        [11]: 'VYUY' (VYUY 4:2:2)
        [12]: 'UYVY' (UYVY 4:2:2)
~/cameracheck $ 

↓事前にpixcel formatを設定しても無駄。コマンドごとに設定は外されるらしい。(コマンドとしては正しい姿とも言える)

raspberrypi:~/cameracheck $  v4l2-ctl --set-fmt-video=width=1296,height=972,pixelformat=10
[1:17:19.099511110] [6020]  INFO Camera camera_manager.cpp:293 libcamera v0.0.0+3777-69ae75b0
[1:17:19.152740124] [6021]  WARN RPI raspberrypi.cpp:1252 Mismatch between Unicam and CamHelper for embedded data usage!
[1:17:19.154276740] [6021]  INFO RPI raspberrypi.cpp:1368 Registered camera /base/soc/i2c0mux/i2c@1/imx219@10 to Unicam device /dev/media3 and ISP device /dev/media0
[1:17:19.157278514] [6020]  INFO Camera camera.cpp:1029 configuring streams: (0) 1296x972-YUYV
[1:17:19.158532838] [6021]  INFO RPI raspberrypi.cpp:759 Sensor: /base/soc/i2c0mux/i2c@1/imx219@10 - Selected sensor format: 1640x1232-SBGGR10_1X10 - Selected unicam format: 1640x1232-pBAA
raspberrypi:~/cameracheck $ 

ストリームを撮って ffmepgでjpegにする

raspberrypi:~/cameracheck $ v4l2-ctl --stream-mmap=3 --stream-to=testrec.raw --stream-count=1 (★ここでフォーマットを設定したら正しく設定されるようだ)
[1:18:30.718666516] [6084]  INFO Camera camera_manager.cpp:293 libcamera v0.0.0+3777-69ae75b0
[1:18:30.771650791] [6085]  WARN RPI raspberrypi.cpp:1252 Mismatch between Unicam and CamHelper for embedded data usage!
[1:18:30.772933657] [6085]  INFO RPI raspberrypi.cpp:1368 Registered camera /base/soc/i2c0mux/i2c@1/imx219@10 to Unicam device /dev/media3 and ISP device /dev/media0
★↓800x600-NV12がConfigureされている(一番上にあるから?)
[1:18:30.816269692] [6084]  INFO Camera camera.cpp:1029 configuring streams: (0) 800x600-NV12
[1:18:30.817259537] [6085]  INFO RPI raspberrypi.cpp:759 Sensor: /base/soc/i2c0mux/i2c@1/imx219@10 - Selected sensor format: 1640x1232-SBGGR10_1X10 - Selected unicam format: 1640x1232-pBAA
<
raspberrypi:~/cameracheck $ ffmpeg -f image2 -c:v rawvideo -pix_fmt nv12 -s:v 800x600 -i testrec.raw image-%04d.jpg
ffmpeg version N-108133-gf976ed7fcf Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 10 (Raspbian 10.2.1-6+rpi1)
  configuration: --prefix=/home/heyanaohiro/ffmpeg_build --pkg-config-flags=--static --extra-cflags=-I/home/heyanaohiro/ffmpeg_build/include --extra-ldflags=-L/home/heyanaohiro/ffmpeg_build/lib --extra-libs='-lpthread -lm' --ld=g++ --bindir=/home/heyanaohiro/bin --enable-gpl --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libx264 --enable-libx265
  libavutil      57. 36.101 / 57. 36.101
  libavcodec     59. 43.100 / 59. 43.100
  libavformat    59. 31.100 / 59. 31.100
  libavdevice    59.  8.101 / 59.  8.101
  libavfilter     8. 49.100 /  8. 49.100
  libswscale      6.  8.112 /  6.  8.112
  libswresample   4.  9.100 /  4.  9.100
  libpostproc    56.  7.100 / 56.  7.100
Input #0, image2, from 'testrec.raw':
  Duration: 00:00:00.04, start: 0.000000, bitrate: N/A
  Stream #0:0: Video: rawvideo (NV12 / 0x3231564E), nv12, 800x600, 25 fps, 25 tbr, 25 tbn
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[swscaler @ 0x2f93380] [swscaler @ 0x2f9c620] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x2f93380] [swscaler @ 0x2fc6ab0] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x2f93380] [swscaler @ 0x2ff13f0] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x2f93380] [swscaler @ 0x301bd30] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0x2f93380] [swscaler @ 0x30467e0] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to 'image-%04d.jpg':
  Metadata:
    encoder         : Lavf59.31.100
  Stream #0:0: Video: mjpeg, yuvj420p(pc, progressive), 800x600, q=2-31, 200 kb/s, 25 fps, 25 tbn
    Metadata:
      encoder         : Lavc59.43.100 mjpeg
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A
frame=    1 fps=0.0 q=5.9 Lsize=N/A time=00:00:00.00 bitrate=N/A speed=   0x    0x    
video:28kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
~/cameracheck $ 

下記のようなコマンド(h264_v4l2m2m)も上手くいく気配があるので謎が解けていきそうだが、今日のところは終わり

ffmpeg -f rawvideo -pix_fmt yuv420p -video_size 640x480 -framerate 30 -i 'testrec.raw' -f mp4 -c:v h264_v4l2m2m -b:v 300k 'testrec.mp4'