FFmpeg 3.x 以前ではソースコードから FFmpeg をビルドしてインストールする場合、NVENC でサポートされる GPU とそのドライバがインストールされていればデフォルトで NVENC が有効になっていました。つまり、h264_nvenc, hevc_nvenc が有効 (–enable-nvenc) であり、HEVC/H.265 にトランスコード(エンコード)できるようになっていました。
しかし、FFmpeg 4.0 以降では、FFmpeg をソースコードからビルドしてインストールした後、
ffmpeg -encoders | grep nvenc
を実行しても何も表示されませんでした。
そのため、FFmpeg 4.0 以降でも FFmpeg で NVENC を有効にし、HEVC/H.265 にトランスコード(エンコード)するための手順を記載していきます。私の GPU は、GTX-1050 です。
なお、NVENC でサポートされる GPU は、NVIDIA のホームページの Video Encode and Decode GPU Support Matrix で確認することができます。
https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new
必要と思われるパッケージのインストール
まず、必要と思われるパッケージを APT でインストールします。私にとって必要なパッケージをインストールしており、他者にとっては過剰なインストールになっているかもしれません。
sudo apt install -y build-essential git wget libasound2-dev \
autoconf libtool pcsc-tools pkg-config libpcsclite-dev pcscd \
cmake yasm curl ssh dkms
GPU ドライバのインストール
NVIDIA のホームページからドライバをダウンロードするのではなく、Ubuntu 内のコマンドでダウンロードすることにしました。
まず、ubuntu-drivers コマンドを実行し、インストールできるドライバの選択肢を確認します。
$ ubuntu-drivers devices
WARNING:root:_pkg_get_support nvidia-driver-390: package has invalid Support Legacyheader, cannot determine support level
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00001C81sv00001462sd00008C97bc03sc00i00
vendor : NVIDIA Corporation
model : GP107 [GeForce GTX 1050]
driver : nvidia-driver-460 - distro non-free recommended
driver : nvidia-driver-460-server - distro non-free
driver : nvidia-driver-450-server - distro non-free
driver : nvidia-driver-390 - distro non-free
driver : nvidia-driver-418-server - distro non-free
driver : nvidia-driver-450 - distro non-free
driver : xserver-xorg-video-nouveau - distro free builtin
recommended であり、バージョン番号が最も大きい最新のドライバである nvidia-driver-460 をインストールします。recommended のドライバは、ubuntu-drivers コマンドの autoinstall オプションでインストールすることができます。インストール後、Ubuntu を再起動します。
sudo ubuntu-drivers autoinstall
sudo reboot
Ubuntu 再起動後、nvidia-smi コマンドを実行すると、ドライバのバージョン、CUDA のバージョンを確認することができます。
$ nvidia-smi
Mon May 10 02:56:19 2021
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.73.01 Driver Version: 460.73.01 CUDA Version: 11.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 GeForce GTX 1050 Off | 00000000:01:00.0 On | N/A |
| 43% 41C P8 N/A / 75W | 333MiB / 1999MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| 0 N/A N/A 768 G /usr/lib/xorg/Xorg 180MiB |
| 0 N/A N/A 1056 G /usr/bin/gnome-shell 87MiB |
| 0 N/A N/A 1703 G gnome-control-center 33MiB |
| 0 N/A N/A 1756 G ...AAAAAAAAA= --shared-files 28MiB |
+-----------------------------------------------------------------------------+
nv-codec-headers のインストール
FFmpeg の wiki によると、NVENC のために nv-codec-headers が必要になります。
https://trac.ffmpeg.org/wiki/HWAccelIntro
nv-codec-headers は、GitHub でソースコードが公開されています。
https://github.com/FFmpeg/nv-codec-headers
適当な作業用ディレクトリを作成し、ソースコードをダウンロードし、ビルドし、インストールします。
mkdir ~/working_directory
cd ~/working_directory && \
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers && \
cd nv-codec-headers && \
make -j$(nproc) && \
sudo make install
FFmpeg のインストール
このポストを書いている 2021 年 5 月時点で最新の 4.3.1 をインストールしました。
cd ~/working_directory && \
wget http://ffmpeg.org/releases/ffmpeg-4.4.tar.gz && \
tar zxvf ffmpeg-4.4.tar.gz && \
cd ffmpeg-4.4 && \
./configure --disable-shared --enable-static && \
make -j$(nproc) && \
sudo make install
トランスコード(エンコード)確認
実際に ffmpeg コマンドを実行し、動作を確認してみます。例えば下記のように、任意のビデオファイルを HEVC/H.265 の MP4 にトランスコードしてみます。
ffmpeg -i input.ts -vcodec hevc_nvenc -tag:v hvc1 output.mp4
FFmpeg のログを確認すると、hevc_nvenc が使用されていることがわかります。つまり、NVENC で HEVC/H.265 へのトランスコードがされています。変換速度も 10 倍であり、ハードウェアアクセラレーションによる変換であることがわかります。
Stream mapping:
Stream #0:8 -> #0:0 (mpeg2video (native) -> hevc (hevc_nvenc))
Stream #0:2 -> #0:1 (aac (native) -> aac (native))
Output #0, mp4, to 'output.mp4':
Metadata:
encoder : Lavf58.45.100
Stream #0:0: Video: hevc (hevc_nvenc) (Main) (hvc1 / 0x31637668), yuv420p, 1440x1080 [SAR 4:3 DAR 16:9], q=-1--1, 2000 kb/s, 29.97 fps, 30k tbn, 29.97 tbc
Metadata:
encoder : Lavc58.91.100 hevc_nvenc
Side data:
cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 4000000 vbv_delay: N/A
Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s
Metadata:
encoder : Lavc58.91.100 aac
frame= 546 fps=304 q=25.0 Lsize= 4488kB time=00:00:18.18 bitrate=2021.7kbits/s dup=17 drop=0 speed=10.1x