Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
openSUSE Tumbleweedでqsvエンコード

openSUSE Tumbleweedでqsvエンコード

openSUSE Advent Calender 2018 12/23分になります はじめましての方はじめまして、GPUおたくのopenSUSE使いzgockと申します

今回はIntel Quick Sync Videoを使用した動画エンコーディングのお話でもさせていただければと思います

Intel Quick Sync Videoとは

Intelが自社製CPU内蔵のGPU(以下iGPU)に搭載している動画のエンコード/デコード支援機能であり、Sandy Bridge(core iシリーズ2xxx)以降に搭載されています この機能を使用することにより、動画のエンコーディング等をCPUによるエンコーディングの数倍の速度で行うことが出来るのが特徴です 同様の機能はNVIDIA(NVENC)やAMD(VCE)のGPUも持っていますが、(GPUエンコードとしては)速度よりも画質/容量優先でチューニングされているため、動画編集/録画圧縮などで利用されるケースが多いです

LinuxでのQSV利用

かつては、Intelが配布しているIntel Media SDKを利用してQSV機能を利用することが一般的でしたが、 Intel Media SDKは専用カーネルとバイナリドライバのセットで、利用する際に色々な制約が多いこともあり、 LinuxでQSVを利用するのはWindowsに比べてちょっと敷居が高い状態になっていました。 しかし近年は汎用ビデオAPIであるVA-APIの進化に伴い比較的簡単に利用することが出来るようになっています

VA-API

VA-APIとは、MITライセンスで公開されているOSSのビデオライブラリ、libvaを操作するAPIで 近年進化が進み、Intel/AMDのGPUエンコーディング機能をほぼフル活用可能なレベルにまで進化しています openSUSEにも標準パッケージとしてインストール可能になっています

openSUSE Tumbleweed

openSUSEには、定期リリースのLeapとローリングリリースのTumbleweedがあり、積極的に最新パッケージを取り込むTumbleweedは動画関係のような進化の速いジャンルの新機能を試してみるような用途に適しています

今回はopenSUSE Tumbleweedでffmpeg 4.xとVA-APIを用いてIntel QSVを利用した動画エンコーディングを行ってみましょう

ffmpeg 4.x

ffmpegの最新系列である4.xではVA-API周りに大幅な改良が入り、従来のffmpeg3.x(Leap 15.0標準)に比べエンコード速度が大幅に改善しています Tumbleweedではffmpeg-4パッケージとして標準で用意されているため、zypperで入れてしまうだけです(libva関連のライブラリが入っていなければ、関連パッケージとしてこの段階で一緒にインストールされます)

sudo zypper in ffmpeg-4

Intel Media Driver

libva標準のintelドライバはSandy Bridge以降のiGPUに対応しており、汎用性は高いですが、Broadwell(core i 5xxx)以降のiGPUの機能をフル活用できません。 IntelからBroadwell以降専用のOSSなVA-APIドライバが出ており、これもTumbleweedには標準で入っています

sudo zypper in intel-media-driver

Sandybridge〜HaswellまでのiGPUの場合は、旧版のmedia driverを入れてください

sudo zypper in intel-vaapi-driver

libva-utils

VA-APIの実装状況を確認するためのツールとしてvainfoコマンドがありますので、これもインストールします。 openSUSEでは特定のコマンドがどのパッケージに入っているかを確認するためのcnfコマンドがありますので、cnf vainfoを実行してみます

cnf vainfo

結果、libva-utilsパッケージに入っていることが確認できますのでインストールします

sudo zypper in libva-utils

vainfo

vainfoを実行してみます

$ vainfo
libva info: VA-API version 1.3.0
libva info: va_getDriverName() returns 0
libva info: User requested driver 'iHD'
libva info: Trying to open /usr/lib64/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_3
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.3 (libva 2.3.0)
vainfo: Driver version: Intel iHD driver - 1.0.0
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
      VAProfileHEVCMain               :	VAEntrypointVLD
      VAProfileHEVCMain               :	VAEntrypointEncSlice
      VAProfileHEVCMain               :	VAEntrypointFEI

「VAEntrypointVLD」がデコーダー、「VAEntrypointEncSlice」がエンコーダーのエントリーポイントになりますので、上記の例であればh264とhevc(h265)のエンコードに対応していることが確認できます

エンコード

では実際にffmpegを使ってエンコードしてみます。下記の例ではハードウェアフィルターによるインターレース解除を行いつつ、地デジ録画のmpeg2-tsファイルをh264でエンコードしてmp4コンテナに格納しています

ffmpeg -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -i input.ts -vf 'format=nv12|vaapi,hwupload,deinterlace_vaapi' -c:v h264_vaapi -c:a ac3 -qp 20 output.mp4

ffmpegの個々のオプション、-vfに渡しているVA-APIの詳細設定についてはffmpeg公式wikiのVAAPIのページを参照してください

テスト結果

簡単にエンコードテストを行った結果を残しておきます

  • テスト環境:Fujitsu FUTRO MS936(Celeron 3955U/Skylake)
  • ソース:30分の地デジ録画ファイル(mpeg2-ts) 3.2GB
設定 速度(実時間比) サイズ
h264 -qp 20 6.5倍速 1.2GB
h264 -qp 25 6.5倍速 632MB
hevc -qp 20 2.2倍速 1.2GB
  • -qpオプションの数値が大きいほどサイズが小さくなり、その分画質は劣化する
  • -qpオプションの値の違いによる速度変化はほぼない
  • 同一qpであればh264とhevcでの出力サイズの差はほぼない(多少hevcの方が小さくなる傾向はある)が、画質はhevcの圧勝

Skylake世代とはいえ、ローエンドに属するMobile Celeronですら倍速以上でhevcエンコード出来てしまう点に少々驚きました

まとめ

従来結構面倒だったIntel Quick Sync Videoを使った動画エンコーディング、openSUSE Tumbleweedではとても簡単に行えるようになっていますのでIntel iGPU、特にBroadwell世代以降のiGPU環境をお持ちの方は是非一度お試しください

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment