購入したビデオカードが使えるようになりました。だましながら、エンコードできるようになったという状況です。
いやー、ほんと苦労しました。Linuxにビデオカードを導入するという記事をネットで探しましたが、あまり無いんですよね。あっても古かったりして、自分で試行錯誤しました。
また、運用している録画サーバでの録画は継続したかったので、録画していないタイミングを狙って作業していたので、時間がかかりました。
この記事では、CentOS7.4でビデオカードを使えるようにするため、どんなことをしたかを記録的に書いています。
Photo by Caspar Camille Rubin on Unsplash
録画サーバの構成
まずは、録画サーバの構成を簡単にまとめると。
ハード
ハードウエアは以下のように、約2年前の構成です。ビデオカードだけ新規購入してます。
- CPU:Pentium Gold G5400(インテルの第8世代)
- MotherBoard:ASUS Intel H310 搭載 LGA1151 対応 マザーボード PRIME H310M-A 【MicroATX】
- memory:8GB
- ビデオカード:MSI GeForce GTX 1650 D6 AERO ITX OCV1 (Bフレーム対応のGPU搭載)
ソフト
OSはCentOS7.4と今となっては古いOSを利用しています。ちなみに、この記事を書いている時点でCentOSの最新は8.2です。
- OS:CentOS7.4
- 録画管理:Chinachu
- チューナー管理:mirakurun
# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core)
ドライバのインストール
まずはドライバを入れないと、何もできません。
以下の記事を参考にしてドライバを入れました。ちなみに、以下の記事はNVIDIAの中の人が書いてます。
記事にもあるように、「パッケージでドライバを入れる、パッケージでできなかったらRUNFILEを利用する」というのがオススメでした。
私はこの記事を見つける前にRUNFILEを入れてしまい、動かない状況となりました。なので、改めてパッケージでドライバを導入しました。
パッケージによるドライバの入れ方は以下のURLから自分のOSを選択していけばコマンドが表示されます。
ドライバがインストールできると、nvidia-smiコマンドを利用してビデオカードの状態を確認できます。
# nvidia-smi Sat Dec 5 11:53:57 2020 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 450.80.02 Driver Version: 450.80.02 CUDA Version: 11.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 GeForce GTX 1650 Off | 00000000:01:00.0 Off | N/A | | 30% 28C P0 8W / 75W | 0MiB / 3911MiB | 0% Default | | | | N/A | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
エンコードするために
Dockerでの利用は諦めた
環境をあまり汚さず、ポータビリティな環境を作りたいので、Dockerを利用してエンコードすることを考えていました。
以下の公式ページにあるようにNVIDIA Container Toolkitをインストールするのですが、これがうまくいきませんでした。Dockerのバージョンを上げたりしたのですが、それでもうまく行かなかったです。あるパッケージが不足しているようなメッセージが出たのですが、これが解決できませんでした。
また、nvidia/cudaのDockerイメージが大きいです。このイメージをベースにffmpegの環境を作ると、約5GBぐらいを利用することになります。
CentOSのインストール時に何も考えずにデフォルト設定のままにしたため、以下のようにルートが50GBしかないです。Dockerイメージはルート領域に格納されるため、これに5GBが加算されるとシステムが動かなくなる可能性も出てきます。
そんなこともあって、Dockerでのエンコードは諦めました。
# df -h ファイルシス サイズ 使用 残り 使用% マウント位置 /dev/mapper/centos-root 50G 42G 8.1G 84% / devtmpfs 3.8G 0 3.8G 0% /dev tmpfs 3.8G 0 3.8G 0% /dev/shm tmpfs 3.8G 33M 3.8G 1% /run tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup /dev/sda2 1014M 180M 835M 18% /boot /dev/sda1 200M 9.8M 191M 5% /boot/efi /dev/mapper/centos-home 1.4T 265G 1.1T 20% /home //192.168.1.13/video 2.7T 2.0T 738G 74% /media tmpfs 767M 0 767M 0% /run/user/0
エラーを無視してffmpegをmakeしたぜ!
Dockerを諦め、以下の記事を参考にしてnvencできるffmpegをmakeしようとしました。
しかしここでも、うまくいきません。詰まったのは、以下の箇所です。
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" ./configure --enable-cuda-nvcc --enable-cuvid --enable-nvenc --enable-nonfree --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64 --prefix=/usr/local
cuda-nvccとnonfreeが無いというのです。ここでドライバやツールキットがちゃんと入っていないんだと予想しました。が、同じ手順でやっても変化は無いのです。
とにかく先に進めようと考えて、「--enable-cuda-nvcc」「--enable-nonfree」の記述を削除しました。
そしたら、なんとかffmpegをmakeできました。エンコードできるものに「hevc_nvenc」「nvenc_hevc」が表示されています。(この2つの違いはなんだろう?)
# ffmpeg -hide_banner -encoders | grep nvenc V..... h264_nvenc NVIDIA NVENC H.264 encoder (codec h264) V..... nvenc NVIDIA NVENC H.264 encoder (codec h264) V..... nvenc_h264 NVIDIA NVENC H.264 encoder (codec h264) V..... nvenc_hevc NVIDIA NVENC hevc encoder (codec hevc) V..... hevc_nvenc NVIDIA NVENC hevc encoder (codec hevc)
以下のように「hevc_nvenc」で使用できるオプションも表示されます。
# ffmpeg -hide_banner -h encoder=hevc_nvenc Encoder hevc_nvenc [NVIDIA NVENC hevc encoder]: General capabilities: delay hardware Threading capabilities: none Supported hardware devices: cuda cuda Supported pixel formats: yuv420p nv12 p010le yuv444p p016le yuv444p16le bgr0 rgb0 cuda hevc_nvenc AVOptions: -preset <int> E..V...... Set the encoding preset (from 0 to 11) (default medium) default 0 E..V...... slow 1 E..V...... hq 2 passes medium 2 E..V...... hq 1 pass fast 3 E..V...... hp 1 pass hp 4 E..V...... hq 5 E..V...... bd 6 E..V...... ll 7 E..V...... low latency llhq 8 E..V...... low latency hq llhp 9 E..V...... low latency hp lossless 10 E..V...... lossless losslesshp 11 E..V...... lossless hp -profile <int> E..V...... Set the encoding profile (from 0 to 4) (default main) main 0 E..V...... main10 1 E..V...... rext 2 E..V...... -level <int> E..V...... Set the encoding level restriction (from 0 to 186) (default auto) auto 0 E..V...... 1 30 E..V...... 1.0 30 E..V...... 2 60 E..V...... 2.0 60 E..V...... 2.1 63 E..V...... 3 90 E..V...... 3.0 90 E..V...... 3.1 93 E..V...... 4 120 E..V...... 4.0 120 E..V...... 4.1 123 E..V...... 5 150 E..V...... 5.0 150 E..V...... 5.1 153 E..V...... 5.2 156 E..V...... 6 180 E..V...... 6.0 180 E..V...... 6.1 183 E..V...... 6.2 186 E..V...... -tier <int> E..V...... Set the encoding tier (from 0 to 1) (default main) main 0 E..V...... high 1 E..V...... -rc <int> E..V...... Override the preset rate-control (from -1 to INT_MAX) (default -1) constqp 0 E..V...... Constant QP mode vbr 1 E..V...... Variable bitrate mode cbr 2 E..V...... Constant bitrate mode vbr_minqp 8388612 E..V...... Variable bitrate mode with MinQP (deprecated) ll_2pass_quality 8388616 E..V...... Multi-pass optimized for image quality (deprecated) ll_2pass_size 8388624 E..V...... Multi-pass optimized for constant frame size (deprecated) vbr_2pass 8388640 E..V...... Multi-pass variable bitrate mode (deprecated) cbr_ld_hq 8388616 E..V...... Constant bitrate low delay high quality mode cbr_hq 8388624 E..V...... Constant bitrate high quality mode vbr_hq 8388640 E..V...... Variable bitrate high quality mode -rc-lookahead <int> E..V...... Number of frames to look ahead for rate-control (from 0 to INT_MAX) (default 0) -surfaces <int> E..V...... Number of concurrent surfaces (from 0 to 64) (default 0) -cbr <boolean> E..V...... Use cbr encoding mode (default false) -2pass <boolean> E..V...... Use 2pass encoding mode (default auto) -gpu <int> E..V...... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from -2 to INT_MAX) (default any) any -1 E..V...... Pick the first device available list -2 E..V...... List the available devices -delay <int> E..V...... Delay frame output by the given amount of frames (from 0 to INT_MAX) (default INT_MAX) -no-scenecut <boolean> E..V...... When lookahead is enabled, set this to 1 to disable adaptive I-frame insertion at scene cuts (default false) -forced-idr <boolean> E..V...... If forcing keyframes, force them as IDR frames. (default false) -spatial_aq <boolean> E..V...... set to 1 to enable Spatial AQ (default false) -spatial-aq <boolean> E..V...... set to 1 to enable Spatial AQ (default false) -temporal_aq <boolean> E..V...... set to 1 to enable Temporal AQ (default false) -temporal-aq <boolean> E..V...... set to 1 to enable Temporal AQ (default false) -zerolatency <boolean> E..V...... Set 1 to indicate zero latency operation (no reordering delay) (default false) -nonref_p <boolean> E..V...... Set this to 1 to enable automatic insertion of non-reference P-frames (default false) -strict_gop <boolean> E..V...... Set 1 to minimize GOP-to-GOP rate fluctuations (default false) -aq-strength <int> E..V...... When Spatial AQ is enabled, this field is used to specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive) (from 1 to 15) (default 8) -cq <float> E..V...... Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control (from 0 to 51) (default 0) -aud <boolean> E..V...... Use access unit delimiters (default false) -bluray-compat <boolean> E..V...... Bluray compatibility workarounds (default false) -init_qpP <int> E..V...... Initial QP value for P frame (from -1 to 51) (default -1) -init_qpB <int> E..V...... Initial QP value for B frame (from -1 to 51) (default -1) -init_qpI <int> E..V...... Initial QP value for I frame (from -1 to 51) (default -1) -qp <int> E..V...... Constant quantization parameter rate control method (from -1 to 51) (default -1) -weighted_pred <int> E..V...... Set 1 to enable weighted prediction (from 0 to 1) (default 0) -b_ref_mode <int> E..V...... Use B frames as references (from 0 to 2) (default disabled) disabled 0 E..V...... B frames will not be used for reference each 1 E..V...... Each B frame will be used for reference middle 2 E..V...... Only (number of B frames)/2 will be used for reference -a53cc <boolean> E..V...... Use A53 Closed Captions (if available) (default true) -s12m_tc <boolean> E..V...... Use timecode (if available) (default true) -dpb_size <int> E..V...... Specifies the DPB size used for encoding (0 means automatic) (from 0 to INT_MAX) (default 0)
エンコードできるけど、オプションは効いてないみたい
ffmpegのmakeで割愛した箇所があったせいか、オプションが効いてないみたいです。
「-b_ref_mode」とか、「-preset」などを指定したものの、作成されたmp4ファイルのサイズは全く同じだったので。。。
ビデオカードを入れた効果
エンコードできているぜ!
オプションは効いてないみたいですが、ちゃんとエンコードはできているようです。h264で作成したファイルサイズと比較して10%~20%ぐらいサイズが大きくなっている印象です。h264の時は1280x720にリサイズしていましたが、h265では1440x1080のままなのでサイズとしては許容範囲と考えています。
爆速エンコード
また、エンコードスピードは約6倍~7倍になっています。今までは60分番組のh264エンコードで60分かかってましたが、ビデオカードのh265のハードエンコードは9分ぐらいです。このスピードアップはとても嬉しいです。
録画サーバは綺麗に作り直したい
ビデオカードを動かすことを第一目標に構築しましたが、ちゃんと作り直したい欲求が出てきました。
ドライバを綺麗に入れたいし、Dockerで動かしたいし、ffmpegでオプションを効かせたいので。また、CentOS7.4は古いので、新しいCentOS8.2に変更したいというのもありますから。
作り直すとなると、録画システム(チューナーとかMirakurunとかChinachu)をインストールし直しになるし、お金と時間が必要そうなので年末年始を乗り越えてから考えようかと思います。