Netflix が使っているエンコードされる前と後の動画の品質評価に使われている VMAF(Video Multimethod Assessment Fusion)スコアを ffmpeg で調べる。以前の記事に異なる解像度でも調べられると書いていたが間違いである。同じ解像度でないと調べられない。対応フォーマットは yuv420p, yuv422p, yuv444p, yuv420p10le, yuv422p10le, yuv444p10le になる。外部ライブラリフィルタなので別途インストールが必要である。しかし現在のところ Windows 環境ではおそらくリンクできていない。–disable-w32threads または –enable-pthreads と、–enable-libvmaf を付けるとリンクできる。v1.3.9 以降は –enable-version3 も付ける。

2018年8月11日、v1.3.9 対応のコミットが追加された。これに伴いマルチスレッド対応で高速になり、v1.3.4 を使う必要がなくなった。

Linux 向けのバイナリは以下から保存できる。
FFmpeg Static Builds

Windows 向けのバイナリの配布を始めた。

2つの映像の画質評価をする psnr
2つの映像の画質評価をする ssim
新しい映像の動きの評価 vmafmotion
vmaf スコアをインターレース解除とデノイズのフィルタを使って調べてみた

VapourSynth で使う場合。
VMAF – Video Multi-Method Assessment Fusion – Doom9’s Forum
HomeOfVapourSynthEvolution/VapourSynth-VMAF: Video Multi-Method Assessment Fusion

基本コマンド

従来の画質評価をする ssim, psnr フィルタと違って、入力するファイルの順番が異なるのに注意。VMAF スコアを調べるのが最初に入力する動画でなければならない。
ffmpeg -i 調べたい動画 -i オリジナル -filter_complex libvmaf=vmaf_v0.6.1.pkl -an -f null -

最終的な品質評価になる VMAF スコアは 100 が最高画質。配信向けには 80 程度を目標とするビットレートになるようにする。ログファイルに書いてある adm2, vif_scalex スコアは VMAF スコアの元となり 0(最低画質)から 1(最高画質)。motion2 は 0(動かない映像)から 20(ものすごく動く映像)。

解像度が同じでオプションを明記する場合。
ffmpeg -i encoded.mp4 -i original.mp4 -filter_complex "libvmaf=model_path=vmaf_v0.6.1.pkl:log_path=log.xml:log_fmt=xml:enable_transform=0:phone_model=0:psnr=0:ssim=0:ms_ssim=0:pool=mean" -an -f null -
ffmpeg -i encoded.mp4 -i original.mp4 -filter_complex "libvmaf=vmaf_v0.6.1.pkl:log.xml:xml:0:0:0:0:0:mean" -an -f null -

YUV の動画を比較する場合。動画は .mp4 などの圧縮した形式と、展開した .yuv の形式とでは処理速度に大きな変化は見られなかった。
ffmpeg -video_size 1280x720 -pixel_format yuv420p -framerate 30 -i encoded.yuv -video_size 1280x720 -pixel_format yuv420p -framerate 30 -i original.yuv -filter_complex libvmaf=vmaf_v0.6.1.pkl -an -f null -

エンコードが終わるとコンソールの最後に以下のような結果が表示される。ログファイルで出力する場合はフレーム毎に指定オプション内容が出力される。Exec FPS は処理速度。

Exec FPS: 4.940972
VMAF score = 96.147066

解像度が異なる場合

解像度が異なる場合に VMAF スコアを調べるには、調べたい動画をフィルタでオリジナルの解像度にリサイズしてから調べればよい。

リサイズする前が 1920X1080、リサイズした後が 1280X720 で、リサイズ方法が scale フィルタの場合。
ffmpeg -i original.mp4 -filter_complex scale=1280:720:flags=spline -acodec copy resized-720p.mp4
ffmpeg -i resized-720p.mp4 -i original.mp4 -filter_complex "scale=1920:1080:flags=lanczos,libvmaf=vmaf_v0.6.1.pkl" -an -f null -

リサイズアルゴリズムの注意点

s でのリサイズと、vfscale フィルタを使い flags を指定しない場合は bicubic が使われるが、filter_complexscale フィルタを使い flags を指定しない場合は bilinear が使われて、vf, filter_complex で使われるアルゴリズムが異なるのに注意する。

リサイズする scale
Zライブラリを使ったリサイズフィルタ zscale

公式ドキュメント:FFmpeg Filters Documentation : libvmaf

オプション

調べる内容を増やすほど処理速度が遅くなる。

  • model_path[string]
    SVM(Support Vector Machines) で使われるモデルのパス指定。配布バイナリの ffmpeg を使う場合には vmaf_v0.6.1.pkl と vmaf_v0.6.1.pkl.model の2つを ffmpeg と同じ場所に置いておくのが楽。vmaf_v0.7.0rc.pkl は VMAF スコアが 100 にならないので使わない
    既定値:”vmaf_v0.6.1.pkl”(インストールされているパス)
  • log_path[string]
    出力されるログファイルのパス指定
    既定値:無指定(指定するとログファイルが出力される)
  • log_fmt[string]
    ログファイルのフォーマット指定。xml, json が指定できる
    既定値:xml
  • enable_transform[boolean]
    VMAF スコアの計算で transform を有効にする
    同一ファイルの VMAF スコアが 100 になる。有効にしないと 100 にならない
    既定値:0
  • phone_model[boolean]
    電話モデルを呼び出してノートPCやTVに適した通常より高い VMAFスコアを計算する。携帯電話などのモバイル端末は画面サイズが大きくなく視聴距離が近いためにビットレートを高くしてもそれほど高画質に見えないからである。詳細は ここを参照
    既定値:0(ノートPC、TV向け)
  • psnr[boolean]
    psnr も一緒に計算する。60 が最高画質
    既定値:0
  • ssim[boolean]
    ssim も一緒に計算する。1 が最高画質
    既定値:0
  • ms_ssim[boolean]
    ms_ssim も一緒に計算する。1 が最高画質
    既定値:0
  • pool[string]
    VMAFスコアの計算方法。mean, min, harmonic_mean(調和平均) が指定できる
    既定値:”mean”
  • n_threads[int]
    VMAF スコアを計算するのに使うスレッド数の指定
    既定値:0(自動設定)
    範囲:0 から UINT32_MAX まで
  • n_subsample[int]
    VMAF スコアを計算するのに使うフレームサブサンプリング間隔の指定
    既定値:1
    範囲:1 から UINT32_MAX まで
  • enable_conf_interval[boolean]
    信頼区間を有効にする
    既定値:0

enable_transform の挙動について

ffmpeg -f lavfi -i color=s=32x32:d=1 -filter_complex split,libvmaf=vmaf_v0.6.1.pkl:enable_transform=0 -an -f null -
Exec FPS: 694.752857
VMAF score = 97.428043
ffmpeg -f lavfi -i color=s=32x32:d=1 -filter_complex split,libvmaf=vmaf_v0.6.1.pkl:enable_transform=1 -an -f null -
Exec FPS: 574.159669
VMAF score = 100.000000

2ファイル入力するフィルタの挙動設定 framesync にも対応している。

VMAF の解説記事

運用方法

Download Handout: Fine-Tuning Adaptive Group With Objective Quality Metrics – Streaming Learning Center から
http://streaminglearningcenter.com/wp-content/uploads/2018/11/Objective_Quality_Metrics_2018.pdf より、スコアが93あれば2DとVR用の映像では元映像と区別が付かないとされる。

The results indicate that if a video service operator were to encode video to achieve a VMAF score of about 93 then they would be confident of optimally serving the vast majority of their audience with content that is either indistinguishable from original or with noticeable but not annoying distortion

引用元PDF:https://www.realnetworks.com/sites/default/files/vmaf_reproducibility_ieee.pdf

ビットレートを少しづつ下げつつ、解像度も下げたときにスコアが逆転する手前を最適値とする方法。また実写とアニメ映像とでは必要ビットレートも変わってくる。

netflix_vmaf_approach

Tying Metrics to Predicted Subjective Ratings
MOS PSNR SSIM SSIMplus VMAF
Scoring 1-5 0-100 0-1 0-100 0-100
No artifact threshold NA 45dB 0.99 100 93
Artifacts present NA 35dB 0.5 NA NA
Excellent 5 45+ 0.99+ 80-100 80-100
Good 4 38 .95-.99 60-80 60-80
Fair 3 30 .88-.98 40-60 40-60
Poor 2 24 .50-.88 20-40 20-40
Bad 1 <15 <.5 <20 <20
Just noticeable difference NA NA NA NA 6
Device ratings No No No Multpile Standard, Phone, 4K
Ownership Open source Open source Open source Proprietary Open source

Windows 向けのバイナリを作る

Windows 向けには以下のスクリプトでリンクできる。しかしライブラリのバージョンアップにより頻繁にその影響で途中エラーになる(build フォルダの該当ライブラリを一度削除してインストールし直す)ので極力不要ライブラリはリンクしない方がよい。また 32bit の ffmpeg ではリンクできない。

jb-alvarado/media-autobuild_suite: This Windows Batchscript is for setup a compiler environment for building ffmpeg and other media tools under Windows.

/build/ffmpeg_options.txt は
–enable-libvmaf
–enable-version3
を残し、
/build/mpv_options.txt は
すべて削除して空欄にし、 media-autobuild_suite.ini は以下のようにする。最新版でライブラリが追加されていることもある。おそらく PC、ネット回線にもよるが1時間あれば Windows 向けのバイナリができあがる。

追記
コメントで指摘のあった部分を追記修正した。2018年3月13日
media-autobuild_suite で有効化できないのに言及した。2018年7月12日、2018年7月13日
Windows 向けのバイナリの配布を始めた。2018年7月24日
v1.3.9 に対応した。2018年8月12日
運用方法を追加した。2019年1月26日

6 thoughts on “新しい映像の品質評価 libvmaf

  • Tac

    色々と参考にさせていただいております。ありがとうございます。
    最近libvmafを試していたので、いくつかコメントします。
    間違いなどあったらすみません。

    ●以下の自動ビルドスクリプトでlibvmafを有効にしたWindows用のffmpegバイナリがビルドできました。
      https://github.com/jb-alvarado/media-autobuild_suite
     VMAFが使いたかっただけなので、”Choose ffmpeg and mpv optional libs: “で
     1(Yes)を選び、ffmpeg_options.txtで–enable-avisynthと–enable-libvmafだけ残し、
     他はdisableにしたり消したりして最低限にしたのですが、
     mpv_options.txtの方も不要なものはここでちゃんと無効にしておかないと、
     mpvのビルドをNoにした場合でもmpv用ライブラリをビルドしにいってしまい
     無駄に時間がかかってしまうので注意。
     ビルドしたのは3/5で、各コミットは以下のとおりです。
      media-autobuild_suite r2654 5f3980c4def9d3a818b94b5cc4eb514ad078f0cb
      ffmpeg 69995a94d8409a704361dce9bc16ede7f88bdf1a
      vmaf r683 7426b6fb090b5754bad0c6c428d7dbc2303d980c

    ●libvmafは現状ではpthread依存のようで、ffmpegに–disable-w32threadsが必要なようですが、
     Zeranoe氏はpthreadだと遅くなるということで避けたいらしく、
     当面はlibvmafはZeranoe版バイナリには入らない模様です。
      https://ffmpeg.zeranoe.com/forum/viewtopic.php?p=13039#p13039

    ●i7-4702MQで1080p/2157framesのSSIMやVMAFを計算させると
     -lavfi ssimなら150fps出るのに、-lavfi libvmafは2.8fpsしか出ませんでした。
     また、ssimでは実行中のメモリ使用量も200MB以下なのですが、
     libvmafでは最大6GBくらいになってかなり重くなりました・・・。
     バグなのか仕様なのかビルドの問題なのか不明ですが
     もうちょっと軽く動くようになると嬉しいですね。

    ●VMAFは基本的にオリジナルソース(=reference)を固定した上で、それを元にして
     リサイズやエンコードした複数の配信用ファイル(=distorted,main)のVMAFスコアを測り、
      「同じビットレートならどれが一番VMAFスコアが高いか」
     を調べて、最適な配信用ファイルを決めるといった形で使うものだと思います。

    ●したがって、リサイズしたもののVMAFスコアを測る場合は、
     リサイズしたものをオリジナル解像度に戻した上で
     VMAFスコアを測るのが一般的ではないかと思います。
     コマンド的には
      ffmpeg -i resized720p_x265_2000kbps.mp4 -i original1080p.mp4 -filter_complex scale=1920:1080:flags=print_info+lanczos,libvmaf=model_path=model/vmaf_v0.6.1.pkl -an -f null –
     といった形の方が順序的にも意味的にもわかりやすいのではないかと思います。

    ●YUVの動画比較のところでoriginal.yuvとreference.yuvという
     表現(どちらもオリジナルを指す)が混在してしまっているので、
      original.yuv → encoded.yuv
      reference.yuv → original.yuv
     といった表現に変えるとわかりやすくなると思います。
     (referenceって一般的にはあまりなじみが無い表現かなーと)

    ●enable_transformは、「transformを計算する」というより
      「VMAFスコアの計算でtransformを有効にする」
     という説明の方がよいかと思います。
     (どういう処理なのかは自分もよくわかってないですが
      同一ファイルのVMAFスコアが100.0になったりするようです。)

    ●poolの harmonic mean の指定は harmonic_mean のようです。

  • Tac

    メモリリークの情報と更新ありがとうございます。
    メモリリークの件は調べていませんでした。

    ●修正後の記事のリサイズの部分ですが、
      ・「リサイズする場合」というタイトルは「解像度が異なる場合」が良いかも。
      ・VMAF計測時のリサイズアルゴリズムは特に縮小時と同じにする必要はなく
       好きなもの(視聴時に期待できるもの)を選択すればよい。
       (高性能なアルゴリズムにすればスコアも上がる)
      ・エンコードする前の動画(オリジナル)をリサイズするのではなく、
       エンコード後の動画をオリジナルサイズにあわせてリサイズする。
      ・VMAF計測時のコマンドでscaleの引数が1280:720になっているが1920:1080のはず。
       (このままだと解像度違いでエラーになる)
     ということで、以下のような感じが良いかもしれません。
     (splineとlanczosにしているのはなんとなくです)

    ——————————————————————–
    解像度が異なる場合

    解像度が異なる場合に VMAF スコアを調べるには、調べたい動画をフィルタでオリジナルの解像度にリサイズしてから調べればよい。

    オリジナルが 1920 x 1080、エンコード後が 1280 x 720 の場合。

    ffmpeg -i original-1080p.mp4 -filter_complex scale=1280:720:flags=spline -acodec copy resized-720p.mp4

    ffmpeg -i resized-720p.mp4 -i original-1080p.mp4 -filter_complex “scale=1920:1080:flags=lanczos,libvmaf” -an -f null –
    ——————————————————————–

    ●SSIMとは違って [encoded][original] と [original][encoded] の結果が異なるので、
     「順序は必ず “-i 調べたい動画 -i オリジナル” にする必要がある」という注意書きもあると良いかなと思いました。

    • admin

      コメント確認しました。スレッドも確認しましたが HEVC の100倍遅いと言われている AV1 ですがそれどころじゃないくらい遅くて今のところ全く実用的ではないですね。

       AV1(libaom-av1)で1920×1080の10フレームだけをエンコードしてみた結果。http://mevius.5ch.net/test/read.cgi/avi/1515759816/378

       他のエンコーダとの速度比較などhttp://mevius.5ch.net/test/read.cgi/avi/1515759816/392

      • Tac

        AV1はまだ最適化もされてませんから遅すぎてテストもままならないですね・・・。
        なおZeranoe版ffmpegではlibaomのビルドミスがあり、
        ffmpeg-20180404-53688b6までは本来よりも更に遅い結果(最大で5.7倍くらい)となります。
        そのため検証するならそれ以降のビルド(このコメントを書いている時点ではまだ未リリース)を使う必要があります。
         https://ffmpeg.zeranoe.com/forum/viewtopic.php?f=5&t=5601#p13513

コメントを残す

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

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