Docker で QSV 対応 ffmpeg のビルド on Ubuntu 20.04 LTS

Docker で QSV 対応 ffmpeg のビルド on Ubuntu 20.04 LTS

はじめに

なぜか年末になると ffmpeg ビルド芸をしている(2年連続2度目)のですが,今年は QSV 対応のビルドにチャレンジしてみた.
最近は身内の Discord でこういう話を垂れ流していてろくにブログを書いてなかったんだけど,ググってもあんまりヒットしなかったので書いておく.

なお,去年の成果物は以下.やたら static build に拘ったがなんの意味があったのかはよくわからない.ここで試行錯誤したことが少し仕事に活きたのでそれで良かったことにしよう.今そう気持ちの整理をした().

github.com

QSV

説明不要だと思いますが Intel Quick Sync Video のことで,ハードウェア支援を利用して動画のエンコード・デコードを行う仕組み.
動画のエンコードは CPU でぶん回すことが多いんですが, CPU がしょっぱいとそんなに速度がでないけど QSV を使うと早くなる.具体的な速度比較はのちほど(CPU のみのエンコードと比較すると多少画質や圧縮率の劣化がある).
サーバ用途に新しい NUC を買ったことで古い NUC が不要になったので退役させて転用することにした(ESXi の USB パススルーでとあるデバイスがうまく動作しないので実機化したかったという裏事情もある).

ハードウェア

今回使ったのは以下のほぼ5年前にサーバにした NUC5i5RYH で CPU は i5-5250U の Broadwell になる.

yuta1024.hateblo.jp

CPU の世代でサポートされているフォーマットの範囲が異なるので非常にややこしい.
今回の Broadwell は h.264エンコードはサポートしているのでそちらを利用した.本当は hevc にしたいんだけど Skylake 以降じゃないと無理なので諦め.

ffmpeg のビルド

今回使った OS は Ubuntu 20.04 LTS で,理由は各種パッケージが揃っていて ffmpeg のビルドだけで済むから.あと最近はなんでもコンテナに押し込んでホストマシンは Docker 入れればオッケーみたいな脳死をしているのでコンテナで ffmpeg をビルドして,利用もコンテナから行う.

というわけでさっそく Dockerfile が以下.ビルド時に FFMPEG_VERSION を build-arg として渡す必要がある.現時点で最新タグの n4.3.1 をビルドする場合は sudo docker build --build-arg FFMPEG_VERSION=n4.3.1 . -t ffmpeg みたいな感じ.

FROM ubuntu:focal
ARG FFMPEG_VERSION
ENV DEBIAN_FRONTEND=noninteractive

WORKDIR /opt/ffmpeg
RUN set -x && \
    apt-get update && \
    apt-get install -y \
      git make g++ yasm \
      libfdk-aac-dev libva-dev libmfx-dev intel-media-va-driver-non-free && \
    git clone https://github.com/FFmpeg/FFmpeg --depth=1 -b $FFMPEG_VERSION . && \
    ./configure \
      --disable-ffplay \
      --disable-debug \
      --disable-doc \
      --enable-libmfx && \
    make -j $(grep cpu.cores /proc/cpuinfo | sort -u | sed 's/[^0-9]//g')

ほとんど何も enable になっていないので,この ffmpegh264_qsv 以外で利用したらほぼ死ぬ.オーディオも copy 推奨.

いくつかはまったポイントが以下.

  • ENV DEBIAN_FRONTEND=noninteractive は依存で入る tzdata がビルド中に timezone を指定しろと言ってくるのを回避するために必要.
  • --enable-libmfx ためになぜか libfdk-aac-dev が必要.ないと libmfx が not found になる.

コンテナから QSV 対応の ffmpeg の利用

上記をマルチステージビルドしてバイナリだけもってくる場合でも以下のパッケージは必要となる.

  • libva2
  • libva-drm2
  • intel-media-va-driver-non-free
  • libmfx1
  • libva-x11-2

また QSV を利用する場合は /dev/dri をコンテナ側にデバイスとして渡してあげる必要がある.以下のような感じで run する(実際はエンコードしたいファイルがあるホスト側のどっかをマウントとかしないとだめだけど).

$ sudo docker run --rm -it --device=/dev/dri ffmepg bash

適当にあった動画をエンコードしてみた結果が以下.

h264_qsv

$ ffmpeg -i <input> -c:v h264_qsv -q:v 23 -c:a copy <output>
(snip)
frame= 4477 fps=222 q=30.0 Lsize=  105735kB time=00:02:29.37 bitrate=5798.7kbits/s speed= 7.4x
video:103283kB audio:2286kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.157409%

h264(QSV なし)

ffmpeg は apt-get で入れたもので独自ビルドではない.)

$ ffmpeg -i <input> -c:v h264 -q:v 23 -c:a copy <output>
(snip)
frame= 4477 fps= 25 q=-1.0 Lsize=   80439kB time=00:02:29.37 bitrate=4411.4kbits/s speed=0.83x
video:77992kB audio:2286kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.200254%

同じビルドの ffmpeg ではないので厳密な比較にはならないが,エンコード速度は8倍以上の差がついた.一方で容量は 32% ほど大きくなった.

まとめ

大体自分の環境では8倍くらい早くなって満足. public にしたかったんだけど他のファイルとの兼ね合いで現状 private repo に.submodule で読めるようにしておけば良かった.気が向けば. もう来年は ffmpeg ビルド芸したくないけどベースイメージは debian にしたいので, debian でパッケージが揃ってたらワンちゃん….

おまけ

ビルドした ffmpeg-encoders を実行した結果.

# ffmpeg -encoders
ffmpeg version n4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-17ubuntu1~20.04)
  configuration: --disable-ffplay --disable-debug --disable-doc --enable-libmfx
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
Encoders:
 V..... = Video
 A..... = Audio
 S..... = Subtitle
 .F.... = Frame-level multithreading
 ..S... = Slice-level multithreading
 ...X.. = Codec is experimental
 ....B. = Supports draw_horiz_band
 .....D = Supports direct rendering method 1
 ------
 V..... a64multi             Multicolor charset for Commodore 64 (codec a64_multi)
 V..... a64multi5            Multicolor charset for Commodore 64, extended with 5th color (colram) (codec a64_multi5)
 V..... alias_pix            Alias/Wavefront PIX image
 V..... amv                  AMV Video
 V..... asv1                 ASUS V1
 V..... asv2                 ASUS V2
 V..... avrp                 Avid 1:1 10-bit RGB Packer
 V..X.. avui                 Avid Meridien Uncompressed
 V..... ayuv                 Uncompressed packed MS 4:4:4:4
 V..... bmp                  BMP (Windows and OS/2 bitmap)
 V..... cinepak              Cinepak
 V..... cljr                 Cirrus Logic AccuPak
 V.S... vc2                  SMPTE VC-2 (codec dirac)
 VFS... dnxhd                VC3/DNxHD
 V..... dpx                  DPX (Digital Picture Exchange) image
 VFS... dvvideo              DV (Digital Video)
 V.S... ffv1                 FFmpeg video codec #1
 VF.... ffvhuff              Huffyuv FFmpeg variant
 V..... fits                 Flexible Image Transport System
 V..... flv                  FLV / Sorenson Spark / Sorenson H.263 (Flash Video) (codec flv1)
 V..... gif                  GIF (Graphics Interchange Format)
 V..... h261                 H.261
 V..... h263                 H.263 / H.263-1996
 V..... h263_v4l2m2m         V4L2 mem2mem H.263 encoder wrapper (codec h263)
 V.S... h263p                H.263+ / H.263-1998 / H.263 version 2
 V..... h264_qsv             H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration) (codec h264)
 V..... h264_v4l2m2m         V4L2 mem2mem H.264 encoder wrapper (codec h264)
 V..... h264_vaapi           H.264/AVC (VAAPI) (codec h264)
 V..... hevc_qsv             HEVC (Intel Quick Sync Video acceleration) (codec hevc)
 V..... hevc_v4l2m2m         V4L2 mem2mem HEVC encoder wrapper (codec hevc)
 V..... hevc_vaapi           H.265/HEVC (VAAPI) (codec hevc)
 VF.... huffyuv              Huffyuv / HuffYUV
 V..... jpeg2000             JPEG 2000
 VF.... jpegls               JPEG-LS
 VF.... ljpeg                Lossless JPEG
 VF.... magicyuv             MagicYUV video
 VFS... mjpeg                MJPEG (Motion JPEG)
 V..... mjpeg_qsv            MJPEG (Intel Quick Sync Video acceleration) (codec mjpeg)
 V..... mjpeg_vaapi          MJPEG (VAAPI) (codec mjpeg)
 V.S... mpeg1video           MPEG-1 video
 V.S... mpeg2video           MPEG-2 video
 V..... mpeg2_qsv            MPEG-2 video (Intel Quick Sync Video acceleration) (codec mpeg2video)
 V..... mpeg2_vaapi          MPEG-2 (VAAPI) (codec mpeg2video)
 V.S... mpeg4                MPEG-4 part 2
 V..... mpeg4_v4l2m2m        V4L2 mem2mem MPEG4 encoder wrapper (codec mpeg4)
 V..... msmpeg4v2            MPEG-4 part 2 Microsoft variant version 2
 V..... msmpeg4              MPEG-4 part 2 Microsoft variant version 3 (codec msmpeg4v3)
 V..... msvideo1             Microsoft Video-1
 V..... pam                  PAM (Portable AnyMap) image
 V..... pbm                  PBM (Portable BitMap) image
 V..... pcx                  PC Paintbrush PCX image
 V..... pgm                  PGM (Portable GrayMap) image
 V..... pgmyuv               PGMYUV (Portable GrayMap YUV) image
 V..... ppm                  PPM (Portable PixelMap) image
 VF.... prores               Apple ProRes
 VF.... prores_aw            Apple ProRes (codec prores)
 VFS... prores_ks            Apple ProRes (iCodec Pro) (codec prores)
 V..... qtrle                QuickTime Animation (RLE) video
 V..... r10k                 AJA Kona 10-bit RGB Codec
 V..... r210                 Uncompressed RGB 10-bit
 V..... rawvideo             raw video
 V..... roqvideo             id RoQ video (codec roq)
 V..... rv10                 RealVideo 1.0
 V..... rv20                 RealVideo 2.0
 V..... sgi                  SGI image
 V..... snow                 Snow
 V..... sunrast              Sun Rasterfile image
 V..... svq1                 Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1
 V..... targa                Truevision Targa image
 VF.... tiff                 TIFF image
 VF.... utvideo              Ut Video
 V..... v210                 Uncompressed 4:2:2 10-bit
 V..... v308                 Uncompressed packed 4:4:4
 V..... v408                 Uncompressed packed QT 4:4:4:4
 V..... v410                 Uncompressed 4:4:4 10-bit
 V..... vp8_v4l2m2m          V4L2 mem2mem VP8 encoder wrapper (codec vp8)
 V..... vp8_vaapi            VP8 (VAAPI) (codec vp8)
 V..... vp9_vaapi            VP9 (VAAPI) (codec vp9)
 V..... vp9_qsv              VP9 video (Intel Quick Sync Video acceleration) (codec vp9)
 V..... wmv1                 Windows Media Video 7
 V..... wmv2                 Windows Media Video 8
 V..... wrapped_avframe      AVFrame to AVPacket passthrough
 V..... xbm                  XBM (X BitMap) image
 V..... xface                X-face image
 V..... xwd                  XWD (X Window Dump) image
 V..... y41p                 Uncompressed YUV 4:1:1 12-bit
 V..... yuv4                 Uncompressed packed 4:2:0
 A..... aac                  AAC (Advanced Audio Coding)
 A..... ac3                  ATSC A/52A (AC-3)
 A..... ac3_fixed            ATSC A/52A (AC-3) (codec ac3)
 A..... adpcm_adx            SEGA CRI ADX ADPCM
 A..... g722                 G.722 ADPCM (codec adpcm_g722)
 A..... g726                 G.726 ADPCM (codec adpcm_g726)
 A..... g726le               G.726 little endian ADPCM ("right-justified") (codec adpcm_g726le)
 A..... adpcm_ima_qt         ADPCM IMA QuickTime
 A..... adpcm_ima_ssi        ADPCM IMA Simon & Schuster Interactive
 A..... adpcm_ima_wav        ADPCM IMA WAV
 A..... adpcm_ms             ADPCM Microsoft
 A..... adpcm_swf            ADPCM Shockwave Flash
 A..... adpcm_yamaha         ADPCM Yamaha
 A..... alac                 ALAC (Apple Lossless Audio Codec)
 A..... aptx                 aptX (Audio Processing Technology for Bluetooth)
 A..... aptx_hd              aptX HD (Audio Processing Technology for Bluetooth)
 A..... comfortnoise         RFC 3389 comfort noise generator
 A..X.. dca                  DCA (DTS Coherent Acoustics) (codec dts)
 A..... eac3                 ATSC A/52 E-AC-3
 A..... flac                 FLAC (Free Lossless Audio Codec)
 A..... g723_1               G.723.1
 A..X.. mlp                  MLP (Meridian Lossless Packing)
 A..... mp2                  MP2 (MPEG audio layer 2)
 A..... mp2fixed             MP2 fixed point (MPEG audio layer 2) (codec mp2)
 A..... nellymoser           Nellymoser Asao
 A..X.. opus                 Opus
 A..... pcm_alaw             PCM A-law / G.711 A-law
 A..... pcm_dvd              PCM signed 16|20|24-bit big-endian for DVD media
 A..... pcm_f32be            PCM 32-bit floating point big-endian
 A..... pcm_f32le            PCM 32-bit floating point little-endian
 A..... pcm_f64be            PCM 64-bit floating point big-endian
 A..... pcm_f64le            PCM 64-bit floating point little-endian
 A..... pcm_mulaw            PCM mu-law / G.711 mu-law
 A..... pcm_s16be            PCM signed 16-bit big-endian
 A..... pcm_s16be_planar     PCM signed 16-bit big-endian planar
 A..... pcm_s16le            PCM signed 16-bit little-endian
 A..... pcm_s16le_planar     PCM signed 16-bit little-endian planar
 A..... pcm_s24be            PCM signed 24-bit big-endian
 A..... pcm_s24daud          PCM D-Cinema audio signed 24-bit
 A..... pcm_s24le            PCM signed 24-bit little-endian
 A..... pcm_s24le_planar     PCM signed 24-bit little-endian planar
 A..... pcm_s32be            PCM signed 32-bit big-endian
 A..... pcm_s32le            PCM signed 32-bit little-endian
 A..... pcm_s32le_planar     PCM signed 32-bit little-endian planar
 A..... pcm_s64be            PCM signed 64-bit big-endian
 A..... pcm_s64le            PCM signed 64-bit little-endian
 A..... pcm_s8               PCM signed 8-bit
 A..... pcm_s8_planar        PCM signed 8-bit planar
 A..... pcm_u16be            PCM unsigned 16-bit big-endian
 A..... pcm_u16le            PCM unsigned 16-bit little-endian
 A..... pcm_u24be            PCM unsigned 24-bit big-endian
 A..... pcm_u24le            PCM unsigned 24-bit little-endian
 A..... pcm_u32be            PCM unsigned 32-bit big-endian
 A..... pcm_u32le            PCM unsigned 32-bit little-endian
 A..... pcm_u8               PCM unsigned 8-bit
 A..... pcm_vidc             PCM Archimedes VIDC
 A..... real_144             RealAudio 1.0 (14.4K) (codec ra_144)
 A..... roq_dpcm             id RoQ DPCM
 A..X.. s302m                SMPTE 302M
 A..... sbc                  SBC (low-complexity subband codec)
 A..X.. sonic                Sonic
 A..X.. sonicls              Sonic lossless
 A..X.. truehd               TrueHD
 A..... tta                  TTA (True Audio)
 A..X.. vorbis               Vorbis
 A..... wavpack              WavPack
 A..... wmav1                Windows Media Audio 1
 A..... wmav2                Windows Media Audio 2
 S..... ssa                  ASS (Advanced SubStation Alpha) subtitle (codec ass)
 S..... ass                  ASS (Advanced SubStation Alpha) subtitle
 S..... dvbsub               DVB subtitles (codec dvb_subtitle)
 S..... dvdsub               DVD subtitles (codec dvd_subtitle)
 S..... mov_text             3GPP Timed Text subtitle
 S..... srt                  SubRip subtitle (codec subrip)
 S..... subrip               SubRip subtitle
 S..... text                 Raw text subtitle
 S..... webvtt               WebVTT subtitle
 S..... xsub                 DivX subtitles (XSUB)