GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 71.4% 10 / 0 / 14
Functions: 57.1% 4 / 0 / 7
Branches: -% 0 / 0 / 0

core/InternalEnvironment.h
Line Branch Exec Source
1 #ifndef _AVS_SCRIPTENVIRONMENT_H_INCLUDED
2 #define _AVS_SCRIPTENVIRONMENT_H_INCLUDED
3
4 #include <avisynth.h>
5 #include <algorithm>
6 #include <string>
7 #include <memory>
8 #include "function.h"
9 #include "CompatEnvironment.h"
10
11 class ClipDataStore;
12
13 typedef enum _ELogLevel
14 {
15 LOGLEVEL_NONE = 0,
16 LOGLEVEL_ERROR = 1,
17 LOGLEVEL_WARNING = 2,
18 LOGLEVEL_INFO = 3,
19 LOGLEVEL_DEBUG = 4
20 } ELogLevel;
21
22 typedef enum _ELogTicketType
23 {
24 LOGTICKET_W1000 = 1000, // leaks during shutdown
25 LOGTICKET_W1001 = 1001, // source plugin with no mt-mode
26 LOGTICKET_W1002 = 1002, // buggy SetCacheHints()
27 LOGTICKET_W1003 = 1003, // too stringent memory limit
28 LOGTICKET_W1004 = 1004, // filter completely without mt-mode
29 LOGTICKET_W1005 = 1005, // filter with inconsequent MT-modes
30 LOGTICKET_W1006 = 1006, // filter with redundant MT-modes
31 LOGTICKET_W1007 = 1007, // user should try 64-bit AVS for more memory
32 LOGTICKET_W1008 = 1008, // multiple plugins define the same function
33 LOGTICKET_W1009 = 1009, // a filter is using forced alignment
34 LOGTICKET_W1010 = 1010, // MT-mode specified for script function
35 LOGTICKET_W1100 = 1100, // memory reallocation occurs
36 } ELogTicketType;
37
38 enum CacheMode {
39 CACHE_FAST_START, // start up time and size balanced mode
40 CACHE_OPTIMAL_SIZE, // slow start up but optimal speed and cache size
41 CACHE_NO_RESIZE, // internal use only
42
43 CACHE_DEFAULT = CACHE_FAST_START,
44 };
45
46 enum DeviceOpt: int {
47 DEV_CUDA_PINNED_HOST, // allocate CPU frame with CUDA pinned host memory
48 DEV_FREE_THRESHOLD, // free request count threshold to free frame
49 };
50
51 class OneTimeLogTicket
52 {
53 public:
54 ELogTicketType _type;
55 const Function *_function = nullptr;
56 const std::string _string;
57
58 OneTimeLogTicket(ELogTicketType type);
59 OneTimeLogTicket(ELogTicketType type, const Function *func);
60 OneTimeLogTicket(ELogTicketType type, const std::string &str);
61 bool operator==(const OneTimeLogTicket &other) const;
62 };
63
64 class Device;
65 class ThreadPool;
66 class ConcurrentVarStringFrame;
67 class FilterGraphNode;
68
69 class ScopedCounter {
70 int& counter;
71 public:
72 12 ScopedCounter(int& counter) : counter(counter) {
73 12 ++counter;
74 12 }
75 12 ~ScopedCounter() {
76 12 --counter;
77 12 }
78 };
79
80 #ifdef ALTERNATIVE_VFB_TIMESTAMP
81 class VideoFrameBuffer;
82
83 // Forward declarations - don't expose full classes
84 class ScriptEnvironment;
85
86 namespace VFBHelper {
87 // Wrapper function to call the nested static method
88 void UpdateVFBFreeTimestamp(VideoFrameBuffer* vfb);
89 }
90 #endif
91
92 // Interface transformation hack
93 class InternalEnvironment; // forward
94 InternalEnvironment* GetAndRevealCamouflagedEnv(IScriptEnvironment* env);
95
96 // Strictly for Avisynth core only.
97 // Neither host applications nor plugins should use
98 // these interfaces.
99 class InternalEnvironment :
100 public IScriptEnvironment2,
101 public IScriptEnvironment_Avs25,
102 public IScriptEnvironment_AvsPreV11C,
103 public INeoEnv {
104 protected:
105 2251 virtual ~InternalEnvironment() {}
106 public:
107 // define commons to fix ambiguous error
108
109 typedef IScriptEnvironment::NotFound NotFound;
110 typedef IScriptEnvironment::ApplyFunc ApplyFunc;
111
112 // IScriptEnvironment
113 virtual int __stdcall GetCPUFlags() = 0;
114 virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;
115 virtual char* Sprintf(const char* fmt, ...) = 0;
116 virtual char* __stdcall VSprintf(const char* fmt, va_list val) = 0;
117 __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) = 0;
118 virtual void __stdcall AddFunction(const char* name, const char* params, INeoEnv::ApplyFunc apply, void* user_data) = 0;
119 virtual bool __stdcall FunctionExists(const char* name) = 0;
120 virtual AVSValue __stdcall Invoke(const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;
121 virtual AVSValue __stdcall GetVar(const char* name) = 0;
122 virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;
123 virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;
124 virtual void __stdcall PushContext(int level = 0) = 0;
125 virtual void __stdcall PopContext() = 0;
126 // NewVideoFrame is replaced with new one
127 virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;
128 virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;
129 virtual void __stdcall AtExit(INeoEnv::ShutdownFunc function, void* user_data) = 0;
130 virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;
131 virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;
132 virtual int __stdcall SetMemoryMax(int mem) = 0;
133 virtual int __stdcall SetWorkingDir(const char * newdir) = 0;
134 virtual void* __stdcall ManageCache(int key, void* data) = 0;
135 virtual bool __stdcall PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key) = 0;
136 virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,
137 int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;
138 // AVISYNTH_INTERFACE_VERSION 5
139 virtual void __stdcall DeleteScriptEnvironment() = 0;
140 virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,
141 int textcolor, int halocolor, int bgcolor) = 0;
142 virtual const AVS_Linkage* __stdcall GetAVSLinkage() = 0;
143
144 // AVISYNTH_INTERFACE_VERSION 6
145 virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) = 0;
146
147 // AVISYNTH_INTERFACE_VERSION 8
148 virtual PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,
149 int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA) = 0;
150
151 // frame properties support
152 virtual void __stdcall copyFrameProps(const PVideoFrame& src, PVideoFrame& dst) = 0;
153
154 virtual const AVSMap* __stdcall getFramePropsRO(const PVideoFrame& frame) = 0;
155 virtual AVSMap* __stdcall getFramePropsRW(PVideoFrame &frame) = 0;
156
157 virtual int __stdcall propNumKeys(const AVSMap* map) = 0;
158 virtual const char* __stdcall propGetKey(const AVSMap* map, int index) = 0;
159 virtual int __stdcall propDeleteKey(AVSMap* map, const char* key) = 0;
160 virtual int __stdcall propNumElements(const AVSMap* map, const char* key) = 0;
161 virtual char __stdcall propGetType(const AVSMap* map, const char* key) = 0;
162
163 virtual int64_t __stdcall propGetInt(const AVSMap* map, const char* key, int index, int* error) = 0;
164 virtual double __stdcall propGetFloat(const AVSMap* map, const char* key, int index, int* error) = 0;
165 virtual const char* __stdcall propGetData(const AVSMap* map, const char* key, int index, int* error) = 0;
166 virtual int __stdcall propGetDataSize(const AVSMap* map, const char* key, int index, int* error) = 0;
167 virtual PClip __stdcall propGetClip(const AVSMap* map, const char* key, int index, int* error) = 0;
168 virtual const PVideoFrame __stdcall propGetFrame(const AVSMap* map, const char* key, int index, int* error) = 0;
169 virtual int __stdcall propSetInt(AVSMap* map, const char* key, int64_t i, int append) = 0;
170 virtual int __stdcall propSetFloat(AVSMap* map, const char* key, double d, int append) = 0;
171 virtual int __stdcall propSetData(AVSMap* map, const char* key, const char* d, int length, int append) = 0;
172 virtual int __stdcall propSetClip(AVSMap* map, const char* key, PClip& clip, int append) = 0;
173 virtual int __stdcall propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append) = 0;
174
175 virtual const int64_t* __stdcall propGetIntArray(const AVSMap* map, const char* key, int* error) = 0;
176 virtual const double* __stdcall propGetFloatArray(const AVSMap* map, const char* key, int* error) = 0;
177 virtual int __stdcall propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) = 0;
178 virtual int __stdcall propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) = 0;
179
180 virtual AVSMap* __stdcall createMap() = 0;
181 virtual void __stdcall freeMap(AVSMap* map) = 0;
182 virtual void __stdcall clearMap(AVSMap* map) = 0;
183
184 // NewVideoFrame with frame prop source is replaced with new one
185
186 virtual size_t __stdcall GetEnvProperty(AvsEnvProperty prop) = 0;
187 virtual void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type) = 0;
188 virtual void __stdcall Free(void* ptr) = 0;
189
190 // Returns TRUE and the requested variable. If the method fails, returns FALSE and does not touch 'val'.
191 virtual bool __stdcall GetVarTry(const char* name, AVSValue* val) const = 0; // ex virtual bool __stdcall GetVar(const char* name, AVSValue* val) const = 0;
192 virtual bool __stdcall GetVarBool(const char* name, bool def) const = 0; // ex: virtual bool __stdcall GetVar(const char* name, bool def) const = 0;
193 virtual int __stdcall GetVarInt(const char* name, int def) const = 0; // ex: int __stdcall GetVar(const char* name, int def) const = 0;
194 virtual double __stdcall GetVarDouble(const char* name, double def) const = 0; // ex: virtual double __stdcall GetVar(const char* name, double def) const = 0;
195 virtual const char* __stdcall GetVarString(const char* name, const char* def) const = 0; // ex: virtual const char* __stdcall GetVar(const char* name, const char* def) const = 0;
196 virtual int64_t __stdcall GetVarLong(const char* name, int64_t def) const = 0; // brand new in v8 - v11: real int64 support
197
198 // Invoke functions renamed for keeping vtable order in IS
199 // moved from IS2
200 virtual bool __stdcall InvokeTry(AVSValue* result, const char* name, const AVSValue& args, const char* const* arg_names = 0) = 0;
201 // Since V8
202 virtual AVSValue __stdcall Invoke2(const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;
203 // moved from INeo
204 virtual bool __stdcall Invoke2Try(AVSValue* result, const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;
205 virtual AVSValue __stdcall Invoke3(const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;
206 virtual bool __stdcall Invoke3Try(AVSValue* result, const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;
207
208 // V9
209 virtual bool __stdcall MakePropertyWritable(PVideoFrame* pvf) = 0;
210
211 // V11
212 virtual int __stdcall propGetIntSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;
213 virtual float __stdcall propGetFloatSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;
214 virtual int __stdcall propGetDataTypeHint(const AVSMap* map, const char* key, int index, int* error) = 0; /* returns AVSPropDataTypeHint */
215 virtual int __stdcall propSetDataH(AVSMap* map, const char* key, const char* d, int length, int type, int append) = 0;
216
217 // V12
218 virtual bool __stdcall AcquireGlobalLock(const char* name) = 0;
219 virtual void __stdcall ReleaseGlobalLock(const char* name) = 0;
220 virtual void __stdcall ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,
221 int textcolor, int halocolor, int bgcolor, bool utf8) = 0;
222 virtual int64_t __stdcall GetCPUFlagsEx() = 0;
223
224 // IScriptEnvironment2
225 virtual bool __stdcall LoadPlugin(const char* filePath, bool throwOnError, AVSValue *result) = 0;
226 virtual void __stdcall AddAutoloadDir(const char* dirPath, bool toFront) = 0;
227 virtual void __stdcall ClearAutoloadDirs() = 0;
228 virtual void __stdcall AutoloadPlugins() = 0;
229 virtual void __stdcall AddFunction(const char* name, const char* params, INeoEnv::ApplyFunc apply, void* user_data, const char *exportVar) = 0;
230 virtual bool __stdcall InternalFunctionExists(const char* name) = 0;
231 virtual void __stdcall SetFilterMTMode(const char* filter, MtMode mode, bool force) = 0;
232 virtual IJobCompletion* __stdcall NewCompletion(size_t capacity) = 0;
233 virtual void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion) = 0;
234
235 // InternalEnvironment
236 virtual char *__stdcall ListAutoloadDirs() = 0;
237 virtual int __stdcall IncrImportDepth() = 0;
238 virtual int __stdcall DecrImportDepth() = 0;
239 virtual void __stdcall AdjustMemoryConsumption(size_t amount, bool minus) = 0;
240 virtual bool __stdcall FilterHasMtMode(const Function* filter) const = 0;
241 virtual MtMode __stdcall GetFilterMTMode(const Function* filter, bool* is_forced) const = 0; // If filter is "", gets the default MT mode
242 virtual ClipDataStore* __stdcall ClipData(IClip *clip) = 0;
243 virtual MtMode __stdcall GetDefaultMtMode() const = 0;
244 virtual void __stdcall SetLogParams(const char *target, int level) = 0;
245 virtual void LogMsg(int level, const char* fmt, ...) = 0;
246 virtual void __stdcall LogMsg_valist(int level, const char* fmt, va_list va) = 0;
247 virtual void LogMsgOnce(const OneTimeLogTicket &ticket, int level, const char* fmt, ...) = 0;
248 virtual void __stdcall LogMsgOnce_valist(const OneTimeLogTicket &ticket, int level, const char* fmt, va_list va) = 0;
249 virtual void __stdcall VThrowError(const char* fmt, va_list va) = 0;
250 virtual void __stdcall SetMaxCPU(const char *feature) = 0;
251 virtual void __stdcall SetFilterProp(const char* filter, const char* key, const AVSValue& value, int mode) = 0;
252 virtual void __stdcall SetFilterPropConditional(const char* filter, const char* param_name, const AVSValue& param_match,
253 const char* key, const AVSValue& value, int mode) = 0;
254 virtual const char* __stdcall GetFilterProps() = 0;
255 virtual void __stdcall SetFilterPropPassthrough(const char* filter) = 0;
256
257 /*
258 How casting down works in Avisynth, when passing differently typed
259 IScriptEnvironment variant pointers to plugins.
260
261 We have one big InternalEnvironment (further inherited by ThreadScriptEnvironment).
262 InternalEnvironment inherits all IScriptEnvironment variants, which have strictly
263 identical function order of their pure virtual functions.
264
265 When we pass an IScriptEnvironment variant to a plugin/client (who is just seeing
266 Avisynth's standard IScriptEnvironment), then really we pass the proper VMT table.
267
268 Let's see an example for IScriptEnvironment_Avs25.
269
270 For the static_cast to work correctly, the IScriptEnvironment_Avs25 interface must
271 have the same order of methods as they appear in the InternalEnvironment class.
272 This ensures that the VMT entries align properly, allowing the cast pointer to
273 correctly access the methods defined in IScriptEnvironment_Avs25.
274
275 In C++, the order of methods in the VMT is determined by the order in which they are
276 declared in the class or interface.
277 Therefore, as long as IScriptEnvironment_Avs25 is a base class of InternalEnvironment
278 and the methods are declared in the same order, the static_cast will work as expected.
279
280 When we cast a Derived* to a Base*, e.g. InternalEnvironment* to IScriptEnvironment2*,
281 the pointer might be adjusted to point to the Base sub-object within Derived.
282 This ensures that the VMT entries for Base methods are correctly aligned.
283
284 If we have multiple base classes with the same pure virtual function names
285 (NewVideoFrame, MakeWritable, etc..), and the derived class (InternalEnvironment)
286 provides the implementation, the VMT entries for all those base classes will point
287 to the same implementation in the derived class.
288
289 The implemented pure virtual function addresses will be written back to all
290 IScriptEnvironmentXXXXX variant's VMT entries. So the same NewVideoFrame address
291 will appear in IScriptEnvironment2 and IScriptEnvironment_Avs25 VMT table.
292
293 Trick:
294 There are differences, that must handle differently for different IScriptEnvironment types.
295 E.g. IScriptEnvironment_Avs25 implements its own AddFunction. Place of AddFunction in VMT table
296 is fixed (VMT index N). In the class definition we use the name AddFunction25 instead
297 of AddFunction. It will appear at VMT index N in IScriptEnvironment_Avs25, since the
298 order is kept similar to IScriptEnvironment's order.
299 Because if was named differently, InternalEnvironment's implementation
300 will put a different address into IScriptEnvironment_Avs25's VMT table.
301 When this pointer is passed to a plugin, (which sees only an IScriptEnvironment*)
302 when it calles AddFunction (that is VMT index N), it hiddenly will call AddFunction25 instead.
303 */
304
305 // interface conversions
306 virtual IScriptEnvironment2* __stdcall GetEnv2() final { return static_cast<IScriptEnvironment2*>(this); }
307 virtual IScriptEnvironment_Avs25* __stdcall GetEnv25() final { return static_cast<IScriptEnvironment_Avs25*>(this); }
308 virtual IScriptEnvironment_AvsPreV11C* __stdcall GetEnvPreV11C() final { return static_cast<IScriptEnvironment_AvsPreV11C*>(this); }
309
310 virtual void __stdcall SetGraphAnalysis(bool enable) = 0;
311
312 virtual Device* __stdcall SetCurrentDevice(Device* device) = 0;
313 virtual Device* __stdcall GetCurrentDevice() const = 0;
314 // replacement of NewVideoFrame
315 virtual PVideoFrame __stdcall NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device) = 0;
316 virtual PVideoFrame __stdcall NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device, const PVideoFrame *prop_src) = 0;
317 virtual PVideoFrame __stdcall GetOnDeviceFrame(const PVideoFrame& src, Device* device) = 0;
318
319 using INeoEnv::SetMemoryMax;
320 using INeoEnv::Invoke;
321 using INeoEnv::NewVideoFrame;
322 using INeoEnv::SaveString;
323
324 // Nekopanda: support multiple prefetcher //
325 // to allow thread to submit with their env
326 virtual void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion, InternalEnvironment *env) = 0;
327 virtual ThreadPool* __stdcall NewThreadPool(size_t nThreads) = 0;
328 virtual void __stdcall AddRef() = 0;
329 virtual void __stdcall Release() = 0;
330
331 virtual ConcurrentVarStringFrame* __stdcall GetTopFrame() = 0;
332
333 // Nekopanda: new cache control mechanism
334 virtual void __stdcall SetCacheMode(CacheMode mode) = 0;
335 virtual CacheMode __stdcall GetCacheMode() = 0;
336 virtual bool& __stdcall GetSupressCaching() = 0;
337
338 // useful to detect chainedCtor
339 virtual size_t __stdcall GetInvokeStackSize() = 0;
340
341 virtual void __stdcall SetDeviceOpt(DeviceOpt mode, int val) = 0;
342
343 virtual void __stdcall UpdateFunctionExports(const char* funcName, const char* funcParams, const char *exportVar) = 0;
344 virtual bool __stdcall Invoke_(AVSValue *result, const AVSValue& implicit_last,
345 const char* name, const Function *f, const AVSValue& args, const char* const* arg_names) = 0;
346
347 virtual InternalEnvironment* __stdcall NewThreadScriptEnvironment(int thread_id) = 0;
348
349 // per thread data access
350 virtual int __stdcall GetThreadId() = 0;
351 virtual int& __stdcall GetFrameRecursiveCount() = 0;
352 virtual int& __stdcall GetSuppressThreadCount() = 0;
353 virtual FilterGraphNode*& GetCurrentGraphNode() = 0;
354 };
355
356 struct InternalEnvironmentDeleter {
357 1809 void operator()(InternalEnvironment* ptr) const {
358 1809 ptr->Release();
359 1760 }
360 };
361 typedef std::unique_ptr<InternalEnvironment, InternalEnvironmentDeleter> PInternalEnvironment;
362
363 #endif // _AVS_SCRIPTENVIRONMENT_H_INCLUDED
364