TL;DR
VMAF はオリジナル動画に対して圧縮等で劣化した動画の品質を評価するツールです。 ffmpeg を利用して計測します。0 ~ 100 のスコアで評価され、100 に近いほど高品質です。
ffmpeg -i 評価したい動画.mp4 -i オリジナル動画.mp4 -filter_complex "libvmaf=n_threads=31" -f null -
はじめに
本記事では ffmpeg を利用して VMAF を計測する方法を紹介します。VMAF の詳しい説明はしません。
VMAF
VMAF (Video Multi-Method Assessment Fusion) は Netflix が開発した映像品質評価アルゴリズムです。圧縮や、オンデマンドストリーミングなどで劣化した映像の品質を評価するために設計されています。 ffmpeg で利用可能です。0 から 100 までのスコアで評価され、100 に近いほど高品質を示します。
サンプル動画ダウンロード
本記事ではウサギの動画を利用します。 以下のコマンドでダウンロードしてください。
Linux
wget https://download.blender.org/demo/movies/BBB/bbb_sunflower_1080p_60fps_normal.mp4.zip -O bbb_sunflower_1080p_60fps_normal.mp4.zip
tar -xf bbb_sunflower_1080p_60fps_normal.mp4.zip
rm bbb_sunflower_1080p_60fps_normal.mp4.zip
Windows
curl https://download.blender.org/demo/movies/BBB/bbb_sunflower_1080p_60fps_normal.mp4.zip -O bbb_sunflower_1080p_60fps_normal.mp4.zip
tar -xf bbb_sunflower_1080p_60fps_normal.mp4.zip
rm bbb_sunflower_1080p_60fps_normal.mp4.zip
ffmpeg インストール
VMAF は ffmpeg を利用して映像を処理するため、ffmpeg をインストールする必要があります。
Linux
sudo apt update
sudo apt install ffmpeg
Windows
管理者権限で以下のコマンドを実行
winget install --id=Gyan.FFmpeg -e
元動画で VMAF 計測
Windows/Linux 共通
ffmpeg -i bbb_sunflower_1080p_60fps_normal.mp4 -i bbb_sunflower_1080p_60fps_normal.mp4 -filter_complex libvmaf -f null -
出力例
[Parsed_libvmaf_0 @ 0000018c20a05580] VMAF score: 98.829036e=N/A speed=0.518x elapsed=0:20:25.76
スコアは 0 から 100 までの範囲で、100 に近いほど高品質を示します。 非劣化動画で 98.8 ですが、少数の誤差や AI モデルの特性により 100 にはならないそうです。ちなみに1080p 60fps 10分の動画で計測すると20分以上かかります。
高速化(並列化)は以下のコマンドで可能です。以下では31スレッドで処理しています。 CPUのコア数 - 1 程度が目安です。20分かかったのが8分程度に短縮されました。
ffmpeg -i bbb_sunflower_1080p_60fps_normal.mp4 -i bbb_sunflower_1080p_60fps_normal.mp4 -filter_complex "libvmaf=n_threads=31" -f null -
劣化動画で VMAF 計測
ffmpeg でビットレートを変えてエンコードして劣化動画を作成し、VMAF を計測します。オリジナルの動画はサラウンド音声が入っているため、サラウンド音声を消したオリジナル動画を作成してから劣化動画を作成します。
ffmpeg -i bbb_sunflower_1080p_60fps_normal.mp4 -vcodec copy -map 0:0 -acodec copy -map 0:1 origin.mp4
劣化動画作成
オリジナル動画のビットレートは 4001 kb/s でした。(ウサギの動画はアニメだからかめっちゃ低い)
とりあえず 2000 kb/s, 1000 kb/s, 500 kb/s, 250 kb/s, 100 kb/s, 50 kb/s の6段階で劣化動画を作成し、VMAF を計測します。
ffmpeg -i origin.mp4 -map 0:v:0 -map 0:a:0 -vf "scale=1920:1080,fps=60" -b:v 2000k -c:a copy bbb_2000k.mp4
ffmpeg -i origin.mp4 -map 0:v:0 -map 0:a:0 -vf "scale=1920:1080,fps=60" -b:v 1000k -c:a copy bbb_1000k.mp4
ffmpeg -i origin.mp4 -map 0:v:0 -map 0:a:0 -vf "scale=1920:1080,fps=60" -b:v 500k -c:a copy bbb_500k.mp4
ffmpeg -i origin.mp4 -map 0:v:0 -map 0:a:0 -vf "scale=1920:1080,fps=60" -b:v 250k -c:a copy bbb_250k.mp4
ffmpeg -i origin.mp4 -map 0:v:0 -map 0:a:0 -vf "scale=1920:1080,fps=60" -b:v 100k -c:a copy bbb_100k.mp4
ffmpeg -i origin.mp4 -map 0:v:0 -map 0:a:0 -vf "scale=1920:1080,fps=60" -b:v 50k -c:a copy bbb_50k.mp4
評価
それぞれの劣化動画で VMAF を計測します。(並列数はよしなに調整してください)
ffmpeg -i bbb_2000k.mp4 -i origin.mp4 -filter_complex "libvmaf=n_threads=31" -f null -
ffmpeg -i bbb_1000k.mp4 -i origin.mp4 -filter_complex "libvmaf=n_threads=31" -f null -
ffmpeg -i bbb_500k.mp4 -i origin.mp4 -filter_complex "libvmaf=n_threads=31" -f null -
ffmpeg -i bbb_250k.mp4 -i origin.mp4 -filter_complex "libvmaf=n_threads=31" -f null -
ffmpeg -i bbb_100k.mp4 -i origin.mp4 -filter_complex "libvmaf=n_threads=31" -f null -
ffmpeg -i bbb_50k.mp4 -i origin.mp4 -filter_complex "libvmaf=n_threads=31" -f null -
| ビットレート | VMAF スコア |
|---|---|
| origin | 98.8 |
| 2000 kb/s | 89.6 |
| 1000 kb/s | 76.8 |
| 500 kb/s | 52.9 |
| 250 kb/s | 20.5 |
| 100 kb/s | 2.6 |
| 50 kb/s | 2.6 |
ビットレートが下がるにつれて VMAF スコアも下がっていることがわかります。ビットレートが低くて何が写っているのかわからない動画のスコアは下がり止まりするようです。今回はアニメ調の動画を使用しましたが、実写動画とか動きの有り無しの動画だとまた変わってくると思います。