🐟

Xilinx評価ボード(ZCU104)でGstreamerを動かしてみる

2022/02/05に公開

1.はじめに

今回はZynq UltraScale+ MPSoC ZCU104 評価キットにPetalinuxをインストールしてGstreamerで動画ストリーミングの動作を確認して行きたいと思います。

2.Petalinuxのインストール

まず最初にPetalinuxのインストールに必要なUbuntuパッケージをインストールしておきます。

sudo apt-get install locales build-essential binutils ncurses-dev u-boot-tools file tofrodos iproute2 gawk git wget net-tools libncurses5-dev tftpd tftpd-hpa zlib1g-dev libssl-dev flex bison libselinux1 diffstat xvfb chrpath xterm libtool socat autoconf unzip screen pax gzip texinfo gcc-multilib libsdl1.2-dev libglib2.0-dev zlib1g:i386 cpio x11-apps vim-common python3-dev libgtk2.0-0 glib-2.0 gnupg tar

以下のXilinxのサイトにアクセスしてPetalinuxとZCU104 BSPをダウンロードします。いずれもVitisと同じバージョンでないといけないので、ここでは2021.1をダウンロードしてきます。
https://japan.xilinx.com/support/download/index.html/content/xilinx/ja/downloadNav/embedded-design-tools/2021-1.html

ダウンロードしたPetalinuxをインストールします。

chmod 755 petalinux-v2021.1-final-installer.run
./petalinux-v2021.1-final-installer.run -d <path-to-install>

ライセンスが表示されるので内容を確認したらqキーを押します。

続いてyキーを押してライセンスに同意します。

3回ラインセスに同意するとインストールが始まります。

3.Petalinuxプロジェクトの作成

Petalinuxのインストールが完了したので、次はPetalinuxのプロジェクトを生成していきます。
プロジェクトを生成するディレクトリに移動し、以下のコマンドを実行してZCU104のBSPからプロジェクトを生成します。

source <path-to-installed-PetaLinux>/settings.sh
petalinux-create -t project -s <path-to-bsp>

生成したプロジェクトディレクトリに移動してrootfsを設定します。

cd <Petalinux-project-root>
petalinux-config -c rootfs

Term上に以下の画面が表示されます。

Gstreamerをインストールするために、以下の設定を有効にします。

  • 「Filesystem Packages」→「misc」→「gstreamer1.0-meta-base」
  • 「Filesystem Packages」→「misc」→「gstreamer1.0-plugins-bad」
  • 「Filesystem Packages」→「misc」→「gstreamer1.0-plugins-base」
  • 「Filesystem Packages」→「misc」→「gstreamer1.0-plugins-good」
  • 「Filesystem Packages」→「misc」→「v4l-utils」
  • 「Filesystem Packages」→「misc」→「matchbox-config-gtk」
  • 「Filesystem Packages」→「misc」→「matchbox-panel-2」
  • 「Filesystem Packages」→「libs」→「libmali-xlnx」
  • 「Filesystem Packages」→「multimedia」→「gstreamer1.0」
  • 「Filesystem Packages」→「multimedia」→「gstreamer1.0-omx」
  • 「Filesystem Packages」→「multimedia」→「gstreamer1.0-rtsp-server」
  • 「Filesystem Packages」→「x11」→「matchbox-keyboard」
  • 「Filesystem Packages」→「x11」→「matchbox-session」
  • 「Filesystem Packages」→「x11」→「matchbox-session-sato」
  • 「Petalinux Package Groups」→「packagegroup-petalinux-opencv」
  • 「Petalinux Package Groups」→「packagegroup-petalinux-v4lutils」
  • 「Petalinux Package Groups」→「packagegroup-petalinux-gstreamer」

次にブート用Imageの設定をします。

cd <Petalinux-project-root>
petalinux-config

Term上に以下の画面が表示されます。

SDカードから起動するため、「Image Packing Configuration」→「Root filesystem type」から
EXT4(SD/eMMC/SATA/USB)を選択して保存します。

PetaLinuxのビルドコンポーネントのダウンロードパスを設定します。
Yocto Settings -> Network sstate feeds URL を開き、http://petalinux.xilinx.com/sswreleases/rel-v2021.1/aarch64/sstate-cacheを設定します。以下にその説明が書いてあります。
https://support.xilinx.com/s/article/76598?language=ja

設定完了したら、petalinux-build を実行してシステムイメージをビルドしていきます。

cd <Petalinux-project-root>
petalinux-build

次にブートイメージを作成します。

cd <Petalinux-project-root>
petalinux-package --boot --u-boot --format BIN

ここまでの処理により、 <Petalinux-project-root>/images/linux ディレクトリに以下のファイルが作られていることを確認します。

  • BOOT.BIN
  • image.ub
  • boot.scr
  • rootfs.tar.gz

4.PetalinuxをSDカードに書き込む

まずはじめに、以下のサイトを参考にVMWare(Ubunt20.04)でSDカードが読み込めるように設定します。
https://armadillo.atmark-techno.com/blog/8700/3163

VMWareの設定が完了したら、PCにSDカードを差し込みデバイス情報を参照します。

dmesg | grep sd

ここではsdbにSDカードが割り当てられていることが確認できます。

次にSDカードをフォーマットするためにfdiskを実行します。

sudo fdisk /dev/sdb

fdiskではインタラクティブにSDカードをフォーマットしていきます。
pコマンドでパーティションを確認します。

コマンド (m でヘルプ): p
ディスク /dev/sdb: 30.18 GiB, 32395755520 バイト, 63272960 セクタ
Disk model: VMware Virtual S
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0x6773dbf1

デバイス   起動 開始位置 最後から   セクタ サイズ Id タイプ
/dev/sdb1           8192   137215   129024    63M  e W95 FAT16 (LBA)
/dev/sdb2         137216 30277631 30140416  14.4G  c W95 FAT32 (LBA)

dコマンドで一度全てのパーティションを削除します。

コマンド (m でヘルプ): d
パーティション番号 (1,2, 既定値 2): 2

パーティション 2 を削除しました。

コマンド (m でヘルプ): d
パーティション 1 を選択
パーティション 1 を削除しました。

nコマンドでパーティション1を作成します。

コマンド (m でヘルプ): n
パーティションタイプ
   p   基本パーティション (0 プライマリ, 0 拡張, 4 空き)
   e   拡張領域 (論理パーティションが入ります)
選択 (既定値 p): p
パーティション番号 (1-4, 既定値 1): 1
最初のセクタ (2048-63272959, 既定値 2048): 2048
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-63272959, 既定値 63272959): 20000000

新しいパーティション 1 をタイプ Linux、サイズ 9.5 GiB で作成しました。

nコマンドでパーティション2を作成します。

コマンド (m でヘルプ): n
パーティションタイプ
   p   基本パーティション (1 プライマリ, 0 拡張, 3 空き)
   e   拡張領域 (論理パーティションが入ります)
選択 (既定値 p): p
パーティション番号 (2-4, 既定値 2): 2
最初のセクタ (20000001-63272959, 既定値 20000768): 20000001
Last sector, +/-sectors or +/-size{K,M,G,T,P} (20000001-63272959, 既定値 63272959): 63272959

新しいパーティション 2 をタイプ Linux、サイズ 20.6 GiB で作成しました。

tコマンドでパーティション1のフォーマットタイプをFAT32に変更します。

コマンド (m でヘルプ): t
パーティション番号 (1,2, 既定値 2): 1
16 進数コード (L で利用可能なコードを一覧表示します): b

パーティションのタイプを 'Linux' から 'W95 FAT32' に変更しました。

aコマンドで起動をパーティション1に設定します。

コマンド (m でヘルプ): a
パーティション番号 (1,2, 既定値 2): 1

パーティション 1 の起動フラグを有効にしました。

最後にpコマンドで正しくパーティションできているか確認し、wコマンドで設定を書き込んで終了します。

コマンド (m でヘルプ): p
ディスク /dev/sdb: 30.18 GiB, 32395755520 バイト, 63272960 セクタ
Disk model: VMware Virtual S
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0x6773dbf1

デバイス   起動 開始位置 最後から   セクタ サイズ Id タイプ
/dev/sdb1  *        2048 20000000 19997953   9.5G  b W95 FAT32
/dev/sdb2       20000001 63272959 43272959  20.6G 83 Linux
	
コマンド (m でヘルプ): w
パーティション情報が変更されました。

一度Ubuntuを再起動してから、以下のコマンドでパーティションをフォーマットします。

sudo mkfs.msdos -n BOOT /dev/sdb
sudo mkfs.ext4 -L RootFs /dev/sdb2

準備が完了したので、SDカードにデータを書き込んでいきます。まずはパーティション1にブートイメージを書き込みます。

sudo mkdir /mnt/sdcard
sudo mount /dev/sdb1 /mnt/sdcard
cd <Petalinux-project-root>
sudo cp ./images/linux/BOOT.BIN /mnt/sdcard
sudo cp ./images/linux/image.ub /mnt/sdcard
sudo cp ./images/linux/boot.scr /mnt/sdcard
sudo umount /mnt/sdcard

次にパーティション2にファイルシステムを書き込みます。

sudo mount /dev/sdb2 /mnt/sdcard/
sudo tar xvf images/linux/rootfs.tar.gz -C /mnt/sdcard/
sync
sudo umount /mnt/sdcard

5.Gstreamerの構成

GStreamerによりZCU104からWindowPCへのストリーミング配信を確認します。
システム構成は以下のようになります。

6.Gstreamerの受信側設定

最初に、受信PC側の設定をしていきます。以下にアクセスしてWindows用のGstreamerをダウンロードしてインストールします。
https://gstreamer.freedesktop.org/download/#windows

ダウンロードが完了したら、インストーラーを起動します。NEXTボタンをクリックします。

I accept the terms in the License AgreementをチェックしてNextボタンをクリックします。

Complete ボタンをクリックします。

Install ボタンをクリックしてインストールを開始します。

インストールが完了したらFinishボタンをクリックして終了します。

最後にPCの環境変数にGstreamerのPATHを設定し、IPアドレスを192.168.0.15 に設定します。

7.Gstreamerの送信側設定

ZCU104のスイッチSW1をSDカードブートモードに設定します。
https://xilinx.github.io/Embedded-Design-Tutorials/docs-jp/docs/Introduction/Versal-EDT/docs/4-boot-and-config.html

Petalinuxイメージを書き込んだSDカードをZCU104のSDカードスロットに差し込みます。USBカメラをZCU104に接続し、シリアル通信用のUSBケーブルでZCU104と受信用PCを接続します。
受信用PCでTerminalソフトを起動します。通信のBAUDレートは115200を設定します。

ZCU104の電源を投入します。起動に成功するとコンソールがTerminal画面に表示されます。

7.ZCU104からWindowsPCにGstreamer配信する

まず始めに、ZCU104のIPアドレスを変更します。ZCU104に接続したTerminalから以下のコマンドを実行します。

ifconfig eth0 192.168.0.20

次に、ZCU104に接続したカメラの解像度パラメータを確認します。
ZCU104に接続したTerminalから以下のコマンドを実行します。

gst-device-monitor-1.0

コマンド実行結果が表示されるので、USBカメラの情報を確認する事ができます。

Device found:

        name  : See3CAM_CU30
        class : Video/Source
        caps  : video/x-raw, format=(string)UYVY, width=(int)2304, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction){ 24/1, 12/1 };
                video/x-raw, format=(string)UYVY, width=(int)2048, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction){ 42/1, 21/1 };
                video/x-raw, format=(string)UYVY, width=(int)2304, height=(int)1296, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction){ 30/1, 15/1 };
                video/x-raw, format=(string)UYVY, width=(int)1920, height=(int)1280, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction){ 50/1, 25/1 };
                video/x-raw, format=(string)UYVY, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction){ 60/1, 30/1, 15/1 };
                video/x-raw, format=(string)UYVY, width=(int)1280, height=(int)960, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction){ 58/1, 30/1 };
                video/x-raw, format=(string)UYVY, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction){ 60/1, 30/1 };
                video/x-raw, format=(string)UYVY, width=(int)1152, height=(int)768, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction){ 60/1, 30/1 };
                video/x-raw, format=(string)UYVY, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction){ 60/1, 30/1 };
                image/jpeg, width=(int)2304, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)48/1;
                image/jpeg, width=(int)2048, height=(int)1536, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)50/1;
                image/jpeg, width=(int)2304, height=(int)1296, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
                image/jpeg, width=(int)1920, height=(int)1280, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)50/1;
                image/jpeg, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
                image/jpeg, width=(int)1280, height=(int)960, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)58/1;
                image/jpeg, width=(int)1280, height=(int)720, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
                image/jpeg, width=(int)1152, height=(int)768, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;
                image/jpeg, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)60/1;

ZCU104でGstreamerコマンドを実行して動画配信します。
gst-device-monitor-1.0コマンドで調べたUSBカメラパラメータから、ここではCODECをMJPEG、解像度とフレームレートをWidth=640, Height=480, FrameRate=60でキャプチャして、WindowsPCに配信してみます。

gst-launch-1.0 v4l2src device=/dev/video0 do-timestamp=true ! image/jpeg,framerate=60/1,width=640,height=480 ! rtpjpegpay ! udpsink host=192.168.0.15 port=9000

今度は受信側PCのGstreamerコマンドを実行します。
受信PCのCMDプロンプトから以下を実行する事で、受信動画を画面表示できます。

gst-launch-1.0 udpsrc name=video_src port=9000 caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MJPEG" ! rtpjpegdepay ! queue ! jpegdec ! videoconvert ! autovideosink

WindowsPC上に画面が立ち上がり、そこに動画が表示されます。

今回は、USBカメラから入力されたMJPEGを配信して表示してみましたが、CODECをCPUで処理しているので、映像のカクツキが目立ちました。
ZCU104には4KP60対応H.264/H.265ビデオコーデック(VCU)がFPGAチップに統合されています。次回はVCUを使ったストリーミング動作を確認していきたいと思います。

Discussion