次世代エンコーダ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
- The WebM Open Media Project Blog: Inside WebM Technology: The VP8 Alternate Reference Frame
- Encode/VP9 – FFmpeg
- VP9 Encoding Guide – wiki
- Recommended Settings for VOD | Google Developers
- The WebM Project | VP8 Encode Parameter Guide
目次
基本コマンド
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -cpu-used 2 -threads 3 -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 -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 -pass 1 -f webm -an -f null -
ffmpeg -i input -c:v libvpx-vp9 -crf 30 -b:v 0 -cpu-used 2 -threads 3 -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 -pass 1 -an -f webm /dev/null
ビットレート指定の 2pass エンコード例。
ffmpeg -i input -c:v libvpx-vp9 -b:v 2M -cpu-used 4 -threads 3 -pass 1 -f webm -an -f null -
ffmpeg -i input -c:v libvpx-vp9 -b:v 2M -cpu-used 2 -threads 3 -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 -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 -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 -pix_fmt yuv444p -colorspace bt709 -color_range pc -c:a libopus -b:a 96k output.webm
ビットレート設定
以下の設定のどれかを必ず指定する。そうしないと-crf 32 -b:v 0でエンコードされる。-qmin、-qmaxの設定を記述していたがほとんど効果が見られないので削除した。2021年1月29日。
- 平均ビットレート(ABR、VBR)
-c:v libvpx-vp9 -b:v 2000k
- 上限と下限を指定した平均ビットレート(Constant Bitrate)
-c:v libvpx-vp9 -b:v 2000k -minrate 1500k -maxrate 2500k
- 固定ビットレート。平均ビットレートと最小と最大の3つを一致させる(Constant Bitrate)
-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
- 品質指定で平均ビットレートを指定(Constrained Quality)
-crf 30で平均ビットレートが2000kになる
-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
エンコード設定
ffmpeg -h encoder=libvpx-vp9
で見られるエンコード設定とエンコーダ全般に指定できる設定の2つがある。以下は libvpx-1.9.0より。
この中で重要なのがエンコード速度と品質に関わる-cpu-used、-deadlineと、馴染みのある-crfである。-cpu-used、-deadlineはエンコード速度と品質に大きく影響する設定である。-cpu-usedの既定値は1で0にするとさらに半分以下にエンコード速度が遅くなるかわりに圧縮率が向上する。値を上げるとそれだけ速度が向上するが品質も悪くなる。品質と速度の面から2や3も候補になるが4、5の品質はよくない。マイナスも指定できるがプラスの時と出力内容は変わらない。
- -cpu-used[int]
マイナスも指定できるがプラスの時と出力内容は変わらない。0にすると最高品質だがものすごく遅くなる。大きな値ほど処理が速い。-deadlineの既定値であるgoodのときは-5から5までしか変化が無い。-deadline realtimeにすると-8から8まで変化がある。-speedと同じ内容
既定値:1
範囲-8から8まで - -deadline[int]
品質指定。-cpu-usedの設定を受け付けない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まで - -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を指定する - -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のアプリケーションの一つ。
- ハイ ダイナミック レンジ(HDR)動画をアップロードする – YouTube ヘルプ
- How to Upload HDR Video to YouTube (with a LUT) — Mystery Box
- attachment – FFMPEG attach file as metadata – Stack Overflow
- 4K HDR anime channelさんはTwitterを使っています 「@shibanyan_1 MKVtoolnix使うと楽だと思います。 MINEタイプにapplication/x-cubeを指定して下さい。 ここが参考になりますね https://t.co/sW95Cy9ZrG」 / Twitter
サンプル動画: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 -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
どうりでアルファチャンネルが読み込めないわけだ "apparently the native VPx decoders still don't decode alpha" https://t.co/VtGgWpCeJ4
— ロべルト@FFmpeg本出ました (@nico_lab) December 23, 2017
バイナリを読む
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 の解説記事(英語)
- VP9 – WikipediaVP9 の解説
- How VP9 works, technical details & diagrams – Doom9’s ForumVP9 の解説
- Do VP9 have B-frame or P-frame ? – Doom9’s ForumVP9 には B-frame がない代わりに altref, golden frame がある
- Instructions to playback Adaptive WebM using DASH – wikiDASH向けにエンコード