3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NVENCを使ったHWEncode環境 (RHEL8版)

Last updated at Posted at 2021-08-13

どうも、やまけんです。
以前書いた下記の記事のRHEL8版です

普段あまりRHELを使うことがないので、この記事はほぼ検証のためだけに実行した結果を残すだけで、元記事のように永続的に更新する予定はありません。

おそらくCUDAのバージョン差異でその時々でインストール方法が変わるぐらいだとは思いますので、なんとか読み替えてください。(元記事のUbuntu向けは自分がその環境で使ってるので、変更があれば適宜直してるんですけど。ちょっとRHELまでは無理)

#環境

# cat /etc/redhat-release 
Red Hat Enterprise Linux release 8.4 (Ootpa)

# lspci | grep -i nvidia
01:00.0 VGA compatible controller: NVIDIA Corporation TU117 [GeForce GTX 1650] (rev a1)
01:00.1 Audio device: NVIDIA Corporation Device 10fa (rev a1)

#準備
##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
こちらを進めれば良いです。

# Development ToolsとKernel Headerを入れる
sudo dnf group install "Development Tools"
sudo dnf install kernel-devel-$(uname -r) kernel-headers-$(uname -r)

# dkmsを入れるためにEPELリポジトリを有効化
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

# nvidiaリポジトリを追加
sudo dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo

# dnf キャッシュをクリーン
sudo dnf clean all

# ドライバーをインストール
sudo dnf -y module install nvidia-driver:latest-dkms

# cudaをインストール
sudo dnf -y install cuda

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

source ~/.bashrc

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

# nvidia-smi
Fri Aug 13 10:43:38 2021       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.57.02    Driver Version: 470.57.02    CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+
| 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 GeForce ...  Off  | 00000000:01:00.0 Off |                  N/A |
| 54%   33C    P0     1W /  75W |      0MiB /  3908MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
# 

##FFmpegのインストール
Compile FFmpeg on CentOS
https://trac.ffmpeg.org/wiki/CompilationGuide/Centos
こちらをベースに全てソースコードで入れていきます。

TLS対応のために openssl-devel をインストールの上
--enable-openssl を追記しています。

また、FFmpeg4以降でnvencを使用する場合は nv-codec-headers が必要です。
これらはNVIDIA Video Codec SDKの一部を使用しています。
https://developer.nvidia.com/ffmpeg
https://github.com/FFmpeg/nv-codec-headers

ちなみに
https://developer.nvidia.com/blog/nvidia-ffmpeg-transcoding-guide/
において、コンパイル時は
./configure --enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64
という記載がありますが、 ./configure --help | grep cuda で調べればわかるとおり、現在は

  --enable-cuda-nvcc       enable Nvidia CUDA compiler [no]

が正しいため、--enable-cuda ではなく --enable-cuda-nvcc に変更しています。

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

なお、インストールされるドライババージョンによって、NVIDIA Video Codec SDKのバージョン依存が発生します。
https://github.com/FFmpeg/nv-codec-headers のREADMEにて対応バージョンを確認ください。

本ドキュメントは基本的に最新のドライバをインストールしてある前提にあります。

必ず nvidia-smi にてインストールされているドライババーションを確認してください。

古いグラボなどで最新ドライバが入らない場合、
https://github.com/FFmpeg/nv-codec-headers の ブランチを切り替えると、過去のSDKでの必要ドライババーションの確認が確認ができます。

ドライバが古い場合は、NVIDIA codec API のインストール時の
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers -b sdk/9.0
のように -b sdk/9.0 でブランチを指定してインストールしてみてください。

# FFmpegコンパイルに必要なものを導入
sudo dnf install autoconf automake bzip2 bzip2-devel cmake freetype-devel gcc gcc-c++ git libtool make pkgconfig zlib-devel openssl-devel

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

# NASM インストール
cd ~/ffmpeg_sources
curl -O -L https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2
tar xjvf nasm-2.15.05.tar.bz2
cd nasm-2.15.05
./autogen.sh
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make
make install

# Yasm インストール
cd ~/ffmpeg_sources
curl -O -L https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar xzvf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make
make install

# libx264 インストール
cd ~/ffmpeg_sources
git clone --branch stable --depth 1 https://code.videolan.org/videolan/x264.git
cd x264
PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static
make
make install

# libx265 インストール
cd ~/ffmpeg_sources
git clone --branch stable --depth 2 https://bitbucket.org/multicoreware/x265_git
cd ~/ffmpeg_sources/x265_git/build/linux
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED:bool=off ../../source
make
make install

# libfdk-aac インストール
cd ~/ffmpeg_sources
git clone --depth 1 https://github.com/mstorsjo/fdk-aac
cd fdk-aac
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install

# libmp3lame インストール
cd ~/ffmpeg_sources
curl -O -L https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz
tar xzvf lame-3.100.tar.gz
cd lame-3.100
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --disable-shared --enable-nasm
make
make install

# libopus インストール
cd ~/ffmpeg_sources
curl -O -L https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz
tar xzvf opus-1.3.1.tar.gz
cd opus-1.3.1
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install

# libvpx インストール
cd ~/ffmpeg_sources
git clone --depth 1 https://chromium.googlesource.com/webm/libvpx.git
cd libvpx
./configure --prefix="$HOME/ffmpeg_build" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --as=yasm
make
make install

# NVIDIA codec API インストール
cd ~/ffmpeg_sources
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
curl -O -L 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-11.4/include" \
  --extra-ldflags="-L/usr/local/cuda-11.4/lib64" \
  --extra-libs="-lpthread -lm" \
  --ld="g++" \
  --bindir="$HOME/bin" \
  --enable-openssl \
  --enable-gpl \
  --enable-libfdk-aac \
  --enable-libfreetype \
  --enable-libmp3lame \
  --enable-libopus \
  --enable-libvpx \
  --enable-libx264 \
  --enable-libx265 \
  --enable-static \
  --enable-nonfree
make
make install

##動作確認
実際にインストールが成功したか、下記のコマンドでnvencエンコード関連オプションが使えるか確認します。

for i in buildconf hwaccels decoders filters encoders; do echo $i:; ffmpeg -hide_banner -${i} | egrep -i "npp|cuvid|nvenc|cuda|nvdec"; done

結果はこのようになると思います。

test@test:~$ for i in buildconf hwaccels decoders filters encoders; do echo $i:; ffmpeg -hide_banner -${i} | egrep -i "npp|cuvid|nvenc|cuda|nvdec"; done
buildconf:
    --enable-cuda-nvcc
    --enable-cuvid
    --enable-nvenc
    --enable-libnpp
    --extra-cflags=-I/usr/local/cuda-11.4/include
    --extra-ldflags=-L/usr/local/cuda-11.4/lib64
hwaccels:
cuda
decoders:
 V..... av1_cuvid            Nvidia CUVID AV1 decoder (codec av1)
 V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
 V..... hevc_cuvid           Nvidia CUVID HEVC decoder (codec hevc)
 V..... mjpeg_cuvid          Nvidia CUVID MJPEG decoder (codec mjpeg)
 V..... mpeg1_cuvid          Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
 V..... mpeg2_cuvid          Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
 V..... mpeg4_cuvid          Nvidia CUVID MPEG4 decoder (codec mpeg4)
 V..... vc1_cuvid            Nvidia CUVID VC1 decoder (codec vc1)
 V..... vp8_cuvid            Nvidia CUVID VP8 decoder (codec vp8)
 V..... vp9_cuvid            Nvidia CUVID VP9 decoder (codec vp9)
filters:
 ... hwupload_cuda     V->V       Upload a system memory frame to a CUDA device.
 ... overlay_cuda      VV->V      Overlay one video on top of another using CUDA
 ... scale_cuda        V->V       GPU accelerated video resizer
 ... scale_npp         V->V       NVIDIA Performance Primitives video scaling and format conversion
 ... thumbnail_cuda    V->V       Select the most representative frame in a given sequence of consecutive frames.
 ... transpose_npp     V->V       NVIDIA Performance Primitives video transpose
 T.. yadif_cuda        V->V       Deinterlace CUDA frames
encoders:
 V....D 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....D hevc_nvenc           NVIDIA NVENC hevc encoder (codec hevc)
test@test:~$

きちんとビルド時のオプションが有効なこと、デコーダ、フィルター、エンコーダにnvenc関連が入っているのがわかります。

表示が出ない場合、今回コンパイルしたffmpegではないパッケージでインストールしたffmpegなどの結果になっている可能性があります。 which ffmpeg にてffmpegのパスを確認し、今回コンパイルしたffmpegで間違い無いかを確認してください。

#実際に使ってみる

では実際に使ってみましょう。

MPEG2からH.265へ720pでエンコード

ffmpeg -hwaccel cuvid -c:v mpeg2_cuvid -deint adaptive -drop_second_field 1 -i input.mp2ts -c:v hevc_nvenc -vf scale_npp=-1:720 -tag:v hvc1 -f mp4 out.mp4

解説です。

-hwaccel cuvid

HWエンコードでcuvidを明示(cuvidについては互換性維持のため残っていますが、そのうちcudaに変わります。しかしscale_npp周りで実装が変わるので、明示的に古いままにしています。)

-c:v mpeg2_cuvid

MPEG2のハードウェアデコードを明示

-deint adaptive -drop_second_field 1

インターレス解除します。-deintだけだとフレーム数が2倍に増えるだけなので-drop_second_field 1 で増えたフレームを間引いています。

-i input.mp2ts

変換元ファイルを指定します。

-c:v hevc_nvenc

H.265でNVEncを使います

-vf scale_npp=-1:720

720Pになるよう縮小 通常はscale=と使うかと思いますが、scale_nppでnvidiaのHWスケーリングを使うので高速になります。

-tag:v hvc1

Apple製品で扱えるH.265は hev1ではなくhvc1の方なので、タグで明示します

-f mp4

出力ファイルフォーマットがをmp4であると明示します

out.mp4

出力先ファイル名を指定

詳しいオプションは
Using FFmpeg with NVIDIA GPU Hardware Acceleration
https://developer.nvidia.com/designworks/dl/Using_FFmpeg_with_NVIDIA_GPU_Hardware_Acceleration-pdf
にて。

##注意
Geforce などのコンシュマー向けGPUでは、同時にエンコードできるストリームは2本に制限されてますので、同時に複数のHWエンコードが必要(ストリーミング環境など)はQuadroやTeslaが必要です。

3
2
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?