(※2022/9/24 追記: libcameraのv4l2-compat.を効かせるようにすればうまくいくようです。WebRTC momoを動かしてみた話↓
)
ちょっとよくわからないところが多いのですが、書かないと忘れるので書きます。
現象としては"とあるv4l2を使っているアプリケーション"がピクセルフォーマットを間違って設定して うまく動かないといったことでした。
RaspiOS(Bullseye)でLegacy cameraはDisable カメラは非公式のPibiger製のIMX219(素直に公式のやつを使っとくと良い?)
~/cameracheck $ uname -a Linux raspberrypi 5.15.32-v7+ #1538 SMP Thu Mar 31 19:38:48 BST 2022 armv7l GNU/Linux
libcameraでカメラ情報は
~/cameracheck $ libcamera-hello --list-cameras Available cameras ----------------- 0 : imx219 [3280x2464] (/base/soc/i2c0mux/i2c@1/imx219@10) Modes: 'SRGGB10_CSI2P' : 640x480 [206.65 fps - (1000, 752)/1280x960 crop] 1640x1232 [41.85 fps - (0, 0)/3280x2464 crop] 1920x1080 [47.57 fps - (680, 692)/1920x1080 crop] 3280x2464 [21.19 fps - (0, 0)/3280x2464 crop] 'SRGGB8' : 640x480 [206.65 fps - (1000, 752)/1280x960 crop] 1640x1232 [41.85 fps - (0, 0)/3280x2464 crop] 1920x1080 [47.57 fps - (680, 692)/1920x1080 crop] 3280x2464 [21.19 fps - (0, 0)/3280x2464 crop]
libcameraはちゃんと動作する。
libcamera-still -r -o test.jpg --width 640 --height 480
ここからv4l2を使ってみようとするがピクセルフォーマット一覧を出すとずらっと並んでしまう。
~/cameracheck $ v4l2-ctl -d /dev/video0 --list-formats ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: 'YUYV' (YUYV 4:2:2) [1]: 'UYVY' (UYVY 4:2:2) ... [11]: 'BA81' (8-bit Bayer BGBG/GRGR) ... [43]: 'Y12 ' (12-bit Greyscale) [44]: 'Y14P' (14-bit Greyscale (MIPI Packed)) [45]: 'Y14 ' (14-bit Greyscale)
これがトラブルの元らしく、これらが全部使えるというわけではないようだ(なにかのネゴシエーションで使えるようになる?)
V4L2 streaming - Raspberry Pi Forums
おとなしく、libcameraを使えということらしいが、それ以外のv4l2を使ってるレガシーのアプリケーションで、このリストを真に受けて一番先頭のYUYVをセットしてしまうアプリケーションではうまく動かないようです。
更に厄介なのはこの値はstatefulでセットすると次も使われるというところです。 なので、
libcamera-still -r -o test.jpg --width 640 --height 480
で正しい値をセットしてもらってからだとうまく動きました。 結局、使えるピクセルフォーマットはPixel Format : 'BA81' (8-bit Bayer BGBG/GRGR)らしい。
~/cameracheck $ v4l2-ctl -d /dev/video0 --all Driver Info: Driver name : unicam Card type : unicam Bus info : platform:3f801000.csi Driver version : 5.15.32 Capabilities : 0xa5a00001 Video Capture Metadata Capture Read/Write Streaming Extended Pix Format Device Capabilities Device Caps : 0x25200001 Video Capture Read/Write Streaming Extended Pix Format Media Driver Info: Driver name : unicam Model : unicam Serial : Bus info : platform:3f801000.csi Media version : 5.15.32 Hardware revision: 0x00000000 (0) Driver version : 5.15.32 Interface Info: ID : 0x03000006 Type : V4L Video Entity Info: ID : 0x00000004 (4) Name : unicam-image Function : V4L2 I/O Flags : default Pad 0x01000005 : 0: Sink Link 0x02000008: from remote pad 0x1000002 of entity 'imx219 10-0010': Data, Enabled, Immutable Priority: 2 Video input : 0 (unicam-image: ok) Format Video Capture: Width/Height : 3280/2464 Pixel Format : 'BA81' (8-bit Bayer BGBG/GRGR) Field : None Bytes per Line : 3296 Size Image : 8121344 Colorspace : Raw Transfer Function : Default (maps to None) YCbCr/HSV Encoding: Default (maps to ITU-R 601) Quantization : Default (maps to Full Range) Flags
v4l2を動かすコードは下記のようなサンプルコードがあり、ここからV4L2_BUF_TYPE_VIDEO_CAPTUREでrawのファイルを書き出すことに成功しました。
プログラムを書かないまでも正しい設定ならば
$ v4l2-ctl --stream-mmap=3 --stream-to=testrec.raw
でrawが取れる。
ffmpegの扱いにも難がありそうだがこれはまた別の話...。
宿題
V4L2 streaming - Raspberry Pi Forums で引用されている記事 と libcameraの実装(https://git.libcamera.org/libcamera/libcamera.git/)を見ると何が起きているかわかりそう。 メディアパイプラインの考え方