/* * Avisynth interface for OverLua * Copyright 2007 Niels Martin Hansen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Contact: E-mail: IRC: jfs in #aegisub on irc.rizon.net */ // Must be included before , otherwise some macros from get in the way #include "image.h" #include #include #include #include "avisynth.h" #include "overlua.h" #include "vfr.h" // Lots of code lifted from the CSRI avisynth.cpp class OverLuaAvisynth : public GenericVideoFilter { private: OverLuaScript *script; double spf; // seconds per frame - for frame/timestamp conversion VFRTranslator *vfr; public: OverLuaAvisynth(PClip _child, IScriptEnvironment *env, const char *file, const char *datastring, const char *vfrfile) : GenericVideoFilter(_child) { switch (vi.pixel_type) { case VideoInfo::CS_BGR24: case VideoInfo::CS_BGR32: // safe break; default: env->ThrowError("OverLua: Unsupported pixel format, only RGB formats supported"); } try { script = new OverLuaScript(file, datastring); spf = (double)vi.fps_denominator / (double)vi.fps_numerator; if (vfrfile) vfr = GetVFRTranslator(vfrfile); else vfr = 0; } catch (const char *e) { env->ThrowError(e); } catch (...) { env->ThrowError("Unknown exception in OverLua"); } } ~OverLuaAvisynth() { if (vfr) delete vfr; delete script; } PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *env) { OutputDebugStringW(L"Entering OverLua GetFrame\n"); PVideoFrame avsframe = child->GetFrame(n, env); env->MakeWritable(&avsframe); double frametime = n * spf; if (vfr) frametime = vfr->TimeStampFromFrameNumber(n); ptrdiff_t stride = avsframe->GetPitch(); unsigned char *plane = avsframe->GetWritePtr(); plane += (vi.height - 1) * stride; stride = -stride; try { switch (vi.pixel_type) { case VideoInfo::CS_BGR24: { ImageBGR *frame = new ImageBGR(vi.width, vi.height, stride, plane); script->RenderFrameRGB(*frame, frametime); } break; case VideoInfo::CS_BGR32: { ImageBGRX *frame = new ImageBGRX(vi.width, vi.height, stride, plane); script->RenderFrameRGB(*frame, frametime); } break; } } catch (const char *e) { wchar_t *ew = new wchar_t[2048]; MultiByteToWideChar(CP_UTF8, 0, e, -1, ew, 2048); MessageBoxW(0, ew, L"OverLua execution error", MB_ICONERROR); delete[] ew; env->ThrowError(e); } catch (...) { MessageBoxW(0, L"Unknown error", L"OverLua execution error", MB_ICONERROR); env->ThrowError("OverLua: unknown execution error"); } OutputDebugStringW(L"Leaving OverLua GetFrame\n"); return avsframe; } static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env) { return new OverLuaAvisynth(args[0].AsClip(), env, args[1].AsString(), args[2].AsString(0), args[3].AsString(0)); } }; extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) { env->AddFunction("OverLua", "cs[data]s[vfr]s", OverLuaAvisynth::Create, 0); return "OverLua"; }