• 傾き指向プログラミング 2018

    2018年05月06日 01時35分
    連休を利用してblogを色々いじった。
    すごく久しぶりにプログラマーっぽいことをした気がする。


    SSL対応


    SSL非対応サイトが排斥されるのが世界的な流れであり、
    ブラウザもそろそろ非SSLサイトを警告扱いしてくるので対応。
    ありがとうLet's Encrypt。


    HTTP 2.0対応


    最近はブラウザもサーバも対応してて
    SSL対応さえしていれば簡単に対応出来るのでついでに設定。

    画像をベタベタ張るようなサイトでないので効果が無さそうなのがやや残念。


    IPv6対応


    サーバ側の設定は割と容易なのだが
    今までは自宅側が対応していなかった為確認しづらく設定していなかった。

    ちょうど先日自宅にIPv6が通ったので試験的に設定。

    さすがにそろそろIPv4が本格的に足りなくなってきたという話も聞くのでみんなも対応するといいよ。


    Nginxが悪いのかOSのネットワークが悪いのか、
    IPv6で繋がったり繋がらなかったり安定しなくて原因もさっぱり。
    まだIPv4使えるからIPv4でいいや。IPv6はまだ早い。


    Nginx


    今まではApacheを使っていたのだけど
    Nginxの方が設定ファイルがシンプルで好みなのと
    キャッシュの制御がしやすいのでNginxにした。


    blogのキャッシュ構造


    アプリケーション内部のメモリ上に画像等のファイルをキャッシュする構造だったのだけど
    そういうのはWebサーバ側でやるべきだよねということで構造を変更。
    Nginxにしたのはこの辺りの絡みも有る。


    blogのバックエンドをPostgreSQLに


    今まではFirebirdを使っていたのだけどPostgreSQLに変更。

    FirebirdのVARCHARが32KBまでしか対応してなくて
    PostgreSQLのTEXTを使いたいんじゃあと変更し始めたのだけど
    冷静に考えたらFirebirdでもBLOBを使えばそれで済んだ。

    済んだのだが、ノリと勢いでだいぶ進めてしまって捨てるのも悔しいからやりきった。

    上記のキャッシュ変更と合わせてバグっているかもしれない。
    気づいた人はそっと教えて欲しい。


    カスペルスキーはウィルス


    久しぶりに自宅PCでWeb開発してたのだが、
    設定したSSL証明書の期限を確認しようとしたらカスペルスキーが変な証明書を表示してきたり
    Content-Encoding: gzipが出力されない!と超悩んだ原因がカスペルスキーがデコードしてたせいだったり
    裏で色々改変しやがるので致命的にWeb開発と相性が悪い。二度と買わない。

    そもそもブラウザのプラグインはOFFってるのにどうやって介入してるんだコイツ。

    あと他にも突然SSL証明書のエラーを吐いたりとか
    変なJavascriptをページに挿入してきたりとか
    細かく妨害してくるのでストレスで寿命がマッハ。
  • 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
  • aomencのオプション

    2018年03月18日 16時03分 (2018年04月03日 00時00分 更新)
    aomencのオプションを調べたメモです。
    自分で使うために調べたのですが、少しは役に立つかもしれないので置いておきます。

    ただ、オプションを完全に理解するには
    エンコード処理の知識と英語の知識両方が必要となり、
    私には完全な内容は作れないため、その前提で参照してください。

    間違いがあったとしても私はあなたを騙そうとしたわけではなく
    単に私が無能なブタであるというだけなのです。

    新たな情報が入ったら随時更新しようと思います。

    使い方
    aomenc <options> -o dst_filename src_filename


    src_filename
    ファイルパスまたは「-」を指定する。
    「-」を指定した場合標準入力から読み出す。
    y4mまたはRAWを指定可能。

    Options

    オプション デフォルト
    説明
    メモ
    --help
    Show usage options and exit
    ヘルプ表示。
    -c <arg>
    --cfg=<arg>
    Config file to use
    コンフィグファイルの指定
    コンフィグファイルはオプション1つを1行に記載した形式。
    オプションは「--」から始まるオプションのキーを「--」を除いた形で指定する。
    オプションのキーと値は「=」ではなく「:」で結合する。
    オプションが値を持たない場合は値に「ON」を指定する。
    例:「--codec=av1」->「codec:av1」 「--webm」->「webm:ON」
    -D --debug
    Debug mode (makes output deterministic)
    デバッグモード有効。
    -o <arg>
    --output=<arg>
    Output filename
    出力ファイルパスの指定。
    --codec=<arg> av1
    Codec to use
    使用するCodecの指定。
    今のところav1しか実装されていない。
    -p <arg>
    --passes=<arg>
    2
    Number of passes (1/2)
    1パスエンコードか2パスエンコードかの指定。
    --pass=<arg>
    Pass to execute (1/2)
    2パスエンコード時の1パス目か2パス目かの指定。
    --fpf=<arg>
    First pass statistics file name
    2パスエンコード時の統計情報ファイルパス。
    --limit=<arg>
    Stop encoding after n input frames
    このフレームまでエンコードする。
    --skip=<arg>
    Skip the first n input frames
    このフレームからエンコードする。
    --good
    Use Good Quality Deadline
    Deprecated
    指定しても無効。
    -q
    --quiet
    Do not print encode progress
    進捗を表示しない。
    -v
    --verbose
    Show encoder parameters
    詳しく表示する。
    --psnr
    Show PSNR in status line
    ステータス行にPSNR(ピーク信号対雑音比)を表示する。
    --webm
    Output WebM (default when WebM IO is enabled)
    WebM形式で出力する。
    デフォルトでWebM形式で出力するため指定の必要はない。
    しておいた方が確実ではある。
    --ivf
    Output IVF
    IVF形式で出力する。
    IVFはコマンドラインとかで処理する用の簡易形式。
    特別にIVFが必要という状況以外では使うことは無いだろう。
    --obu
    Output OBU
    OBUはBitstreamで使われているOBUのことだと思う。
    つまり、コンテナを使わずAV1のBitstreamをそのまま出力するということのようだ。
    -P
    --output-partitions
    Makes encoder output partitions. Requires IVF output!
    IVF形式で出力する際に分割して出力できるっぽい?
    --q-hist=<arg>
    Show quantizer histogram (n-buckets)
    量子化ヒストグラム?を表示する。
    見て意味のわかる人はONにしてみたらいいのではなかろうか。
    --rate-hist=<arg>
    Show rate histogram (n-buckets)
    レートヒストグラム?を表示する。
    見て意味のわかる人はONにしてみたらいいのではなかろうか。
    --disable-warnings
    Disable warnings about potentially incorrect encode settings.
    潜在的なエンコードオプションの間違いについての警告を無効にする。
    この手のはちゃんと直しておいた方がいいので無効にしない方がよさそう。
    -y --disable-warning-prompt
    Display warnings, but do not prompt user to continue.
    警告は表示するけどユーザーへの確認を行わなくする。
    警告を無視してバッチ処理するときとかに使うのだろうけどそもそも警告は直した方がいい。
    --test-decode=<arg>warn
    Test encode/decode mismatch off, fatal, warn
    エンコード結果をデコードしてテストする。
    off: テストしない
    warn: テストしてエラーが出たら警告を出して処理を続ける
    fatal: テストしてエラーが出たら警告を出して処理を終了する
    滅多に出ないだろうしデコードしてエラーが出るのを渡されても困るのでfatalがいいのではなかろうか。

    Encoder Global Options

    オプション デフォルト
    説明
    メモ
    --yv12
    Input file is YV12
    入力ファイルのフォーマットがYV12。
    入力ファイルがy4mの場合はそこから読み出すため指定しなくてよい。
    --i420
    Input file is I420 (default)
    入力ファイルのフォーマットがI420
    入力ファイルがy4mの場合はそこから読み出すため指定しなくてよい。
    --i422
    Input file is I422
    入力ファイルのフォーマットがI422
    入力ファイルがy4mの場合はそこから読み出すため指定しなくてよい。
    --i444
    Input file is i444
    入力ファイルのフォーマットがi444
    入力ファイルがy4mの場合はそこから読み出すため指定しなくてよい。
    -u <arg>
    --usage=<arg>
    0
    Usage profile number to use
    使用するエンコード設定デフォルト値セットのセット番号。
    ただし現在0しか実装されていなくてデフォルトが0。
    -t <arg>
    --threads=<arg>
    Max number of threads to use
    使用するスレッド数。
    現在の実装では--tile-columnsを1以上に設定いた場合のみマルチスレッド動作する。
    (並列処理は横に分割されたタイルでのみ行われる)
    ただ、タイル分割してスレッド数を増やしてもイマイチCPUを使ってくれない。
    --profile=<arg>
    Bitstream profile number to use
    使用するプロファイル番号
    Profile, Bit depth, SRGB Colorspace support, Chroma subsampling
    0, 8 or 10, No, YUV 4:2:0
    1, 8 or 10, Yes, YUV 4:4:4
    2, 8 or 10, No, YUV 4:2:2
    2, 12, Yes, YUV 4:2:0, YUV 4:2:2, YUV 4:4:4
    -w <arg>
    --width=<arg>
    Frame width
    出力データの横の解像度をピクセル単位で指定する。
    入力ファイルがy4mの場合はそこから読み出すため拡大縮小をしないならば指定しなくてよい。
    拡大縮小はI420のみ対応出来るらしいけどエンコーダに渡す前にやっといたほうがいいと思う。
    -h <arg>
    --height=<arg>
    Frame height
    出力データの縦の解像度をピクセル単位で指定する。
    入力ファイルがy4mの場合はそこから読み出すため拡大縮小をしないならば指定しなくてよい。
    拡大縮小はI420のみ対応出来るらしいけどエンコーダに渡す前にやっといたほうがいいと思う。
    --forced_max_frame_width
    Maximum frame width value to force
    0以外を指定した場合その値を強制的に最大幅としてヘッダに書き出す。
    用途がイマイチわからない。
    --forced_max_frame_height
    Maximum frame height value to force
    0以外を指定した場合その値を強制的に最大高さとしてヘッダに書き出す。
    用途がイマイチわからない。
    --stereo-mode=<arg>
    Stereo 3D video format mono, left-right, bottom-top, top-bottom, right-left
    ステレオ3D動画用の設定らしい。
    --timebase=<arg>
    Output timestamp precision (fractional seconds)
    出力データのタイムスタンプの精度?
    タイミングがシビアな用途で使用?
    小数点込みの秒数で指定する。

    Indicates the smallest interval of time, in seconds, used by the stream.
    For fixed frame rate material, or variable frame rate material where frames are timed at a multiple of a given clock (ex: video capture), the \ref RECOMMENDED method is to set the timebase to the reciprocal of the frame rate (ex: 1001/30000 for 29.970 Hz NTSC).
    This allows the pts to correspond to the frame number, which can be handy.
    For re-encoding video from containers with absolute time timestamps, the \ref RECOMMENDED method is to set the timebase to that of the parent container or multimedia framework (ex: 1/1000 for ms, as in FLV).
    aom/aom_encoder.h
    --fps=<arg>30/1
    Stream frame rate (rate/scale)
    フレームレートの指定。
    「30/1」のように指定する。
    入力ファイルがy4mの場合はそこから読み出すため指定しなくてよい。
    変更したい場合はエンコーダに渡す前に編集しておいた方がよいかと。
    --global-error-resilient=<arg>0
    Enable global error resiliency features
    エラー耐性機能?の設定。

    The error resilient bitfield indicates to the encoder which features it should enable to take measures for streaming over lossy or noisy links.
    aom/aom_encoder.h
    -b <arg>
    --bit-depth=<arg>
    8
    Bit depth for codec (8 for version <=1, 10 or 12 for version 2) 8, 10, 12
    出力データのビット深度を指定する。(8 or 10 or 12)
    --lag-in-frames=<arg>19
    Max number of frames to lag
    エンコード時にここで指定したフレーム分だけ出力を遅延させてフレーム間圧縮に使用する。
    フレームを入力してから出力されるまでのレイテンシが上がるので例えばリアルタイムエンコードのような用途には向かない。
    (そもそもリアルタイムエンコードが可能な速度ではない気がするが・・・)
    0を指定するとこの機能を無効にする。
    --large-scale-tile=<arg>0
    Large scale tile coding (0: off (default), 1: on)
    Large scale tileを有効可する設定だがLarge scale tileがどういう物でどういう効果を及ぼすかは不明。
    --monochrome
    Monochrome video (no chroma planes)
    モノクロ動画を出力する。

    Rate Control Options

    オプション デフォルト
    説明
    メモ
    --drop-frame=<arg>0
    Temporal resampling threshold (buf %)
    ターゲットデータバッファの使用率を指定する。
    この使用率を下回った場合にフレームのドロップが発生する。
    0を指定するとフレームのドロップを無効にする。
    という説明だがターゲットデータバッファというのが何者かよくわからない。
    フレームドロップしてオッケーというケースは今時の個人用途ではあまりないと思うのでデフォルトの0でいいんじゃないかな。
    --resize-mode=<arg>0
    Frame resize mode
    フレームを縮小してエンコードしてデコード時にアップスケールする設定。
    0: 縮小しない
    1: 固定の倍率で縮小する
    2: 動的な倍率で縮小する
    --resize-denominator=<arg>8
    Frame resize denominator
    --resize-mode=1の時の倍率の分母を8~16の範囲で指定する。
    分子は8となる。(つまり8/resize-denominatorに縮小される)
    --resize-kf-denominator=<arg>8
    Frame resize keyframe denominator
    --resize-denominatorに対して特にキーフレームだけ別途設定する値。
    --superres-mode=<arg>0
    Frame super-resolution mode
    --resize-modeと同じくフレームを縮小してエンコードする超解像度処理バージョン。
    --superres-denominatorの説明を読む限り--resize-modeとは同時に使える模様。
    0: 縮小しない
    1: 固定の倍率で縮小する
    2: 動的な倍率で縮小する
    3: q-index(謎)を使って縮小する
    --superres-denominator=<arg>8
    Frame super-resolution denominator
    --superres-mode=1の時の倍率の分母を8~16の範囲で指定する。
    分子がいくつになるかは書いてないので不明。
    --resize-modeの倍率と合わせて1/2以上になると--superres-denominatorだけが有効になる的なことが書いてあるがよくわからん。
    --superres-kf-denominator=<arg>8
    Frame super-resolution keyframe denominator
    --superres-denominatorに対して特にキーフレームだけ別途設定する値。
    --superres-qthresh=<arg>63
    Frame super-resolution qindex threshold
    --superres-mode=3の時に使用する超解像度処理後のクオリティ閾値。
    1から63を指定する。
    たぶん数字が大きいほうが綺麗になるよう処理すると思う。
    --superres-kf-qthresh=<arg>63
    Frame super-resolution keyframe qindex threshold
    --superres-qthreshに対して特にキーフレームだけ別途設定する値。
    --end-usage=<arg>vbr
    Rate control mode vbr, cbr, cq, q
    vbr: 可変ビットレート
    cbr: 固定ビットレート
    cq: 固定品質(ただしビットレートの上限まで)
    q: 固定品質
    --target-bitrate=<arg>
    Bitrate (kbps)
    目標とするビットレートを指定する(Kbit/s)
    --min-q=<arg>0
    Minimum (best) quantizer
    品質の上限(数値的には最小値)を0~63の範囲で指定する。
    --max-q=<arg>63
    Maximum (worst) quantizer
    品質の下限(数値的には最大値)を0~63の範囲で指定する。
    --undershoot-pct=<arg>25
    Datarate undershoot (min) target (%)
    This value, expressed as a percentage of the target bitrate, controls the maximum allowed adaptation speed of the codec.
    This factor controls the maximum amount of bits that can be subtracted from the target bitrate in order to compensate for prior overshoot.

    Valid values in the range 0-1000.
    aom/aom_encoder.h
    --overshoot-pct=<arg>25
    Datarate overshoot (max) target (%)
    This value, expressed as a percentage of the target bitrate, controls the maximum allowed adaptation speed of the codec.
    This factor controls the maximum amount of bits that can be added to the target bitrate in order to compensate for prior undershoot.

    Valid values in the range 0-1000.
    aom/aom_encoder.h
    --buf-sz=<arg>
    Client buffer size (ms)
    This value indicates the amount of data that may be buffered by the decoding application.
    Note that this value is expressed in units of time (milliseconds).
    For example, a value of 5000 indicates that the client will buffer (at least) 5000ms worth of encoded data.
    Use the target bitrate (#rc_target_bitrate) to convert to bits/bytes, if necessary.
    aom/aom_encoder.h
    --buf-initial-sz=<arg>4000
    Client initial buffer size (ms)
    This value indicates the amount of data that will be buffered by the decoding application prior to beginning playback.
    This value is expressed in units of time (milliseconds).
    Use the target bitrate (#rc_target_bitrate) to convert to bits/bytes, if necessary.
    aom/aom_encoder.h
    --buf-optimal-sz=<arg>5000
    Client optimal buffer size (ms)
    This value indicates the amount of data that the encoder should try to maintain in the decoder's buffer.
    This value is expressed in units of time (milliseconds).
    Use the target bitrate (#rc_target_bitrate) to convert to bits/bytes, if necessary.
    aom/aom_encoder.h


    Twopass Rate Control Options

    オプション デフォルト
    説明
    メモ
    --bias-pct=<arg>50
    CBR/VBR bias (0=CBR, 100=VBR)
    Bias, expressed on a scale of 0 to 100, for determining target size for the current frame.
    The value 0 indicates the optimal CBR mode value should be used.
    The value 100 indicates the optimal VBR mode value should be used.
    Values in between indicate which way the encoder should "lean."
    aom/aom_encoder.h
    --minsection-pct=<arg>0
    GOP min bitrate (% of target)
    This value, expressed as a percentage of the target bitrate, indicates the minimum bitrate to be used for a single GOP (aka "section")
    aom/aom_encoder.h
    --maxsection-pct=<arg>2000
    GOP max bitrate (% of target)
    This value, expressed as a percentage of the target bitrate, indicates the maximum bitrate to be used for a single GOP (aka "section")
    aom/aom_encoder.h

    Keyframe Placement Options

    オプション デフォルト
    説明
    メモ
    --kf-min-dist=<arg>0
    Minimum keyframe interval (frames)
    This value, expressed as a number of frames, prevents the encoder from placing a keyframe nearer than kf_min_dist to the previous keyframe.
    At least kf_min_dist frames non-keyframes will be coded before the next keyframe.
    Set kf_min_dist equal to kf_max_dist for a fixed interval.
    aom/aom_encoder.h
    --kf-max-dist=<arg>9999
    Maximum keyframe interval (frames)
    This value, expressed as a number of frames, forces the encoder to code a keyframe if one has not been coded in the last kf_max_dist frames.
    A value of 0 implies all frames will be keyframes. Set kf_min_dist equal to kf_max_dist for a fixed interval.
    aom/aom_encoder.h
    --disable-kf
    Disable keyframe placement
    設定するとAOM_KF_DISABLED
    設定しないとAOM_KF_AUTO

    This value indicates whether the encoder should place keyframes at a fixed interval, or determine the optimal placement automatically (as governed by the #kf_min_dist and #kf_max_dist parameters)
    aom/aom_encoder.h

    AV1 Specific Options

    オプション デフォルト
    説明
    メモ
    --cpu-used=<arg>
    CPU Used (0..8)
    0 ~ 8を指定する。
    主に動き予測に影響を与える設定で、大きい数字になるほどエンコード速度が速くなり品質が下がる。
    0にすると1より10倍くらい時間がかかるようになる。
    1 ~ 8の間の変化はそこそこなのでこの辺りから適当に選べばよいと思う。
    --dev-sf=<arg>
    Dev Speed (0..255)
    開発用の速度設定?
    セットしても特別早くなったり遅くなったりしないようなのでよくわからない。
    --auto-alt-ref=<arg>
    Enable automatic alt reference frames
    1を指定するとAlt reference frameがONになる。
    Alt reference frameとは対象のフレームより未来のフレームを参照することらしい。
    ONにすると圧縮率が上がってシーク性能が落ちると思われる。
    --sharpness=<arg>
    Loop filter sharpness (0..7)
    デブロッキングフィルタの効き具合の設定と思われる。
    出来上がった動画を見ながら調整すればよいかと。
    --static-thresh=<arg>
    Motion detection threshold
    Codec control function to set the threshold for MBs treated static.
    aomcx.h
    --single-tile-decoding=<arg>0
    Single tile decoding (0: off (default), 1: on)
    タイルの並列デコードを無効にする設定?
    --tile-columns=<arg>0
    Number of tile columns to use, log2
    並列エンコード/デコードのためにフレームを分割する場合の横の分割数
    log2で指定するため以下のようになる
    0: 分割しない
    1: 2分割する
    2: 4分割する
    n: 2^n分割する

    分割されたサイズが256ピクセルより小さいまたは4096ピクセルより大きい場合それぞれ256ピクセル、4096ピクセルになるようキャップされる。
    分割した分だけ並列エンコードが出来る。(--threads参照)
    あと分割した分いくらか容量が増えるようだ。
    --tile-rows=<arg>0
    Number of tile rows to use, log2 (set to 0 while threads > 1)
    並列エンコード/デコードのためにフレームを分割する場合の縦の分割数
    ただ、縦に分割しても後のタイルが前のタイルに依存するため並列処理は出来なく、
    後ろのタイル処理中の前のタイルに対して先にI/Oを行えるというだけ。
    問題なのはI/Oではなく処理時間の方なので設定してもあんまり意味なさそう。
    0: 分割しない
    1: 2分割する
    2: 4分割する
    --arnr-maxframes=<arg>
    AltRef max frames (0..15)
    Alt reference frameを何個作るかの最大値の設定のような気がする。
    たくさんあると圧縮率が上がってシーク性能が下がるのだと思う。
    とりあえず最大で設定してみてシーク性能が気に入らなければ下げればよいか。
    --arnr-strength=<arg>
    AltRef filter strength (0..6)
    Alt reference frameを作るときのフィルタのパラメータっぽいけどさっぱりわからない。
    --tune=<arg>
    Distortion metric tuned with psnr, ssim, cdef-dist, daala-dist
    画質測定方法の設定。
    psnr: PSNR
    ssim: SSIM ただし現時点では未実装
    cdef-dist: わからん
    daala-dist: daalaと付いているのでdaalaで実装された何らかの処理なのだと思う
    --cq-level=<arg>
    Constant/Constrained Quality level
    品質を0~63で設定する。数字が小さいほど画質がよくなり容量が増える。
    --max-intra-rate=<arg>0
    Max I-frame bitrate (pct)
    This value controls additional clamping on the maximum size of a keyframe.
    It is expressed as a percentage of the average per-frame bitrate, with the special (and default) value 0 meaning unlimited, or no additional clamping beyond the codec's built-in algorithm.

    For example, to allocate no more than 4.5 frames worth of bitrate to a keyframe, set this to 450.
    aomcx.h
    --max-inter-rate=<arg>0
    Max P-frame bitrate (pct)
    This value controls additional clamping on the maximum size of an inter frame.
    It is expressed as a percentage of the average per-frame bitrate, with the special (and default) value 0 meaning unlimited, or no additional clamping beyond the codec's built-in algorithm.

    For example, to allow no more than 4.5 frames worth of bitrat to an inter frame, set this to 450.
    aom/aomcx.h
    --gf-cbr-boost=<arg>0
    Boost for Golden Frame in CBR mode (pct)
    CBRモードでGolden frameのサイズ(容量)を%で指定して増量する。
    (例えば100%を指定すると2倍の容量を使うようになる)
    Golden frameはキーフレーム的な物だが増やすとどうなるんだろう?
    --lossless=<arg>
    Lossless mode (0: false (default), 1: true)
    可逆圧縮の設定。
    未指定だとだいたい非可逆圧縮になるが場合によっては可逆圧縮になるかもしれない。
    可逆圧縮したいときだけ設定すればよいと思う。
    0: 非可逆圧縮
    1: 可逆圧縮
    --enable-cdef=<arg>1
    Enable the constrained directional enhancement filter (0: false, 1: true (default))
    Constrained Directional Enhancement Filter(CDEF)の設定
    0: 使用しない
    1: 使用する
    たぶんOFFにすると画質が下がってエンコード速度が上がるのだと思う。
    --enable-restoration=<arg>1
    Ebable the loop restoration filter (0: false, 1: true (default))
    Loop restoration filter?の設定
    0: 使用しない
    1: 使用する
    たぶんOFFにすると画質が下がってエンコード速度が上がるのだと思う。
    --enable-qm=<arg>0
    Enable quantisation matrices (0: false (default), 1: true)
    量子化マトリクスの設定
    0: 使用しない
    1: 使用する
    たぶん離散コサイン変換した後のピクセルデータにかけるマトリクスのことだと思うけどAV1はデフォルトでは使わないらしい。
    --qm-min=<arg>8
    Min quant matrix flatness (0..15), default is 8
    量子化マトリクス生成時のパラメータだと思うんだけど何を設定するとどういうマトリクスが生成されるかわからない。

    AOM can operate with different ranges of quantisation matrices.
    As quantisation levels increase, the matrices get flatter.
    This control sets the minimum level of flatness from which the matrices are determined.

    By default, the encoder sets this minimum at half the available range.
    aom/aomcx.h
    --qm-max=<arg>15
    Max quant matrix flatness (0..15), default is 15
    量子化マトリクス生成時のパラメータだと思うんだけど何を設定するとどういうマトリクスが生成されるかわからない。

    AOM can operate with different ranges of quantisation matrices.
    As quantisation levels increase, the matrices get flatter.
    This control sets the maximum level of flatness possible.

    By default, the encoder sets this maximum at the top of the available range.
    aom/aomcx.h
    --enable-dist-8x8=<arg>0
    Enable dist-8x8 (0: false (default), 1: true)
    画質評価を8x8ピクセルで行う設定のような気がするけど元がいくつでやってるかわからないので有効にしたら良くなるのか悪くなるのかわからない。

    The dist_8x8 is enabled automatically for model tuning parameters that require measuring distortion at the 8x8 level.
    This control also allows measuring distortion at the 8x8 level for other tuning options (e.g., PSNR), for testing purposes.
    0 = do not use dist_8x8
    1 = use dist_8x8

    By default, the encoder does not use dist_8x8
    aom/aomcx.h
    --frame-parallel=<arg>0
    Enable frame parallel decodability features (0: false (default), 1: true)
    有効にすると並列デコード可能なようにエンコードする。
    ただし並列デーコードのためにフレーム間の依存性を下げるらしいのでたぶん容量が増える。
    --error-resilient=<arg>0
    Enable error resilient features (0: false (default), 1: true)
    有効にするとフレーム情報の取得を保証してくれるらしい?
    --aq-mode=<arg>0
    Adaptive quantization mode (0: off (default), 1: variance 2: complexity, 3: cyclic refresh)
    適応量子化マトリクスのアルゴリズム指定のような気がするけどどれがどういう効果になるか謎。

    AV1 has a segment based feature that allows encoder to adaptively change quantization parameter for each segment within a frame to improve the subjective quality.
    This control makes encoder operate in one of the several AQ_modes supported.

    By default, encoder operates with AQ_Mode 0(adaptive quantization off).
    aom/aomcx.h
    --deltaq-mode=<arg>0
    Delta qindex mode (0: off (default), 1: deltaq 2: deltaq + deltalf)
    適応量子化マトリクスのアルゴリズム指定のような気がするけどういう効果になるか謎。

    AV1 has a segment based feature that allows encoder to adaptively change quantization parameter for each segment within a frame to improve the subjective quality.
    The delta q mode is added on top of segment based feature, and allows control per 64x64 q and lf delta.
    This control makes encoder operate in one of the several DELTA_Q_modes supported.

    By default, encoder operates with DELTAQ_Mode 0(deltaq signaling off).
    aom/aomcx.h
    --frame-boost=<arg>0
    Enable frame periodic boost (0: off (default), 1: on)
    周期性を元に品質を上げてくれる設定?
    自動で適切な設定を選んでくれるとか書いてあるけどdefault 0とも書いてあってよくわからん。

    One AV1 encoder speed feature is to enable quality boost by lowering frame level Q periodically. This control function provides a mean to turn on/off this feature.
    0 = off
    1 = on

    By default, the encoder is allowed to use this feature for appropriate encoding modes.
    aom/aomcx.h
    --noise-sensitivity=<arg>0
    Noise sensitivity (frames to blur)
    0~6の間で設定できるみたいだけど設定するとどうなくかはよくわからない。
    --tune-content=<arg>
    Tune content type default, screen
    default: 通常の動画
    screen: スクリーンキャプチャ動画(使い方動画みたいな静止画が多い動画向け?)
    --cdf-update-mode=<arg>1
    CDF update mode for entropy coding (0: no CDF update; 1: update CDF on all frames(default); 2: selectively update CDF on some frames
    累積分布関数の更新方法?
    たぶん何か予測する処理のためのデータの更新頻度の設定だと思うけどよくわからない。
    デフォルトで毎フレーム更新しているようなのでそれでいいのではなかろうか。
    --color-primaries=<arg>
    Color primaries (CICP) of input content: bt709, unspecified, bt601, bt470m, bt470bg, smpte240, film, bt2020, xyz, smpte431, smpte432, ebu3213
    入力動画の色空間指定
    --transfer-characteristics=<arg>
    Transfer characteristics (CICP) of input content: unspecified, bt709, bt470m, bt470bg, bt601, smpte240, lin, log100, log100sq10, iec61966, bt1361, srgb, bt2020-10bit, bt2020-12bit, smpte2084, hlg, smpte428
    入力動画の表示階調特性(ガンマカーブとか)の指定
    --matrix-coefficients=<arg>
    Matrix coefficients (CICP) of input content: identity, bt709, unspecified, fcc73, bt470bg, bt601, smpte240, ycgco, bt2020ncl, bt2020cl, smpte2085, chromncl, chromcl, ictcp
    入力動画の係数行列(RGB⇔YUV変換行列)指定
    --chroma-sample-position=<arg>
    The chroma sample position when chroma 4:2:0 is signaled: unknown, vertical, colocated
    たぶんNV12とNV21の違いを指定するのだと思う。
    --min-gf-interval=<arg>0
    min gf/arf frame interval (default 0, indicating in-built behavior)
    Golden frameとAlt reference frameの間に入るフレームの最小値。
    いまいち操作するとどうなるかわからない。
    0を指定するとデフォルトの動作(4を指定した時と同じ動作になる模様)
    --max-gf-interval=<arg>0
    max gf/arf frame interval (default 0, indicating in-built behavior)
    Golden frameとAlt reference frameの間に入るフレームの最大値。
    いまいち操作するとどうなるかわからない。
    0を指定するとデフォルトの動作(16を指定した時と同じ動作になる模様)
    --sb-size=<arg>
    Superblock size to use dynamic, 64, 128
    スーパーブロック?のサイズ指定。
    デフォルトではフレームごとに自動で選択してくれるそうなのでそれでいいのではなかろうか。
    --num-tile-groups=<arg>1
    Maximum number of tile groups, default is 1
    分割したタイルをグループ化した時の1グループに入るタイルの数?
    --mtu-sizeを指定した場合はその値を元に上書きされる。
    ということなのでたぶんストリーミング配信とかする時用のパラメータではなかろうか。
    --mtu-size=<arg>0
    MTU size for a tile group, default is 0 (no MTU targeting), overrides maximum number of tile groups
    タイルグループに対するByte数。
    MTUはMaximum Transmission UnitのMTUでよいのか?
    たぶんストリーミング配信とかする時用のパラメータではなかろうか。
    --timing-info=<arg>0
    Signal timing info in the bitstream: unspecified, constant
    Signal picture(キーフレーム?)の挿入タイミングの設定。
    --film-grain-test=<arg>0
    Film grain test vectors (0: none (default), 1: test-1 2: test-2, ... 16: test-16)
    Film grainのプリセット番号を設定する?
    --film-grain-table=<arg>
    Path to file containing film grain parameters
    Film grain用のパラメータが記載された設定ファイル的な物を指定するようだがどのような内容を書くかがわからない。
    --enable-ref-frame-mvs=<arg>1
    Enable temporal mv prediction (default is 1)
    フレーム間予測をONにする。
    ONにすると画質が上がってエンコード速度が下がるのだと思う。
    ONにするオプションでデフォルトがONということはOFFにするときには0を明示的に指定しろということらしい。
    -b <arg>
    --bit-depth=<arg>
    Bit depth for codec (8 for version <=1, 10 or 12 for version 2) 8, 10, 12
    出力データのビット深度を指定する。(8 or 10 or 12)
    --input-bit-depth=<arg>
    Bit depth of input
    入力データのビット深度を指定する。
    --sframe-dist=<arg>
    S-Frame interval (frames)
    引数の処理が怪しくて何故かDual filter(AV1E_SET_ENABLE_DF)にセットされている(未実装?)
    --sframe-mode=<arg>
    S-Frame insertion mode (1..2)
    引数の処理が怪しくて何故か超解像度(AV1E_SET_ENABLE_JNT_COMP)にセットされている(未実装?)
    --annexb=<arg>
    Save as Annex-B
    Annex Bの形式で出力する(複数のOBUを含む形式)
    引数の処理が怪しくて対応する設定値が無いようだ(未実装?)
  • Alliance for Open Media Video 1を試した

    2018年03月17日 22時35分
    AppleがAlliance for Open Mediaに加入したよという記事(CNET Japan)を見てAV1を知り、
    色々調べたのでまとめておこうと思います。


    AV1の概要についてはWikipediaあたりが丁度いいと思います。

    個人的に注目したのはGoogle・Microsoft・ Mozilla・Appleがメンバーに入っているため、
    多くのブラウザで対応されることが期待できそうというところです。
    (SafariがVP9に対応してくれればそれでいいのですが・・・)

    既に実装も進んでおり、Firefox Nightlyでは再生もサポートされているということだったので
    エンコードと再生を試してみました。


    エンコードにはリファレンスのエンコーダを使用します。
    AV1のGitはこちら。

    https://aomedia.googlesource.com/aom

    AV1は現在も絶賛開発中となっており
    仕様の確定が2017年末予定 → 2018年初め予定 → 現在も未確定という状況のようです。

    よって、デコーダのバージョンとエンコーダのバージョンを合わせておかないと「再生出来ねぇ!」という状況になります。
    そこでまずはFirefox Nightlyで使用されているデコーダのバージョンを調べます。


    Firefoxに使用されているデコーダのバージョンの確認方法は以下のページにあります。

    DASH playback of AV1 video in Firefox - Mozilla Hacks - the Web developer blog

    「av1.experimental.<aomのコミットハッシュ>」をMediaSource.isTypeSupportedに入れて通ったらそのバージョンということです。
    MediaSource.isTypeSupported('av1.experimental.e87fb2378f01103d5d6e477a4ef6892dc714e614');

    aomのlogからコミットハッシュのリストを取ってきて一致するか調べて行けばどれかが当たります。


    デコーダのバージョンが分かったら同じバージョンのソースを取得しビルドします。

    ビルドの方法はREADMEに丁寧に書いてあるので基本はその通りにやればよいです。
    補足として私がWindows上でビルドした時のメモも記載しておきます。

    • Visual Studio 2017
      • C++開発を追加する
    • CMake version 3.5 or higher.
      • CMakeは手動で叩くのでPATHを通すとかは必要ではない
    • Git
      • Makeの中でチェックしてるっぽいけど必須かはわからない
      • ソースも落とせるのでとりあえず入れておけばよいだろう
      • Gitクライアントなら何でも良さそうだがGit for windowsで動作を確認
    • Perl
      • Active Perlで大丈夫
      • 特に追加のPPMとかは要らない
    • Yasm
      • Visual Studioと連携出来るっぽいvsyasmというのもあるけど普通のyasmの方でよい
      • Make中に参照されているのでPATHを通しておく必要がある
      • VSの再頒布可能パッケージが必要(どのバージョンかは忘れた)

    CMakeのオプションが重要です。
    cmake -G "Visual Studio 15 2017 Win64" -DCONFIG_CDEF_SINGLEPASS=1 -DCONFIG_UNIT_TESTS=0 path/to/aom


    Visual Studio 2017用のファイルを作成するオプション。
    -G "Visual Studio 15 2017 Win64"

    「Win64」は64bitアプリをビルドする設定。
    エンコーダはかなりメモリを食って普通に2GBを突破したりするので64bitで作るべきです。

    Firefoxが追加しているオプション。
    -DCONFIG_CDEF_SINGLEPASS=1

    デフォルトはOFFですがFirefoxがONでビルドしているので合わせてONにします。
    この設定は最新のバージョンには存在しません。(OFF時の実装が削除され、標準でONの動作となる)

    テストを省略するオプション。
    -DCONFIG_UNIT_TESTS=0

    ちょっと使ってみるだけなので外しました。
    ONにするとPythonを要求されて面倒なので・・・。

    Makeが済むとVisual Studio用のファイルが生成されるので、ソリューションファイルを開けばビルドできます。
    特に何も無ければビルドが成功してライブラリや実行ファイルが出力されるはずです。
    エンコーダは aomenc.exe です。

    割と作るのが面倒なのでビルドしたエンコーダも置いておきます。
    私がビルドしたバイナリを信用できる人はお使いください。
    あとこれを使って何が起きても私は知らん。

    aomenc (for Firefox Nightly 61.0a1)


    エンコーダが準備できたので今回は以下のようにエンコードしました。
    aomenc.exe ^
    --verbose ^
    --psnr ^
    --cpu-used=8 ^
    --threads=4 ^
    --tile-columns=2 ^
    --passes=2 ^
    --input-bit-depth=8 ^
    --webm ^
    --codec=av1 ^
    --profile=0 ^
    --end-usage=cq ^
    --cq-level=32 ^
    --target-bitrate=2048 ^
    --bit-depth=8 ^
    --color-space=bt709 ^
    --output=output.webm ^
    input.y4m

    オプションについては別にまとめたので細かいことが知りたければ参照してください。
    (ただし最新バージョンのオプションを元に書いたのでe87fb2378f01103d5d6e477a4ef6892dc714e614とは微妙に使えるオプションが違います)


    ソースの映像はカスタムオーダーメイド3D2をキャプチャしてきて、
    データ的には i420 960 * 540 30fps 総フレーム数4916となっています。

    これをCore i7 3770でエンコードしたところ丁度5時間かかりました。
    ただ、CPUを使い切ってくれないのでマルチスレッドがイマイチのようです。
    VP9のソースと比較してみましたが、そもそもVP9もあまりマルチスレッド化をしていないようなので
    処理内容的に向かなくて出来ないのかもしれません。


    エンコードもアレですが、デコードもかなり遅いです。

    最初は i444 1920 * 1080 60fps でエンコードしていたのですが、
    再生してみるとデコード処理が間に合わないので
    解像度とかFPSとかビットレートとかを下げて行って上記の内容になりました。

    Core i7 3770ではデコード出来ていますがCPUによってはデコード出来ないかもしれません。
    Firefoxはデコードが間に合わない場合次にデコードが間に合うフレームまで映像がストップするようです。


    エンコードが遅いのは時間をかければなんとかならなくもないですが、
    デコードが間に合わないとなると実用は無理ではないかと思います。

    Gitのlogを見ているとSIMDで頑張って最適化しているようですが
    SIMDとマルチスレッドでガリガリにチューニングしてどこまで行けるか。

    さすがにハードウェアでのサポートが必須と言えるレベルではないかと思います。
    ただ、ここから仕様を固めてハードウェアを設計してとなるとだいぶ未来の話になりそうです。


    エンコードしたものはこちらになります。(45,290,322 Byte)


    バージョンの合うデコーダでCPUパワーがあれば再生出来ます。
    (あと、about:configでmedia.av1.enabledをtrueにする必要があります。)


    あと音声をmuxしようとするとffmpegでもmkvtoolnixでも
    「AV1とかWebmの仕様にはない!」とか怒られて入れられないので
    結局libwebmのサンプルを元に簡単なプログラムを書いてmuxしました。
    一応これも置いておきます。
    例によってこれを使って何が起きても私は知らない。

    webmmuxer


    WebMはMatroskaのサブセットなのでMatroskaとして作って
    拡張子をwebmに変えてFirefoxに突っ込んだらそこはかとなく動いたのでそれでもいいと思います。

    この辺りの整備もまだまだこれからというところでしょうか。
  • Key sequencer 1.2.0

    2018年02月18日 23時43分
    MIDI入力の切り替えがボタンだと不便だったのでホットキーに変更した上でUIの挙動を整理した。

    Key sequencer