GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 86.1% 31 / 0 / 36
Functions: 81.8% 9 / 0 / 11
Branches: 68.4% 26 / 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 41 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 41 result.clear();
51 size_t current;
52 41 size_t next = (size_t)-1;
53 do {
54
1/2
✓ Branch 4 → 5 taken 109 times.
✗ Branch 4 → 9 not taken.
109 if (empties == split1::no_empties) {
55 109 next = s.find_first_not_of(delimiters, next + 1);
56
2/2
✓ Branch 6 → 7 taken 8 times.
✓ Branch 6 → 8 taken 101 times.
109 if (next == Container::value_type::npos) break;
57 101 next -= 1;
58 }
59 101 current = next + 1;
60 101 next = s.find_first_of(delimiters, current);
61
2/4
✓ Branch 10 → 11 taken 101 times.
✗ Branch 10 → 19 not taken.
✓ Branch 11 → 12 taken 101 times.
✗ Branch 11 → 17 not taken.
101 result.push_back(s.substr(current, next - current));
62
2/2
✓ Branch 13 → 14 taken 68 times.
✓ Branch 13 → 15 taken 33 times.
101 } while (next != Container::value_type::npos);
63 41 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 134 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 17 ExprOp(SOperation op, float val) : op(op), dx(0), dy(0) {
99 17 e.fval = val;
100 17 }
101 115 ExprOp(SOperation op, int32_t val = 0) : op(op), dx(0), dy(0) {
102 115 e.ival = val;
103 115 }
104 2 ExprOp(SOperation op, int32_t val, int dx, int dy) : op(op), dx(dx), dy(dy) {
105 2 e.ival = val;
106 2 }
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
7/12
✓ Branch 3 → 4 taken 390 times.
✗ Branch 3 → 15 not taken.
✓ Branch 5 → 3 taken 390 times.
✓ Branch 5 → 6 taken 15 times.
✓ Branch 9 → 7 taken 60 times.
✓ Branch 9 → 10 taken 15 times.
✓ Branch 13 → 11 taken 60 times.
✓ Branch 13 → 14 taken 15 times.
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 19 not taken.
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
525 ExprData() : clips(), vi(), proc() {}
147 #else
148 ExprData() : clips(), vi() {}
149 #endif
150
3/6
✓ Branch 6 → 7 taken 15 times.
✗ Branch 6 → 13 not taken.
✓ Branch 13 → 14 taken 15 times.
✗ Branch 13 → 20 not taken.
✓ Branch 20 → 21 taken 15 times.
✗ Branch 20 → 27 not taken.
555 ~ExprData() {
151 #ifdef VS_TARGET_CPU_X86
152
2/2
✓ Branch 5 → 3 taken 60 times.
✓ Branch 5 → 6 taken 15 times.
75 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 60 munmap((void *)proc[i], 0);
157 #endif
158 #endif
159
6/6
✓ Branch 8 → 9 taken 60 times.
✓ Branch 8 → 12 taken 15 times.
✓ Branch 15 → 16 taken 60 times.
✓ Branch 15 → 19 taken 15 times.
✓ Branch 22 → 23 taken 390 times.
✓ Branch 22 → 26 taken 15 times.
555 }
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 17 inline const VideoInfo& __stdcall GetVideoInfo() {
206 17 return vi;
207 }
208
209 inline bool __stdcall GetParity(int n) {
210 return children[0]->GetParity(n);
211 }
212
213 9 int __stdcall SetCacheHints(int cachehints, int frame_range) {
214 AVS_UNUSED(frame_range);
215
1/2
✓ Branch 2 → 3 taken 9 times.
✗ Branch 2 → 4 not taken.
9 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
216 }
217
218 };
219
220 #endif //__Exprfilter_h
221