2011年7月9日土曜日

バッファサイズ

前回の記事で筆者は「avs2yuvはバッファが512Bしかないから、256KiBのavs2pipemodよりも遅い」と書いたわけですが、これを読んだ人なら誰でも「じゃあ、avs2yuvのほうもバッファを増やせば速くなるんじゃね?」と考えるのではないでしょうか?

はい、もちろん速くなります。

バッファの拡張なんていうとなにやら大げさですが、やることといえば単にsetvbuf()というCの標準関数を使うだけです。
試しにavs2yuvの書き込みバッファを128KiBに増やして前回のベンチマークをもう一度回してみると…平均284.48fps。
ぐは、今度はavs2pipemodが負けた…orz

悔しいので、avs2pipemodのほうのバッファサイズを256KiBから128KiBに減らしてみると…平均285.05fps。 どうやら引き分けといったところでしょうか。
             avs2yuv     avs2pipemod     avs2pipemod
buffsize     128KiB         256KiB          128KiB
1st (fps)    285.18         279.97          281.66
2nd (fps)    283.45         274.59          285.96
3rd (fps)    281.75         272.27          286.85
4th (fps)    285.86         271.92          285.63
5th (fps)    286.16         274.00          285.18
avg (fps)    284.48         274.55          285.05
このように、バッファサイズは少なすぎてはいけませんが、かといって多ければいいというものでもない。
ハードや扱う素材等によっても最適値は変化するでしょう。
でもそこらへんまで追求を始めると「湾岸ミッドナイト」な世界に突入してしまいそうです。
まあ、64KiB~256KiBくらいにしておくのが無難じゃないですかね。

てなわけで、このへんでお開き。
とりあえずバッファを128KiBにしたavs2yuv(MasterNobody版ベース)とavs2pipemodを置いときます。
avs2yuv_c99-mod.zip
avs2pipemod-20110709.zip

追記 2011.09.21
Doom9でこのことについて少し書いたら、MasterNobody氏がこれを取り込んだバージョンを出しました。
http://forum.doom9.org/showthread.php?t=162578
avs2yuv-0.24bm2.zip
追加機能でi422/i444対応も入っているので、自分の改造板avs2yuvを使うメリットはもはやありません。
MasterNobody氏のavs2yuvを使うことをおすすめします。

avs2yuv その2

前回avs2yuvの修正/改造版をリリースしたら、直後に今度はMasterNobody(Anton Mitrofanov、別名BugMaster)氏がC言語版のavs2yuvを出した。
avsからy4mで出力するツールが一気に増えてしまったので、ここらへんで整理してみようかと思う。

まずavs2yuvを使うならどれがいいのか?
avs2yuvは本家(pengvado版)、kemuri-_9版、MasterNobody版、そして筆者のものの4種類がありますが、一番のオススメはMasterNobody氏の最新版です。
スピードや出力自体はどれもたいして変わりませんが、終了時、及びエラー時の処理が一番丁寧に行われています。
加えてバイナリのサイズも一番小さく、筆者版のように追加で必要なランタイムもありません。
さらにavisynthMTを使っている場合は自動でavsの最後にDistributor()を追加するようにもなっています。
おまけにmingw用のコードなので、LinuxやMacでも簡単にクロスコンパイル出来ます。
ついでに言えば、64bit用バイナリも同梱されています。
avs2yuvを使うなら、多分これが一番いいでしょう。

では他のツールも含めた場合ならどれがいいのか?
とりあえず使用目的が32bitのavisynthの出力をpipeで64bitのx264に渡すこと、もしくはwineでavisynthを使うことなら、現状ではavs2pipemodが一番いいです。
理由は単純に一番速いから。
avs2yuvの現在配布されているバイナリすべて、そしてavs2pipe-0.0.3は、ファイル書き込み用バッファを512Byteしか持っていません(stdio.hで定義されている値をそのまま使っています)。
非圧縮フォーマットであるy4mにとって、これはいささか少なすぎます。
ffmpegに至っては、avs2yuvよりもさらに遅い上にオプションがやたら長くなります。

ffmpeg -v 0 -i foo.avs -pix_fmt yuv420p -vcodec rawvideo -an -f yuv4mpegpipe - | x264 - --demuxer y4m ...

一方avs2pipemodは、以前書いたように書き込み用バッファを拡張しています(20110703版の時点では256KiByte)。
これにより発生するスピード差は次のようなベンチマークをしてみれば一目瞭然です。
#!/bin/bash

echo ColorBars\(1280,720,\"YV12\"\).Trim\(0,4999\) > ./ColorBars.avs

#avs2yuvとavs2pipemodで同じavs(5000フレーム)をそれぞれ5回ずつ回してみる。
#avs2yuvはMasterNobody版を使用

for i in {1..5}; do
avs2yuv ./ColorBars.avs -o - | x264 - --demuxer y4m --preset ultrafast -o /dev/null
done

for i in {1..5}; do
avs2pipemod -y4mp ./ColorBars.avs | x264 - --demuxer y4m --preset ultrafast -o /dev/null
done
さて、自分の環境での結果は以下の通りでした。
        avs2yuv     avs2pipemod
1st    213.04fps     276.53fps
2nd    211.18fps     273.69fps
3rd    213.53fps     275.32fps
4th    213.69fps     276.53fps
5th    213.07fps     276.59fps
avg    212.90fps     275.73fps
実際のエンコードにおいてはこんなに軽いavsを使うことはないでしょうし、x264の設定もずっと重くなりますから、差はかなり縮まるでしょう。
しかし、avs2pipemodがavs2yuvよりも遅くなることは、まずありえない話です。

2011年7月4日月曜日

avs2yuv

Windows7を使い始めてからしばらくした頃、avs2yuvがクラッシュするようになった。
Doom9とかでは特に問題になっていなかったので自分の環境だけかと思っていたのだが、しばらくしてdoom10のほうにこんなスレッドが立ち、自分以外にも同じ問題を抱えている人がいることを知った。

解決策が見つからないので、しばらくの間はavs2yuvのかわりにffmpegを使っていた。
そのうちにdoobry氏がavs2pipeをリリースしたので自分はこちらに乗り換え、さらにこれをより自分好みなツールに改造すべくC/C++の学習を本格的に始めてしまったわけだが、avs2yuvの件はずっと脳内の片隅に引っ掛かっていた。

さて、今日になってこのスレッドを何気なく読んでいたら、とても気になる記述が…。
avs2yuv 0.24 fix: http://forum.doom9.org/showthread.php?t=145912


まさか2年以上前に、すでに解決策が出ていたとはなぁ…不覚orz
とりあえず、このパッチを適用したバイナリはどこにもないようなので、ビルドして配布することにした。
ついでに-hfyu用のエンコーダーをmencoderからffmpegに変更(現在のmencoderはffmpeg以上に信用出来ない地雷ツールなので)したので、もうちょっと便利になったと思う。

avs2yuv-0.24m.zip (要msvcr100.dll)
https://github.com/chikuzen/avs2yuv

2011年7月3日日曜日

avs2pipemod その7

更新。
この前waviのコードを読んだのをきっかけに、RIFF-WAVEフォーマットについていろいろ調べてみました。
どうやらものに出来たようなので、avs2pipemodに新機能を追加。

avs2pipemod-20110703.zip
https://github.com/chikuzen/avs2pipemod

*'-audio'オプションを廃止し、'-wav'と'-extwav'オプションを追加
'-wav'は、一般的なriff-wave(.wav)フォーマットで出力します。
'-extwav'は、チャンネルマスク付きのwave extensible formatで出力します。
チャンネルマスクはチャンネル数に応じて決め打ちになるので、特殊なスピーカー配置の場合はwaviを使ったほうが良いでしょう。
PCM音声の場合、wave extensible formatが普通のwavよりいいところはチャンネルマスクを付けられる点だけなわけですが、これをサポートしているソフトはそれほど多くはないようです。
よく分からない場合は'-wav'を使いましょう。
ちなみにこれまでの'-audio'は「チャンネルマスク無しのwave extensible format」という微妙すぎるものしか出力できませんでした。

*'-rawvideo'の引数にvflipを追加
avs2pipemod -rawvideo=vflip input.avs とすれば、映像の上下を反転して出力します。
RGB出力時の反転対策です。

追記
Doom9に投稿したらIanB氏にオプションを変えたことでお小言をくらってしまったので、-audioでも-extwavと同じ挙動をするように変更しました。
avs2pipemod-20110703-2.zip