2013年7月3日水曜日

AviSynth2.6用プラグインの書き方

AviSynthプラグインを書く場合、各プラグインは必ず#include "avisynth.h"しなければならないわけですが、このavisynth.hが2.6でこれまでのものに比べて大きく変更されました。

2.5xまでのavisynth.hは
...
  bool HasVideo() const { return (width!=0); }
  bool HasAudio() const { return (audio_samples_per_second!=0); }
  bool IsRGB() const { return !!(pixel_type&CS_BGR); }
  bool IsRGB24() const { return (pixel_type&CS_BGR24)==CS_BGR24; } // Clear out additional
...
の様な感じで、helper系の関数はヘッダーに実体が書かれているというなんとも自由奔放で微妙なものでした。
さすがにこれはかっこ悪すぎるだろってことで2.6からはこれらの関数はavisynth.dllの内部に用意されるようになったわけですが、これにともなって新しいavisynth.hを使用したプラグインは2.6以降でしか使えなくなりました。

まあ、2.6でも2.5用のプラグインは特に問題なく使えますし、新しいものを古いavisynthで使うのはナンセンスです。
そもそもsource forgeで配布されている公式バイナリは、かの悪名高きVC++6でビルドされているため、XPどころかPentium2なWindows2000でも動きます。
みんながIanB氏に「いい加減コンパイラ新しくしてよ」と言っても頑なに古いものにこだわり続けているのです(そういえばAviUtlもVC++6だっけ?)。
まだ2.5xを使っている人は早急に2.6に変えましょう。

さて、2.6用avisynth.hを使う場合のプラグインの書き方ですが、以下のようになります。

・AVS_Linkage構造体
これまでavisynth.hに実体が書かれていた(つまり各プラグイン毎にコンパイルされていた)関数群がavisynth.dll内にAVS_Linkage構造体としてまとめられ、各プラグインはLoadPlugin()する際にこれのポインタを受け取るように変更されました。これに伴いinitializerもこれまでのAvisynthPluginInit2からAvisynthPluginInit3に変更されています。
で、avisynth.hには以下のように記述されていますので
extern const AVS_Linkage* AVS_linkage;
よってPlugin.cppはこう書きます。
...
const AVS_Linkage* AVS_linkage = 0;
...
extern "C" __declspec(dllexport) const char* __stdcall
AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors)
{
    AVS_linkage = vectors;
    env->AddFunction("FunctionName", "arguments string", create_filter_function, user_data);
    return "some string";
}
avisynth.dllが各プラグインのinitializerを呼び出す際にAVS_Linkageのポインタを渡してくるので、それを保持するための変数を"AVS_linkage"という名前で静的領域に用意するだけです。
あとは今までと何も変わりません。

0 件のコメント:

コメントを投稿