RaspberryPi Zero W と libcamera で H264 ストリーミング

はじめに

これまで RPI Zero で映像ストリーミングの方法をいくつか試してみた.

ffmpeg はカメラモジュールの映像と USB マイクの音声をお手軽にミックスできるのは便利だが,遅延が大きすぎてカムロボの目としての実用は無理そう.mjpg streamer は低遅延である点については問題なさそうだが,RPI Zero が貧弱すぎて常に動作させておくのは辛いかもしれない.ということで今の所有実用面で mjpg streamer が優勢ではあるものの,動画ストリーミングといえば H264 なので最新 Bullseye で簡単にできる方法を模索してみた.

libcamera で動画ストリーミング

RPI のカメラ周りの仕様変更は OSS に大きな混乱をもたらしたように思うが,徐々に環境は整備されつつある様子.

未だにレガシーカメラの仕組みを使った記事がゴロゴロ転がっているが,RaspberryPi 公式ドキュメントによれば libcamera-vid コマンドで h264 のストリーミングができるらしい.ということでこれを試す.

Just a moment...

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 そろそろもとの値段で流通してくれ...

コメント

タイトルとURLをコピーしました