mirror of https://github.com/odrling/Aegisub
139 lines
3.7 KiB
C++
139 lines
3.7 KiB
C++
/*
|
|
* 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: <jiifurusu@gmail.com>
|
|
IRC: jfs in #aegisub on irc.rizon.net
|
|
|
|
*/
|
|
|
|
// Must be included before <windows.h>, otherwise some macros from <windows.h> get in the way
|
|
#include "video_frame.h"
|
|
|
|
#include <windows.h>
|
|
#include <string.h>
|
|
#include <memory.h>
|
|
|
|
#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";
|
|
}
|
|
|