#ifndef AVISYNTH_COMPAT_H
#define AVISYNTH_COMPAT_H
#include "avisynth.h"
#include "VapourSynth4.h"
#include "VSHelper4.h"
#include <map>
#include <set>
#include <vector>
#include <string>
#include <mutex>
namespace AvisynthCompat {
struct WrappedClip;
class FakeAvisynth : public IScriptEnvironment2 {
friend class VSClip;
friend class ::VideoFrame;
private:
VSCore *core;
std::set<std::string> savedStrings;
const VSAPI *vsapi;
std::map<VideoFrame *, const VSFrame *> ownedFrames;
int interfaceVersion;
std::string charToFilterArgumentString(char c);
std::mutex registerFunctionLock;
std::set<std::string> registeredFunctions;
public:
const VSFrame *avsToVSFrame(VideoFrame *frame);
bool initializing;
int uglyN;
VSNode *uglyNode;
VSFrameContext *uglyCtx;
FakeAvisynth(int interfaceVersion, VSCore *core, const VSAPI *vsapi) : core(core), vsapi(vsapi), interfaceVersion(interfaceVersion), initializing(true), uglyN(-1), uglyNode(nullptr), uglyCtx(nullptr) {}
AVSC_CC ~FakeAvisynth();
int __stdcall GetCPUFlags();
char* __stdcall SaveString(const char* s, int length = -1);
char* __stdcall Sprintf(const char* fmt, ...) ;
char* __stdcall VSprintf(const char* fmt, void* val);
__declspec(noreturn) void __stdcall ThrowError(const char* fmt, ...);
void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data);
bool __stdcall FunctionExists(const char* name);
AVSValue __stdcall Invoke(const char* name, const AVSValue args, const char* const* arg_names = 0);
AVSValue __stdcall GetVar(const char* name);
bool __stdcall SetVar(const char* name, const AVSValue& val);
bool __stdcall SetGlobalVar(const char* name, const AVSValue& val);
void __stdcall PushContext(int level = 0);
void __stdcall PopContext();
PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align = FRAME_ALIGN);
bool __stdcall MakeWritable(PVideoFrame* pvf);
void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height);
void __stdcall AtExit(ShutdownFunc function, void* user_data);
void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION);
PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height);
int __stdcall SetMemoryMax(int mem);
int __stdcall SetWorkingDir(const char * newdir);
void* __stdcall ManageCache(int key, void* data);
bool __stdcall PlanarChromaAlignment(PlanarChromaAlignmentMode key);
PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,
int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV);
void __stdcall DeleteScriptEnvironment();
void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,
int textcolor, int halocolor, int bgcolor);
const AVS_Linkage* const __stdcall GetAVSLinkage();
AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue());
size_t __stdcall GetProperty(AvsEnvProperty prop);
bool __stdcall GetVar(const char* name, AVSValue *val) const;
bool __stdcall GetVar(const char* name, bool def) const;
int __stdcall GetVar(const char* name, int def) const;
double __stdcall GetVar(const char* name, double def) const;
const char* __stdcall GetVar(const char* name, const char* def) const;
bool __stdcall LoadPlugin(const char* filePath, bool throwOnError, AVSValue *result);
void __stdcall AddAutoloadDir(const char* dirPath, bool toFront);
void __stdcall ClearAutoloadDirs();
void __stdcall AutoloadPlugins();
void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data, const char *exportVar);
bool __stdcall InternalFunctionExists(const char* name);
void __stdcall SetFilterMTMode(const char* filter, MtMode mode, bool force); IJobCompletion* __stdcall NewCompletion(size_t capacity);
void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion);
bool __stdcall Invoke(AVSValue *result, const char* name, const AVSValue& args, const char* const* arg_names = 0);
void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type);
void __stdcall Free(void* ptr);
using IScriptEnvironment::Invoke;
using IScriptEnvironment::AddFunction;
using IScriptEnvironment::GetVar;
PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,
int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA);
};
class VSClip : public IClip {
private:
VSNode *clip;
FakeAvisynth *fakeEnv;
const VSAPI *vsapi;
int numSlowWarnings;
VideoInfo vi;
public:
VSClip(VSNode *inclip, FakeAvisynth *fakeEnv, bool pack, const VSAPI *vsapi);
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *env);
bool __stdcall GetParity(int n) {
return true;
}
void __stdcall GetAudio(void *buf, int64_t start, int64_t count, IScriptEnvironment *env) {}
int __stdcall SetCacheHints(int cachehints, int frame_range) {
return 0;
}
VSNode *GetVSNode() const {
return clip;
}
const VideoInfo &__stdcall GetVideoInfo() {
return vi;
}
virtual AVSC_CC ~VSClip() {
vsapi->freeNode(clip);
}
};
struct PrefetchInfo {
int div;
int mul;
int from;
int to;
PrefetchInfo(int div, int mul, int from, int to) : div(div), mul(mul), from(from), to(to) { }
};
struct WrappedClip {
std::string filterName;
PrefetchInfo prefetchInfo;
std::vector<VSNode *> preFetchClips;
PClip clip;
FakeAvisynth *fakeEnv;
WrappedClip(const std::string &filterName, const PClip &clip, const std::vector<VSNode *> &preFetchClips, const PrefetchInfo &prefetchInfo, FakeAvisynth *fakeEnv);
~WrappedClip() {
clip = nullptr;
delete fakeEnv;
}
};
struct AvisynthArgs {
std::string name;
short type;
bool required;
AvisynthArgs(const std::string &name, short type, bool required) : name(name), type(type), required(required) {}
};
struct WrappedFunction {
std::string name;
FakeAvisynth::ApplyFunc apply;
std::vector<AvisynthArgs> parsedArgs;
void *avsUserData;
int interfaceVersion;
WrappedFunction(const std::string &name, FakeAvisynth::ApplyFunc apply, const std::vector<AvisynthArgs> &parsedArgs, void *avsUserData, int interfaceVersion);
};
}
#endif