モチベーション
gStreamerはaptやインストーラーで入れると入らないパッケージがある。
ライセンス関係で入らないものや動作環境が限られるものがある。
今回は以下のpluginを利用するために自分でビルドする。
- OpenH264
- Cisco製のH264エンコーダ
- これはライセンスの関係でaptでは入らない
- Windowsのインストーラーでは入ったが理由は調べていない
- NVCodec
- NVENCを利用している動画のエンコーダ・デコーダ
- H264, H265用
- 動作環境が限られるのでaptでは入らないようだ
- NVENCを利用している動画のエンコーダ・デコーダ
対象環境
Ubuntu19.10とWindows10
その他の環境でも方法は同じだがコンパイラの設定等の調整は多分必要。
gStreamerのPluginについて
個別のplugin環境はgitで公開されているので、それぞれ個別にビルドすることは可能。pluginは3種類あって、https://github.com/GStreamer/gst-plugins-bad/blob/master/README にかなり文学的だが説明があり、概ね以下の通り。
- [gst-plugins-good]
- 公式が利用を推奨するplugin
- コードの品質がいい
- ドキュメントまでちゃんとそろっている
- ライセンスもLGPLである
- [gst-plugins-ugly]
- コードの品質はgoodと同じくらいいいらしい
- uglyというのはコードがきったねぇという意味ではない
- ただしライセンスで縛られていて完全にフリーなコードではないので、利用に際しては注意が必要
- 特に配布は困難
- 特許が取られているものもある
- そういうところが気に入らないのでuglyって名前にしている
- コードの品質はgoodと同じくらいいいらしい
- [gst-plugins-bad]
- 見た目上うまく動いているかもしれんけど無保証
- 何かが欠けていてgoodになれないものたち
- 品質
- テスト
- レビュー
- ドキュメント
- これら全てが解決された段階でgoodかuglyに昇格する
- フリーソフトウェアなので自分でパッチを当てろ
- パッチを当ててうまく行ったらプルリクしてくれ。頼むぞ
- gStreamerのコントリビューターになりたい場合、まずここから始めることができる
ということらしい。
具体的なビルド手順
これらのpluginをビルドしようとすると、autotoolsで依存ライブラリを揃えることになる。Ubuntuだと割とサックリできたが、後述のWindowsなんかだと色々面倒だった。gStreamerの公式のビルド環境としてCerberoがあり、これを利用するのが一番ラクなのでこの記事はCerberoについて記載。
Ubuntu 19.10
既存のgStreamerとのバージョン合わせ
そもそもgStreamerが標準で入っているので、gStreamer自体のビルドは不要で、pluginの格納ディレクトリにビルドしたpluginを入れてやるだけで良い。但し本体とpluginのバージョンを合わせないといけない。
標準で入っているバージョンは1.16.1(2020/3/2時点)で、cerberoでmasterブランチから取ってくるコードのバージョンは1.17.0.1。マイナーバージョンまで合わせてやる必要があるので、Ubuntuに元々入っているgStreamerを利用する場合は1.16系をビルドすることになる。
古いバージョンのビルド方法についてちょっとググると、cerberoのバージョンを戻すと古いものがビルドされるという情報がいっぱい出てくる(http://mil-o.jp/yb/gstreamer-cerbero/)。
$git clone -b 1.14 https://github.com/GStreamer/cerbero
が、これではうまく行かなかった。ビルドスクリプトそのものが古いため、pythonの想定バージョンが2系だったりして、最新の環境ではうまくいかない。
メンテされていない古いビルドスクリプトを動かすよりも、新しいビルドスクリプトで古いものをビルドしたほうが良いに決まっているので、やり方を探す。
cerberoのビルド設定はrecipesとして管理されている。この中のrecipes/custom.pyの14行目が想定するgStreamerのバージョンなのでここを修正する。パッチ番号まで指定されているが、実際に1.16.0と指定しても1.16.2がビルドされたので、パッチ番号は自動的に最新のものを取ってくるようだ(強制的に1.16.0をビルドさせる方法は必要がなかったので調べていない)。
nvcodecとopenh264のビルドのための環境構築
標準の状態でビルドしてもaptで入るものしかビルドされず、nvcodecとopenh264はビルドされない。ビルドするためにはまず環境の構築とvariantの設定が必要。
依存ライブラリ入れ
- openh264
openh264はgithubのリポジトリから取ってきて入れる。但しcerberoがlibopenh264.so.4を決め打ちで読みに行っているので、シンボリックリンクを貼ってやる必要がある(↓の一番最後の行)
$git clone https://github.com/cisco/openh264
$cd openh264
$make && sudo make install
$sudo ln -s /usr/local/lib/libopenh264.so.2.1.0 /usr/lib/libopenh264.so.4
- nvcodec
NVIDIAのGPUとCUDAが必要。GPUが入っているマシンを準備してUbuntuを入れる。
ドライバとcudaのtoolkitはaptで入る。
$sudo apt install nvidia-driver-435 nvidia-cuda-toolkit
がダメで、Cerberoがcudaは10.1を要求してくるので10.1をNVIDIAのサイトからダウンロードしてきて入れる。
https://developer.nvidia.com/cuda-10.1-download-archive-base
一番新しい18.10のrunfile(local)をダウンロードする。NVIDIAのサイトには
Installation Instructions:
Run `sudo sh cuda_10.1.105_418.39_linux.run`
Follow the command-line prompts
と書いてあるが、Ubuntu19.10だとこれでは入らない。cudaのインストーラーがgcc8系を要求するのに対し、Ubuntu19.10はgcc9系しか入ってないので途中で止まってしまう。ググると、古いgccを入れたら良いじゃんという記載が見つかったが、そんなことはしたくないのでもう少し探したところ、--overrideというオプションを付けるとgcc9系でもビルドできるらしい。
$chmod +x cuda_10.1.105_418.39_linux.run
$sudo ./cuda_10.1.105_418.39_linux.run --override
でインストール完了。ドライバを入れたのでLinuxを再起動する。
コンパイラのオプション
ビルドスクリプトの内部でconfigureする際にオプションを指定しておかないと、必要ないものとしてskipされてしまう。
ビルドスクリプトの動かし方を調べると、オプションはvariantとして指定できる。
$./cerbero-uninstalled
usage: cerbero-uninstalled [-h] [-t] [--list-variants] [-v VARIANTS]
[-c CONFIG] [-m MANIFEST]
[--self-update SELF_UPDATE]
{genvsprops,fetch,fetch-package,fetch-cache,bootstrap,fetch-bootstrap,deps,buildone,build-deps,build,gensdkshell,rdeps,wipe,bundle-source,package,add-package,graph,genlibfiles,packageinfo,list,list-packages,show-config,debug-packages,tag,run,checkpackage,shell,add-recipe,edit-cache,genxcconfig,check}
...
Build and package a set of modules to distribute them in a SDK
positional arguments:
{genvsprops,fetch,fetch-package,fetch-cache,bootstrap,fetch-bootstrap,deps,buildone,build-deps,build,gensdkshell,rdeps,wipe,bundle-source,package,add-package,graph,genlibfiles,packageinfo,list,list-packages,show-config,debug-packages,tag,run,checkpackage,shell,add-recipe,edit-cache,genxcconfig,check}
sub-command help
genvsprops Generate Visual Studio property sheets to use the SDK
from VS
fetch Fetch the recipes sources
fetch-package Fetch the recipes sources from a package
fetch-cache Fetch a cached build from GitLab CI based on cerbero
git revision.
bootstrap Bootstrap the build system installing all the
dependencies
fetch-bootstrap Fetch the sources required for bootstrap
deps List the dependencies of a recipe
buildone Build or rebuild a single recipe without its
dependencies
build-deps Build only the dependencies of the specified recipes
build Build a recipe
gensdkshell Create a script with the shell environment for the SDK
rdeps List the reverse dependencies of a recipe
wipe Wipes everything to restore the build system
bundle-source Bundle Source code of recipes and Cerbero
package Creates a distribution package
add-package Adds a new package
graph Create a graph of dependencies using dot from graphviz
genlibfiles Generate MSVC compatible library files (.lib)
packageinfo Print information about this package
list List all the available recipes
list-packages List all the available packages
show-config Show configuration settings
debug-packages Outputs debug information about package, like
duplicates files or files that do not belong to any
package
tag Tag a git recipe or all git recipes using their
sdk-$version branch
run Runs a command in the cerbero shell
checkpackage Run checks on a given package
shell Starts a shell with the build environment
add-recipe Adds a new recipe
edit-cache View and edit the local cache
genxcconfig Generate XCode config files to use the SDK from VS
check Run checks on a given recipe
optional arguments:
-h, --help show this help message and exit
-t, --timestamps Print timestamps with every message printed
--list-variants List available variants
-v VARIANTS, --variants VARIANTS
Variants to be used for the build
-c CONFIG, --config CONFIG
Configuration file used for the build
-m MANIFEST, --manifest MANIFEST
Manifest file used to fixate git revisions
--self-update SELF_UPDATE
Update cerbero git repository from manifest and exit.
variantの一覧は以下
$ ./cerbero-uninstalled --list
Loading default configuration from /home/nakakura/.cerbero/cerbero.cbc
Available variants are: alsa, cdparanoia, debug, gi, intelmsdk, nvcodec, pulse, python, qt5, rpi, testspackage, unwind, v4l2, vaapi, visualstudio, werror, x11
デフォルトでonになっているものもあるので、必要なものだけ追加する。今回はnvcodecをつける必要がある。
$ ./cerbero-uninstalled bootstrap
$ ./cerbero-uninstalled build gstreamer-1.0
$ ./cerbero-uninstalled -v vnvcodec build gst-plugins-bad-1.0
これでgst-plugins-bad-1.0がビルドされる。ちなみにこれは設定ファイルを書いておくと並列でビルドすることができて高速化できる。設定ファイルは~/.cerbero/cerbero.cbc
$ cat ~/.cerbero/cerbero.cbc
allow_parallel_build=True
num_of_cpus=8
なお、一旦ビルドしてしまってからオプションを変えて再度ビルドしようとした場合、wipeを実行しないと反映されないので注意(はまった)
ビルドしたライブラリのインストール
pluginのディレクトリにファイルをコピーするだけ。pluginのディレクトリはgst-inspect-1.0で適当なライブラリを表示してやると書いてある。
$gst-inspect-1.0 autovideosink
...中略...
Filename /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstautodetect.so
...略...
/usr/lib/x86_64-linux-gnu/gstreamer-1.0/に入れればいいことがわかったので、入れてやる。ビルドしたバイナリはbuild/dist/linux_x86_64/の中にある。
$ ls build/dist/linux_x86_64/
bin/ etc/ include/ lib/ libexec/ man/ share/ var/
binの中にはgst-launch等々の実行ファイルがあり、pluginはlibの中にある。
$cd build/dist/linux_x86_64/lib/gstreamer-1.0
$sudo cp libgstnv* /usr/lib/x86_64-linux-gnu/gstreamer-1.0/
$sudo cp libgstopenh264* /usr/lib/x86_64-linux-gnu/gstreamer-1.0/
これで無事に入ったはずなので確認する。
$ gst-inspect-1.0 openh264enc
Factory Details:
Rank marginal (64)
Long-name OpenH264 video encoder
...
$gst-inspect-1.0 nvh264enc
Factory Details:
Rank primary + 256 (512)
Long-name NVENC H.264 Video Encoder
...
Ok
ハマりポイント
- cudaは10.1が必要(10.2じゃだめ)
- openh264encはlibopenh264.so.4が/usr/libにある必要がある
- variantを設定する前に一旦ビルドしていると、wipeをかけるかcerberoごと入れ直さないとビルドに反映されない
Windows10
Windows10については、こちらの記事が神がかっているのでほぼそのまま手順に従えばいい。
https://qiita.com/maruo2/items/387e2322f72bf61c8e02
Windows環境に関してはまっさらからの構築なので、1.17.0.1をそのままビルドした。
今回試して追加でわかったのは以下
- Visual Studio2019のcommunity版でもビルドできた
- variantでvisualstudioを指定してやるとVisual Studioでビルドされ、指定しないとMSYSでビルドされる
- MSYSは32bit環境だがちゃんと64bitのものがビルドされる
- MSYSの方は(流れていったのでちゃんと読めなかったが)警告がたくさん表示されたので、何かしら怪しいかもしれない
その他気づいたこと
- Ubuntuの1.16はバイナリがnvenc, nvdecに別れたが、Windowsの1.17はバイナリがnvcodecに統一されていた
- 1.14を見るとソースコードもnvenc, nvdecに分かれているが、1.16はソースコードレベルではnvcodecというディレクトリだったので、統一される方向っぽい
- Ubuntuのnvencはnvh264enc, nvh265encに内部的に別れているが、nvdecはnvdecとしてかなり使いづらいインタフェースだった
- 1.17はnvh264dec, nvh265decと別れているので、1.16のnvcodecは変更中の過渡期っぽい
ということ。