最初は、64ビット版のRaspberry Pi OSにて、Shinobi CCTVを動かして。防犯カメラ、録画機能に加えて、yoloのオブジェクト認識等を動かそうと思ったのですが。
実際に試したところ、動かせるものの、負荷が重すぎてダメでした。Raspberry Piではなく、より性能の高いPCが必要とわかりました。
そのような理由から、カメラモジュールを搭載したRaspberry Pi 3または4は、ハードウェアエンコードに対応したネットワークカメラとして動かすことで、有効活用したいと思います。
64ビット版のRaspberry Pi OSをRaspberry Pi 3または4で動かしまして。H.264ハードウェアエンコードに対応した、ストリーミングの方法を記録しておこうと思います。
目次
Raspberry Pi OS+カメラモジュールで動画ストリーミング
Pi 3またはPi 4はエンコード+ストリーミングで精一杯?
そもそも、Raspberry Pi 3または4で、ハードウェアH.264エンコードするには。GPUメモリーが128GB必要であることに加えて、解像度も1080pまでのようです。
カメラモジュールを取り付けて、ハードウェアエンコードしながら、ストリーミングする。正直、性能的にそれでほぼ一杯な気がします。
過去に、Raspberry Piで防犯カメラ機能を持つシステムを構築してみたものの。
性能が不足している感がありました。microSDカードも半年くらいで壊れましたし。
そして64ビット版のRaspberry Pi OSを使用しても、性能不足は同じでした。1台のRaspberry Pi本体で、動体検知やオブジェクト認識、録画等の機能と、カメラ接続+エンコードを両立するのは難しいと思います。
というわけで。Pi 3またはPi 4にカメラモジュールを接続して、ストリーミング、つまり動画の入力デバイスとして使用する方法を考えたいと思います。
ストリーミングの使用例
Windows PCでVLCを起動し、「ネットワークストリームを開く」からRaspberry Piに接続してみました。
このような感じで、カメラモジュールで撮影した映像を見ることが可能です。
またVLCではなく、CCTVカメラシステムから接続することで、録画や動体検出、顔認識やオブジェクト認識等も可能になります。そちらは別途、システムを構築したいと思います。
まずは、Raspberry Piの電源を入れると、このような感じでRTSPで接続できる、という状態に設定したいと思います。
OSは64ビット版を使用
使用するOSは、Raspberry Pi OS Lite(64bit)を選択しました。
書き込むメディアは、microSDカードまたはUSBメモリー、USBスティックSSDになります。
Raspberry Pi 4は、ブートローダーの更新で、USB起動が可能になります。
Raspberry Pi 3 Model B+は、最初からUSB起動が可能です。
Model B(プラスなし)の場合、OTPレジスタを書き換えることで、USB起動が可能になります。
microSDカードは寿命が短いため。USBメモリーでRaspberry Pi 3を起動して、ストリーミングサーバとして使用するのは悪くない感じがします。
カメラモジュールの接続
カメラモジュールの接続後、raspi-configでなにか設定を変更する必要はありません。
こちらの記事のように「libcamera-still」コマンドで、カメラモジュールが正しく接続されているか確認が可能です。
静的IPアドレス設定
sudo vi /etc/dhcpcd.conf
44行目付近のコメントを外しまして。
静的IPアドレスを設定しました。再起動は、次のraspi-config後に。
GPUメモリーの容量を128に変更
raspi-configを起動して、GPUメモリーの容量を変更します。
sudo raspi-config
「4 Performance Options」
「P2 GPU Memory」
カメラモジュールを1台接続する場合、128を入力しました。2台の場合は256になります。
raspi-configを終了すると再起動されて、設定変更が反映されます。
OS更新とツールのインストール
OSを更新後、VLCをインストールしました。
sudo apt update
sudo apt upgrade -y
sudo apt install -y vlc
カメラモジュールの動画をストリーミングするコマンド
vlcのインストールが完了しましたら。次のコマンドで、ストリーミングを開始できます。
/usr/bin/libcamera-vid -t 0 --inline -o - \
--level 4.2 --denoise cdn_off \
--width 1920 --height 1080 \
| /usr/bin/cvlc stream:///dev/stdin \
--sout='#rtp{sdp=rtsp://:8554/stream1}' :demux=h264 \
--preferred-resolution 1080
ストリームに接続する場合は、VLC等から次のURLを開きます。
rtsp://<Raspberry PiのIPアドレスまたはホスト名.local>:8554/stream1
解像度は1920×1080、FullHD、ハードウェアエンコードが有効なサイズを指定しました。
ハードウェアエンコードを行わない場合は、libcamera-vidコマンドではなく、libcamera-rawコマンドを使用することで、NULLデバイスを指定できるそうです。
コマンドが正しく動作することを確認できましたら。Raspberry Pi起動後に、自動的にストリーミングが開始するように設定したいと思います。
ストリーミングを自動開始する設定
libcameraについての情報はこちらです。
こちらの情報を参考に、ストリーミングのシェルスクリプトを作成しました。
touch video-stream.sh
chmod +x video-stream.sh
cat << EOF | tee -a video-stream.sh
#!/bin/sh
/usr/bin/libcamera-vid -t 0 --inline -o - \
--level 4.2 --denoise cdn_off \
--width 1920 --height 1080 \
| /usr/bin/cvlc stream:///dev/stdin \
--sout='#rtp{sdp=rtsp://:8554/stream1}' :demux=h264 \
--preferred-resolution 1080
EOF
起動時、こちらが動作するように、systemdを設定します。
こちらの記事を参考にさせて頂きました。
video-stream.serviceファイルを作成します。
sudo vi /etc/systemd/system/video-stream.service
次の内容になりますが。cvlcコマンドはroot権限では動かないため、ユーザを指定しています。「hide」の部分は、使用するユーザに書き換えてください。
[Unit]
Description=Video Stream service.
Wants=network.target
After=syslog.target network-online.target
[Service]
Type=simple
ExecStart=/home/hide/video-stream.sh
Restart=on-failure
RestartSec=10
KillMode=process
User=hide
Group=hide
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable video-stream.service --now
再起動してから、VLC等でストリーミング配信されるか確認してみてください。
Raspberry Pi カメラのチューニングとコーデック調整
※23.9.9追記:
使用するカメラモジュールや、ストリーミングの目的の違いによって、カメラ映像の読み込みオプションやストリーミングオプションの調整が可能です。
そのあたりの覚書を記録させて頂こうと思います。
/boot/config.txtのチューニング
クロックが低下しないforce_turboモード有効
raspberry piカメラでストリーミングを行う際、force_turboを有効にすることで、ビデオキャプチャ中のCPUクロックの低下を防げるそうです。
/boot/config.txtに、次の1行を追加します。
force_turbo=1
GPUオーバークロック
Raspberry Pi 4は、下記のオプションでGPUのオーバークロックが可能=ストリーミング時の画質の安定化が可能です。
gpu_freq=550
カメラモジュールの自動認識設定の調整
既定では、/boot/config.txtのcamera_auto_detect=1、カメラモジュールの自動認識が有効かと思います。
使用するカメラモジュールによっては、こちらを無効化して、dtoverlay=にてドライバを直接指定したほうが画質が向上する場合があるそうです。
Raspberry Pi純正のカメラモジュールを使用する場合は、既定の設定で問題無いと思います。
ストリーミングコマンドの調整
libcamera-vid h.264ハードウェアエンコード + vlc RSTP
Raspberry Piのh.264ハードウェアエンコードを行う場合のlibcamera-vidオプションは、–level 4.2 –denoise cdn_offが必要のようです。
/usr/bin/libcamera-vid -n -t 0 --inline -o - \
--level 4.2 --denoise cdn_off \
--width 1920 --height 1080 \
| /usr/bin/cvlc stream:///dev/stdin \
--sout='#rtp{sdp=rtsp://:8554/stream1}' :demux=h264 \
--preferred-resolution 1080
VLCでストリーミングを見る場合のURLは下記になります。pi4.localはRaspberry Piのホスト名になります。
rtsp://pi4.local:8554/stream1
libcamera-vid h.264ハードウェアエンコード + vlc http
RSTPに対応していないビューアを使用する場合、次のオプションでhttpストリーミングが可能です。
/usr/bin/libcamera-vid -n -t 0 --inline -o - \
--level 4.2 --denoise cdn_off \
--width 1920 --height 1080 \
| /usr/bin/cvlc stream:///dev/stdin \
--sout='#std{access=http, mux=ts, dst=:8554/stream1}' :demux=h264 \
--preferred-resolution 1080
VLCから接続するためのURLはhttpになります。
http://pi4.local:8554/stream1
libcamera-vid Motion Jpeg + vlc http
h.264ではなく、Motion JPEGでストリーミングする場合は下記のオプションになります。
/usr/bin/libcamera-vid -n -t 0 --inline -o - \
--codec mjpeg --denoise cdn_off \
--width 1920 --height 1080 \
| /usr/bin/cvlc stream:///dev/stdin \
--sout='#std{access=http, mux=ts, dst=:8554/stream1}' :demux=mjpeg \
--preferred-resolution 1080
URLは同じです。
http://pi4.local:8554/stream1
ffmpegは別途ストリーミングサーバが必要?
ffmpegはrtspによるストリーミング機能を持っていますが、サーバとしての待受(listen)機能が無いように見えます。
# 使用可能なフォーマットの確認
ffmpeg -pix_fmts
# コーデックの確認
ffmpeg -codecs
# フォーマットの確認
ffmpeg -formats
rtspを使用したい場合の例
ffmpeg -re -i - -y -f rtp -rtsp_transport tcp rtp://0.0.0.0:8554/stram1
別途、サーバのプロセスを作る必要がある感じです。
libcamera-vidの覚書
使用できるcodec
Raspberry Pi 3 Model B + Raspberry Pi OS 64ビット版で確認
- h264(既定)
- mjpeg
- yuv420
既定でハードウェアエンコードが有効ですが。
mpeg等にソフトウェアエンコードしたい場合は、yuv420やmjpegでエンコードアプリにパイプで繋げる感じでしょうか。
カメラモジュールごとのチューニング
接続するカメラモジュールの種類ごとに、libcamera-vidにチューニングオプションを追加することが可能です。
- V1 camera (OV5647)
- V2 camera (IMX219)
- HQ camera (IMX477)
- GS camera (IMX296)
- Camera Module 3 (IMX708)
チューニングオプションに、下記のファイルを指定します。
--tuning-file /usr/share/libcamera/ipa/rpi/vc4/imx708.json
# または
--tuning-file /usr/share/libcamera/ipa/rpi/vc4/imx708_wide.json
FullHD解像度でh.264ハードウェアエンコード、RTSPストリーミング、カメラモジュール3に画質を最適化するコマンドは下記になります。
/usr/bin/libcamera-vid -n -t 0 --inline -o - \
--level 4.2 --denoise cdn_off \
--width 1920 --height 1080 \
--tuning-file /usr/share/libcamera/ipa/rpi/vc4/imx708_wide.json \
| /usr/bin/cvlc stream:///dev/stdin \
--sout='#rtp{sdp=rtsp://:8554/stream1}' :demux=h264 \
--preferred-resolution 1080
それと、赤外線フィルがが無いカメラの場合、NO-IR版の最適化ファイルを使用するほうが良さそうです。
防犯カメラシステムを作る場合、Raspberry Pi+カメラモジュールで作るのは悪くないと思っていたのですが、性能が不足していました。
では32ビットOSではなく、64ビットOSでは?試してみましたが、性能不足を補うことはできませんでした。
さらに、microSDカードで動画を録画すると、半年から1年で、microSDカードが壊れてしまいます。実用性は低い状況でした。
実用性がより高い構成を考えますと。
- Raspberry Pi 3 + USBメモリーで64ビット版OS起動 +カメラモジュール = ハードウェアエンコードが有効なストリーミング = ネットワークカメラとして使う
- 録画や動体検出は、より性能が高い別のPCで行う
という構成で防犯カメラシステムを作る方が、性能不足・安定性(永く使える)が高い感じがします。
カメラ部分は構築できましたので、次はCCTVカメラシステム、録画側を作りたいと思います。
クラスタで動かそうかしら・・・。
※23.9.3追記:dockerではなくRaspberry Pi 4に直接Shinobiをインストールしてみました。