10
7

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.

Debianで QSV (-hwaccel qsv) が使える ffmpegをビルドする手順

Last updated at Posted at 2020-06-14

#DebianでQSVで爆速エンコードしたい!※
この記事では 
ffmpeg -hwaccel vaapi (VAAPI + i965) より 高スループット/高品質が狙える
ffmpeg -hwaccel qsv  (libmfx + iHD) が使えるffmpegのビルドをまっさらなdebianで行います。

※mpeg2ts -> h.264 HWトランスコードが 9.53倍速くらい。 CPU使用率15%。

###そのまえに、、Ubuntuならもっと簡単です
Ubuntuの場合、依存ライブラリがパッケージ化されているのでもっと簡単です。
ビルドするのはffmpegだけがいい!という方はUbuntu使いましょう。
(ubuntuもパッケージ版ffmpegは --enable-libmfx されてないのでffmpegだけはビルド必要)

2020/06/19現在のパッケージ提供状況

Source libmxf libva iHD
Ubuntu Package 20.1.0 2.7.0 20.1.1
Debian Package No Packgae 2.4.0-1(too old) 18.4.1(too old)
github 20.1.1 2.7.1 20.1.1

では、始めていきます。

##構成

###ソフトウェア

Debian は 2020年06月現在最新の 10.4.0(buster) amd64 で試しています。
ビルドが必要なもの以外はなるべくパッケージを使って楽する方針です。

現在 Debian10(buster) には、、

種別 ソフトウェア バージョン ソース
OS Debian 10.4.0-amd64  
VA-API libva 2.7.0 github
VA-API Driver iHD_drv_video.so 20.2.pre github
Intel-Mdia-SDK msdk 20.1.1 github
Va-API Util vainfo 2.4.0+ds1-1 Package

###ハードウェア
Intel Quick Sync Video (libmfx + iHD)を使ったハードウェアエンコード/デコードには、Core iシリーズでいえば第6世代以上が必要になります。この手順では第8世代のIntel Core i5を使って動作確認しています。
CPUごとの機能対応表は https://trac.ffmpeg.org/wiki/Hardware/QuickSync が詳しいです。

ハードウェア種別 名称 備考
CPU Intel(R) Core(TM) i5-8500 CPU @ 3.00GHz Coffee Lake
Memory 8GB PC4-21300 (2666MT/s) 8GBx1

ちなみにモノはヤフオクで中古品ぽちりとやりました。
image.png

#インストール手順
Debian新規にインストールし終わったところからスタート

###作業ユーザで sudoが 使えるようにします。

bash
$ su -
# usermod -aG sudo daigo
# apt install sudo
# exit
$ exit

共通して使うビルドツールのインストール

bash
#ビルドに共通して使用するパッケージをインストール
$ sudo apt install build-essential git cmake pkg-config

###libva (VA-API) のビルド、インストール、動作確認

bash
#依存するパッケージのインストール
$ sudo apt install meson libdrm-dev automake libtool

#LibVAの最新版を取得
$ git clone https://github.com/intel/libva.git
$ cd libva

# ビルドとインストール。
$ ./autogen.sh
$ make
$ sudo make install
...(略)
Libraries have been installed in:
   /usr/local/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the 'LD_RUN_PATH' environment variable
     during linking
   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to '/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.

libvaがインストールされた /usr/local/lib はLD-PATHに含まれれないので、以下のコマンドで追加します。
これによって、"libva2 Package(バージョン 2.4.0-1 )" が/usr/lib にインストールされていても、今回インストールした最新版が優先して読み込まれます。

bash
sudo sh -c "echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf"
sudo ldconfig

ldconfigの効果の確認します。vainfo から参照される libvaが/usr/local/lib を指していることを確認します。

bash
# vainfoをパッケージでインストール
$ sudo apt install vainfo
# vainfoが参照しているlibvaがビルドしたものであることを確認
$ ldd /usr/bin/vainfo | grep /usr/local/
        libva-drm.so.2 => /usr/local/lib/libva-drm.so.2 (0x00007fe6f8bc4000)
        libva.so.2 => /usr/local/lib/libva.so.2 (0x00007fe6f8b95000)

この段階で、vainfoコマンドでVA-APIの状況を確認してみます。
まだVA-APIドライバが所定の場所に置かれてないのでドライバが開けないとエラーが出ます。

bash
# vainfoを実行してもドライバがないのでエラーになる
$ vainfo
error: can't connect to X server!
libva info: VA-API version 1.8.0
libva info: Trying to open /usr/local/lib/dri/iHD_drv_video.so
libva info: va_openDriver() returns -1
libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so
libva info: va_openDriver() returns -1
vaInitialize failed with error code -1 (unknown libva error),exit

###VA-APIドライバ(iHD_drv_video.so)のビルドとインストール

iHD_drv_video.so をビルドしていきます。

bash
#依存パッケージのインストール
sudo apt install libpciaccess-dev

#依存ライブラリ(Intel(R) Graphics Memory Management Library)のビルド
$ cd
$ git clone https://github.com/intel/gmmlib
$ cd gmmlib/
$ mkdir build && cd build
$ cmake ..
$ make

#VA-APIドライバ(iHD_drv_video.so)のビルド
$ cd
$ git clone https://github.com/intel/media-driver
$ mkdir build_media
$ cd build_media/
$ cmake ../media-driver
$ make
$ sudo make inatall

ここまでくれば vainfo コマンドで新しいドライバが認識されるはずですので確認します。

bash
# vainfoを実行
$ sudo vainfo
error: can't connect to X server!
libva info: VA-API version 1.8.0
libva info: Trying to open /usr/local/lib/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_8
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.8 (libva 2.4.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 20.2.pre (3640b64c)
vainfo: Supported profile and entrypoints
      VAProfileNone                   : VAEntrypointVideoProc
      VAProfileNone                   : VAEntrypointStats
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Simple            : VAEntrypointEncSlice
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointFEI
      VAProfileH264Main               : VAEntrypointEncSliceLP
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointFEI
      VAProfileH264High               : VAEntrypointEncSliceLP
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointEncPicture
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline: VAEntrypointFEI
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
      VAProfileVP8Version0_3          : VAEntrypointVLD
      VAProfileVP8Version0_3          : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointFEI
      VAProfileHEVCMain10             : VAEntrypointVLD
      VAProfileHEVCMain10             : VAEntrypointEncSlice
      VAProfileVP9Profile0            : VAEntrypointVLD
      VAProfileVP9Profile2            : VAEntrypointVLD```

やりました。これで Media SDKに必要なVA-API(libva)の最新版とドライバの最新版が導入できました。

Media SDKのビルド、インストール

gitから Media SDKをダウンロードし、ビルド、インストールしていきます。
ビルドフラグ、およびインストール先が途中表示されますので確認しておきます。

bash

# git からMediaSDKをダウンロード
$ git clone https://github.com/Intel-Media-SDK/MediaSDK msdk
$ cd msdk

# ビルドフォルダを作る
$ mkdir build && cd build

# cmake を実行。ビルドフラグが最後に表示される。
$ cmake ..
...()...
Release flags:
  CMAKE_C_FLAGS_RELEASE                   : -O3 -DNDEBUG
  CMAKE_CXX_FLAGS_RELEASE                 : -O3 -DNDEBUG
Debug flags:
  CMAKE_C_FLAGS_DEBUG                     : -g -D_DEBUG
  CMAKE_CXX_FLAGS_DEBUG                   : -g -D_DEBUG
Install:
  CMAKE_INSTALL_PREFIX                    : /opt/intel/mediasdk
  CMAKE_INSTALL_FULL_INCLUDEDIR           : /opt/intel/mediasdk/include
  CMAKE_INSTALL_FULL_LIBDIR               : /opt/intel/mediasdk/lib
  CMAKE_INSTALL_FULL_DATADIR              : /opt/intel/mediasdk/share
Enable:
  ENABLE_OPENCL                           : ON
  ENABLE_X11                              : OFF
  ENABLE_X11_DRI3                         : OFF
  ENABLE_WAYLAND                          : OFF
  ENABLE_ITT                              : OFF
  ENABLE_TEXTLOG                          : OFF
  ENABLE_STAT                             : OFF
Build:
  BUILD_RUNTIME                           : ON
  BUILD_DISPATCHER                        : ON
  BUILD_SAMPLES                           : ON
  BUILD_TUTORIALS                         : ON
  BUILD_TESTS                             : OFF
  BUILD_TOOLS                             : OFF
  BUILD_KERNELS                           : OFF
...()...


# make & mke install 。インストール先を確認。
$ make
$ sudo make install
...()...
-- Install configuration: "release"
-- Installing: /opt/intel/mediasdk/share/mfx/plugins.cfg
-- Installing: /opt/intel/mediasdk/lib/libmfx.so.1.32
-- Installing: /opt/intel/mediasdk/lib/libmfx.so.1
-- Installing: /opt/intel/mediasdk/lib/libmfx.so
-- Installing: /opt/intel/mediasdk/lib/pkgconfig/libmfx.pc
-- Installing: /opt/intel/mediasdk/include/mfx
-- Installing: /opt/intel/mediasdk/include/mfx/mfxvideo++.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxpcp.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxvstructures.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxcommon.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxla.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxastructures.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxplugin.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxscd.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxaudio++.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxpak.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxaudio.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxadapter.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxdefs.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxplugin++.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxvp8.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxvideo.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxjpeg.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxfeihevc.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxsession.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxfei.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxdispatcherprefixedfunctions.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxvp9.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxstructures.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxbrc.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxenc.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxcamera.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxsc.h
-- Installing: /opt/intel/mediasdk/include/mfx/mfxmvc.h
-- Installing: /opt/intel/mediasdk/lib/pkgconfig/mfx.pc
-- Installing: /opt/intel/mediasdk/share/mfx/samples/sample_decode
-- Installing: /opt/intel/mediasdk/share/mfx/samples/sample_encode
-- Installing: /opt/intel/mediasdk/share/mfx/samples/sample_fei
-- Installing: /opt/intel/mediasdk/share/mfx/samples/sample_hevc_fei
-- Installing: /opt/intel/mediasdk/share/mfx/samples/sample_hevc_fei_abr
-- Installing: /opt/intel/mediasdk/share/mfx/samples/sample_vpp
-- Installing: /opt/intel/mediasdk/share/mfx/samples/sample_multi_transcode
-- Installing: /opt/intel/mediasdk/share/mfx/samples/libsample_rotate_plugin.so
-- Installing: /opt/intel/mediasdk/share/mfx/samples/libvpp_plugin.a
-- Installing: /opt/intel/mediasdk/share/mfx/samples/libcttmetrics.so
-- Installing: /opt/intel/mediasdk/share/mfx/samples/metrics_monitor
-- Installing: /opt/intel/mediasdk/lib/libmfxhw64.so.1.32
-- Installing: /opt/intel/mediasdk/lib/libmfxhw64.so.1
-- Installing: /opt/intel/mediasdk/lib/libmfxhw64.so
-- Installing: /opt/intel/mediasdk/lib/pkgconfig/libmfxhw64.pc
-- Installing: /opt/intel/mediasdk/lib/mfx/libmfx_hevce_hw64.so
-- Installing: /opt/intel/mediasdk/lib/mfx/libmfx_hevc_fei_hw64.so
-- Installing: /opt/intel/mediasdk/lib/mfx/libmfx_vp9e_hw64.so
-- Installing: /opt/intel/mediasdk/lib/mfx/libmfx_h264la_hw64.so
-- Installing: /opt/intel/mediasdk/lib/mfx/libmfx_hevcd_hw64.so
-- Up-to-date: /opt/intel/mediasdk/lib/mfx/libmfx_hevcd_hw64.so
-- Installing: /opt/intel/mediasdk/lib/mfx/libmfx_vp8d_hw64.so
-- Installing: /opt/intel/mediasdk/lib/mfx/libmfx_vp9d_hw64.so

$ cd 

mediasdkがインストールされた /opt/intel/mediasdk/lib はLD-PATHに含まれれないので、以下のコマンドで追加します。

bash
$ sudo sh -c "echo /opt/intel/mediasdk/lib/ >> /etc/ld.so.conf.d/mediasdk.conf"
$ sudo ldconfig

ffmpegのビルド

いよいよ ffmpegをビルドします。

bash

#libfdk-aac のために non-freeレポジトリを加える必要がある。
$ sudo apt install software-properties-common
$ sudo apt-add-repository non-free

#依存パッケージのインストール
$ sudo apt update -qq && sudo apt -y install \
   autoconf \
   automake \
   build-essential \
   cmake \
   git-core \
   libass-dev \
   libfreetype6-dev \
   libgnutls28-dev \
   libsdl2-dev \
   libtool \
   libva-dev \
   libvdpau-dev \
   libvorbis-dev \
   libxcb1-dev \
   libxcb-shm0-dev \
   libxcb-xfixes0-dev \
   pkg-config \
   texinfo \
   wget \
   yasm \
   zlib1g-dev \
   nasm \
   libx264-dev \
   libx265-dev libnuma-dev \
   libvpx-dev \
   libfdk-aac-dev \
   libmp3lame-dev \
   libopus-dev \
   libaom-dev


# mediasdk の lib や include の位置を示す pkgconfig が非標準の場所にあるため、
# このままだとConfigureで場所が解決できない。環境変数で参照を追加してやる。
$ export PKG_CONFIG_PATH=/opt/intel/mediasdk/lib/pkgconfig:$PKG_CONFIG_PATH

# ffmpegのソースのダウンロードとビルド、インストール
$ cd 
$ wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
$ tar xjvf ffmpeg-snapshot.tar.bz2
$ cd ffmpeg
$ ./configure \
  --extra-libs="-lpthread -lm" \
  --enable-libmfx \
  --enable-gpl \
  --enable-gnutls \
  --enable-libaom \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libfreetype \
  --enable-libmp3lame \
  --enable-libopus \
  --enable-libvorbis \
  --enable-libvpx \
  --enable-libx264 \
  --enable-libx265 \
  --enable-nonfree
$ make
$ sudo make install

これでffmpegのインストールが完了しました。

動作テスト

###インストールしたffmpegの確認

ビルドしたlibmfxを参照していることを確認します。
また、エンコーダー、デコーダ一覧を表示して QSV対応コーデックがリストされることを確認します。

bash

# mediasdk を参照していることの確認
daigo@epgstation:~$ ldd /usr/local/bin/ffmpeg | grep /opt
        libmfx.so.1 => /opt/intel/mediasdk/lib/libmfx.so.1 (0x00007f44af339000)

# QSVを使ったデコーダがリストされることの確認
$  ffmpeg -decoders|grep qsv
 V....D h264_qsv             H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration) (codec h264)
 V....D hevc_qsv             HEVC (Intel Quick Sync Video acceleration) (codec hevc)
 V....D mjpeg_qsv            MJPEG video (Intel Quick Sync Video acceleration) (codec mjpeg)
 V....D mpeg2_qsv            MPEG-2 video (Intel Quick Sync Video acceleration) (codec mpeg2video)
 V....D vc1_qsv              VC-1 video (Intel Quick Sync Video acceleration) (codec vc1)
 V....D vp8_qsv              VP8 video (Intel Quick Sync Video acceleration) (codec vp8)
 V....D vp9_qsv              VP9 video (Intel Quick Sync Video acceleration) (codec vp9)

# QSVを使ったエンコーダがリストされることの確認
$  ffmpeg -encoders|grep qsv
 V..... h264_qsv             H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration) (codec h264)
 V..... hevc_qsv             HEVC (Intel Quick Sync Video acceleration) (codec hevc)
 V..... mjpeg_qsv            MJPEG (Intel Quick Sync Video acceleration) (codec mjpeg)
 V..... mpeg2_qsv            MPEG-2 video (Intel Quick Sync Video acceleration) (codec mpeg2video)
 V..... vp9_qsv              VP9 video (Intel Quick Sync Video acceleration) (codec vp9)

###ちょっくら録画したアニメをエンコードしてみる。→ 9.53倍速

9.53倍速でエンコード完了。CPU使用率は高々16%前後。

※この時なぜかsudoしないとデバイスが開けないと怒られました。。video groupには加えてみたのですが改善せず。。
ちょっとよくわからない。。

bash
# アニメ 30分番組 の mpeg2tsを h.264 へトランスコード。
$ sudo ffmpeg -y -hwaccel qsv -c:v mpeg2_qsv -i input.ts -c:v h264_qsv -global_quality 25 -acodec copy  output.mp4
.........
frame=54092 fps=285 q=26.0 Lsize=  417871kB time=00:30:04.76 bitrate=1896.8kbits/s dup=5222 drop=0 speed=9.53x
video:360246kB audio:56376kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.299822%
# 9.53倍速でエンコード完了

6並列でエンコードしてみる。→ 2.00 倍速

興味本位で6並列でエンコードしてみました。

結果、ちょうど2x 倍速でエンコードが終了しました。

bash
# アニメ 30分番組 の mpeg2tsを h.264 へトランスコード。 x6プロセス
$ seq 1 1 6 | parallel -j 6 sudo ffmpeg -y -hwaccel qsv -c:v mpeg2_qsv -i input.ts -c:v h264_qsv -global_quality 25 -acodec copy  output{}.mp4
.........
frame=54092 fps= 60 q=26.0 Lsize=  417871kB time=00:30:04.76 bitrate=1896.8kbits/s dup=5222 drop=0 speed=   2x
video:360246kB audio:56376kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.299822%

###システム負荷を見てみる。

1プロセス 6プロセス
ロードアベレージ 0.75 1.20
CPU使用率 20%前後 60%前後
メモリ VSZ 800.076MB 528.172MB* 6
メモリ RSS 92.572MB 67.824MB * 6
トランスコード速度 9.53x 2x

単純にFFMPEGを並走させるだけの場合、CPU system time / user time は同じリソースを食い合うような動きになるようです。 iowait timeだけプロセス分増えているような格好になってます。
並列させても iowait だけが上がり、load averageはほとんど影響を受けないようです。
実質的なメモリ使用率もだいぶ低い印象。

image.png
image.png
image.png

これくらいの負荷なら、録画プロセスへの影響も特段気にせずにガンガンエンコードできそうです。よかったです(小並感)。

##参照した公式ドキュメント

Build Media SDK on Ubuntu (Intel-Media-SDK)

手順上の変更点

  1. LD_LIBRARY_PATHに /usr/local/lib を追加する手順を加えています。
  2. LD_LIBRARY_PATHに /opt/intel/mediasdk/lib/ を追加する手順を加えています。

Compile FFmpeg for Ubuntu, Debian, or Mint

手順上の変更点

  1. ビルドの際のフォルダの使い方をより単純にしています。
  2. 今回の本題、QSVに対応させるために --enable-libxmf の追加しています。
  3. liboam はソースからのビルドでなくパッケージを使ってます。
  4. gnutlsパッケージが--pkg-config-flags="--static" に対応してなったので--pkg-config-flags="--static" を削除しています。

Hardware/QuickSync – FFmpeg

https://trac.ffmpeg.org/wiki/Hardware/QuickSync
概要説明や動作確認用のコマンドを参考にしています。

10
7
2

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
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?