H.264 vs H.265 vs VP8 vs VP9 vs AV1
ソフトウェア
- TOP
- Old Archives
- H.264 vs H.265 vs VP8 vs VP9 vs AV1
序
実は先のビデオ関連の記事はMimir Yokohamaのほうにupしようかと思っていた。
こっちにしてよかった…Mimir Yokohamaのフォーマットで書いてたら絶対地獄を見た…
さて、先の記事の途中でAV1を試したが、実際AV1がどの程度使い物になるのか(いや、実際は強烈に遅いので全く使い物にならないのだが)試してみたくてちょっと検証してみた。
ソースビデオはコントラスト差、動きともに激しく、部分的にはほとんど更新されないドラムマニアのプレイ動画を使用した。 10MbpsほどのH.264ビデオである。
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.12.100
Duration: 00:00:04.79, start: 0.308970, bitrate: 9998 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, smpte170m/unknown/smpte170m), 1080x1920 [SAR 1:1 DAR 9:16], 9995 kb/s, 29.88 fps, 29.88 tbr, 15296 tbn, 59.75 tbc (default)
Metadata:
handler_name : VideoHandler
libvpxはビットレートコントロールがうまくいかなかったことから、aomav1はそもそも変換できなかったことからこれらはrawvideoに変換し、それぞれvpxenc
,
aomenc
を使用して2パスで変換した。
メインビットレートはH.264で荒れる512kを選択。 VP8はあまりに小さいビットレートコントロールが困難だったため、512kについては200kを指定したCBRとした。
比較
ソース動画
ソースは10Mbpsということもあり、暗い中非常にキレイに撮れている。 なお、撮影機材はZenfone Selfie(ZD511KL)である。
H.264
$ ffmepg -i base.mp4 -c:v libx264 -b:v 512k h264.mp4
そもそもH.264で荒れさせるのが基準だったため、512kでは動きのある部分は完全にブロックだし、パッド部分も相当粗い。
ビットレートが上がると順当にスムーズになっていき、素直な特性のようだ。
H.265
$ ffmepg -i base.mp4 -c:v libx265 -b:v 512k h265.mp4
現状最も有力なH.265。 さすがというか、静止画にすると打点のスティックが消えてしまっていて、VP9のほうが良さそうなのだが、 全体でみれば安定していてキレイ。動画では画質がよく感じられる。
全体的なざらつきがないので綺麗に見えるがこの静止画からわかるとおり動きの激しい部分でディティールがVP9よりも消えやすい。 ディティールにこだわる場合はビットレートに余裕を取るべきだと思うけれども、静止画に切り出す場合などはVP9のほうがうまくいく。
ビットレートが上がったときにも順当によくなっている。 H.264よりひとまわりいいといった感じで、ビットレートが上がると差は縮まり、ビットレートが非常に低いときはがんばっている感じだ。
H.265 (NVENC)
$ ffmpeg -i base.mp4 -c:v hevc_nvenc -b:v 512k h265-nvenc.mp4
NVENCは画質がよくないと言われているので、比較してみた。
テクスチャが雑で、なんか「下塗りです」といった感じ。 成る程、VP9 QSVのようにあからさまに目立つわけではないのだが、ディティールを見てしまうとなかなか厳しい。 利用できる状況は限られそうだ。
VP8
$ vpxenc --end-usage=cbr --bias-pct=0 --codec=vp8 --target-bitrate=200 --passes=2 -h 1920 -w 1080 -o vp8-cbr.webm raw.y4m
普及しなかったし残念なことになったVP8。768kならがんばってくれるが、512kはどうがんばっても到達せず、このセッティングでもちょっと大きめの586k。
画質は全体的にザラザラ。大きなブロックがないので静止画だとキレイっぽいけれど、常時こんな感じ(H.264なんかは部分的に、そしてちょいちょいブロック化してしまう感じである)なのでちょっとお話にならない。
何より目立つのは「色がおかしい」ことだが。
VP9
$ vpxenc --codec=vp9 --target-bitrate=512 --passes=2 -h 1920 -w 1080 -o vp9.webm raw.y4m
VP9は結構優秀で、H.264よりは良いし、H.265とどちらが良いかというと好みの問題と言えるくらいには仕上がっている。 ディティールを見ると損なわれ感があるのでやや厳しいが、ビットレートにある程度余裕を持たせればH.264よりも良い。
フリーコーデックに魅力を見ると感じるなら画質面ではアリだ。
だが、いかんせん遅い。x265の1/10くらいの速度である。 速度優先にしないと10fpsも夢のまた夢。
VP9もまともにマルチスレッドしないので、マルチスレッド化するだけでだいぶ実用になる気がするのだけど… (少なくともlibx265に負けない程度には)
ビットレートが上がるとH.265より良いように見える。 1Mbpsは完全に及第点だろう。
VP9 (QSV)
ffmpeg -init_hw_device vaapi=foo:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device foo -i invideo.mp4 -filter_hw_device foo -vf 'format=nv12|vaapi,hwupload' -c:v h264_vaapi -b:v 512k -c:a copy outvideo.mp4
VP9を唯一実用する方法であるQSV。しかし、QSVのVP9は相当画質が悪い。 ビデオでの印象としてはVP8に近い。ちょっとこの品質ではよほど高ビットレートでない限り実用にならないという感じだ。 エンコードは100fpsほど出るのだが…
AV1
AV1はデフォルト設定では到底終わらないほどの時間がかかったため、次のようにした。
% aomenc --codec=av1 -t 40 --cpu-used=8 --target-bitrate=512 --passes=2 -h 1920 -w 1080 -o av1.mkv raw.y4m
Pass 1/2 frame 142/143 27456B 1546b/f 46186b/s 19657 ms (7.22 fps)
Pass 2/2 frame 142/142 298568B 16820b/f 502497b/s 2741931 ms (0.05 fps)
なお、どちらもスレッド数を指定しているが、AV1は完全にシングルスレッドで動作していた。
H.265よりもディティールが消え、のっぺりしている。 VP9とはほとんど見分けがつかないが、よく見ればなんとVP9のほうが良い。 VP9(512k)に対してAV1(512k)は
- シャツの前のほうのシワが消滅
- 打点部分のスティックが巨大なブロックによって消滅
- シャツはのっぺりしてしまっている
と残念な結果に。
ビットレートがあがってもあまり改善していない。
速度優先の--cpu-used
のせいかもしれないがVP9の10倍は時間をかけた意味はどこへ…
追記: VP9/AV1 のマルチスレッド処理
テスト
コメントにてyusukeさんから
AV1がシングルスレッドでしか動かないのは–tile-columnsと–tile-rowsを指定していないからではないでしょうか
と情報頂いたので試してみた。
% aomenc --codec=av1 --cpu-used=8 --target-bitrate=512 --threads=16 --tile-columns=2 --tile-rows=2 --passes=2 -h 1920 -w 1080 -o av1-512-pararell.mkv raw.y4m
この場合、シングルスレッドで動作した。
% aomenc --codec=av1 --cpu-used=8 --target-bitrate=512 --threads=16 --tile-columns=6 --frame-parallel=1 --passes=2 -h 1920 -w 1080 -o av1-512-pararell.mkv raw.y4m
--tile-rows
をやめて、デコード用オプションである--frame-parallel
を有効にしたところ、
マルチスレッドで動作した。
ただし、大部分はシングルスレッドで、ときどき6から10スレッド程度で動作するような挙動。
結果は
Pass 1/2 frame 142/143 27456B 1546b/f 46186b/s 19934 ms (7.12 fps)
Pass 2/2 frame 142/142 303279B 17086b/f 510444b/s 1562704 ms (0.09 fps)
aomenc --codec=av1 --cpu-used=8 --target-bitrate=512 --threads=16 --passes= 3502.70s user 67.02s system 224% cpu 26:29.29 total
CPUは200%越えてるけれど、速度的には2倍にはなっていない程度。
そして次の場合
% aomenc -w 1080 -h 1920 --tile-columns=6 --limit=48 -t 24 -b 8 --input-bit-depth=8 --end-usage=vbr --target-bitrate=512 -p 1 --webm --num-tile-groups=32 -o av1-512-parallel2.webm raw.y4m
Pass 1/1 frame 142/142 290129B 16345b/f 488306b/s 7850851 ms (0.02 fps)
aomenc -w 1080 -h 1920 --tile-columns=6 -t 24 -b 8 --input-bit-depth=8 -p 1 38460.66s user 114.83s system 491% cpu 2:10:55.73 total
ずっと激しく使われているのでなかなか効率はよさそう。
この違いは--cpu-used
にあるようだった。
--cpu-used=4
の場合:
Pass 1/1 frame 142/142 295824B 16666b/f 497896b/s 1581372 ms (0.09 fps)
aomenc -w 1080 -h 1920 --cpu-used=$i --tile-columns=6 -t 24 -b 8 -p 1 -o 4379.28s user 54.32s system 279% cpu 26:26.07 total
--cpu-used=8
より少し多めに動いている。
--cpu-used=2
:
Pass 1/1 frame 142/142 297030B 16734b/f 499928b/s 3251395 ms (0.04 fps)
aomenc -w 1080 -h 1920 --cpu-used=$i --tile-columns=6 -t 24 -b 8 -p 1 -o 10423.02s user 70.17s system 322% cpu 54:16.15 total
結構動くようになった。
では待望の画質はというと
結構差は大きい。 cpu-used=8のAV1よりはcpu-used=1のVP9のほうが綺麗だけども、4だとディティールは潰れているけれどざらつきが減るため好みで済ませられるように思える。cpu-used=4より上であればH.265に対するアドバンテージは認められる。 のっぺりしているのはAV1のキャラクターのようだが、ノイズが消えるため感覚的には綺麗に見える。再変換したときに情報の欠落が気になりそうだが。
おまけ。同じセッティングでVP9を作ってみる(vpxenc
とaomenc
はだいたいコマンド互換性がある)。
--num-tile-groups
は使えないので外し、--codec=vp9
を追加する。
% vpxenc --codec=vp9 -w 1080 -h 1920 --cpu-used=8 --tile-columns=6 -t 24 -b 8 --input-bit-depth=8 --end-usage=vbr --target-bitrate=512 -p 1 --webm -o vp9-parallel.webm raw.y4m
Pass 1/1 frame 142/118 242873B 5835948 us 24.33 fps [ETA 0:00:01] 1125F 1298F 11937F 943F 792F 849F 1104F 1271F 1022F 1030F 24348F 1382F 1316F 1264F 2220F 1162F 1152F 1072F 1084F 1386F 13097FPass 1/1 frame 142/142 316309B 17820b/f 532379b/s 6950835 us (20.43 fps)
vpxenc --codec=vp9 -w 1080 -h 1920 --cpu-used=8 --tile-columns=6 -t 24 -b 8 16.91s user 0.73s system 235% cpu 7.478 total
おぉぉ、速いぞ!!! 実用になるぞ!!!よくみたらちょこっとだけ粗いけれど、全然いけるいける。
ただ、--cpu-used
しないとさすがに厳しい。
% vpxenc --codec=vp9 -w 1080 -h 1920 --tile-columns=6 -t 24 -b 8 --input-bit-depth=8 --end-usage=vbr --target-bitrate=512 -p 1 --webm -o vp9-parallel-used1.webm raw.y4m :(
Pass 1/1 frame 142/118 242579B 50719 ms 2.80 fps [ETA 0:00:10] 1121F 1252F 11933F 982F 752F 916F 1059F 1293F 973F 1027F 21951F 1641F 1210F 1324F 2162F 1095F 1044F 1052F 1099F 1382F 13774F Pass 1/1 frame 142/142 314260B 17704b/f 528930b/s 60777 ms (2.34 fps)
vpxenc --codec=vp9 -w 1080 -h 1920 --tile-columns=6 -t 24 -b 8 -p 1 --webm 143.78s user 1.13s system 236% cpu 1:01.31 total
所感
これをテストした上での感想としては
--cpu-used=1
はとても遅い。VP9でもかなり厳しい--cpu-used=8
はあまり効果がなく、--cpu-used=4
が軽量設定としてはよさそう- 確かに画質は良いが
--cpu-used=8
だと悪い。--cpu-used=1
でx265並の速度が出れば革命的だけども… - マルチスレッドはVP9よりはAV1で改善されている
- しかしAV1であっても対してCPUを活用できておらず、いまいちと言われているx265のほうがよっぽど計算リソースを有効活用する
- だいたい活用できているのは8スレッドあたり。クロスしている部分を考慮しても12スレッド
- AV1はいくらスレッド数を多く指定しても現実的な速度にならない。4114が遅いとしてもCOre i7であってもコアあたり8倍は速くないので、10FPSには到達しない感じ
- スレッド数を増やしてもせいぜい2倍程度しか速くならないため、スレッド数よりも
--cpu-used
のほうが影響が大きい - VP9の
--cpu-used=4
は速度的にも(うちでは30FPS出ないが)使えるが、H.265(libx265)との差は開いてしまい、よほど強い動機がないと厳しい (--cpu-used=2
でも結構粗い) - AV1がハードウェア支援されたら使えるかというと、現状QSVのVP9がひどいという言葉では片付けられないくらいひどいので、全く期待できない
基本的には「向上するソース画質に対して可能な限り損なわないようにする」には「ソースサイズが大きくなったとき(あるいは画質が向上したときに)に同等ビットレートでソースの改善を反映できるように」動画コーデックは進化しているのであり、つまり情報の少ないソースであれば結果的により小さなサイズに圧縮できる、ということを反映意味する。
そのことを踏まえれば、「画質とサイズを妥協すれば新しいコーデックでも実用できる」というのは完全に本末転倒であり、全く価値がない。これは速度的にVP9の最高画質とAV1の最低画質が同ビットレートで逆転し、かつVP9のほうが速い、というのはまさにそれだ。
確かにAV1の画質は魅力的だが、それはあまりにも現実的ではないリソースをつぎ込めばという話である。 それをいくらか緩和しようとした時点でAV1の画質というメリットは損なわれてしまい、VP9のほうがまだマシという結果になる。
もちろん、一般で使われることは最初から投げ捨てて、配信者向けに作っているのでありユーザーには関係ない、というのであればわからなくはないが、現状のAV1はそれこそGoogleクラスでなければ実用できないようなものであり、ユーザーはデコードすらままならない。 そうすると単に「特殊で扱いにくいもの」になってしまい、そのようなものがどんな経過をたどり今残っていないのかということを完全に忘れ去ってしまっているように思う。
現状は、一般ユーザーにとってVP9であれAV1であれ利用を考慮する価値のないものであり、 フリーであることの価値を理解するのであればVP9は考えられるがAV1は存在自体忘れていても構わない。
ユーザーが使うならばH.265(あるいはH.264)が良い。 (特許問題など気持ち悪いとは思うが…)
画質、処理速度、コスト、処理の安定性などH.265(x265)の何が好まれていて、何を達成しなければならないのか、優位性を口にするくらいなら真剣に考えて欲しいと思う。