目的
環境を汚さず最小構成で、Nvidia GPUを使用したハードウェアエンコードが可能なFFmpegを手に入れます。
環境
- OS: Ubuntu 22.04 on WSL2
- GPU: Geforce RTX 4090
- GPUドライバ: NVIDIA Studioドライバー 566.14
結論
次の内容のDockerfile
を作成して
FROM nvidia/cuda:12.6.2-devel-ubuntu24.04
# Select and pull from "https://catalog.ngc.nvidia.com/orgs/nvidia/containers/cuda".
# `base` does NOT include `nvcc` that is required to compile ffmpeg with nvcodec.
# The first one is necessary not to stop at installing git with time zone selection.
ENV DEBIAN_FRONTEND=noninteractive
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES video,compute,utility
# NVIDIA have not set these fundamental environment variables which most programs refer to
# while they selves are requiring in "https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#mandatory-actions".
# An error about missing (not found) `nvcc` can raise without these setup.
ENV PATH="/usr/local/cuda-12.6/bin${PATH:+:${PATH}}"
ENV PKG_CONFIG_PATH="/usr/local/lib/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}"
ENV LD_LIBRARY_PATH="/usr/local/cuda-12.6/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
# See "https://docs.nvidia.com/video-technologies/video-codec-sdk/12.0/ffmpeg-with-nvidia-gpu/index.html#compiling-for-linux".
# git, nasm and pkg-config are also required to install ffmpeg, however they are not included in above instruction.
# So they are added in following command.
RUN apt-get update \
&& apt-get install -y build-essential yasm cmake libtool libc6 libc6-dev unzip wget libnuma1 libnuma-dev git nasm pkg-config
# Check what version of Video Codec SDK is available with README in "https://github.com/FFmpeg/nv-codec-headers".
# Match the SDK and cuda.
# Ref) https://docs.nvidia.com/video-technologies/video-codec-sdk/12.2/read-me/index.html#system-requirements
RUN mkdir ffmpeg-nvcodec && cd ffmpeg-nvcodec \
&& git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git \
&& cd nv-codec-headers && make && make install
RUN git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg/ && cd ffmpeg \
&& wget https://ffmpeg.org/releases/ffmpeg-7.1.tar.xz \
&& tar -xf ffmpeg-7.1.tar.xz \
&& rm ffmpeg-7.1.tar.xz \
&& cd ffmpeg-7.1 \
&& ./configure \
--enable-nonfree --extra-cflags=-I/usr/local/cuda/include \
--extra-ldflags=-L/usr/local/cuda/lib64 \
--disable-static \
--enable-shared \
--enable-cuda-nvcc \
--enable-libnpp \
&& make -j $(nproc) \
&& make install
RUN echo 'export PATH=$PATH' >> ~/.bashrc \
&& echo 'export PKG_CONFIG_PATH=$PKG_CONFIG_PATH' >> ~/.bashrc \
&& echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH' >> ~/.bashrc \
&& mkdir workspace
ビルドする
sudo docker pull nvidia/cuda:12.6.2-devel-ubuntu24.04
sudo docker build -t ffmpeg:12.6.2-devel-ubuntu24.04 .
sudo docker run --gpus all -it --rm -v $(pwd):/workspace ffmpeg:12.6.2-devel-ubuntu24.04
手順
事前準備
WSL2にインストールしたDocker
でGPUを使用可能になっていることが必要です。
そこまでの方法は以前に紹介しています。
NVIDIA Container Toolkitのインストールまで完了して下さい。
使用可能なCUDAのバージョン確認
ffnvcodecが対応しているCUDAを調べます。これは2段階で行います。
まず配布ページのREADMEでffnvcodecが対応しているVideo Codec SDKのバージョンを調べます。
続いてそのSDKのページを探して対応しているCUDAのバージョンを確認します。
例えばSDK v12.2であればhttps://docs.nvidia.com/video-technologies/video-codec-sdk/12.2/read-me/index.html#system-requirements にCUDA 11.0以上と記載されています。
CUDAインストール済みDockerイメージの入手
使えるバージョンのCUDAがインストールされたイメージをNVIDIA NGCで探します。
注意点としてタグにbase
とあるイメージはNVENCを有効にするために必要なnvcc
がインストールされていません。このためdevel
とあるイメージから好みのものを選択して下さい。この記事では12.6.2-devel-ubuntu24.04
を選択します。
sudo docker pull nvidia/cuda:12.6.2-devel-ubuntu24.04
FFmpegのバージョンを選択
リリースされているものから選んでください。この記事では7.1を選びます。
Dockerfileの作成
冒頭のコードの編集
FFmpegをインストールしたDockerイメージを作るためにDockerfile
を準備します。
結論に記載したコードをDockerfile
に書き込み、次のように修正して下さい。
- 1行目を入手したCUDAインストール済みDockerイメージに合わせる
- CUDAのバージョン(例 12.6)に合わせて
ENV PATH="/usr/local/cuda-12.6/bin${PATH:+:${PATH}}"
を書き換える - 同じく
ENV LD_LIBRARY_PATH="/usr/local/cuda-12.6/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
を書き換える - 3つ目の
RUN
のFFmpegのバージョン4箇所を書き換える
解説
CUDAのインストールガイドで必須とされているにも関わらず、NVIDIAが提供しているDockerイメージでは環境変数が設定されていません。このまま放置するとnvcc
が見つからないというエラーが出たり、肝心のNVENCが含まれないFFmpegが出来上がったりします。そのためENV
で設定しています。ただし、イメージから起動したコンテナ中には持ち込まれないため最後のRUN
を行っています。
またENV DEBIAN_FRONTEND=noninteractive
がない場合には、最初のRUN
でライブラリのインストール中にタイムゾーンを選ばされて処理が止まります。これは(普通はインストール済みのため)NVIDIAの説明にないgit
を追加したことで起こります。
NVENC有効なFFmpegをインストールしたDockerイメージの作成
作成したDockerfile
があるディレクトリで次を実行します。基にしたイメージが分かる方が管理しやすいため、タグは基のイメージと同じにします。ただの好みなので変更しても問題ありません。
sudo docker build -t ffmpeg:12.6.2-devel-ubuntu24.04 .
あとはDockerコンテナを起動すればNVENC可能なFFmpegが使えます。
sudo docker run --gpus all -it --rm -v $(pwd):/workspace ffmpeg:12.6.2-devel-ubuntu24.04
オプションの意味は次の通りです。
-
--gpus all
: 起動したコンテナでGPUを使用するために必須 -
-it
: インタラクティブシェルに入る -
--rm
: 同じイメージ由来のコンテナが起動済みの場合は古いコンテナを削除 -
-v $(pwd):/workspace
: カレントディレクトリをコンテナ中の/workspace
に接続
結言
パスの設定を忘れずに。