ffmpeg で使える QSV(Intel Quick Sync Video)のビルド方法と使い方。CPU の世代によって使えるエンコーダ、デコーダ、オプションやフィルタが異なる。

CPU の世代が分かる : Intel Core – Wikipedia
hardware acceleration の Wiki : HWAccelIntro – FFmpeg
各世代のエンコーダ、デコーダ、コーデックの対応表:Hardware/QuickSync – FFmpegIntel 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ダウンロード お気に入りの動画を携帯で見よう

ffmpeg をつくる

Windows 環境なら media-autobuild_suite を使うのが楽。--enable-libmfx を指定する。

エラーの回避方法

以下のようなエラーが出る場合は -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

以下のようなエラーが出る場合は読み込み時のバッファを増やす。

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

ffmpeg -analyzeduration 30M -probesize 30M -i input.ts -c copy output.ts

また Drop したフレームがあり読み込みに失敗するときには、それを読み込まない入力オプション -fflags +discardcorrupt を付ける方法もある。以下は QSV フィルタの併用例。

ffmpeg -hwaccel qsv -c:v mpeg2_qsv -fflags +discardcorrupt -analyzeduration 30M -probesize 30M -i input.ts -vf deinterlace_qsv,scale_qsv=1280:720,hwdownload,format=nv12,fps=30000/1001,decimate -r 24000/1001 -c:v h264_qsv -look_ahead 0 -q:v 20 -c:a copy out.mp4

以下のエラーが出る場合は hwupload=extra_hw_frames フィルタをつける。

The input must have a hardware frame reference.

以下のエラーが出る場合は hwupload=extra_hw_frames フィルタのフレーム数を増やす。

Error while filtering: Cannot allocate memory
Failed to inject frame into filter network: Cannot allocate memory
Error while processing the decoded data for stream #0:0

QSV リサイズフィルタの利用例。
ffmpeg -init_hw_device qsv=qsv:hw -hwaccel qsv -filter_hw_device qsv -fflags +discardcorrupt -i input.mp4 -vf hwupload=extra_hw_frames=10,scale_qsv=1280:720 -c:v h264_qsv -q:v 20 -c:a copy out.mp4

Windows 以外の環境
centos7でffmpeg h264_qsv感想など。

ffmpeg Documentation : Format Options

実行コマンド例

CBR(固定ビットレート):ffmpeg -i input -c:v h264_qsv -look_ahead 0 -b:v 2000k -maxrate 2000k -c:a copy output.mp4

VBR(可変ビットレート):ffmpeg -i input -c:v h264_qsv -look_ahead 0 -b:v 4000k -c:a copy output.mp4

CQP(品質指定):ffmpeg -i input -c:v h264_qsv -look_ahead 0 -q:v 20 -c:a 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)

HD未満
ffmpeg -i input -c:v h264_qsv -look_ahead 0 -b:v 2000k -maxrate 2000k -color_primaries smpte170m -color_trc smpte170m -colorspace smpte170m -bsf:v h264_metadata=colour_primaries=6:transfer_characteristics=6:matrix_coefficients=6 -c:a copy output.mp4

HD以上
ffmpeg -i input -c:v h264_qsv -look_ahead 0 -b:v 2000k -maxrate 2000k -color_primaries bt709 -color_trc bt709 -colorspace bt709 -bsf:v h264_metadata=colour_primaries=1:transfer_characteristics=1:matrix_coefficients=1 -c:a copy output.mp4

ffmpeg: explicitly tag h.264 as bt.601, rather than leaving unspecified? – Video Production Stack Exchange

h264_qsv エンコーダの設定

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(第7世代)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)

HD未満
ffmpeg -i input -c:v hevc_qsv -load_plugin hevc_hw -b:v 2000k -maxrate 2000k -color_primaries smpte170m -color_trc smpte170m -colorspace smpte170m -bsf:v hevc_metadata=colour_primaries=6:transfer_characteristics=6:matrix_coefficients=6 -c:a copy output.mp4

HD以上
ffmpeg -i input -c:v hevc_qsv -load_plugin hevc_hw -b:v 2000k -maxrate 2000k -color_primaries bt709 -color_trc bt709 -colorspace bt709 -bsf:v hevc_metadata=colour_primaries=1:transfer_characteristics=1:matrix_coefficients=1 -c:a copy output.mp4

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

mjpeg_qsv エンコーダの設定

Haswell(第4世代)CPU 以降であれば mjpeg_qsv エンコーダが使える。
ffmpeg -h encoder=mjpeg_qsv

コマンド例
ffmpeg -hwaccel qsv -c:v h264_qsv -i video.mp4 -c:v mjpeg_qsv -global_quality 80 img-%03d.jpg

-global_quality[int]
品質指定。100に近いほど大容量高画質。
既定値:80

通常は品質指定しなくても最適な品質を選ぶ。
ffmpeg -hwaccel qsv -c:v h264_qsv -i video.mp4 -c:v mjpeg_qsv img-%03d.jpg

QSV デコーダを使う

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

デコーダ一覧

  • h264_qsv
  • mjpeg_qsv
  • mpeg2_qsv
  • hevc_qsv
  • vc1_qsv
  • vp8_qsv
  • vp9_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 -c:v h264_qsv -i input

hevc の場合。
ffmpeg -c:v hevc_qsv -i input

ffplay の場合。
ffplay -codec:v h264_qsv -i input

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

QSV フィルタを使う

ffmpeg 3.3 からデインターレーサとリサイザが追加された。ただし ffmpeg で使えても ffplay では使えないのでプレビュー用途なら標準出力して ffplay に渡す。また入力ファイルに応じて QSV デコーダを使わないと QSV フィルタが使えない-filter_hw_device qsvhwupload フィルタでフレーム数を増やせば QSV デコーダを使わなくてもよい。ffmpeg 4.0 以降はフィルタの hwdownload,format=nv12 が不要になり付けない方が高速になった。ただし例外が2つあり普通のフィルタに切り替えるときは hwdownload,format=nv12 を挟み、ソフトウェアエンコーダを使うときはフィルタの最後に hwdownload,format=nv12 をつける。

参考記事
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. · GitHub

使えるフィルタ一覧

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

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

コマンド例は2つあり1行目が QSV のデコード、フィルタ、エンコードを併用し、2行目が QSV フィルタだけ当てている。

リサイズ
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.mp4 -vf hwupload=extra_hw_frames=10,scale_qsv=1280:720 -c:v h264_qsv -q:v 20 -c:a copy output.mp4
ffmpeg -init_hw_device qsv=qsv:hw -hwaccel qsv -filter_hw_device qsv -i input.mp4 -vf hwupload=extra_hw_frames=10,scale_qsv=1280:720,hwdownload,format=nv12 -c:v libx264 -c:a copy output.mp4

デインターレース(bob になる)。QSV のデコードとインターレス解除を併用すると映像が乱れるのでコマンド例がない
ffmpeg -init_hw_device qsv=qsv:hw -hwaccel qsv -filter_hw_device qsv -fflags +discardcorrupt -analyzeduration 30M -probesize 30M -i input.ts -vf hwupload=extra_hw_frames=64,deinterlace_qsv,hwdownload,format=nv12 -c:v libx264 -c:a copy output.mp4

TS ファイルをデインターレースとリサイズし、重複フレームを間引く(30p)
ffmpeg -init_hw_device qsv=qsv:hw -hwaccel qsv -filter_hw_device qsv -fflags +discardcorrupt -analyzeduration 30M -probesize 30M -i input.ts -vf hwupload=extra_hw_frames=64,deinterlace_qsv,scale_qsv=1280:720,hwdownload,format=nv12,fps=30000/1001 -c:v libx264 -c:a copy output.mp4

TS ファイルをデインターレースとリサイズし、重複フレームを間引く(30p->24p)
ffmpeg -init_hw_device qsv=qsv:hw -hwaccel qsv -filter_hw_device qsv -fflags +discardcorrupt -analyzeduration 30M -probesize 30M -i input.ts -vf hwupload=extra_hw_frames=64,deinterlace_qsv,scale_qsv=1280:720,hwdownload,format=nv12,fps=30000/1001,decimate -r 24000/1001 -c:v libx264 -c:a copy output.mp4

動画に動画をオーバーレイ
ffmpeg -hwaccel qsv -c:v h264_qsv -i bgv.mp4 -c:v h264_qsv -i overlay.mp4 -filter_complex [0:v]hwupload=extra_hw_frames=10[0v];[1:v]hwupload=extra_hw_frames=10,[0v]overlay_qsv -c:v h264_qsv -q:v 20 -c:a copy output.mp4
ffmpeg -init_hw_device qsv=qsv:hw -hwaccel qsv -filter_hw_device qsv -i bgv.mp4 -i overlay.mp4 -filter_complex [0:v]hwupload=extra_hw_frames=10[0v];[1:v]hwupload=extra_hw_frames=10,[0v]overlay_qsv -c:v libx264 -c:a copy output.mp4

画像をオーバーレイ
ffmpeg -init_hw_device qsv=qsv:hw -hwaccel qsv -filter_hw_device qsv -i bgv.mp4 -loop 1 -i overlay.png -filter_complex "[0:v]format=nv12,hwupload=extra_hw_frames=10[0v];[1:v] format=nv12,hwupload=extra_hw_frames=10[1v];[0v][1v]overlay_qsv" -c:v libx264 -c:a copy output.mp4

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.

コメントを残す

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

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