• FFmpegでVP9エンコード

    2017年09月21日 20時25分
    時々ゲームプレイを録画して残していまして、
    CODECをh.264、色空間はYUV420にしていました。

    ただ、ゲーム画面だと隣り合うピクセルの色が全然違ったり彩度の高いピクセルが多かったりで
    YUV420にすると全体的に色が薄く見えるのが不満でした。

    これを解決すべく色空間をYUV444に変更し
    ついでにCODECも高圧縮なVP9に変更しようというのが今回の話の始まり。


    今時高圧縮なCODECというとh.265かVP9で迷います。

    h.265はハードウェアエンコード対応が多く
    VP9はだいたいのブラウザで再生できるのがそれぞれの利点でしょうか。

    画質と圧縮率はだいたい同じくらいのようで
    私には良し悪しが判断出来ません。

    今回は大量にエンコードするわけではないので再生環境が多いVP9を採用することにしました。


    VP9のエンコーダというと、最初はlibvpxに付いているvpxencを使おうと思ったのですが
    録画したaviファイルをy4mに変換する必要があり
    y4mの変換にffmpegを使うことになったので、それならもう全部ffmpegでいいかとffmpegを採用。


    それでいざffmpegでエンコードしようとすると
    オプション大量すぎてわけわからんで苦労したので調べた情報を書いておこうと思います。


    私はffmpegについて詳しいわけではないので
    不確かなことを書くのもどうかとは思ったのですが
    あまりに情報が少なかったので全く無いよりはいいかと書いておくことにしました。

    調べる時のとっかかり程度の情報と思って見ていただきたい。


    参考情報




    CODEC


    動画CODECにVP9を指定。
    -c:v libvpx-vp9


    WebMの音声CODECはOpusまたはVorbisになりますが、後発のOpusを使えばいいと思います。(性能もいいらしい)
    音声CODECにOpusを指定。
    -c:a libopus


    コンテナは出力ファイルの拡張子から判断してくれるようですが、一応指定しておけば確実かなと思います。
    -f webm



    RGB → YUV444変換


    エンコーダに渡すピクセルの色空間指定はpix_fmtで行います。
    -pix_fmt yuv444p


    カラーマトリクスは全然別のオプションでこうです。
    -vf "scale=out_color_matrix=bt709:out_range=full"


    ffmpegのログを見ると、-vfでscaleを指定しない場合auto_scalerというのが挿入され、こいつが色空間の変換処理をしているようです。
    「-vf "scale=out_color_matrix=bt709:out_range=full"」のように明示的に指定してやるとauto_scalerが自動挿入されなくなり、指定したscalerが入ります。


    ビットレート


    VP9にはビットレートのモードが4つ。

    • Constant Quantizer (Q)
    • Constrained Quality (CQ)
    • Variable Bitrate (VBR)
    • Constant Bitrate (CBR)

    ストリーミングで配信するわけでもなく
    自分用にアーカイブするのが主な目的なので
    品質固定のConstant Quantizer (Q)を採用しました。

    Constant Quantizer (Q)の指定。
    -crf 30 -b:v 0


    crfは0-63の範囲で指定し、0に近づくほど画質がよくなりデータサイズが大きくなるので
    結果のファイルサイズと画質のバランスで決めることになると思います。

    思ったより数字を大きくしても画質は良いと感じました。
    目安としていくらか試した感じだと1080p 30fpsで30-35あたりが良いのではないかと。

    「-b:v 0」は必須です。というかこの指定がConstant Quantizer (Q)の意味。


    Opusのビットレートの指定は簡単。
    -b:a 160k

    Youtubeが160kでエンコードしているらしいのでその辺りが良さそうです。


    エンコード品質と速度


    -speed 1


    0-4の間で指定し、0に近い程エンコード速度が遅くなり画質が良くなる。
    基本的には0を指定したいところですが、ただでさえ遅いVP9のエンコードがさらに遅くなるので
    エンコード時間を考慮して決めることになります。


    カラーマトリクス


    YUVからRGBに戻す時のカラーマトリクスを指定します。
    RGB → YUVの変換で指定したものを指定すればいいと思うのですが
    なぜ3個もあるのかよくわかりません。

    ffmpegのログを見ると3つとも同じにしておけばひとまとめにして認識してくれているようなのでこれで合っている気がします。
    -colorspace bt709 -color_primaries bt709 -color_trc bt709



    デコード用オプション


    公式のエンコードガイドに、画面を分割して並列デコードできるようになるみたいなオプションがエンコード例に記載してあります。
    -tile-columns 6 -frame-parallel 1


    効果はイマイチわかりませんが今のところ特に害はないです。
  • ARROWS Tab QH55/M クリーンインストール方法

    2016年09月24日 15時38分
    Windows 10にアップデートして使ってたらある日突然起動画面で固まって動かない状態になって
    さすがマイクロソフトだな!とか思いながらいっそ初期状態にリカバリするかと
    リカバリ領域からリカバリかけたら途中で止まってリカバリ出来ない上に起動ドライブのデータがぶっ壊れて
    さすが富士通クオリティだな!とか思いながらWindows 10でクリーンインストールしようとしたら
    思いの外手こずったのでクリーンインストール方法を書いておこうと思う。
    またなんかすぐ動かなくなってやると思うので。

    BIOSからセキュアブートを切る


    1. 電源入れた直後にオプション?ボタンを連打
    2. 起動マネージャがというのが出たらメニュー切り替えするとBIOS起動がある
    3. BIOSを起動
    4. 管理者パスワードを適当に設定(これを設定しないとセキュリティ設定が出来ない)
    5. セキュアブートをOFF
    6. セキュリティチップもOFFったほうが良いかも?
    7. 高速起動もOFFった方が良いかも?
    8. 設定後管理者パスワードを空欄で更新してOFFったほうが良いかも?

    この辺りいじりまくったので他にも影響するのがあるかもしれん。

    起動メディア


    64bit版を入れようとして起動しない!とか悩んだけど
    このマシンは32bit用だった。よって今時32bit版を入れる。

    あとUSBメモリだとブートしなくてDVDだとブートした。
  • SAStrutsのHTML5対応 その3

    2015年06月18日 01時04分
    taglib-html5_1_2_9_2.zip

    ナウなHTML5で必要な属性が足りていなかったのでいくらか足しました。
    • textareaタグ
      • maxlength属性
      • wrap属性

    やはり無条件に全て受け入れてそのまま出すというのが正解だった気がしますが今更後には引けない。

    というか、これJava1.3のソースをtarget=Java1.2で作っているのですが、
    Java9以降は3バージョンくらい古いバージョンしかサポートしてくれない予定のようなので
    さすがにそろそろ延命措置も厳しい気がします。
  • libvpxのVisual Studio用ファイルをLinux上で作る

    2015年06月11日 20時38分
    libvpxをWindows用にビルドしたいけどMinGWをインストールするのが嫌でLinuxはある人向けという
    隙間産業的な記事。


    VP9のエンコードはそろそろ早くなったりしないかなあと思いつつlibvpxの中身を眺めていたら、
    なんか行けそうな気がしてやってみたら出来たのでメモっておきます。

    ちなみに私はlibvpxの中身を熟知しているわけではなく、
    部分部分をちょいちょいとつまんで解釈し
    なんとなく合ってそうというものであるとご理解ください。


    きっかけは、libvpxの中身を見ていたら「gen_msvs_sln.sh」とか「gen_msvs_vcxproj.sh」とかが有るのに気づいたことで、
    同時に「これをLinux上で動かしてslnとかvcxprojとか作れればそれを持ってきてVSでビルド出来るんじゃね?」と閃きました。

    これらのスクリプトはconfigureでtargetにvsを選択すると使われるようになっています。

    例えば、VS12で64bit用にビルドしたい場合はtargetにx86_64-win64-vs12を指定します
    # ./configure --target=x86_64-win64-vs12

    ※targetの一覧はconfigureのhelpに出てきます。


    これでmakeすると、指定したVS向けファイルが作成されます。

    configureの中のヘッダチェックとかも気になったのですが、主にtargetを確認する処理になっていて、
    実際そのヘッダが有るかないかとかは見てないので大丈夫そうです。


    細かい手順や注意点は以下になります。

    gitのcloneを取る
    # git clone https://chromium.googlesource.com/webm/libvpx
    # cd libvpx


    試した時のrevisionはこれでした
    # git rev-parse HEAD
    44afbbb72d8a5fa0528f8a571a5023a843d02f33


    作業用にまるっとコピーします
    # mkdir ../export
    # git archive --format=tar HEAD | tar -x -C ../export
    # cd ../export


    VSプロジェクトファイル内のincludeディレクトリ指定に、configureした時のLinux上のフルパスが現れないように書き換えます
    # sed -i -e 's/SRC_PATH_BARE=$source_path/SRC_PATH_BARE=./' build/make/configure.sh
    # sed -i -e 's/CFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH)/CFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT)/' -e 's/CXXFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH)/CXXFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT)/' build/make/Makefile


    vpxenc以外コンパイルしたくないんじゃあという場合は、examplesの対象をvpxencだけに書き換えます
    # sed -i -e 's/ALL_EXAMPLES    = $(UTILS) $(EXAMPLES)/ALL_EXAMPLES    = vpxenc.c/' examples.mk


    お好みのオプションを選択してconfigure
    # ./configure --log=no --target=x86_64-win64-vs12 --enable-static-msvcrt --disable-vp8 --disable-unit-tests

    vp9のdecoderも要らないのでOFFにしようと思ったのですが
    decoderが一個も無くなると一部ソースがコンパイルエラーになるのでやめました。

    makeするとVS用のプロジェクトファイルとかソリューションファイルが作成されます
    # make


    後はこのソースツリーをまるごとWindowsに持ってきてvpx.slnをVSで開けばビルドできます。
    ※yasmのインストールも必要です



    さて、VP9のエンコードは今どのくらいの速度なのでしょうか。
    1920 * 1080 FPS30の動画をエンコードしてみました。
    CPUはCore i7 3770です。

    オプションがまだ完全に把握出来ていないのですが、
    まずはおそらく最速の設定であろう「good cpu-used=8」を試しました
    vpxenc --output=output.webm --threads=4 --good --cpu-used=8 --passes=1 --codec=vp9 --webm --end-usage=cq --cq-level=10 --i420 --color-space=bt709 --width=1920 --height=1080 input.y4m


    思ったより早い!11FPSくらい出ました。
    そこそこ使えなくもない早さな気がします。
    でも、どうせなら遅くても品質を取りたいので、次は「best」を設定してみました。
    vpxenc --output=output.webm --threads=4 --best --passes=1 --codec=vp9 --webm --end-usage=cq --cq-level=10 --i420 --color-space=bt709 --width=1920 --height=1080 input.y4m


    結果は14FPMでした。
    FPSじゃないです。FPMです。
    最初表示がバグったかと思いました。
    こんな表示が用意してあるあたり開発側もまだ遅いと思っているのでしょう。

    品質についてはbestのエンコード終了を待てなかったので比較していません。
  • x264とffmepg

    2015年06月05日 01時16分
    動画エンコード関連は色々と難しすぎて未だによくわからないのですが
    トラブルに遭い、解消方法がわかったのでメモしておこうと思います。


    LoVAのオープンβが始まるということで
    復習用に録画を手早くエンコードする準備をしていました。

    以下の手順をbatファイルで行います
    1. x264で映像部をH.264にエンコード
    2. neroaacencで音声部をAACにエンコード
    3. ffmpegで結合


    この手順で試しにエンコードしたところ、映像がカックカクです。


    問題を切り分けて行ったところ、
    x264の出力を.264→.mp4に変更したら直りました。

    .264をffmpegで結合するとプログレスバーがニョキニョキ動いているので
    なんか映像データに手を加えておかしくなっているのだと思います。
    (.mp4だとそういうのが出なくてあっさり処理が終わります)

    ちなみにコマンドはこんな感じでした
    ffmpeg -i 映像.264 -i 音声.aac -vcodec copy -acodec copy 出力ファイル.mp4

    FPSがおかしくなっているのかと思い、試しに-rオプションで元動画のFPS(30)を指定してみたのですがダメでした。

    「このPCまだmp4box入れてないわあ、ffmepg入ってるからこれでいいや」とか横着したのがそもそも失敗だったかもしれません。


    あと、LoVAはもうだめかもしれません。