Dockerコンテナ上のFFmpegでNVENCハードウェアエンコード

Docker コンテナ上にインストールされた FFmpeg で、NVENC を使用したH.264、HEVC/H.265 ハードウェアエンコードを行います。そのためには、予め Docker をインストールするマシンに NVIDIA のビデオカードを装着し、NVIDIA ドライバをインストールしておく必要があります。

環境

私の環境は以下のとおりです。

OS

  • Ubuntu 20.04.2 LTS (5.11.0-25-generic)

Docker

  • Docker 20.10.7

FFmpeg

  • FFmpeg 4.4

NVIDIA ビデオカード

  • MSI GeForce GTX 1050 2GT LP

NVIDIA ドライバ

  • Driver Version: 470.57.02
  • CUDA Version: 11.4

NVIDIA ドライバのインストール

Ubuntu 20.04 への NVIDA ドライバのインストール手順は、別のポストに記述しています。

Docker のインストール

Docker の公式ドキュメントを参考に行います。ここではログインしているユーザーを docker グループに入れ、OS 再起動後に docker コマンドを実行できるようにしています。

sudo apt update
sudo apt install -y \
  apt-transport-https \
  ca-certificates \
  curl \
  gnupg \
  lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
sudo usermod -aG docker $USER
sudo reboot

docker run hello-world
Docker Documentation

Jumpstart your client-side server applications with Docker E…

Dockerfile

最低限必要と考えられる記述を抜粋しています。

FROM nvidia/cuda:11.4.1-devel-ubuntu20.04

ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES all

# Package
RUN apt-get update

RUN apt-get install -y --no-install-recommends \
  git build-essential \
  # FFmpeg
  pkg-config nasm yasm


# FFmpeg
RUN cd /tmp && \
    git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers && \
    cd nv-codec-headers && \
    make -j$(nproc) && \
    make install

RUN cd /tmp && \
    wget https://ffmpeg.org/releases/ffmpeg-4.4.tar.gz && \
    tar zxvf ffmpeg-4.4.tar.gz && \
    cd ffmpeg-4.4 && \
    ./configure --enable-nonfree --enable-cuda-nvcc --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64 --nvccflags="-gencode arch=compute_52,code=sm_52 -O2" && \
    make -j$(nproc) && \
    make install

大元の Dockerfile は下記のものです。

動作確認

まず、Docker コンテナを起動します。下記は私の事例であり一例です。重要な点は、gpus オプションを付けることです。これを忘れるとコンテナ上でハードウェアエンコードができません。

docker run \
  --name izanami \
  --net nihon \
  --gpus all \
  --privileged \
  --volume /dev/:/dev/ \
  --volume /opt/izanami/video:/opt/izanami/video \
  --volume /etc/localtime:/etc/localtime:ro \
  -p 8080:8080 \
  -d \
  -it $USER/izanami:1.0.0-SNAPSHOT

コンテナにログインし、ffmpeg コマンドでコーデックを確認します。h264_nvenc, hevc_nvenc をサポートしていることがわかります。

$ docker exec -it izanami bash

root@5a81edb88e4d:/# ffmpeg -codecs | grep nvenc

ffmpeg version 4.4 Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-17ubuntu1~20.04)
  configuration: --enable-nonfree --enable-cuda-nvcc --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64 --nvccflags='-gencode arch=compute_52,code=sm_52 -O2'
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
 DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_v4l2m2m h264_cuvid ) (encoders: h264_nvenc h264_v4l2m2m nvenc nvenc_h264 )
 DEV.L. hevc                 H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_v4l2m2m hevc_cuvid ) (encoders: nvenc_hevc hevc_nvenc hevc_v4l2m2m )

参考情報

NVIDIA が提供している、GPU に対応した Docker イメージです。

上記の Docker イメージの環境変数に関する説明が記載されています。

GitHub

NVIDIA container runtime. Contribute to NVIDIA/nvidia-contai…

NVENC に対応した FFmpeg を Linux でコンパイルするための説明が記載されています。