東京生まれHOUSE MUSIC育ち

悪そうな奴はだいたい友達なの?

ビデオカードを使えるようにするまでに実施したこと


スポンサードリンク

購入したビデオカードが使えるようになりました。だましながら、エンコードできるようになったという状況です。

いやー、ほんと苦労しました。Linuxにビデオカードを導入するという記事をネットで探しましたが、あまり無いんですよね。あっても古かったりして、自分で試行錯誤しました。

また、運用している録画サーバでの録画は継続したかったので、録画していないタイミングを狙って作業していたので、時間がかかりました。

この記事では、CentOS7.4でビデオカードを使えるようにするため、どんなことをしたかを記録的に書いています。

f:id:padobure:20201205110523j:plain

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の中の人が書いてます。

medium.com

記事にもあるように、「パッケージでドライバを入れる、パッケージでできなかったらRUNFILEを利用する」というのがオススメでした。

私はこの記事を見つける前にRUNFILEを入れてしまい、動かない状況となりました。なので、改めてパッケージでドライバを導入しました。

パッケージによるドライバの入れ方は以下のURLから自分のOSを選択していけばコマンドが表示されます。

developer.nvidia.com

ドライバがインストールできると、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のバージョンを上げたりしたのですが、それでもうまく行かなかったです。あるパッケージが不足しているようなメッセージが出たのですが、これが解決できませんでした。

docs.nvidia.com

また、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しようとしました。

blog.goo.ne.jp

しかしここでも、うまくいきません。詰まったのは、以下の箇所です。

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)をインストールし直しになるし、お金と時間が必要そうなので年末年始を乗り越えてから考えようかと思います。