備忘録

趣味に生きるオタクの備忘録

RaspiとWebカメラでIPで見れるカメラ的なのが欲しい

題名の通り。
監視カメラみたいな使い方とか、よくあるRaspiの使い方を試してみたくなった感じ。

良い感じのオープンソース無いかなぁ。。。と思っていたらありました。

v4l2rtspserver
github.com

V4L2だから、UVCのカメラを繋いだら、なんのことなくUDP/RTPで配信できちゃうのかな?

ということでお試し。
サクっとテストしたいだけなので、RaspbianOSをmicroSDに焼いてRaspberryPi3B+でテスト。
クロスビルドしろとかいうツッコミが入るかもしれませんが、本当にお試しなので実機上で。



使ったカメラはコレ。
Logitech, Inc. Webcam C270

HD 720p (1280 x 720) フレームレート : 最大30 フレーム

今回の騒ぎになる前から適当にストックされてました。。。

Raspbianを焼いて、スタートメニュー→Prerefernce→Raspberry Pi configから、SSHをEnableにしておきます。

USBカメラ見えてるかなぁ・・・と思いlsusbコマンドで確認すると、フツーに認識されてました。

pi@raspberrypi:~ $ lsusb
Bus 001 Device 009: ID 046d:0825 Logitech, Inc. Webcam C270
Bus 001 Device 005: ID 0424:7800 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
:
pi@raspberrypi:~ $ lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 3, If 0, Class=Hub, Driver=hub/3p, 480M
|__ Port 1: Dev 5, If 0, Class=Vendor Specific Class, Driver=lan78xx, 480M
|__ Port 2: Dev 9, If 0, Class=Video, Driver=uvcvideo, 480M
|__ Port 2: Dev 9, If 3, Class=Audio, Driver=snd-usb-audio, 480M
|__ Port 2: Dev 9, If 1, Class=Video, Driver=uvcvideo, 480M
|__ Port 2: Dev 9, If 2, Class=Audio, Driver=snd-usb-audio, 480M

Audioとして見えてるのがあるのは、マイクを内蔵しているからですね。

さて、話を戻すとv4l2rtspserverを動かさないといけません。
gitにあるREADMEの依存関係をみると、

Dependencies
liblivemedia-dev License LGPL > live.2012.01.07 (need StreamReplicator)
libv4l2cpp Unlicense
liblog4cpp5-dev License LGPL (optional) If liblog4cpp5-dev is not present, a simple log using std::cout is used.
libasound2-dev Licence LGPL (optional) If libasound2-dev is not present in the build environment, there will have no audio support.

liblivemedia-devと、libv4l2cppは必須っぽいですね。

ビルドする必要あるかな?と思いましたが、liblivemedia-devはaptで取れるっぽいです。

pi@raspberrypi:~ $ sudo apt install liblivemedia-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
liblivemedia-dev
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 166 kB of archives.
After this operation, 803 kB of additional disk space will be used.
Get:1 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf liblivemedia-dev armhf 2018.11.26-1.1 [166 kB]
Fetched 166 kB in 1s (128 kB/s)
Selecting previously unselected package liblivemedia-dev:armhf.
(Reading database ... 93514 files and directories currently installed.)
Preparing to unpack .../liblivemedia-dev_2018.11.26-1.1_armhf.deb ...
Unpacking liblivemedia-dev:armhf (2018.11.26-1.1) ...
Setting up liblivemedia-dev:armhf (2018.11.26-1.1) ...

v4l2の方はダメですね。

pi@raspberrypi:~ $ sudo apt install libv4l2cpp
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package libv4l2cpp
pi@raspberrypi:~ $

ビルドしましょう。

pi@raspberrypi:~/build $ git clone https://github.com/mpromonet/libv4l2cpp
Cloning into 'libv4l2cpp'...
remote: Enumerating objects: 90, done.
remote: Counting objects: 100% (90/90), done.
remote: Compressing objects: 100% (63/63), done.
remote: Total 881 (delta 58), reused 54 (delta 27), pack-reused 791
Receiving objects: 100% (881/881), 178.68 KiB | 493.00 KiB/s, done.
Resolving deltas: 100% (593/593), done.
pi@raspberrypi:~/build $ ls
libv4l2cpp
pi@raspberrypi:~/build $ cd libv4l2cpp/
pi@raspberrypi:~/build/libv4l2cpp $ make
g++ -c -o src/V4l2Access.o src/V4l2Access.cpp -W -pthread -g -pipe -I inc
g++ -c -o src/V4l2MmapDevice.o src/V4l2MmapDevice.cpp -W -pthread -g -pipe -I inc
g++ -c -o src/V4l2Capture.o src/V4l2Capture.cpp -W -pthread -g -pipe -I inc
g++ -c -o src/V4l2Device.o src/V4l2Device.cpp -W -pthread -g -pipe -I inc
g++ -c -o src/V4l2ReadWriteDevice.o src/V4l2ReadWriteDevice.cpp -W -pthread -g -pipe -I inc
g++ -c -o src/V4l2Output.o src/V4l2Output.cpp -W -pthread -g -pipe -I inc
g++ -c -o src/logger.o src/logger.cpp -W -pthread -g -pipe -I inc
ar rcs libv4l2wrapper.a src/V4l2Access.o src/V4l2MmapDevice.o src/V4l2Capture.o src/V4l2Device.o src/V4l2ReadWriteDevice.o src/V4l2Output.o src/logger.o
pi@raspberrypi:~/build/libv4l2cpp $ make install
mkdir -p /usr/include/libv4l2cpp/
mkdir: cannot create directory ‘/usr/include/libv4l2cpp/’: Permission denied
make: *** [Makefile:30: install] Error 1
pi@raspberrypi:~/build/libv4l2cpp $ sudo make install
mkdir -p /usr/include/libv4l2cpp/
install -D -m 0755 inc/*.h /usr/include/libv4l2cpp/
install -D -m 0755 *.a /usr/lib
pi@raspberrypi:~/build/libv4l2cpp $


本題のv4l2rtspserverをgit cloneしてビルドしていきます。

pi@raspberrypi:~/build $ git clone https://github.com/mpromonet/v4l2rtspserver
Cloning into 'v4l2rtspserver'...
remote: Enumerating objects: 142, done.
remote: Counting objects: 100% (142/142), done.
remote: Compressing objects: 100% (106/106), done.
remote: Total 2061 (delta 69), reused 74 (delta 28), pack-reused 1919
Receiving objects: 100% (2061/2061), 645.28 KiB | 908.00 KiB/s, done.
Resolving deltas: 100% (1315/1315), done.
pi@raspberrypi:~/build $ cd
libv4l2cpp/ v4l2rtspserver/
pi@raspberrypi:~/build $ cd v4l2rtspserver/
pi@raspberrypi:~/build/v4l2rtspserver $ ;s

  • bash: syntax error near unexpected token `;'

pi@raspberrypi:~/build/v4l2rtspserver $ ls
CMakeLists.txt Dockerfile.rpi index.html nanopi.toolchain snap v4l2wrapper
debian hls.js LICENSE raspberry.toolchain src
Dockerfile inc mips.toolchain README.md v4l2rtspserver.service.in
pi@raspberrypi:~/build/v4l2rtspserver $ cmake . && make

  • bash: cmake: command not found

あらら。Cmakeいるんですね。

pi@raspberrypi:~/build/v4l2rtspserver $ sudo apt install cmake
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
cmake-data libjsoncpp1 librhash0 libuv1
Suggested packages:
cmake-doc ninja-build
The following NEW packages will be installed:
cmake cmake-data libjsoncpp1 librhash0 libuv1
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 4,330 kB of archives.
After this operation, 21.8 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf cmake-data all 3.13.4-1 [1,476 kB]
Get:2 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf libjsoncpp1 armhf 1.7.4-3 [66.2 kB]
Get:3 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf librhash0 armhf 1.3.8-1 [132 kB]
Get:4 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf libuv1 armhf 1.24.1-1 [96.7 kB]
Get:5 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian buster/main armhf cmake armhf 3.13.4-1 [2,559 kB]
Fetched 4,330 kB in 11s (403 kB/s)
Selecting previously unselected package cmake-data.
(Reading database ... 93735 files and directories currently installed.)
Preparing to unpack .../cmake-data_3.13.4-1_all.deb ...
Unpacking cmake-data (3.13.4-1) ...
Selecting previously unselected package libjsoncpp1:armhf.
Preparing to unpack .../libjsoncpp1_1.7.4-3_armhf.deb ...
Unpacking libjsoncpp1:armhf (1.7.4-3) ...
Selecting previously unselected package librhash0:armhf.
Preparing to unpack .../librhash0_1.3.8-1_armhf.deb ...
Unpacking librhash0:armhf (1.3.8-1) ...
Selecting previously unselected package libuv1:armhf.
Preparing to unpack .../libuv1_1.24.1-1_armhf.deb ...
Unpacking libuv1:armhf (1.24.1-1) ...
Selecting previously unselected package cmake.
Preparing to unpack .../cmake_3.13.4-1_armhf.deb ...
Unpacking cmake (3.13.4-1) ...
Setting up libuv1:armhf (1.24.1-1) ...
Setting up librhash0:armhf (1.3.8-1) ...
Setting up cmake-data (3.13.4-1) ...
Setting up libjsoncpp1:armhf (1.7.4-3) ...
Setting up cmake (3.13.4-1) ...
Processing triggers for man-db (2.8.5-2) ...
Processing triggers for libc-bin (2.28-10+rpi1) ...
pi@raspberrypi:~/build/v4l2rtspserver $

リトライ。

pi@raspberrypi:~/build/v4l2rtspserver $ cmake . && make

    • The C compiler identification is GNU 8.3.0
    • The CXX compiler identification is GNU 8.3.0
    • Check for working C compiler: /usr/bin/cc
    • Check for working C compiler: /usr/bin/cc -- works
    • Detecting C compiler ABI info
    • Detecting C compiler ABI info - done
    • Detecting C compile features
    • Detecting C compile features - done
    • Check for working CXX compiler: /usr/bin/c++
    • Check for working CXX compiler: /usr/bin/c++ -- works
    • Detecting CXX compiler ABI info
    • Detecting CXX compiler ABI info - done
    • Detecting CXX compile features
    • Detecting CXX compile features - done
    • Found Git: /usr/bin/git (found version "2.20.1")
    • CMAKE_TOOLCHAIN_FILE=



[ 99%] Building CXX object CMakeFiles/v4l2rtspserver.dir/src/main.cpp.o
[100%] Linking CXX executable v4l2rtspserver
[100%] Built target v4l2rtspserver
pi@raspberrypi:~/build/v4l2rtspserver $ sudo make install
[ 4%] Built target v4l2wrapper
[ 94%] Built target live555
[100%] Built target v4l2rtspserver
Install the project...

    • Install configuration: ""
    • Installing: /lib/systemd/system/v4l2rtspserver.service
    • Installing: /usr/local/bin/v4l2rtspserver
    • Installing: /usr/local/share/v4l2rtspserver/index.html
    • Installing: /usr/local/share/v4l2rtspserver/hls.js/dist/hls.light.min.js

pi@raspberrypi:~/build/v4l2rtspserver $

あ、クライアントどうしよう・・・VLCでいっか。
Windows10の対向機に
VLC media player(64bit版) v3.0.10をインストール。

とりあえず、IPたたけば見えるのかな?ということでテスト。
RaspiのIPは192.168.11.9だったです。

Raspi側

pi@raspberrypi:~ $ sudo modprobe bcm2835-v4l2
pi@raspberrypi:~ $ sudo v4l2rtspserver /dev/video0 &
[1] 3627
pi@raspberrypi:~ $ log level:500

[NOTICE] /home/pi/build/v4l2rtspserver/src/main.cpp:564
Version: 0.2.0-6-g3542b6f live555 version:2020.04.24
[NOTICE] /home/pi/build/v4l2rtspserver/src/main.cpp:608
Create V4L2 Source.../dev/video0
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:124
driver:uvcvideo capabilities:84a00001 mandatory:4000001
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:127
/dev/video0 support capture
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:130
/dev/video0 support streaming
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:62
/dev/video0:MJPG size:640x480 bufferSize:302080
[ERROR] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:193
Cannot set pixelformat to:H264 format is:YUYV
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:206
/dev/video0:MJPG size:640x480 bufferSize:341333
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:62
/dev/video0:MJPG size:640x480 bufferSize:341333
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:227
fps:1/25
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:228
nbBuffer:0
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2MmapDevice.cpp:49
Device /dev/video0
[NOTICE] /home/pi/build/v4l2rtspserver/v4l2wrapper/src/V4l2MmapDevice.cpp:73
Device /dev/video0 nb buffer:10
[NOTICE] /home/pi/build/v4l2rtspserver/src/main.cpp:631
Create Source .../dev/video0
[NOTICE] /home/pi/build/v4l2rtspserver/src/DeviceSource.cpp:93
begin thread
[NOTICE] /home/pi/build/v4l2rtspserver/src/main.cpp:150

これでサーバとして動いているみたいです。Motion JPEGか・・・
VLC側はこんな感じ。(画像で理解を促す)

rtsp://192.168.11.9:8554/unicast

f:id:hu2mmc:20200430204854p:plain
f:id:hu2mmc:20200430204859p:plain
f:id:hu2mmc:20200430204903p:plain
f:id:hu2mmc:20200430204906p:plain
f:id:hu2mmc:20200430204909p:plain
しかしこれ、遅延がクソでかい。どうしよう・・・

CPUをさぞかし食っている?と思ったんですが全然でした。
f:id:hu2mmc:20200430205146p:plain

また、フレームレートも全然出てません。。。
ということで

pi@raspberrypi:~ $ v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture

[0]: 'YUYV' (YUYV 4:2:2)
[1]: 'MJPG' (Motion-JPEG, compressed)

nakereba, sudo apt install v4l-utils


YUYVの時のFPS

pi@raspberrypi:~ $ v4l2-ctl --set-fmt-video=width=1280,height=720,pixelformat=0
pi@raspberrypi:~ $ v4l2-ctl --stream-mmap=3 --stream-count=300


4.96 fps

MJPGの時のFPS

pi@raspberrypi:~ $ v4l2-ctl --set-fmt-video=width=1280,height=720,pixelformat=1
pi@raspberrypi:~ $ v4l2-ctl --stream-mmap=3 --stream-count=300


15.07 fps

げー、こりゃあ出ないわけだよ。。。という感じです。

もういっかい、下記の設定でv4l2rtspserverを実行。

pi@raspberrypi:~ $ v4l2rtspserver -W 1280 -H 720 -F 60

VLCで見えてる、コンテンツビットレートは8900[kb/s]くらい。
Raspi側をみると、CPU使用率は6.9~7.4%くらいで推移している。

いまいち、遅延は2~3秒ある感じ。USBから送るだけだけど、Raspiだと遅いのか?と思って、今度は普通のx86PCで試すことに。
Core(TM) i5-2450M CPU @ 2.50GHzなノートPCです。

build@build-FMVS7GN5S7:~$ v4l2-ctl --device=2 --list-formats
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2

Index : 1
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : Motion-JPEG
build@build-FMVS7GN5S7:~$ v4l2-ctl --device=2 --set-fmt-video=width=1280,height=720,pixelformat=1
build@build-FMVS7GN5S7:~$ v4l2-ctl --device=2 --stream-mmap=3 --stream-count=300

29.80 fps

FPSはやはり拾えるようです。


build@build-FMVS7GN5S7:~/build/v4l2rtspserver$ v4l2rtspserver -W 1280 -H 720 -F 60 /dev/video2
log level:500

[NOTICE] /home/build/build/v4l2rtspserver/src/main.cpp:564
Version: 0.2.0-6-g3542b6f live555 version:2020.04.24
[NOTICE] /home/build/build/v4l2rtspserver/src/main.cpp:608
Create V4L2 Source.../dev/video2
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:124
driver:uvcvideo capabilities:84a00001 mandatory:4000001
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:127
/dev/video2 support capture
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:130
/dev/video2 support streaming
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:62
/dev/video2:MJPG size:1280x720 bufferSize:816000
[ERROR] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:193
Cannot set pixelformat to:H264 format is:YUYV
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:206
/dev/video2:MJPG size:1280x720 bufferSize:816000
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:62
/dev/video2:MJPG size:1280x720 bufferSize:816000
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:227
fps:1/30
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2Device.cpp:228
nbBuffer:0
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2MmapDevice.cpp:49
Device /dev/video2
[NOTICE] /home/build/build/v4l2rtspserver/v4l2wrapper/src/V4l2MmapDevice.cpp:73
Device /dev/video2 nb buffer:10
[NOTICE] /home/build/build/v4l2rtspserver/src/main.cpp:631
Create Source .../dev/video2
[NOTICE] /home/build/build/v4l2rtspserver/src/main.cpp:150
Play this stream using the URL "rtsp://192.168.11.10:8554/unicast"
[NOTICE] /home/build/build/v4l2rtspserver/src/DeviceSource.cpp:93

で、VLCで眺めてみました。CPU使用率はさすがにCorei5なので、2.6~3.3%くらいで推移。ただしビットレートはあまり出ないかなぁ、8000行かないくらい。絵は多少滑らかになりました。でも、遅延はやはり2秒くらいある。RTPってそんなに遅れんのか!(まとまらない)