2011年12月9日金曜日

AviSynth Script Reader for AviUtl

VFR_maniac改めMP4_maniac氏がlsmashinput.aui(L-SMASHとLibavを利用したAviUtl用入力プラグイン)を発作的に書き始めてしまったのに付き合っていた流れで、AviUtlの入力プラグインの書き方が少しだけ理解できるようになった。

AviUtlといえば前から不思議に思っていたのが「なぜavsを読むのにわざわざ別に入力プラグインが必要なのか」である。
そもそもAviSynthはスクリプトをAVIに偽装するソフトウェアである。
もし任意のソフトウェアがVFWのAVIFileOpen関数を使って拡張子がavsのファイルを開こうとすれば、レジストリ登録情報によりavisynth.dllが動いて、ただのテキストはAVIとして扱われるような仕組みになっている。
AviUtlにはVFWを使用する入力プラグイン(AVI File Reader)が内蔵されているのだから、本来外部プラグイン(avsinp.aui)は必要ないはずなのだ。

で、このたびPluginSDKのサンプルコード(avi_input.cpp)を読んでみたら、疑問はすぐに解決した。
AviUtlは、まずファイルの拡張子を見てプラグインが対応しているかどうかを判別するため、*.avsというファイルはAVI File Readerには渡されないというだけのことだった。

てなわけで、ちょっと実験。
まず、avi_input.cppのINPUT_PLUGIN_TABLE構造体のfilefilter変数の中身を*.aviから*.avsに変更。
入力プラグイン名をAviSynth Script Reader (VFW)にして、コメント以外の日本語文字を除去(CP932は色々面倒)、ついでにファイル名を.cppから.cにして(avi_input.cppはC++ではなくCで書かれている)、あとはGCCでコンパイルしてやれば…
gcc -c avi_input.c -o avsread.o
gcc -o avsread.aui -shared -Wl,--dll,--add-stdcall-alias avsread.o -lavifil32
ああ、読めた。

つまり、KENくん氏が内蔵のAVI File Readerに拡張子*.avsを追加してくれれば、avsinp.auiは要らなくなるんだよなぁ…。

2011年10月15日土曜日

Oneiric入れてみた

Ubuntu11.10(OneiricOcerot)が出たのでWindows7上のVMWarePlayer3.1.4(4.0は様子見中)に入れてみました。

インターフェース
とうとうVMWarePlayerでもUnityになってしまいました。
まあ、UbuntuのUIは最初に9.10を入れたときの感想が「なんか林檎臭くてやな感じ」で特に気に入っていたわけでもありませんし、別にどうということもありません。
メインで使ってるわけでもないし、多分一ヶ月もすれば慣れてるんじゃないかと思います。
それに当たり前のことではありますが、Terminalの使い勝手はMSYSやCygwinよりも遥かにいいわけですしね。
(でも、画面左のランチャーは、Windows7のタスクバーに比べて遥かに糞だと思います)

さて、自分にとってとりあえず重要なのはwine(というか、avisynthが動くこと)とmingwですので、早速試してみることにしましょう。

wineとavisynth
wineは使い始めた当初よりLatest official releaseのPPAを利用しています。
launchpadに行ってみたら、Oneiric用のパッケージも既に配布されていました。
今後は1.3だけの配布になるのかな?
$ sudo add-apt-repository ppa:ubuntu-wine/ppa
$ sudo apt-get update
$ sudo apt-get install wine1.3
あとはsourceforgeからavisynth2.6.0α3とVirtualDubをDLして、avisynthはwine経由でインストール、VirtualDubは~/.wine/drive_c/Program Files以下に展開。

さて、ここで注意したいのは、最近のwine1.3ではそのままではavisynthが動かないこと。
どうやらmsvcrt関連に1.3.1xのあたりで大きな変更があったらしく、runtimeの追加が必要になっています。
と言ってもやることは簡単で、Winetricks->Select the default wineprefix->Install a Windows DLL or componentでvcrun6をインストールするだけです。
Windows実機でMicrosoftからVC++XX再頒布可能パッケージとかをDLしてインストールするよりも遥かに速くて楽ですし、どのWindowsアプリケーションでどのruntimeが要求されるかもわかりませんので、vcrun*は全て入れてしまってもいいかも知れません。
これでavisynthは動きます。

mingw
GCCを使ったWindows用アプリケーションのビルドは、MSYSやCygwinよりもLinux上でクロスコンパイルしたほうが速いです。
特にconfigureのスピードは桁違いで、MSYS環境だと3分はかかるffmpegのconfigureが、LinuxだとVM上でも15秒で終わります。
ただ11.04までのUbuntuのmingw関連は、mingw32はGCC4.2.1のまま放置、mingw-w64はGCCこそ4.4.3と少しはマシのようだけどいろいろぶっ壊れていたりして、使いものになりませんでした(getopt.hとかが無いってどーいうことよ?)

さて、今回のパッケージはどうでしょうか?
とりあえずmingw32のほうは相変わらず放置のままのようですが、mingw-w64はGCC4.6.1に更新されていて抜けていたヘッダーもちゃんとあります。
triplexもi586-mingw32msvc/amd64-mingw32msvcという「お前はGCCなのかMSVCなのかはっきりしろ」と言いたくなるようなDebian流のものから、i686-w64-mingw32/x86_64-w64-mingw32というmingw-w64の標準的なものに変更されてていい感じです。

しかし、ここで一つ問題に気づきました。
このパッケージにはlibvfw32.aが入っていません。
mingw-w64はmingw32よりも開発が活発でどんどん良くなっていってはいるのですが、まだまだいくつかライブラリに抜けがあったりして、ときどきハマることがあります。
libvfw32.aが追加されたのはたしか7月の終わりあたり…そしてこのパッケージはバージョンを見ると5月終わり頃のもののよう。
折りしもmingw-w64は数日前にv2.0をリリースしたばかりだし、GCCも4.6.2がすぐに出ます(っていうか、たしか今月頭に出るはずだったんだが)…結局今回も11.04同様、自ビルドすることになりそうですorz

2011年10月11日火曜日

GPL violation?

x264LLCと契約した某社が、libx264を使うBD用エンコードソフトのベータ版を出した」とkierank氏に聞いたので、ダウンロードしてみることにした。
まずは配布ページに行ってユーザー登録。次にインストーラをDL。
商用ソフトのベータ版というだけあってインストーラはinnoやmsiではなく最新のInstall Shieldだった。うーむ、これでは7zipでは解凍できないね。
仕方ないのでインストーラをダブルクリックしてみると、EULAの次に表示されたのがこれ。
えー、なんでー? これって商用なんでしょ?
正式リリース後はお金払わなきゃ使えなくなるんでしょ?
開いたままふさがらない口を閉めつつ、早速カスタマーサポートに次のようなメールを送ってみることにした。
この度御社のhogehogeベータ版をインストールしたところ、fugafuga.dllのライセンスに関して、
GNU General Public License Version3であるとの提示がありました。
GPLなプログラムを配布する場合は、そのプログラム自体のソースコードはもとより、プログラムをプラグインとして
使用するアプリケーション本体等に関しても、OSやコンパイラが提供する「システムライブラリ」以外は全て
ソースコードの開示義務が発生することはご存知であると思います。
つきましては、GPLで保護された配布物の受領者として、全ソースコードの開示請求の権利を行使いたしたく思います
ので、よろしくお取り計らいいただけますようお願いいたします。
でもって数日後に返ってきたお返事はこんな感じ
お問い合わせの件ですが、まず、fugafuga.dllについては、GPLライセンス下のプログラムとなりますので、
ご要望とあれば、ソースコードを郵送でお送りさせていただきます。お届け先のお名前、ご住所、お電話番号を
お知らせください。
また、「(GPL)プログラムをプラグインとして使用するアプリケーション本体等に関しても、OSやコンパイラが
提供する「システムライブラリ」以外は全てソースコードの開示義務が発生すること」については、過去の例を含めて
再度確認いたしましたが、開示義務があると断定することはできません。
ただ、今後もこのようなご意見を頂戴することも考えられますので、本日よりfugafuga.dllの提供を停止させて
いただきました。
今後とも、hogehogeをよろしくお願いいたします。

そりゃあ、義務があると断定するためには裁判所の判決が必要になるでしょうが、少なくともGPLの条文には義務が生じると書かれています
foobar2000とSecretRabitCodeの一件*とか、裁判まではいかなくても揉めた事例はいくつもあるわけで。
もし誰かがFSFに垂れ込んだら、ひょっとすると本気で食いついてくるかも知れないよ?
動画編集用Free-softwareの開発は、GNUのHigh Priority Free Software Projectsの一つとしてここ数年間、ずっと掲げられているのを知ってる?
そもそもGPLなライブラリを簡単に使えるんだったら、なんであんたらx264LLCと契約したの?
LGPLと勘違いしてないか?
まあ、自分は当初の目的(この会社をからかって遊ぶこと、及びこのライブラリの使用を即刻やめさせること)は果たしたので、これ以上何かするつもりはないんですけどね。

なんで使用をやめさせたかったかといえば、このソフトが商売としてちゃんと成功して欲しいと思っているから(自分が買う予定はまったくないけど)。
x264LLCに入った利益はlibx264の開発に貢献した度合いに応じて各開発者に分配されることになっており、現にPegasysのTMVW5やSplitMediaLabsのXSplitといった商用ソフトのライセンス料の分配は始まっている。
日本人の自分から見ればそれほどたいした金額ではないみたいなんだけど、例えばロシア人の某氏が受け取ったお金は、彼の本職のサラリー数カ月分に相当するそうである(JEEB氏によれば、彼の給料はロシアでは結構もらってるほうらしい)。
ソフトウェアの共同開発を楽しみながらそこそこの小遣い稼ぎも出来るのであれば、特に物価の安いロシア/東欧/南米といった地域から生きの良い開発者が新たに出現する可能性は高くなるだろう。
そして、そういう仕組みが出来上がったところでH.265が正式に勧告され、x264がx265になったら(もちろん彼らはそれくらいのことは既に考え始めている)、かなり面白いことになるんじゃないかな?
そういう夢をみるためには、一つでも多くの成功事例が必要なのです。

で、それはそれとして一人でニヤニヤしてればいいのに、なんでわざわざこんなのを書いているかといえば、似たようなライセンス爆弾を抱えているツールだのプラグインだのを結構見かけたりするから。
すでにそのようなバイナリを配布しているあなたや、これから配布しようと思っているあなた、ホントにそれで大丈夫ですか?
不注意から起こったトラブルでストレス貯めこんでハゲても知りませんよ?
まあ、うっかりなんてことはそれこそ誰でもやっちゃうものですから、直せるなら早めに直したほうがいいでしょう。

*foobar2000は無料で配布されているWindows用オーディオプレーヤー(プラグインSDK以外のコードは非公開)。
SecretRabitCode(別名libsamplerate)は現在最も高品質と言われているオーディオリサンプル用ライブラリ(x264と同様のGPLv2又は商用の二重ライセンス)。
かつてSRCを使用したfoobar2000用リサンプラープラグインが書かれたことがあるが、これを見つけたSRCの作者Erik氏はプラグイン作者にfoobar2000の全コード、もしくはSRCの商用ライセンス料の支払いを要求し、件のプラグインは開発/配布の永久停止となった(まあ、探せばどこかで拾えるでしょうが)。

2011年9月26日月曜日

RawSource.dll その6

RawSource26(avisynth2.6.0以降専用)を更新しました。

rawsource_26_dll_20110925.zip
https://github.com/chikuzen/RawSource_2.6x

*widthの最大値を65536に変更。
*あらたに最大解像度を設定(width x height <= 134217728)。
*その他少々の手直し(出力には影響なし)

必要なもの
avisynth2.6.0α2以降
sseが使えるマシン
msvcr100.dll (Microsoft Visual C++ 2010 再頒布可能パッケージのことです)

以前、読み込み用のバッファの確保をオリジナルのMAX_WIDTH x 4から動的確保に変更したので、現在のコードベースにおけるwidth及び解像度の上限は、単に非常識に大きな数値を入力された場合のout of memory回避のために設けてあります。
とりあえず最大width4096で十分だろうと思っていたのですが、一部の変な人達にはそれでは足りないらしいので増やしました。
まあ、たとえwidth=65536, height=2048の場合でも、
読み込み用バッファのサイズは65536*4=256KiB (RGB32の場合)
avisynthが用意する1フレーム分のメモリは134217728x4=512MB(RGB32の場合)
なので、とりあえずこれだけでクラッシュすることは無い(はず)です......大丈夫だといいなぁ

それにしても最近のDoom9はMTとhigh-bit-colorと64bitでグチャグチャになっておりますな。
自分はそういうハックに夢中になる暇があるなら、とりあえずさっさと2.6.0の正式リリースに漕ぎ着けられるよう、協力体制を取って欲しいものですが。
2.6.0が正式リリースになれば2.5.8なんて誰も使わないのは目に見えてるんですから、もはや2.5.8でも使えるような配慮は単なる時間の無駄だと思っています。

2011年9月20日火曜日

xvidcore-1.4.0

今月に入ってxvidのMLに幾つかビルド関連のパッチを投げたりしてみた。
http://list.xvid.org/pipermail/xvid-devel/2011-September/thread.html

もともと自分はただビルドするだけなのにパッチを当てたりするのは嫌いである。
第一に、パッチの存在を知らない人間にはパッチは役に立たない。
第二に、パッチを管理するのはめんどくさい。
第三に、殆どの場合ビルドエラーの原因はあほらしい理由によるものなので、原因が分かったときに激しい虚しさに襲われることになる。

たしかに開発本家にパッチ投げるのってパッチ書く以上にめんどいけど、やらないといつまでもその状態が続いてしまうので、とりあえず出来そうなところは修正してもらったほうがいいだろう。

で、まあ、結果としていくつか採用されてsvnにコミットされたので、いままで必要だった手間は幾分減ることになった。
次のstable release予定の1.4.0では、インストール時にライブラリを別名でコピーするくらいで済むのかな。

追記 2011年10月22日
Ubuntu11.10上でクロスコンパイルしようかと思いsvnのログを確認してみたら、ライブラリ名変更のリクエストもちゃんと受理してもらえてました。
http://websvn.xvid.org/cvs/viewvc.cgi?view=rev&revision=2044
これで自分としてはパッチは完全に不要になりました。
Isibaarさん、ありがとうございました!

2011年9月19日月曜日

avs2pipemod その8

更新しました。

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

*新機能'trim'を追加。

Doom9で「avs2yuvみたいに-seekや-framesをサポート出来ないか」とリクエストを受けたので追加してみました。
内部でavisynthのTrim()を呼び出すだけの簡単なお仕事だし、まああっても邪魔にはならないと思ったので。

使い方
avs2pipemod -y4mp -trim=100,200 input.avs > output.y4m
というふうにすれば、avsの最後にTrim(100,200)を書いたのと同じようになります。
-infoと-x264bdでは無視されます。

ところでリクエストしてきたStephen R. Savage氏は別名thewebchatというファンサブ界の厄介者らしい。
そーいや昔120fpsAVIの作り方とか調べてたな…物好きなこと。

2011年9月4日日曜日

コンパイラによる最適化の押し付けにむかついた件について

GCCの各オプティマイズレベルで有効になる最適化を調べるを読んでちょっと興味がわいたので、いろいろ手元の環境でも確認してみた。
試したマシンはQ9450とT7300のせいかどれもリンク先と同じ結果になったわけですが、とにかく意外だったのは
*-O2と-Osの違いは-finline-functionsの有無だけ(-Osは有り、-O2は無し)。

-Osはサイズ優先の最適化のはずだけど、-O3(とにかくスピード優先)でも-finline-functionsがつくのであれば、これを有効にすればそこそこスピードアップの可能性があるということだろう。
じゃあ、-O2の存在意義って一体なあに?
-O3程ではないが、それなりにスピード優先のはずなんだけど…。

とまあ、前置きはこのくらいにして、今度は各プロジェクトが設定しているデフォルトの最適化設定を調べてみた。

例えばx264は--extra-cflagsを設定しなければ
"-O3 -ffast-math -march=i686 -mfpmath=sse -msse -fomit-frame-pointer -fno-tree-vectorize -fno-zero-initialized-in-bss"
がつく(x86の場合)。
いかにも互換性を気にしつつも速そうな設定という感じですね。
まあ、クリティカルな部分はほぼすべてasmで書かれてCPU検出で自動的に有効にするので、コンパイラによるCコードの最適化はあまり影響しないそうですが。

これがxvidだと
"-O2 -fstrength-reduce -finline-functions -ffast-math -fomit-frame-pointer"
となっている。
configure.inには
First we test if CFLAGS have been passed on command line
I do that because autoconf defaults (-g -O2) suck and they would kill performance.
To prevent that we define a good defult CFLAGS at the end of the script if and only
if CFLAGS has not been passed on the command line
なんて書かれてますが、それにしては中途半端という印象が否めない。
現在でも更新は続いているんだから、いい加減sseをデフォルトにするくらいはしてもいいのでは?
configure.inにはこのデフォルト値に対して"Default CFLAGS -- Big impact on overall speed"とも書かれているあたり、コンパイラによる最適化はかなり重要みたいなんだけど…自分で設定したほうがよさそうですな。

さて問題はa52dec。
これのconfigure.inは以下のような感じになっている。
if test x"$GCC" = x"yes"; then
    changequote(<<,>>)
    OPT_CFLAGS=`echo "$CFLAGS"|sed "s/-O[0-9]*//g"`
    changequote([,])
    OPT_CFLAGS="$OPT_CFLAGS -O3"
    AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS])
なんとコンパイラがGCCだったら有無を言わさず-O3強制です。
たとえば何らかの理由でデバッグビルドしようと思ってCFLAGS="-O0 -g"しても、-O0は削除されて"-g -O3"なんていうへんてこりんなコードが出力されてしまいます。
しかも-O3は勝手につけるのに、-fno-tree-vectorizeはなし。
liba52はとても古いプロジェクトでCVSの最終更新は7年前。もはや死んだといってもおかしくない。
当時は-O3だけでも問題なかったのかも知れませんが、現在ではまともな出力が得られるかどうか非常に疑わしい、地雷コードと化しています。
これは不安定な-ftree-vectorizeを-O3で有効にしたままなかなか直さない(直せない?)GCCが悪いとも言えるかも知れないけど、素人がコードいじらなきゃいけないような自体はなるべく避けて欲しいなぁ。
とりあえずこんなパッチを書いてみたので、何かの事情で今時a52decをビルドしなければならない人は当てたほうがいいかもしれません。

あともう一つ、openjpegプロジェクト。
現在のstable release?であるはずのopenjpeg_v1_4_sources_r697.tgzをビルドしてみたら、設定したCFLAGSが全く反映されません。
なんでかな?とlibopenjpeg/Makefile.amを見てみたら
INCLUDES = -I.. -I.
COMPILERFLAGS = -Wall -O3 -ffast-math -std=c99
if with_sharedlibs
COMPILERFLAGS += -DOPJ_EXPORTS
else
COMPILERFLAGS += -DOPJ_STATIC
libopenjpeg_la_LDFLAGS += -static
endif
CFLAGS = $(COMPILERFLAGS) $(INCLUDES)
お前もかよ(そしてこれも-fno-tree-vectorizeなし)。
svnの最新コードなら直ってるかなと見てみると今度はcomfigure.acのほうで
if test "x${want_debug}" = "xyes" ; then
   OPJ_COMPILER_FLAG([-g])
   OPJ_COMPILER_FLAG([-O0])
else
   OPJ_COMPILER_FLAG([-O3])
fi
あくまでも-O3は決定ですかそーですか...........むかつくわホント

追記:
gcc4.7ではOsに-foptimize-strlenも追加されたようです(O2は追加なし)。
ますますO2の存在意義って…?