ffmpeg で使える QSV(Intel Quick Sync Video) のビルド方法と使い方。CPU の世代によって使えるオプションやフィルタが異なるが、実物がないのでどこから使えるのかよく分かっていない。

CPU の世代が分かる : Intel Core – Wikipedia
hardware acceleration の Wiki : HWAccelIntro – FFmpeg
各世代のエンコーダ、デコーダ、コーデックの対応表:Intel Graphics Technology – Wikipedia
2016年1月次点での公式のベンチマーク PDF : Intel® Quick Sync Video and FFmpeg Performance – cloud-computing-quicksync-video-ffmpeg-white-paper.pdf

関連記事
ffmpeg に nvenc(cuda) をインストールする
AMD VCE 対応の ffmpeg をつくる

他のサイト
This gist will generate an Intel QSV-enabled FFmpeg build using the open source Intel Media SDK. Testbed used: Ubuntu 18.04LTS. A fallback is also provided for the intel vaapi driver where needed.

基本となるファイル

Zeranoe build が ffmpeg-20150525-git-e48a9ac から対応した。
libmfx Added | Zeranoe FFmpeg

ffmpeg-20150610-git-913685f を最後に非対応になっているので必要な場合は直接保存する。理由は XP 対応 のため。
Zeranoe FFmpeg – Builds win32
Zeranoe FFmpeg – Builds win64

その後、2016年3月1日より XP のサポートを終了し配布を再開した。
Windows XP Support And Intel QSV – Zeranoe FFmpeg

XP でも使える ffmpeg はこちらで配布している。
FFmpegダウンロード お気に入りの動画を携帯で見よう

ビルド環境の構築

ビルド環境の構築は 【AAC+】 HE-AAC が使える ffmpeg をつくる方法 を参考に msysgitMSYS_MinGW-w64_GCC_xxx_x86-x64_Full を上書きした物を使う。

msys.bat を実行して MSYS/home/<ユーザー名> 以下にソースファイルを解凍してインストールを行うが、その前に MSYS/bin の pkg-config.exe をコピー&リネームする。

$ copy pkg-config.exe i686-w64-mingw32-pkg-config.exe
$ copy pkg-config.exe x86_64-w64-mingw32-pkg-config.exe

ffmpeg をつくる

mfx_dispatch-master

$ cd mfx_dispatch-master
$ autoreconf -fiv
$ PKG_CONFIG_PATH="/mingw/i686-w64-mingw32/lib/pkgconfig" ./configure --build=i686-w64-mingw32 --host="i686-w64-mingw32" --prefix="/mingw/i686-w64-mingw32" --bindir=/mingw/i686-w64-mingw32 --disable-shared --enable-static --enable-fast-install
$ make && make install

64bit なら

$ PKG_CONFIG_PATH="/mingw/x86_64-w64-mingw32/lib/pkgconfig" ./configure --build=x86_64-w64-mingw32 --host="x86_64-w64-mingw32" --prefix="/mingw/x86_64-w64-mingw32" --bindir=/mingw/x86_64-w64-mingw32 --disable-shared --enable-static --enable-fast-install

ffmpeg

$ cd ffmpeg
$ PKG_CONFIG_PATH="/mingw/i686-w64-mingw32/lib/pkgconfig" ./configure --prefix=/mingw/i686-w64-mingw32 --enable-version3 --enable-gpl --enable-libmfx --disable-ffplay --disable-ffprobe --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages"
$ make

64bit なら

$ PKG_CONFIG_PATH="/mingw/x86_64-w64-mingw32/lib/pkgconfig" ./configure --cross-prefix="x86_64-w64-mingw32-" --enable-version3 --enable-cross-compile --enable-version3 --enable-gpl --enable-libmfx --disable-ffplay --disable-ffprobe --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-debug --extra-ldflags=-static  --target-os=mingw32 --arch=x86_64 --cpu=x86_64

実行コマンド例

以下のようなエラーが出る場合は look_ahead 0 をつける。現在は既定値が 0 になっているので設定する必要はない。

More than one of: { constant qscale, lookahead, VCM } requested, only one of them can be used at a time.Error initializing output stream 0:0 — Error while opening encoder for output stream #0:0 – maybe incorrect parameters such as bit_rate, rate, width or height

以下のようなエラーが出る場合は init_hw_device qsv:hw をつける。
https://trac.ffmpeg.org/ticket/6492 より。
詳しくは https://ffmpeg.org/ffmpeg-all.html#Advanced-Video-options

No device available for encoder (device type qsv for codec h264_qsv).
Selected ratecontrol mode is not supported by the QSV runtime. Choose a different mode.
Error initializing output stream 0:0 — Error while opening encoder for output stream #0:0 – maybe incorrect parameters such as bit_rate, rate, width or height

逆に、付けるとエラーになる場合 init_hw_device qsv:hw を外す。
https://trac.ffmpeg.org/ticket/6827 より。

Failed to create Direct3D device
Device creation failed: -1313558101.
Failed to set value ‘qsv:hw’ for option ‘init_hw_device’: Unknown error occurred

Error parsing global options: Unknown error occurred
以下のようなエラーが出る場合は一度 remux するとエラーがなくなるかもしれない。

Decoding pixel format ‘(null)’ is not supported
Error while decoding stream #0:0: Function not implemented

remux
ffmpeg -analyzeduration 30M -probesize 30M -i input.ts -c copy output.ts
また Drop したフレームがあり読み込みに失敗するときには、それを読み込まないオプション -fflags +discardcorrupt を付ける方法もある。

ffmpeg Documentation : Format Options

CBR(固定ビットレート):ffmpeg -i input -c:v h264_qsv -look_ahead 0 -b:v 2000k -maxrate 2000k -acodec copy output.mp4
VBR(可変ビットレート):ffmpeg -i input -c:v h264_qsv -look_ahead 0 -b:v 4000k -acodec copy output.mp4
CQP(品質指定):ffmpeg -i input -c:v h264_qsv -look_ahead 0 -q:v 20 -acodec copy output.mp4

ニコ生のように制限ビットレートがある場合は VBR にすることで制限できる。CQP のビットレートは配信映像に依存するので使い慣れればこちらでも良い。

色空間を明示する場合は H.264 だと -bsf:v h264_metadata を設定する。

FFmpeg Bitstream Filters Documentation : h264_metadata
colour_primaries, transfer_characteristics, matrix_coefficientsの値。ただし colorprim, colormatrix の 9 は bt2020, bt2020nc になるが、transfer の 9 は log100 になる。x265 と同じ内容になるので公式ドキュメントを参照する。

1 : BT.709
6 : BT.601(smpte170m)

ffmpeg -i input -c:v h264_qsv -look_ahead 0 -b:v 2000k -maxrate 2000k -bsf:v h264_metadata=colour_primaries=1:transfer_characteristics=1:matrix_coefficients=1 -acodec copy output.mp4

エンコード設定

ffmpeg -h encoder=h264_qsvで見られるエンコード設定とエンコーダ全般に指定できる設定の2つがある。

エンコーダ全体のオプション

g [int]
group of picture size で、keyint のこと。無指定だと10秒に1つキーフレームが付く。libx264 のようにキーフレーム間隔は可変にならない。

公式ドキュメント:FFmpeg Codecs Documentation : QSV-encoders

hevc_qsv エンコーダを使う

Kaby Lake CPU 以降であれば hevc_qsv エンコーダが使える。
ffmpeg -h encoder=hevc_qsv

コマンド例
ffmpeg -i input -c:v hevc_qsv -load_plugin hevc_hw -preset:v faster output.mkv

色空間を明示する場合は H.265 だと -bsf:v hevc_metadata を設定する。

FFmpeg Bitstream Filters Documentation : hevc_metadata
colour_primaries, transfer_characteristics, matrix_coefficientsの値
1 : BT.709
6 : BT.601(smpte170m)

colorprim, colormatrix の 9 は bt2020, bt2020nc になるが、transfer の 9 は log100 になる。詳しくは H.265 section E.3.1 and tables E.3, E.4 and E.5 にある。わかりやすい記事は x265 の公式ドキュメントを読む。

QSV デコーダを使う

ハードウェアデコードは再生時のデコードを目的としていて、最新の CPU のソフトウェアデコードよりも高速ではない。 さらに通常デコードされたフレームを GPUメモリからシステムメモリにコピーする必要があり、その結果パフォーマンスがさらに低下する。考えられる用途は CPU をなるべく使いたくなかったり、リアルタイム配信、速度を重視しない場合などである。

デコーダ覧

  • h264_qsv
  • mpeg2_qsv
  • hevc_qsv
  • vc1_qsv
  • vp8_qsv

CPU をフル活用してエンコードする場合、デコードの CPU 負荷を減らしその分をエンコードに使うことで速度の向上の可能性がある。

デコーダの部分についてコメントをいただいていたが、サーバのアカウント削除によりデータベースの保存が間に合わなかったのでコメントが消えてしまった。申し訳ない。

追記 2015年7月29日
デコーダも追加された。他にも HEVC、H264 も追加されている。
avcodec: Add QSV MPEG-2 video decoder :: git.videolan.org Git – ffmpeg.git/commitdiff
avcodec: Add QSV VC-1 video decoder :: git.videolan.org Git – ffmpeg.git/commitdiff

無指定だとソフトウェアデコードになるので、入力の前にデコーダを指定
ffmpeg -vcodec h264_qsv -i input
hevc の場合
ffmpeg -vcodec hevc_qsv -i input

デコーダは ffmpeg -decoders > decoders.txt で一覧をテキストで見ることが出来る。

QSV フィルタを使う

ffmpeg 3.3 からデインターレーサとリサイザが追加された。ただし ffmpeg で使えても ffplay では使えないのでプレビュー用途ならパイプして ffplay に渡す。また入力ファイルに応じて QSV デコーダを使わないと QSV フィルタが使えない。 ffmpeg 4.0 以降はフィルタの hwdownload,format=nv12 が不要になり付けない方が高速になった。ただし標準出力で使う rawvideo は例外である。

使えるフィルタ覧

  • vpp_qsv(3.4以降)
  • scale_qsv(3.3以降)
  • overlay_qsv(4.0以降)
  • deinterlace_qsv(3.4以降)

vpp_qsv フィルタは第3世代の Intel Core シリーズでは一部が使えてない。これらのフィルタは公式ドキュメントに記載がないのでコマンドからオプション内容を調べる。
ffmpeg -h filter=vpp_qsv > vpp_qsv.txt

リサイズ
ffmpeg -hwaccel qsv -vcodec h264_qsv -i input.mp4 -vf scale_qsv=1280:720 -fflags +discardcorrupt -vcodec h264_qsv -look_ahead 0 -q:v 20 -acodec copy out.mp4

デインターレース(bob になる)
ffmpeg -hwaccel qsv -vcodec mpeg2_qsv -i input.ts -vf deinterlace_qsv -fflags +discardcorrupt -vcodec h264_qsv -look_ahead 0 -q:v 20 -acodec copy out.mp4

TS ファイルをデインターレスしてリサイズし、重複フレームを間引く(30p)
ffmpeg -hwaccel qsv -vcodec mpeg2_qsv -i input.ts -vf deinterlace_qsv,scale_qsv=1280:720,fps=30000/1001 -fflags +discardcorrupt -vcodec h264_qsv -look_ahead 0 -q:v 20 -acodec copy out.mp4

TS ファイルをデインターレスしてリサイズし、重複フレームを間引く(24p)
ffmpeg -hwaccel qsv -vcodec mpeg2_qsv -i input.ts -vf deinterlace_qsv,scale_qsv=1280:720,fps=30000/1001,decimate -fflags +discardcorrupt -r 24000/1001 -vcodec h264_qsv -look_ahead 0 -q:v 20 -acodec copy out.mp4

画像をオーバーレイ
ffmpeg -hwaccel qsv -vcodec h264_qsv -i input.mp4 -loop 1 -i img.png -filter_complex [1:v]hwupload=extra_hw_frames=10[watermark];[0:v][watermark]overlay_qsv=x=30:y=30 -vcodec h264_qsv -look_ahead 0 -q:v 20 -acodec copy out.mp4

ffplay に標準出力する
ffmpeg -hwaccel qsv -vcodec mpeg2_qsv -i input.ts -vf deinterlace_qsv,scale_qsv=1280:720,hwdownload,format=nv12,fps=30000/1001,decimate -fflags +discardcorrupt -c:v rawvideo -acodec copy -f nut - | ffplay -

2 thoughts on “qsv 対応の ffmpeg をつくる

  • Kenny Lam

    Sorry to violating “日本語が含まれない投稿は無視されますのでご注意ください” below, I can read a little にほんご but I can’t write it with confident.

    Thanks for your detailed guide on using qsv filters, that helped me a lot to get FFMPEG+QuickSync working 🙂

    Just a friendly sharing for utilizing QSV with Decoding+Scale+Encoding, we can now remove “hwdownload,format=nv12″ in video filter, like this sample on using scale_qsv

    ffmpeg -hwaccel qsv -vcodec h264_qsv -i input.mp4 -vf scale_qsv=1280:720 -fflags +discardcorrupt -vcodec h264_qsv -look_ahead 0 -q:v 20 -acodec copy out.mp4

    As a result, the h264_qsv(input decoder) will result video in pix_fmt=”qsv”, that doesn’t require hwdownload and convert to NV12 but go to the h264_qsv(output encoder) directly, the performance increase will be significant. Only worked on FFMPEG 4.0 and after.

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)