• FFmpegでVP9エンコード 補足

    2018年03月30日 20時12分
    AV1について色々調べた結果、動画の色関連の意味がようやく分かってきたので、
    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

    コメントを書く

    名前
    本文
    編集用パスワード
    管理者のみ閲覧