NVENCを使ったHWEncode環境 (Ubuntu 20.04 簡易版)

元記事

https://qiita.com/yamakenjp/items/7474f210efd82bb28490

上記記事では主にx264などもソースから入れるという前提で紹介していましたが、

- 最新のビルドを別に追いかけなくてもいい
- なるべくパッケージで入れたい
- 余計なものも不要

という形向けの手順になります。
この内容なら Dockerfile に転記して docker build してもそんなに時間も手間もかからない気がする。

#必須環境

・NVIDIAのGPUが載っている Ubuntu 20.04 x86_64 マシン

#準備
##CUDAのインストール

NVIDIA CUDA Installation Guide for Linux に従って入れます
https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html

今回はパッケージで入れたいと思いますので、
2. Pre-installation Actions
3. Package Manager Installation
7. Post-installation Actions
こちらを進めれば良いです。

```
# Kernel Headerを入れる
sudo apt-get install linux-headers-$(uname -r)

# 古いapt-keyを削除する
sudo apt-key del 7fa2af80

# cuda-keyring パッケージをDL
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb

# cuda-keyring パッケージをインストール
sudo dpkg -i cuda-keyring_1.1-1_all.deb

# リポジトリ更新
sudo apt-get update

# CUDAインストール
sudo apt-get -y install cuda

# パスを通す
echo 'export PATH=/usr/local/cuda-12.2/bin${PATH:+:${PATH}}' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}' >> ~/.bashrc

source ~/.bashrc
```

サーバなどで、GUIを使っておらず、CLI利用の場合、ドライバ類のインストールと共にX関連も入れるので、必要に応じてCLI起動するように設定しましょう。（必須ではありません。Tesla使ってたらそもそも不要）

```
# 現在の設定を確認
test@test:~$ systemctl get-default
graphical.target
```
graphical.targetと帰ってくると、GUI起動になってるので、CLI(sysvinitでいうrunlevel3)に設定変更

```
# multi-user.target へ変更
test@test:~$sudo systemctl set-default multi-user.target
Created symlink /etc/systemd/system/default.target → /lib/systemd/system/multi-user.target.
```
これで再起動後よりCLIになります。

インストールが完了したら再起動し、 nvidia-smi にてドライバインストールも含め完了しているか確認しましょう。



```
test@test:~$ nvidia-smi
Fri Sep 29 21:12:54 2023       
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.104.12             Driver Version: 535.104.12   CUDA Version: 12.2     |
|-----------------------------------------+----------------------+----------------------+
| 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  NVIDIA T400                    On  | 00000000:01:00.0 Off |                  N/A |
| 42%   52C    P8              N/A /  31W |      1MiB /  2048MiB |      0%      Default |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+
                                                                                         
+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|  No running processes found                                                           |
+---------------------------------------------------------------------------------------+
test@test:~$ 
```

##FFmpegのインストール
Compile FFmpeg for Ubuntu, Debian, or Mint
https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
こちらをベースにffmpegとnv-codec-headers以外はパッケージで入れます。

またインストールされるCUDAのバージョン次第で
`  --extra-cflags="-I/usr/local/cuda-11.5/include" `
`  --extra-ldflags="-L/usr/local/cuda-11.5/lib64" `
を正しいCUDAライブラリのパスに直す必要があります。

```
# FFmpegコンパイルに必要なものを導入
sudo apt-get update -qq && sudo apt-get -y install \
  autoconf \
  automake \
  build-essential \
  cmake \
  git-core \
  libass-dev \
  libfreetype6-dev \
  libgnutls28-dev \
  libunistring-dev \
  libmp3lame-dev \
  libtool \
  libvorbis-dev \
  pkg-config \
  texinfo \
  wget \
  yasm \
  zlib1g-dev

# 作業ディレクトリ作成
mkdir -p ~/ffmpeg_sources ~/bin

# NASM インストール
sudo apt-get -y　install nasm

# libx264 インストール
sudo apt-get -y install libx264-dev

# libx265 インストール
sudo apt-get -y install libx265-dev libnuma-dev

# libvpx インストール
sudo apt-get -y install libvpx-dev

# libfdk-aac インストール
sudo apt-get -y install libfdk-aac-dev

# libopus インストール
sudo apt-get -y install libopus-dev

# libaom インストール
sudo apt-get -y install libaom-dev

# NVIDIA codec API インストール
cd ~/ffmpeg_sources && \
git -C nv-codec-headers pull 2> /dev/null || git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers && \
cd nv-codec-headers && \
make && \
make install PREFIX="$HOME/ffmpeg_build"

# FFmpeg インストール

cd ~/ffmpeg_sources && \
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && \
tar xjvf ffmpeg-snapshot.tar.bz2 && \
cd ffmpeg && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --prefix="$HOME/ffmpeg_build" \
  --pkg-config-flags="--static" \
  --extra-cflags="-I$HOME/ffmpeg_build/include" \
  --extra-ldflags="-L$HOME/ffmpeg_build/lib" \
  --enable-cuda-nvcc \
  --nvccflags="-gencode arch=compute_52,code=sm_52 -O2" \
  --enable-cuvid \
  --enable-nvenc \
  --enable-libnpp \
  --extra-cflags="-I/usr/local/cuda-12.2/include" \
  --extra-ldflags="-L/usr/local/cuda-12.2/lib64" \
  --extra-libs="-lpthread -lm" \
  --ld="g++" \
  --bindir="$HOME/bin" \
  --enable-gpl \
  --enable-gnutls \
  --enable-libaom \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libfreetype \
  --enable-libmp3lame \
  --enable-libopus \
  --enable-libvorbis \
  --enable-libvpx \
  --enable-libx264 \
  --enable-libx265 \
  --enable-nonfree && \
PATH="$HOME/bin:$PATH" make && \
make install && \
hash -r

パスを通したり
source ~/.profile
echo "MANPATH_MAP $HOME/bin $HOME/ffmpeg_build/share/man" >> ~/.manpath
```

あとの使い方は元記事を参考に。