GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 36
Functions: 0.0% 0 / 0 / 11
Branches: 0.0% 0 / 0 / 38

filters/exprfilter/exprfilter.h
Line Branch Exec Source
1 #ifndef __Exprfilter_h
2 #define __Exprfilter_h
3
4 #include <avisynth.h>
5 #include <mutex>
6 #ifdef AVS_POSIX
7 #include <sys/mman.h>
8 #endif
9
10 #define MAX_C_VECT 16 // C Expr part: 16*float has still have benefit, less interpreter overhead.
11
12 #define MAX_EXPR_INPUTS 26
13 #define INTERNAL_VARIABLES 6
14 #define MAX_FRAMEPROP_VARIABLES 64
15 #define MAX_USER_VARIABLES 128
16
17 // indexing RWPTR array (pointer sized elements)
18 #define RWPTR_START_OF_OUTPUT 0 // 1
19 #define RWPTR_START_OF_XCOUNTER 1 // 1
20 #define RWPTR_START_OF_INPUTS 2 // count = 26
21 #define RWPTR_START_OF_PADDING 4 // padding to have 32 pointers (rfu for 8 ptr/cycle ymm simd)
22 #define RWPTR_START_OF_STRIDES 32 // count = 26 for relative_y
23 #define RWPTR_START_OF_INTERNAL_VARIABLES 58 // count = 6
24
25 // special frame-by-frame variables (incl. frame properties) occupy only float size
26 #define INTERNAL_VAR_CURRENT_FRAME 0
27 #define INTERNAL_VAR_RELTIME 1
28 #define INTERNAL_VAR_RFU2 2
29 #define INTERNAL_VAR_RFU3 3
30 #define INTERNAL_VAR_RFU4 4
31 #define INTERNAL_VAR_RFU5 5
32 #define INTERNAL_VAR_FRAMEPROP_VARIABLES_START 6
33 #define RWPTR_START_OF_INTERNAL_FRAMEPROP_VARIABLES (RWPTR_START_OF_INTERNAL_VARIABLES + INTERNAL_VAR_FRAMEPROP_VARIABLES_START) // count = 256
34
35 // pad to 32 bytes boundary in x86: 64 * sizeof(pointer) is 32 byte aligned
36 #define RWPTR_START_OF_USERVARIABLES (RWPTR_START_OF_INTERNAL_FRAMEPROP_VARIABLES + MAX_FRAMEPROP_VARIABLES) // count = max.256 (for 2*ymm sized variables)
37 #define RWPTR_SIZE (RWPTR_START_OF_USERVARIABLES + MAX_USER_VARIABLES * (2*32 / sizeof(void *)))
38
39 struct split1 {
40 enum empties_t { empties_ok, no_empties };
41 };
42
43 template <typename Container>
44 Container& split(
45 Container& result,
46 const typename Container::value_type& s,
47 const typename Container::value_type& delimiters,
48 split1::empties_t empties = split1::empties_ok)
49 {
50 result.clear();
51 size_t current;
52 size_t next = (size_t)-1;
53 do {
54 if (empties == split1::no_empties) {
55 next = s.find_first_not_of(delimiters, next + 1);
56 if (next == Container::value_type::npos) break;
57 next -= 1;
58 }
59 current = next + 1;
60 next = s.find_first_of(delimiters, current);
61 result.push_back(s.substr(current, next - current));
62 } while (next != Container::value_type::npos);
63 return result;
64 }
65
66 typedef enum {
67 opLoadSrc8, opLoadSrc16, opLoadSrcF32, opLoadSrcF16,
68 opLoadRelSrc8, opLoadRelSrc16, opLoadRelSrcF32,
69 opLoadConst,
70 opLoadSpatialX, opLoadSpatialY,
71 opLoadInternalVar,
72 opStore8, opStore10, opStore12, opStore14, opStore16, opStoreF32, opStoreF16, // avs+: 10,12,14 bit store
73 opDup, opSwap,
74 opAdd, opSub, opMul, opDiv, opMax, opMin, opSqrt, opAbs, opSgn,
75 opFmod,
76 opGt, opLt, opEq, opNotEq, opLE, opGE, opTernary,
77 opAnd, opOr, opXor, opNeg, opNegSign,
78 opExp, opLog, opPow,
79 opSin, opCos, opTan, opAsin, opAcos, opAtan, opAtan2,
80 opClip, opRound, opFloor, opCeil, opTrunc,
81 opStoreVar, opLoadVar, opLoadFramePropVar, opStoreVarAndDrop1
82 } SOperation;
83
84 union ExprUnion {
85 float fval;
86 int32_t ival;
87 uint32_t uval;
88 constexpr ExprUnion() : uval{} {}
89 constexpr ExprUnion(int32_t _i) : ival(_i) {}
90 constexpr ExprUnion(uint32_t _u) : uval(_u) {}
91 constexpr ExprUnion(float _f) : fval(_f) {}
92 } ;
93
94 struct ExprOp {
95 ExprUnion e;
96 uint32_t op;
97 int dx, dy;
98 ExprOp(SOperation op, float val) : op(op), dx(0), dy(0) {
99 e.fval = val;
100 }
101 ExprOp(SOperation op, int32_t val = 0) : op(op), dx(0), dy(0) {
102 e.ival = val;
103 }
104 ExprOp(SOperation op, int32_t val, int dx, int dy) : op(op), dx(dx), dy(dy) {
105 e.ival = val;
106 }
107 };
108
109 struct ExprFramePropData {
110 int srcIndex;
111 std::string name;
112 int var_index;
113 float value;
114 };
115
116 enum PlaneOp {
117 poProcess, poCopy, poUndefined, poFill
118 };
119
120 struct ExprData {
121 #ifdef __VAPOURSYNTH__
122 VSNodeRef *node[MAX_EXPR_INPUTS];
123 VSVideoInfo vi;
124 #else
125 PClip clips[MAX_EXPR_INPUTS];
126 VideoInfo vi;
127 #endif
128 bool clipsUsed[MAX_EXPR_INPUTS]; // not doing GetFrame unreferenced input clips
129 std::vector<ExprOp> ops[4]; // 4th: alpha
130 std::vector<ExprFramePropData> frameprops[4];
131 int plane[4];
132 float planeFillValue[4]; // optimize: fill plane with const
133 int planeCopySourceClip[4]; // optimize: copy plane from which clip
134 bool planeOptAvx2[4]; // instruction set constraints
135 bool planeOptSSE2[4];
136
137 int lutmode; // 0: no, 1:1D (lutx), 2:2D (lutxy)
138 uint8_t* luts[4]; // different lut tables, reusable by multiple planes
139 // int planeLutIndex[4]; // which luts is used by the plane. todo: when luts are the same for different planes
140
141 size_t maxStackSize;
142 int numInputs;
143 #ifdef VS_TARGET_CPU_X86
144 typedef void(*ProcessLineProc)(void *rwptrs, intptr_t ptroff[RWPTR_SIZE], intptr_t niter, uint32_t spatialY);
145 ProcessLineProc proc[4]; // 4th: alpha
146 ExprData() : clips(), vi(), proc() {}
147 #else
148 ExprData() : clips(), vi() {}
149 #endif
150 ~ExprData() {
151 #ifdef VS_TARGET_CPU_X86
152 for (int i = 0; i < 4; i++) // 4th: alpha
153 #ifdef VS_TARGET_OS_WINDOWS
154 VirtualFree((LPVOID)proc[i], 0, MEM_RELEASE);
155 #else
156 munmap((void *)proc[i], 0);
157 #endif
158 #endif
159 }
160 };
161
162 class Exprfilter : public IClip
163 /**
164 *
165 **/
166 {
167 private:
168 std::vector<PClip> children;
169 std::vector<std::string> expressions;
170 VideoInfo vi;
171 ExprData d;
172 const bool optAvx2; // disable avx2 path
173 const bool optSingleMode; // generate asm code using only one XMM/YMM register set instead of two
174 const bool optSSE2; // disable simd path
175 const bool optVectorC; // if non-SIMD C path, then this goes to a vectorization friendly implementation
176
177 // scale_inputs related settings
178 const std::string scale_inputs;
179 bool autoconv_full_scale;
180 bool autoconv_conv_int;
181 bool autoconv_conv_float;
182 const int clamp_float_i;
183 int lutmode;
184
185 // special internal flag since v2.2.20: set when scale_inputs is "floatUV"
186 // like in masktools 2.2.20+, preshifts chroma -0.5..+0.5 to 0..1.0 range and then shifts the result back.
187 bool shift_float;
188
189 void preReadFrameProps(int plane, std::vector<PVideoFrame>& src, IScriptEnvironment* env);
190 void calculate_lut(IScriptEnvironment *env);
191 public:
192 Exprfilter(const std::vector<PClip>& _child_array, const std::vector<std::string>& _expr_array, const char *_newformat, const bool _optAvx2,
193 const bool _optSingleMode2, const bool _optSSE2, const bool _optVectorC, const std::string _scale_inputs, const int _clamp_float, const int _lutmode, IScriptEnvironment *env);
194 void processFrame(int plane, int w, int h, int pixels_per_iter, float framecount, float relative_time, int numInputs,
195 uint8_t*& dstp, int dst_stride,
196 std::vector<const uint8_t*>& srcp, std::vector<int>& src_stride, std::vector<intptr_t>& ptroffsets, std::vector<const uint8_t*>& srcp_orig);
197 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *env);
198 ~Exprfilter();
199 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
200
201 inline void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {
202 children[0]->GetAudio(buf, start, count, env);
203 }
204
205 inline const VideoInfo& __stdcall GetVideoInfo() {
206 return vi;
207 }
208
209 inline bool __stdcall GetParity(int n) {
210 return children[0]->GetParity(n);
211 }
212
213 int __stdcall SetCacheHints(int cachehints, int frame_range) {
214 AVS_UNUSED(frame_range);
215 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
216 }
217
218 };
219
220 #endif //__Exprfilter_h
221