5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Jetson Nano から NDI 送信してみた。(※実用的でした)

Last updated at Posted at 2020-04-28

はじめに

Jetson Nano で NVMPI を有効にした FFmpeg が動作するようになった ので、NDI プラグインも試してみました。
結論から先に言うと、問題なく NDI 送信できましたが、ラズパイカメラから NDI 送信した実績 があったので、同じ手順で進めていたところ途中でビルドに失敗した箇所があったので、備忘録を兼ねてメモに残しておきます。
スクリーンショット 2020-04-28 23.17.10.png

Raspberry Pi と Jetson Nano のスペック比較

Raspberry Pi と Jetson Nano のスペックで GPU 性能以外 (CPU、メモリ容量、Debian 系 OS) は大きな差がないと思って手順を進めたのが間違いでした。

Jetson Nano Raspberry Pi 3 Model B+ Raspberry Pi 4 Model B
CPU ARM Cortex-A57(4コア 1.43GHz) ARM Cortex-A53(4コア 1.4GHz) ARM Cortex-A72(4コア 1.5GHz)
メモリー 4GB 1GB 1GB / 2GB / 4GB
GPU NVIDIA Maxwell 128コア(CUDA対応) Broadcom VideoCore IV Broadcom VideoCore VI
USBコネクター USB 3.0×4 USB 2.0×4 USB 3.0×2、USB 2.0×2
ネットワーク 10/100/1000Mbps 10/100/1000Mbps 10/100/1000Mbps
WiFi / Bluetooth なし IEEE802.11b/g/n/ac、 Bluetooth 4.2 IEEE802.11b/g/n/ac、 Bluetooth 4.2
OS Ubuntu (64bit) Raspbian (32bit) Raspbian (32bit)

動作 OS の違い

Jetson Nano は Raspberry Pi とほぼ同じ ARM CPU を使用しているので、最初は Raspberry Pi で動作実績のあった NDI SDK LINUX ライブラリを使用しました。
しかし、FFmpeg のビルド途中でエラーになり、エラー原因を調べたところ Jetson Nano は 64bit OS (aarch64) で、NDI SDK LINUX ライブラリは 32bit バイナリでした。
NDI SDK はソースコードが公開されていないため、 64bit バイナリが提供されていなければ Jetson Nano で使用することができません。

環境

  • Jetson Nano (新リビジョン B01 では試していません)
  • OS イメージ JetPack 4.3 (nv-jetson-nano-sd-card-image-r32.3.1.zip)
    • Ubuntu 18.04.4 LTS (Bionic Beaver)
  • ウェブカメラ (Logitech, Inc. Webcam C270)
# Jetson Nano
$ uname -a
Linux jetson-desktop 4.9.140-tegra #1 SMP PREEMPT Mon Dec 9 22:47:42 PST 2019 aarch64 aarch64 aarch64 GNU/Linux
# Raspberry Pi 4 Model B+
$ uname -a
Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux
# NDI SDK LINUX (arm-rpi3-linux-gnueabihf)
$ file libndi.so.4.5.1 
libndi.so.4.5.1: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (GNU/Linux), dynamically linked, stripped

NDI SDK と NDI EDK

NewTek 社のホームページで NDI SDK を調べていたところ EDK (Embedded Developer Kit) を見つけました。
説明に ARM based SDK と記載されていたので、ダウンロードして確認したところ、64bit バイナリ (aarch64-newtek-linux-gnu) が含まれていました。
スクリーンショット 2020-04-28 21.14.16.png

$ ls -l
total 52
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 aarch64-himix100-linux
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 aarch64-newtek-linux-gnu
drwxr-xr-x 6 jetson jetson 4096  4月  1 14:31 android
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 arm-himix100-linux
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 arm-himix200-linux
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 arm-hisiv300-linux
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 arm-hisiv400-linux
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 arm-hisiv500-linux
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 arm-hisiv510-linux
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 arm-hisiv600-linux
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 arm-newtek-linux-gnueabihf
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 i686-linux-gnu
drwxr-xr-x 2 jetson jetson 4096  4月 28 12:04 x86_64-linux-gnu

$ cd aarch64-newtek-linux-gnu
$ file libndi.so.4.5.1 
aarch64-newtek-linux-gnu/libndi.so.4.5.1: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked, stripped

FFmpeg に NDI ライブラリを組み込む

ライブラリが入手できれば FFmpeg に NDI ライブラリを組み込んでビルドして完了ですが、もう 1 点注意があります。

FFmpeg 4.1系以降から NDI のサポートが削除された経緯

FFmpeg 3.4 で NDI がサポートされた際に ラズパイカメラから NDI 送信 を試してみましたが、その後、NewTek 社が GPL ライセンス違反で適切な対応が取られなかったことで、FFmpeg 4.1系以降から NDI のサポートが削除されました。

(参考)
https://trac.ffmpeg.org/ticket/7589
https://patchwork.ffmpeg.org/project/ffmpeg/patch/CAB0OVGpkpyFzmkuC+kO3-Er3iNYH9hpO4zDTQZbRpEyFu=fjuQ@mail.gmail.com/

ビルド手順 (FFmpeg 4.0系)

FFmpeg 4.1系以降で NDI がサポートされなくなったため、FFmpeg 4.0系 (4.0 系の最終 4.0.5) のビルド手順です。

# NDI EDK のインストール
$ mkdir NDIE
$ cd NDIE
$ wget http://new.tk/NDISDKE
$ mv NDISDKE InstallNDISDK_v4_Linux_Embedded.tar.gz
$ tar xvzf InstallNDISDK_v4_Linux_Embedded.tar.gz
$ sh InstallNDISDK_v4_Linux_Embedded.sh
$ sudo mkdir /usr/include/ndi
$ sudo cp NDI\ SDK\ for\ Linux/include/* /usr/include/ndi/
$ sudo cp NDI\ SDK\ for\ Linux/lib/aarch64-newtek-linux-gnu/* /usr/lib/

# FFmpeg のビルド
$ git clone git://source.ffmpeg.org/ffmpeg.git -b release/4.0 --depth=1
$ cd ffmpeg
$ ./configure --enable-nonfree --enable-libndi_newtek --extra-cflags="-I/usr/include/ndi/" --extra-ldflags="-L/usr/include/ndi/" --enable-libx264 --enable-gpl

$ make -j3

実行手順

ウェブカメラは /dev/video0、ウェブカメラのマイクは card 2 で認識されている場合、以下のコマンドで実行します。
画像サイズ (-s 1280x720) と フレームレート (-r 30) はウェブカメラの性能に応じて変更します。

$ ./ffmpeg -f alsa -ac 1 -thread_queue_size 4096 -i hw:2 -i /dev/video0 -s 1280x720 -r 30 -vcodec wrapped_avframe -g 50 -strict experimental -f libndi_newtek -pix_fmt uyvy422 JetsonNanoCamera

(実行後の画面出力)
JetsonNano_FFmpeg+NDI.png

(負荷状況)
jetson_stats の jtop コマンドで確認したところ、NDI はソフトウェアエンコーディングなので 50% 程度の負荷でした。

受信側は OBS-StudioNDI プラグインを追加して動作を確認しました。

(参考) カメラとマイクの確認方法

ウェブカメラは /dev/video0 で認識されていました。

$ lsusb
Bus 002 Device 002: ID 0bda:0411 Realtek Semiconductor Corp. 
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 006: ID 15ca:00c3 Textech International Ltd. Mini Optical Mouse
Bus 001 Device 005: ID 04fe:0006 PFU, Ltd 
Bus 001 Device 004: ID 04fe:0008 PFU, Ltd 
Bus 001 Device 003: ID 046d:0825 Logitech, Inc. Webcam C270
Bus 001 Device 002: ID 0bda:5411 Realtek Semiconductor Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ ls /dev/video*
/dev/video0

ウェブカメラのマイクは card 2 で認識されていました。

$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 0: ADMAIF1 CIF ADMAIF1-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 1: ADMAIF2 CIF ADMAIF2-1 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 2: ADMAIF3 CIF ADMAIF3-2 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 3: ADMAIF4 CIF ADMAIF4-3 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 4: ADMAIF5 CIF ADMAIF5-4 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 5: ADMAIF6 CIF ADMAIF6-5 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 6: ADMAIF7 CIF ADMAIF7-6 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 7: ADMAIF8 CIF ADMAIF8-7 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 8: ADMAIF9 CIF ADMAIF9-8 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 9: ADMAIF10 CIF ADMAIF10-9 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: U0x46d0x825 [USB Device 0x46d:0x825], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

v4l2-ctl コマンドでウェブカメラの性能を確認できます。

$ v4l2-ctl --list-formats-ext --device=/dev/video0
ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'YUYV'
	Name        : YUYV 4:2:2
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 160x120
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 176x144
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 320x176
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 320x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 352x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 432x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 544x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 752x416
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 800x448
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 864x480
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 960x544
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 960x720
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1024x576
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1184x656
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.133s (7.500 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1280x960
			Interval: Discrete 0.133s (7.500 fps)
			Interval: Discrete 0.200s (5.000 fps)

	Index       : 1
	Type        : Video Capture
	Pixel Format: 'MJPG' (compressed)
	Name        : Motion-JPEG
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 160x120
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 176x144
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 320x176
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 320x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 352x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 432x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 544x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 752x416
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 800x448
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 864x480
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 960x544
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 960x720
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1024x576
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1184x656
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1280x960
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?