次世代エンコーダVP9(webm、mp4)のエンコード設定についてffmpegで使う設定をまとめた。libvpx-vp9は外部ライブラリなので別途インストールする必要がある。さらに音声のエンコーダで使われるlibopusも外部ライブラリなのでこれもインストールする必要がある。

設定内容は多くあるがほとんどの設定は何も変えず、ビットレートの設定と品質・速度のトレードオフで考える。VP9は処理が遅いとよく言われるが、-threadsを設定することで速くなる。libx264のように自動設定してくれないので一番下の方にある解像度に併せて設定する。

libvpx-1.7.0から 10、12ビット深度に対応した。

Downloads – Opus Codec

VP9コーデックメモ – Qiita

基本コマンド

ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -cpu-used 2 -threads 3 -row-mt 1 -c:a libopus -b:a 128k output.webm

libopus をインストールしていない場合。
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -cpu-used 2 -threads 3 -row-mt 1 -c:a opus -b:a 128k -strict -2 output.webm

品質指定(CQ)の 2pass エンコード例。
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -cpu-used 4 -threads 3 -row-mt 1 -pass 1 -f webm -an -f null -
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -cpu-used 2 -threads 3 -row-mt 1 -pass 2 -auto-alt-ref 1 -c:a libopus -b:a 128k output.webm

linux などの 1pass 目の例。
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -cpu-used 4 -threads 3 -row-mt 1 -pass 1 -an -f webm /dev/null

ビットレート指定の 2pass エンコード例。
ffmpeg -i input -c:v libvpx-vp9 -b:v 2000k -cpu-used 4 -threads 3 -row-mt 1 -pass 1 -f webm -an -f null -
ffmpeg -i input -c:v libvpx-vp9 -b:v 2000k -cpu-used 2 -threads 3 -row-mt 1 -pass 2 -auto-alt-ref 1 -c:a libopus -b:a 128k output.webm

分割エンコードしてつなげるコマンド例。
ffmpeg -f concat -safe 0 -i input.txt -c copy output.webm

input.txt の内容。

file output-0.webm
file output-1.webm

詳しくは 【ffmpeg】動画・音声を連結する concat の使い方 其の3

高ビット深度の場合は出力フォーマットを指定する。
ffmpeg -i input -c:v libvpx-vp9 -crf 18 -keyint_min 24 -g 240 -b:v 0 -cpu-used 2 -threads 3 -row-mt 1 -pix_fmt yuv420p10le -c:a libopus -b:a 96k output.webm

アルファチャンネル付きの動画で出力。出力フォーマットにアルファチャンネルを含める。
ffmpeg -f lavfi -i testsrc2=d=10,chromakey=blue:.03:.1 -pix_fmt yuva420p -c:v libvpx-vp9 -crf 30 -b:v 0 -cpu-used 2 -threads 3 -row-mt 1 -pix_fmt yuva420p output.webm

RGB映像からYUV映像にエンコードする。
ffmpeg -i rgb -vf "scale=out_color_matrix=bt709:out_range=full" -c:v libvpx-vp9 -crf 30 -keyint_min 30 -g 300 -b:v 0 -cpu-used 2 -threads 3 -row-mt 1 -pix_fmt yuv444p -colorspace bt709 -color_range pc -c:a libopus -b:a 96k output.webm

ビットレート設定

以下の設定のどれかを必ず指定する。そうしないと-crf 32 -b:v 0でエンコードされる。-qmin、-qmaxの設定を差し戻した。-qmin、-qmax-b:vなどのビットレート設定では-b:vなどの設定のほうが強く出るので-qmin、-qmaxの効果がみられないという誤解につながった。2021年4月3日

VP9 bitrate modes | Google Developers

  • 平均ビットレート(ABR、VBR)
    -c:v libvpx-vp9 -b:v 2000k
  • 上限と下限を指定した平均ビットレート(ABR、VBR)
    -c:v libvpx-vp9 -b:v 2000k -minrate 1500k -maxrate 2500k
  • 固定ビットレート。平均ビットレートと最小と最大の3つを一致させる(CBR)
    -c:v libvpx-vp9 -b:v 2000k -minrate 2000k -maxrate 2000k
  • 品質指定(Constant Quality)
    (-1から63まで小さい値ほど高品質)-b:v 0は必須項目
    -c:v libvpx-vp9 -crf 30 -b:v 0
  • 上限と下限を指定した品質指定(Constant Quality)
    (-1から63まで小さい値ほど高品質)-b:v 0は必須項目。品質の上下を指定。最小値を10にすることでビットレートを上げすぎなくする
    -c:v libvpx-vp9 -crf 30 -b:v 0 -qmin 10 -qmax 63
  • 品質指定で平均ビットレートを指定(Constrained Quality)。-crf 30で平均ビットレートが2000kになる。-crf-b:vの併用は扱いが難しく、-crf N -b:v 0の併用のビットレートを元に-b:vを指定しないと意図せずビットレートが高くなったり低くなったりする
    -c:v libvpx-vp9 -crf 30 -b:v 2000k
  • 品質指定で上限と下限ビットレートを指定。-crf 30で平均ビットレートが2000kになる
    -c:v libvpx-vp9 -crf 30 -b:v 2000k -minrate 1500k
    -c:v libvpx-vp9 -crf 30 -b:v 2000k -maxrate 2500k
    -c:v libvpx-vp9 -crf 30 -b:v 2000k -minrate 1500k -maxrate 2500k
  • ロスレス(可逆圧縮)
    -c:v libvpx-vp9 -lossless 1

-bufsizeは例えば-maxrate 4350k -minrate 1500k -b:v 3000k -bufsize 5000kを指定するとエンコードログの最後にのるが、出力内容に変化がなく公式ドキュメントにも特に記載がない。

cpb: bitrate max/min/avg: 4350000/1500000/3000000 buffer size: 5000000 vbv_delay: N/A

映像の特定領域だけ品質を変える addroi

エンコード設定

Basic Encoding

ffmpeg -h encoder=libvpx-vp9で見られるエンコード設定とエンコーダ全般に指定できる設定の2つがある。以下はlibvpx-v1.10.0-rc1-14-g90c1cc651より。

この中で重要なのがエンコード速度と品質に関わる-cpu-used、-deadlineと、馴染みのある-crfである。-cpu-used、-deadlineはエンコード速度と品質に大きく影響する設定である。-cpu-used既定値は1で0にするとさらに半分以下にエンコード速度が遅くなるかわりに圧縮率が向上する。値を上げるとそれだけ速度が向上するが品質も悪くなる。品質と速度の面から2や3も候補になるが4、5の品質はよくない。マイナスも指定できるがプラスの時と出力内容は変わらない。さらに処理を速める-row-mt 1を併用する。

  • -cpu-used[int]
    マイナスも指定できるがプラスの時と出力内容は変わらない。0にすると最高品質だがものすごく遅くなる。大きな値ほど処理が速くビットレート当たりの品質が悪くなる。-deadlineの既定値であるgoodのときは-5から5までしか変化が無い。-deadline realtimeにすると-8から8まで変化がある。-speedと同じ内容。-cpu-used 3から-cpu-used 2で15%から25%程度遅くなる。少し下の「-deadline-cpu-usedを併用して処理速度をコントロールする。」を参照
    既定値:1
    範囲:-8から8まで
  • -deadline[int]
    品質指定。-cpu-usedの設定を受け付けないbest(一番高品質一番低速度)、既定値のgood、realtimeの3つの指定が出来る。設定を細かく分けるときはrealtimeを指定する。-qualityと同じ内容
    既定値:”good”
    指定値:best、good、realtime
  • -row-mt[boolean]
    マルチスレッド処理を有効化する。既定値は自動指定だが無指定より1を指定した方が処理が速くなる
    既定値:”auto”
  • -tile-columns[int]
    分割エンコード数で指定した値の2のべき乗になり、0なら分割しない、1なら2分割、2なら4分割になる。分割するほどエンコードとデコードは速くなるものの品質はわずかに低下する。設定できる値の範囲でも解像度によって影響を与える数値が異なる。複数同時処理すると分割しないほうの処理速度差が縮まる。ffmpeg – VP9 encoding limited to 4 threads? – Stack Overflow
    既定値:-1
    範囲:-1から6まで

    解像度 -tile-columnsの数値で変化あり
    256×144 0
    512×288 01
    768×432 01
    1024×576 012
    1280×720 012
    1920×1080 012
    3840×2160 0123
  • -crf[int]
    品質の数値指定。小さい値ほど高画質、高ビットレート。30から1減るごとに10%程度ビットレートが増え、20、21付近でビットレートがおよそ倍になる
    既定値:-1
    範囲:-1から63まで
  • -auto-alt-ref[int]
    パス指定の2パス目時-pass 2のときに指定できる。。数値が大きいと高画質で容量も多く速度も遅くなる。映像によって最適値は変わるので基本は無指定のままにする
    既定値:-1
    範囲:-1から6まで
  • -aq-mode[int]
    映像によっては最適な値が変わるかもしれない
    • 0, none:既定値
    • 1, variance
    • 2, complexity
    • 3, cyclic
    • 4, equator360:360度映像用
  • -ts-parameters[dictionary]
    スケール時の設定内容の指定。key1=value1:key2=value2のように指定する。設定内容はvpx/vpx_encoder.hに書いてあるが、レイヤー数やビットレートなどの指定ができる。参考記事
    指定例:-ts-parameters ts_number_layers=3:ts_target_bitrate=250000,500000,1000000:ts_rate_decimator=4,2,1:ts_periodicity=4:ts_layer_id=0,2,1,2

-deadline-cpu-usedを併用して処理速度をコントロールする。
video – VP9 encoding with FFmpeg: relation between -speed and -deadline options – Super Userより。

  • best:ものすごく遅く非推奨
  • good:既定値で一般的にはこちらを使う。-cpu-usedを0から5までの6段階指定できる
    • -cpu-used 0:-deadline bestにとても近い結果になるが2倍速い
    • -cpu-used 1、-cpu-used 2:処理速度は大幅に向上するが品質やレートコントロールにも影響を与え始める
    • -cpu-used 4、-cpu-used 5:「レート歪みの最適化」をオフにするが、処理速度はさらに向上する
  • realtime:品質と処理速度のトレードオフ。-cpu-usedを-8から8までの17段階指定できるが、負の値と正の値の絶対値が同じだと結果に変化がない

公式ドキュメント:ffmpeg Documentation : libvpx

libvpx-vp9の設定以外に品質の上限下限の指定と、キーフレーム間隔、色空間がある。

  • -g[int]
    group of picture sizeで、keyintのこと
    既定値:-1
  • -keyint_min[int]
    既定値:-1
  • -threads[int]
    下にある解像度に合わせて設定しないと速度が上がらない。指定値の2のべき乗になるので3の場合は下のグラフの8になる。CPUがスレッド数に対応していないと大きな値の効果は得られない
    既定値:-1(自動設定ではない)
  • -pass[:stream_specifier]
    2パスエンコードで使う。1、または2を指定。1パス目で解析して、2パス目で解析したログを使って指定したビットレート、品質にする。1パス目は動画を出力しなくてもよいので-an -f null –を併用する。stream_specifierは2トラック目以降の映像を指定するときに使う。1パスに-cpu-used, -speedを遅い設定にしても2パスの出力に影響を与えないので処理の速い4を指定する。また複数解像度にリサイズするときも一番大きい解像度のパスログ、1080pなら2160pにアップスケールして流用する方がvmafスコアが高くなる傾向(Big Buck Bunnyで検証)にあった。2pass目のエンコードは-crfエンコードよりもかなり遅くなる
  • -passlogfile[:stream_specifier] [string]
    -passで使うログファイルの指定。1パス目では出力ログ名の指定。2パス目では入力ログ名の指定になる。記入内容はPREFIX-N.logのPREFIX部分になる。Nはstream_specifier
    既定値:ffmpeg2pass

公式ドキュメント:ffmpeg Documentation : Video Options

色の情報の設定

カラースペースなどの入力、出力オプションは以下の記事を参照。
色の情報の扱いについて

出力オプションの-colorspaceが効いてないのでビットストリームフィルタでcolorspaceを指定する。

HD未満
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -bsf:v vp9_metadata=color_space=bt601:color_range=tv -color_primaries smpte170m -color_trc smpte170m -c:a libopus -b:a 96k output.webm

HD以上
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -bsf:v vp9_metadata=color_space=bt709:color_range=tv -color_primaries bt709 -color_trc bt709 -c:a libopus -b:a 96k output.webm

カラースペースを明示する場合にffmpeg 4.1からは -bsf:v vp9_metadataからでも設定できる。カラープライマリーとカラートランスファーが指定できないので上の出力オプションで指定するほうが他のコーデックでも共通なので使いやすい。

ビットストリームフィルタのまとめ

ffmpeg -h bsf=vp9_metadata

color_space[int]

  • unknown
  • bt601
  • bt709
  • smpte170
  • smpte240
  • bt2020
  • rgb

color_range[int]

  • tv
  • pc

色の情報が未指定のときは出力オプションとビットストリームフィルタの両方を指定してコーデックコピーするとメタデータを付与できる。

HD未満
ffmpeg -i input -c copy -bsf:v vp9_metadata=color_space=bt601:color_range=tv -color_primaries smpte170m -color_trc smpte170m output.webm

HD以上
ffmpeg -i input -c copy -bsf:v vp9_metadata=color_space=bt709:color_range=tv -color_primaries bt709 -color_trc bt709 output.webm

推奨ビットレートと品質、スレッド数の設定

Recommended Settings for VOD  |  Google Developersより
ビットレートの下限は指定ビットレートの50%、上限は145%としている。

Frame Size/Frame Rate Target Bitrate (VOD, kbps) Min Bitrate (50%) Max Bitrate (145%)
320x240p @ 24,25,30 150 75 218
640x360p @ 24,25,30 276 138 400
640x480p @ 24,25,30 512 (LQ), 750 (MQ) 256 (LQ) 375 (MQ) 742 (LQ) 1088 (MQ)
1280x720p @ 24,25,30 1024 512 1485
1280x720p @ 50,60 1800 900 2610
1920x1080p @ 24,25,30 1800 900 2610
1920x1080p @ 50,60 3000 1500 4350
2560x1440p @ 24,25,30 6000 3000 8700
2560x1440p @ 50,60 9000 4500 13050
3840x2160p @ 24,25,30 12000 6000 17400
3840x2160p @ 50,60 18000 9000 26100

縦解像度と品質指定(crf)

Frame Height Target Quality (CQ)
240 37
360 36
480 34 (LQ) or 33 (MQ)
720 32
1080 31
1440 24
2160 15

2パスエンコードのときには1パス2パスどちらも-deadline good-cpu-usedを以下の値にするとエンコード時間と品質のバランスがよい。1パスに-cpu-usedを遅い設定にしてもパスログファイルの出力に影響を与えないので処理の速い4を指定している。

Frame Height Speed (First Pass) Speed (Second Pass)
240 4 1
360 4 1
480 4 1
720 4 2
1080 4 2
1440 4 2
2160 4 2

tile-columns と threads の指定。

Frame Size Number of tile-columns Number of threads
320x240p 1 (-tile-columns 0) 2 (-threads 1)
640x360p 2 (-tile-columns 1) 4 (-threads 2)
640x480p 2 (-tile-columns 1) 4 (-threads 2)
1280x720p 4 (-tile-columns 2) 8 (-threads 3)
1920x1080p 4 (-tile-columns 2) 8 (-threads 3)
2560x1440p 8 (-tile-columns 3) 16 (-threads 4)
3840x2160p 16 (-tile-columns 4) 24 (-threads 5?)

こちらも参照
VP9 Bitrate Modes in Detail
Live Encoding

HDR エンコード

VP9 HDR Encoding  |  Google DevelopersよりYoutubeに投稿できるHDR動画のエンコード。SMPTE 2086のメタデータ書き込みに対応してないのでエンコードが終わったらmkvmergeを使う。mkvmergeはmkvtoolnixのアプリケーションの一つ。

サンプル動画:strobe_scientist.mkv

以下のサンプルコマンドは Google が2パス指定をしているのを参考にしているが、1パスの品質指定や固定ビットレートで YouTube に投稿しても HDR 形式にエンコードされる。どちらにしろ再エンコードされるのでビットレートをたくさん盛っておけば良さそう。

18Mbps 4k 2-pass
ffmpeg -report -i strobe_scientist.webm -b:v 18000000 -speed 4 -pass 1 -pix_fmt yuv420p10le -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 -maxrate 26800000 -minrate 8040000 -profile:v 2 -vcodec libvpx-vp9 -an -f null -
ffmpeg -report -i strobe_scientist.webm -b:v 18000000 -pass 2 -pix_fmt yuv420p10le -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 -maxrate 26800000 -minrate 8040000 -profile:v 2 -vcodec libvpx-vp9 strobe_scientist_18Mbps.webm

6Mbps 4k 2-pass
ffmpeg -report -i strobe_scientist.mkv -b:v 6000000 -speed 4 -pass 1 -pix_fmt yuv420p10le -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 -maxrate 8000000 -minrate 4000000 -profile:v 2 -vcodec libvpx-vp9 -f webm -an -f null -
ffmpeg -report -i strobe_scientist.mkv -b:v 6000000 -pass 2 -pix_fmt yuv420p10le -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 -maxrate 8000000 -minrate 4000000 -profile:v 2 -vcodec libvpx-vp9 2pass_HDR_strobe_scientist_6Mbps-static.webm

18Mbps 1080p 2-pass
ffmpeg -report -i strobe_scientist.mkv -b:v 18000000 -speed 4 -pass 1 -pix_fmt yuv420p10le -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 -maxrate 20800000 -minrate 15040000 -profile:v 2 -vf scale=-2:1080 -vcodec libvpx-vp9 -f webm -an -f null -
ffmpeg -report -i strobe_scientist.mkv -b:v 18000000 -pass 2 -pix_fmt yuv420p10le -color_primaries 9 -color_trc 16 -colorspace 9 -color_range 1 -maxrate 20800000 -minrate 15040000 -profile:v 2 -vf scale=-2:1080 -vcodec libvpx-vp9 1080_2pass_HDR_strobe_scientist_18Mbps-static.webm

18Mbps 4k HDR to SDR with LUT。lut3dフィルタで色を指定する。
ffmpeg -i strobe_scientist.mkv -b:v 18000000 -speed 4 -pass 1 -pix_fmt yuv420p -color_primaries 1 -color_trc 1 -colorspace 1 -color_range 1 -maxrate 26800000 -minrate 8040000 -profile:v 0 -vf scale=-1:-1:in_color_matrix=bt2020,format=rgb48,lut3d=bt2020_to_bt709_example.cube,scale=-1:-1:out_color_matrix=bt709 -vcodec libvpx-vp9 -f webm -an -f null -
ffmpeg -i strobe_scientist.mkv -b:v 18000000 -pass 2 -pix_fmt yuv420p -color_primaries 1 -color_trc 1 -colorspace 1 -color_range 1 -maxrate 26800000 -minrate 8040000 -profile:v 0 -vf scale=-1:-1:in_color_matrix=bt2020,format=rgb48,lut3d=bt2020_to_bt709_example.cube,scale=-1:-1:out_color_matrix=bt709 -vcodec libvpx-vp9 -f webm SDR_strobe_scientist_18Mbps-static.webm

18Mbps 4k 2-Pass HLG。HLG は元動画が HLG に対応していなければならない。

サンプル動画:strobe_scientist_hlg.mkv

ffmpeg -i strobe_scientist_hlg.mkv -b:v 18000000 -pass 1 -speed 4 -pix_fmt yuv420p10le -color_primaries 9 -color_trc 18 -colorspace 9 -color_range 1 -maxrate 26800000 -minrate 8040000 -profile:v 2 -vcodec libvpx-vp9 -f webm -an -f null -
ffmpeg -i strobe_scientist_hlg.mkv -b:v 18000000 -pass 2 -pix_fmt yuv420p10le -color_primaries 9 -color_trc 18 -colorspace 9 -color_range 1 -maxrate 26800000 -minrate 8040000 -profile:v 2 -vcodec libvpx-vp9 HLG_strobe_scientist_18Mbps-static.webm

MKVToolNix Downloads – Matroska tools for Linux/Unix and Windows
mkvmerge Doc — Merge multimedia streams into a Matroska file

mkvmerge -o HDR_strobe_scientist_18Mbps.mkv--colour-matrix 0:9 --colour-range 0:1 --colour-transfer-characteristics 0:16 --colour-primaries 0:9 --max-content-light 0:1000 --max-frame-light 0:300 --max-luminance 0:1000 --min-luminance 0:0.01 --chromaticity-coordinates 0:0.68,0.32,0.265,0.690,0.15,0.06 --white-colour-coordinates 0:0.3127,0.3290 HLG_HDR_strobe_scientist_18Mbps.webm

アルファチャンネル付き動画を読み込む

yuv420p, yuva420p, yuv422p, yuv440p, yuv444p, gbrpと高ビット深度に対応しているが特にyuva420pのアルファチャンネルは注意が必要で ffmpeg ではデコーダにlibvpx-vp9を指定しないとアルファチャンネルを読み込んでくれない。

アルファチャンネルのある PNG からのエンコード例(画像は連番のファイル名 img-001.png 形式)
ffmpeg -i img-%03d.png -vf format=yuva420p -c:v libvpx-vp9 -crf 30 -b:v 0 -threads 3 -row-mt 1 -pix_fmt yuva420p output.webm

デコード例(入力ファイルの前にコーデックを指定する)
ffmpeg -c:v libvpx-vp9 -i output.webm output
ffplay -codec:v libvpx-vp9 -i output.webm

動画にアルファチャンネルが意図した通りに透過しているかを調べるコマンド例。アルファチャンネルだけ取り出してグレーフォーマットで出力。透過部分だけ黒くなる。
ffmpeg -c:v libvpx-vp9 -i output.webm -vf alphaextract -vframes 1 alphaextract.png
ffmpeg -c:v libvpx-vp9 -i output.webm -vf extractplanes=a -vframes 1 extractplanes.png

アルファチャンネルをグレーで出力する alphaextract
各映像チャンネルを分離する extractplanes

バイナリを読む

RAW ファイルコンテナには入れられないが lightweight IVFフォーマットに入れると32バイトグローバルヘッダとフレーム毎の12バイトヘッダで読みやすくなる。ffrprobe で見るときは動画時間が長いと莫大なデータ量になる。
ffmpeg – How to extract raw VP9 stream from WebM file? – Stack Overflow
ffmpeg -i input.webm -c copy stream.ivf
ffprobe -show_packets -show_data -i stream.ivf > show_data.txt

ハードウェアの対応

エンコードでコードのハードウェアの対応。
SoCs Supporting VP8/VP9 : wiki.webmproject.org

VP9 の解説記事(英語)

コメントを残す

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

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