VP9エンコードする時の設定を再確認しました。
元になる記事はこちら。
FFmpegでVP9エンコード
まずはVP9のBitstream仕様を見て、色関連のデータがどのように格納されているか確認します。
color_space
color_space | Name of color space | Description |
0 | CS_UNKNOWN | Unknown (in this case the color space must be signaled outside the VP9 bitstream). |
1 | CS_BT_601 | Rec.ITU-R BT.601-7 |
2 | CS_BT_709 | Rec.ITU-R BT.709-6 |
3 | CS_SMPTE_170 | SMPTE-170 |
4 | CS_SMPTE_240 | SMPTE-240 |
5 | CS_BT_2020 | Rec.ITU-R BT.2020-2 |
6 | CS_RESERVED | Reserved |
7 | CS_RGB | sRGB (IEC 61966-2-1) |
color_range
color_range | Description | Details |
0 | Studio swing | For BitDepth equals 8: Y is between 16 and 235 inclusive. U ans V are between 16 and 240 inclusive. For BitDepth equals 10: Y is between 64 and 940 inclusive. U ans V are between 64 and 960 inclusive. For BitDepth equals 12: Y is between 256 and 3760 inclusive. U ans V are between 256 and 3840 inclusive. |
1 | Full swing | No restriction on Y, U, V values |
subsampling_x, subsampling_y
subsampling_x | subsampling_y | Description |
0 | 0 | YUV 4:4:4 |
0 | 1 | YUV 4:4:0 |
1 | 0 | YUV 4:2:2 |
1 | 1 | YUV 4:2:0 |
※color_space = CS_RGBの時だけは特殊でcolor_range = 1固定、subsampling_x,subsampling_yは無効。
よくよく見てみるとsRGBが居ます。
エンコードするソースはゲームをキャプチャしたsRGBのデータなので
使えるならこれを使った方が良い気がしたのですが、
Firefoxではそもそも再生出来なかったりChromeだと色がおかしくなりました。
現状は再生側の対応がイマイチなようなので
今まで通りYUV 4:4:4を使っておいた方が無難なようです。
そうするとcolor_spaceはBT.709を使うことになります。
厳密にはsRGBとBT.709ではtransfer characteristics(ガンマ)が違うのですが
この辺りをきちんと処理している再生環境がどの程度あるか微妙だと思うので
そこまで気にしなくていいかなと思います。
実際にBitstreamにセットされているかが確認出来ないのが遺憾ではありますが、
ffmpegのソースを見る限り以下のオプションでcolor_spaceにセットされるようです。
-colorspace bt709
color_rangeの設定はこう。
-color_range jpeg
-color_primariesと-color_trcは設定するとffmpegのログ的には反応するのですが、
VP9のBitstreamの仕様上入れるところが無いので効果は無いと思います。
(一応WebMのメタ情報には書き込まれるのですが使うソフトが有るかどうか)
まあ入れて害があるわけでもないでしょうから入れておけば良いという見方もあります。
参考として他の値についても記載しておきます。
color_space
color_space | Description | ffmpeg内の対応するデータ | ffmpegのオプション例 |
0 | Unknown (in this case the color space must be signaled outside the VP9 bitstream). | AVCodecContext.colorspace = AVCOL_SPC_UNSPECIFIED | -colorspace unspecified |
1 | Rec.ITU-R BT.601-7 | AVCodecContext.colorspace = AVCOL_SPC_BT470BG | -colorspace bt470bg |
2 | Rec.ITU-R BT.709-6 | AVCodecContext.colorspace = AVCOL_SPC_BT709 | -colorspace bt709 |
3 | SMPTE-170 | AVCodecContext.colorspace = AVCOL_SPC_SMPTE170M | -colorspace smpte170m |
4 | SMPTE-240 | AVCodecContext.colorspace = AVCOL_SPC_SMPTE240M | -colorspace smpte240m |
5 | Rec.ITU-R BT.2020-2 | AVCodecContext.colorspace = AVCOL_SPC_BT2020_NCL | -colorspace bt2020nc |
6 | Reserved | ||
7 | sRGB (IEC 61966-2-1) | AVCodecContext.colorspace = AVCOL_SPC_RGB | -pix_fmt gbrp -colorspace rgb |
color_range
color_range | Description | ffmpeg内の対応するデータ | ffmpegのオプション例 |
0 | Studio swing | AVCodecContext.color_range = AVCOL_RANGE_UNSPECIFIED AVCodecContext.color_range = AVCOL_RANGE_MPEG | -color_range unspecified -color_range mpeg |
1 | Full swing | AVCodecContext.color_range = AVCOL_RANGE_JPEG | -color_range jpeg |
あと謎だったオプションはAV1と一緒だったので分かりました。
-tile-columns 6
フレーム内を横に分割して並列エンコード/デコードする。
2の指定した数値乗するのでこの例だと2^6 = 64分割する。
ただ、設定してもイマイチ効果がよくわからない。
コアが一杯あるCPUとかだと変わるのかも?
-frame-parallel 1
複数フレームを並列デコード出来るようにする。
デフォルトでONなので特別指定する必要は無い。
並列デコード出来るようにしている分他のフレームへの依存性が下がっているはずなので
データ量的には増えるはずだが逆に僅かに減ってたりして謎。
以上を元にffmpegでゲームをキャプチャした動画をVP9でエンコードする例。
ffmpeg ^ -loglevel verbose ^ -i input.avi ^ -vf "scale=out_color_matrix=bt709:out_range=full" ^ -pix_fmt yuv444p ^ -colorspace bt709 ^ -color_range jpeg ^ -f webm ^ -c:v libvpx-vp9 ^ -threads 4 ^ -speed 1 ^ -crf 30 ^ -b:v 0 ^ -c:a libopus ^ -b:a 160k ^ output.webm