x264 と x265 で CRF 毎に SSIM と Bitrate の関係をグラフ化した

動画
この記事は約9分で読めます。
この記事は最終更新日より 1 年以上経過しています。
画像やリンクが無効になっている可能性もあるのでご了承下さい。

はじめに

 過去にも同じ様な記事名で CRF 毎の画質評価を行った。

 ただ、当時の x265.exe にはバグがって無駄に Bitrate がモリモリ状態となって居た為、Bitrate に関わるデータが結果的になんのアテにもならないデータと化していた。
 そこで改めて前記事から 4 年の時を経た現在ではどんなデータが取れるかなと、重すぎる腰を持ち上げてデータ取りとまとめる作業に没頭してみた。

データ採取環境

 作業はメインマシンで行った。
 スペックは次の通りだが、CPU である Ryzen 7 1700X は 3.8GHz に OC した状態に。

エンコード

ソース

 TOKYO MX で放送していた「転生したらスライムだった件」の 16 話の TS ファイルを使う事にした。理由は特になく何となくで。
 このファイルからオープニング部分のみを Murdoc Cutter を用いて切り出してソースとして使用した。

 今回まとめるデータは上記ソース固有のものであり、ソース次第では如何様にも変化する。よってどんなエンコードの結果にも当てはまる物では無いことを予めご了承願いたい。

エンコード方法

 ちまちまやっていられないので Windows でバッチファイル書いて x264 と x265 それぞれを一発でエンコードさせた。
 念のため x264 と x265 それぞれ preset fast, medium ,slow の crf 18 から 30 まで 2step ずつ下げてエンコードするバッチファイルの例を示してみる。
 必要なプログラムに対するパスを設定して echo.DirectShowSource("test.ts") 部分のソースファイル名を記述すれば動くはず。
 AvisynthPlus のプラグインパスに Yadifmod2 と TIVTC が存在する必要もある。

x264 でエンコードするバッチファイル例

@echo off

set AVS4X26X="path\to\avs4x26x-x64.exe"
set MUXER="path\to\muxer.exe"
set X26X="path\to\x264_2935_x64.exe"
set LOG="log264.txt"

rem Make AVS File.
echo.DirectShowSource("test.ts")>> temp.avs
echo.Spline36Resize(1440, 1080)>> temp.avs
echo.AssumeTFF()>> temp.avs
echo.Yadifmod2(mode=0, order=-1, field=-1).TDecimate(mode=1, hybrid=0)>> temp.avs
echo.Prefetch(threads=16)>> temp.avs
echo.return last>> temp.avs

for %%P in (fast medium slow) do (
    for /l %%C in (18, 2, 30) do (
        @echo "--x26x-binary %X26X% --crf %%C --preset %%P" filename encoded_x264_%%C_%%P.264
        %AVS4X26X% --x26x-binary %X26X% --tune ssim --ssim --crf %%C --preset %%P --sar 4:3 --asm avx -o encoded_x264_%%C_%%P.264 temp.avs >> %LOG% 2>&1
        %MUXER% -i encoded_x264_%%C_%%P.264?fps="24000/1001" -o encoded_x264_%%C_%%P.mp4

    )
)
del temp.avs

x265 でエンコードするバッチファイル例

@echo off

set AVS4X26X="path\to\avs4x26x-x64.exe"
set MUXER="path\to\muxer.exe"
set X26X="path\to\x265.exe"
set LOG="log.csv"

rem Make AVS File.
echo.DirectShowSource("test.ts")>> temp.avs
echo.Spline36Resize(1440, 1080)>> temp.avs
echo.AssumeTFF()>> temp.avs
echo.Yadifmod2(mode=0, order=-1, field=-1).TDecimate(mode=1, hybrid=0)>> temp.avs
echo.Prefetch(threads=16)>> temp.avs
echo.return last>> temp.avs

for %%P in (fast medium slow) do (
    for /l %%C in (18, 2, 30) do (
        @echo "--x26x-binary %X26X% --crf %%C --preset %%P" filename encoded_x265_%%C_%%P.26x
        %AVS4X26X% --x26x-binary %X26X% --tune ssim --ssim --crf %%C --preset %%P --sar 4:3 --csv %LOG% -o encoded_x265_%%C_%%P.265 temp.avs
        %MUXER% -i encoded_x265_%%C_%%P.265?fps="24000/1001" -o encoded_x265_%%C_%%P.mp4
    )
)
del temp.avs

エンコード詳細

 次に示す AVS ファイルをバッチファイル内で生成して AvisynthPlus 経由でフィルタを適用する。

DirectShowSource("test.ts")
Spline36Resize(1440, 1080)
AssumeTFF()
Yadifmod2(mode=0, order=-1, field=-1).TDecimate(mode=1, hybrid=0)
Prefetch(threads=16)
return last

 ソースの TS ファイルは 1440x1080 SAR 4:3 表示なので同様の形式で処理させることにした。
 デインタレは特に環境依存も無く高速で無難な Yadifmod2 で行い、Tdecimate で重複フレームを間引く事でデテレシネをする。
 Prefetch は Ryzen 7 1700X は 16threads なので 16 にしている。

 各エンコードオプションは次の通り。

  • x264
    --tune ssim --ssim --crf 18~30 --preset {fast,medium,slow} --sar 4:3 --asm avx
  • x265
    --tune ssim --ssim --crf 18~30 --preset {fast,medium,slow} --sar 4:3 --csv LOGFILENAME

 両者共に引数は同じ様なもんで動作するが、ログ出力に関しては x265 のみ有効な為に x264 のログはリダイレクトを用いてファイルに出力させる必要があった。x264 の mod 版ならログファイルを吐けるけど今回はパスとした。

データをまとめる

 作成したバッチファイル 2 つを順に実行すれば合計 36 パターンでエンコードされたファイルが出来上がる。
 あとはログを整理整頓して表計算に打ち込みしたりコピペしてグラフ化するのみ。といってもこれが一番時間の掛かる作業だったりもした。
 x265 に関してはログが CSV 形式で出力されるのでまとめるのは非常に楽。
 逆に x264 のログはテキストファイルになるし不要な部分が殆どなのでテキストエディタを用いて必要な箇所だけ残るように正規表現で不要な部分はドカッと除去すると見やすくなる。
 加えて x264 はログにエンコードファイルのビットレートが出ないので、ffprobe を用いて必要な情報をファイルに落とす必要があった。かなり面倒だったり。

for %F in (.\*fast.mp4) do ( ffprobe.exe -hide_banner -pretty -show_entries format=bit_rate %F >> result_fast.txt )

 なんて preset 毎にやってやると mp4 のコンテナに mux したファイルから Bitrate だけをファイル出力出来て少し楽出来る。

まとめたデータ

 前置きが長くなりすぎたが、今までの内容を踏まえて採取したデータをまとめた物を示す。

Bitrate と SSIM の関係

 エンコーダーの性質が最も表れる部分と思われる場所。
 x265 の方がより低い Bitrate で SSIM を維持する事が可能となる。つまり効率良く圧縮の効いたエンコードが成されていると言える。
 Bitrate が低く済むという事は成果物となるファイルのサイズが同じ位の比率で小さくなると言う事でもある。

 エンコーダー自体の所感としては x264 の場合、preset を重くするほど画質を維持して Bitrate を抑える動きが目立ち、x265 の場合はとにかく画質を上げ、それを維持する為なら多少の Bitrate は盛ってしまおうという動きに感じられた。

エンコード速度と SSIM の関係

 どれだけ高効率でエンコードが可能と言っても実用度はエンコード速度もまた重要となってくる。
 x265 の様に SSIM も高く Bitrate も低く効率が幾ら良いとは言えエンコード速度はそれらに比例して低下する。
 x264 は preset slow であっても十分実用的な速度を示す。

 無論、エンコード速度に関しては Avisynth 等で適用するフィルタによっても左右される部分なのでそこも加味した上で最終的な判断が必要となる。
 しかしこのグラフに示した以上の速度にはならないから相対的な比較にはなるかなと思われる。

エンコード速度比較

 x264 と x265 のエンコード速度のみを抜き出してみた。
 こうしてみるとエンコード速度を最優先にしたい場合の選択肢は x264 に軍配が上がる。再生デバイスの互換性と言った面でも優位である。
 x265 は preset medium でアニメソースだと律速にエンコード可能な点から、画質を保ちつつファイルサイズを抑えたい場合に選択肢に入りうる。筆者の場合、今後もまた繰り返し見るであろうアニメに関しては x265 で preset medium を常用している。

CRF 毎の SSIM と Bitrate 比較

 最後に x264 と x265 も混ぜた CRF 毎の SSIM と Bitrate の比較グラフ。
 トータルで評価すると今回使用したソースの場合、x265 の preset fast を使うくらいであれば x264 で preset slow とした方が何かと幸せになれるハズ。
 筆者個人の指標としては SSIM 0.985 以上を目指しているのでエンコード速度を天秤にかけつつ CRF 18~23 の間でエンコードを行うことになる。

おわりに

 最終的に 6 個のグラフを掲載する事となったが、読み方は人それぞれ必要な部分を行き来してみると良いかも知れない。
 エンコード速度を最重要視するのであれば指標とする SSIM を定めてそれを満たせる CRF 値を見るだけで良いし、画質ベースで色々バランスをとりたいのであれば SSIM 値を元にエンコード速度のグラフと Bitrate のグラフを交互に見て妥協点を探してみたり等々。
 見る人によって異なる物が見えてくるかと思うので CRF や Preset をどうしようかなと悩んでいる方に何か役立つことがあればこれ幸い。

著者プロフィール
ぶっち

本格的に PC へ触れ始めてたのは 1990 年位から。
興味は PC 全般。OS は Windows と Linux などを嗜む。
プログラマやネットワークエンジニアを経てフリーに活動している 40 代も後半に入ったおじさんです。

ぶっちをフォローする

コメント

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.