はじめに
これまで RPI Zero で映像ストリーミングの方法をいくつか試してみた.
ffmpeg はカメラモジュールの映像と USB マイクの音声をお手軽にミックスできるのは便利だが,遅延が大きすぎてカムロボの目としての実用は無理そう.mjpg streamer は低遅延である点については問題なさそうだが,RPI Zero が貧弱すぎて常に動作させておくのは辛いかもしれない.ということで今の所有実用面で mjpg streamer が優勢ではあるものの,動画ストリーミングといえば H264 なので最新 Bullseye で簡単にできる方法を模索してみた.
libcamera で動画ストリーミング
RPI のカメラ周りの仕様変更は OSS に大きな混乱をもたらしたように思うが,徐々に環境は整備されつつある様子.
未だにレガシーカメラの仕組みを使った記事がゴロゴロ転がっているが,RaspberryPi 公式ドキュメントによれば libcamera-vid コマンドで h264 のストリーミングができるらしい.ということでこれを試す.
libcamera-vid の説明によると,このコマンドはデフォルトで RPI の H264 ハードウェアエンコーダを使用するらしい.mgpg streamer の場合は CPU リソースを多く使うので RPI Zero 2 を利用すれば性能改善する可能性があるかもしれないが,libcamera-vid なら H264 ハードウェアエンコーダとして利用されている Broadcom VideoCore IV (理論値で 24GFLOPSらしい)はどちらも共通なので RPI Zero でも性能差異はあまり無いかもしれない.昨今 RPI Zero 2 が入手困難な状況が続いているので比較しようもない.
いつもどおり環境は次の通り.
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
$ uname -r
5.15.61+
$ cat /sys/firmware/devicetree/base/model
Raspberry Pi Zero W Rev 1.1
早速 libcamera-vid のストリーミングを試してみる.構成は,以前の ffmpeg を使った H264 ストリーミングと同じく,RPI Zero の カメラ映像を VLC Media Player で見る形になる.
v4l2-ctl で利用可能なカメラデバイスを確認すると次の通り.
$ v4l2-ctl --list-device
unicam (platform:20801000.csi):
/dev/video0
/dev/media3
bcm2835-codec-decode (platform:bcm2835-codec):
/dev/video10
/dev/video11
/dev/video12
/dev/video18
/dev/video31
/dev/media2
bcm2835-isp (platform:bcm2835-isp):
/dev/video13
/dev/video14
/dev/video15
/dev/video16
/dev/video20
/dev/video21
/dev/video22
/dev/video23
/dev/media0
/dev/media1
これらのカメラデバイスの内,カメラ側の h264 ハードウェアエンコーダが利用できるのは video11.これを利用できれば RPI の VideoCore IV の負担を軽減できるはず.
$ for dev in $(ls /dev/video*); do echo $dev; v4l2-ctl --device $dev --list-formats; done
<略>
$ v4l2-ctl --device /dev/video11 --list-formats
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture Multiplanar
[0]: 'H264' (H.264, compressed)
<略>
一方で libcamera-vid で利用できるカメラは次のコマンドで確認できる.この結果だと video11 が使えるのかよくわからない.
$ libcamera-vid --list-camera
Available cameras
-----------------
0 : ov5647 [2592x1944] (/base/soc/i2c0mux/i2c@1/ov5647@36)
Modes: 'SGBRG10_CSI2P' : 640x480 [58.92 fps - (16, 0)/2560x1920 crop]
1296x972 [43.25 fps - (0, 0)/2592x1944 crop]
1920x1080 [30.62 fps - (348, 434)/1928x1080 crop]
2592x1944 [15.63 fps - (0, 0)/2592x1944 crop]
ということで,よくわからないことがわかったので,libcamera-vid でストリーミングしてみる.コマンドは次の通り.動かしてみると一応 video11 を使っているっぽい.
$ libcamera-vid -t 0 --inline --listen -o tcp://0.0.0.0:8888 --rotation 180 --verbose
<略>
Video setup complete
Opened H264Encoder on /dev/video11 as fd 25
<略>
コマンドを実行したら VLCMedia Player 側で RPI のネットワークストリームを開く.
tcp/h264://$(IP_ADDR):$(PORT)
遅延時間は結構ばらつきがあるようで,測定時は大体 5 秒くらい.ただ映像を垂れ流す用途なら問題なさそうだけど,カムロボの目として使うなら極力遅延は小さくしたいところ.
CPU 使用率は 60% くらい.mjpg streamer より CPU 負荷は軽減されているものの,もうちょい遅延を小さくしたいところ.
おわりに
ここまで 3 つの方法で映像ストリーミングを試してみたが,やっぱり mjpg-streamer が一番遅延がなくていいかもしれない.
RPI Zero 2 そろそろもとの値段で流通してくれ...
コメント