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

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

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

webmproject/libvpx: github.com
libvpx/CHANGELOG at master · webmproject/libvpx

Downloads – Opus Codec

VP9コーデックメモ – Qiita

基本コマンド

ffmpeg -i input -c:v libvpx-vp9 -crf 30 -qmin 3 -qmax 40 -b:v 0 -threads 3 -c:a libopus -b:a 128k output.webm

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

subtitlesフィルタを使いハードサブで開始時間を指定する場合-output_ts_offsetをつける。
ffmpeg -ss 25:00 -to 26:00 -copyts -i video -vf subtitles=sub.srt -c:v libvpx-vp9 -crf 30 -b:v 0 -qmin 3 -qmax 40 -c:a copy -output_ts_offset 25:00 output.webm

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

linux などの 1pass 目の例。
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -qmin 3 -qmax 40 -b:v 0 -threads 3 -pass 1 -an -f webm /dev/null

ビットレート指定の 2pass エンコード例。
ffmpeg -i input -c:v libvpx-vp9 -b:v 2M -threads 3 -pass 1 -f webm -an -f null -
ffmpeg -i input -c:v libvpx-vp9 -b:v 2M -threads 3 -pass 2 -auto-alt-ref 6 -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

高画質にエンコードするにはcrf、qmin、qmaxを下げて、キーフレームを適切に挿入する。
ffmpeg -i input -c:v libvpx-vp9 -crf 18 -qmin 3 -qmax 32 -keyint_min 24 -g 240 -b:v 0 -threads 3 -c:a libopus -b:a 96k output.webm

高ビット深度の場合は出力フォーマットを指定する。
ffmpeg -i input -c:v libvpx-vp9 -crf 18 -qmin 3 -qmax 32 -keyint_min 24 -g 240 -b:v 0 -threads 3 -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 -qmin 3 -qmax 40 -b:v 0 -threads 3 -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 -qmin 3 -qmax 32 -keyint_min 30 -g 300 -b:v 0 -threads 3 -pix_fmt yuv444p -colorspace bt709 -color_range pc -c:a libopus -b:a 96k output.webm

ffmpeg でクロマキー合成 その2

ビットレート設定

以下の設定のどれかを必ず指定する-crfを指定する場合は、-qmin、-qmaxまたは-minrate、-maxrateの設定も必ず併用する

  • 平均ビットレート(ABR, VBR)
    -c:v libvpx-vp9 -b:v 1000k
  • 平均ビットレート(上限と下限指定)
    -c:v libvpx-vp9 -b:v 2000k -minrate 1500k -maxrate 2500k
  • 品質指定(CQ)
    (-1 から 63 まで小さい値ほど高品質)-b:v 0は必須項目
    品質指定をしながら、平均ビットレートを指定せず-b:v 0に上限ビットレートmaxrateの指定はできない
    -c:v libvpx-vp9 -crf 30 -b:v 0 -qmin 3 -qmax 40
  • 品質指定で平均ビットレートを指定
    最大品質が-crf 30で平均ビットレートが 1000k になる
    -c:v libvpx-vp9 -crf 30 -b:v 1000k -qmin 3 -qmax 40
  • 品質指定で上限と下限ビットレートを指定
    最大品質が-crf 24で平均ビットレートが 2000k になる
    -c:v libvpx-vp9 -crf 24 -b:v 2000k -minrate 1500k -maxrate 2500k
  • 固定ビットレート、ビットレートと最小と最大の3つを一致させる(CBR)
    -c:v libvpx-vp9 -b:v 1000k -minrate 1000k -maxrate 1000k
  • ロスレス(可逆圧縮)
    -c:v libvpx-vp9 -lossless 1

エンコード設定

Basic Encoding

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

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

  • -cpu-used[int]
    マイナスも指定できるがプラスの時と出力内容は変わらない。0 にすると最高品質だがものすごく遅くなる。大きな値ほど処理が速い。-qualityの既定値であるgoodのときは -5 から 5 までしか変化が無い。-quality realtimeにすると -8 から 8 まで変化がある。-speedと同じ内容
    既定値:1
    範囲:-8 から 8 まで

  • -deadline[int]
    品質指定。-cpu-used, -speedの設定を受け付けないbest(一番高品質一番低速度)、既定値のgood、realtimeの3つの指定が出来る。設定を細かく分けるときはrealtimeを指定する。-qualityと同じ内容
    既定値:good
    指定値:best、good、realtime

  • -crf[int]
    品質の数値指定。小さい値ほど高画質
    既定値:-1
    範囲:-1 から 63 まで

  • -auto-alt-ref[int]
    パス指定の2パス目-pass 2に指定。数値が大きいと高画質で容量も多く、速度も遅くなる
    既定値:-1
    範囲:-1 から 6 まで

-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段階指定できるが、負の値と正の値の絶対値が同じだと結果に変化がない

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

  • -qmin[int]
    品質の上限指定。小さい値ほど高画質になる。-crfを参考に設定する
    既定値:-1

  • -qmax[int]
    品質の下限指定。大きい値ほど低画質になる。-crfを参考に設定する
    既定値:-1

  • -g[int]
    group of picture sizeで、keyintのこと
    既定値:-1

  • -keyint_min[int]
    既定値:-1

  • -threads[int]
    下にある解像度に合わせて設定しないと速度が上がらない。指定値の2の累乗になるので3の場合は下のグラフの8になる。CPUがスレッド数に対応していないと大きな値の効果は得られない
    既定値:-1(自動設定ではない)

色の情報の設定

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

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

HD未満
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -qmin 3 -qmax 40 -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 -qmin 3 -qmax 40 -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パスどちらも-quality good-speedを以下の値にするとエンコード時間と品質のバランスがよい。

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 のアプリケーションの一つ。

ハイ ダイナミック レンジ(HDR)動画をアップロードする – YouTube ヘルプ

サンプル動画:strobe_scientist.mkv

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

18Mbps 4k 2-pass
ffmpeg -report -i strobe_scientist.webm -b:v 18000000 -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 -qmin 3 -qmax 40 -b:v 0 -threads 3 -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 の解説記事(英語)

コメントを残す

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

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