GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 39.6% 55 / 0 / 139
Functions: 57.1% 12 / 0 / 21
Branches: 12.9% 32 / 0 / 248

filters/debug.cpp
Line Branch Exec Source
1 // Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al.
2 // http://avisynth.nl
3
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
17 // http://www.gnu.org/copyleft/gpl.html .
18 //
19 // Linking Avisynth statically or dynamically with other modules is making a
20 // combined work based on Avisynth. Thus, the terms and conditions of the GNU
21 // General Public License cover the whole combination.
22 //
23 // As a special exception, the copyright holders of Avisynth give you
24 // permission to link Avisynth with independent modules that communicate with
25 // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
26 // terms of these independent modules, and to copy and distribute the
27 // resulting combined work under terms of your choice, provided that
28 // every copy of the combined work is accompanied by a complete copy of
29 // the source code of Avisynth (the version of Avisynth used to produce the
30 // combined work), being distributed under the terms of the GNU General
31 // Public License plus this exception. An independent module is a module
32 // which is not derived from or based on Avisynth, such as 3rd-party filters,
33 // import and export plugins, or graphical user interfaces.
34
35
36 #include "debug.h"
37
38 #ifdef AVS_WINDOWS
39 #include <avs/win.h>
40 #else
41 #include <avs/posix.h>
42 #endif
43
44 #include "../core/bitblt.h"
45 #include "../core/internal.h"
46
47
48
49 /**********************************************
50 ******* PlanarLegacyAlignment Filter *******
51 ******* for pitch challenged plugins *******
52 **********************************************/
53
54 class PlanarLegacyAlignment : public GenericVideoFilter
55 {
56 private:
57 const IScriptEnvironment::PlanarChromaAlignmentMode mode;
58
59 public:
60 1 PlanarLegacyAlignment( PClip _child, const bool _mode, IScriptEnvironment* env )
61 1 : GenericVideoFilter(_child),
62 1 mode(_mode ? IScriptEnvironment::PlanarChromaAlignmentOff // Legacy PLANAR_Y alignment
63
3/6
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 11 not taken.
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 9 not taken.
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 7 not taken.
1 : IScriptEnvironment::PlanarChromaAlignmentOn) // New PLANAR_UV priority alignment
64 {
65 AVS_UNUSED(env);
66 1 }
67
68 1 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env)
69 {
70 const IScriptEnvironment::PlanarChromaAlignmentMode
71 1 oldmode = env->PlanarChromaAlignment(mode) // Set the PLANAR alignement mode
72
1/2
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 5 not taken.
1 ? IScriptEnvironment::PlanarChromaAlignmentOn
73 1 : IScriptEnvironment::PlanarChromaAlignmentOff;
74
75 1 PVideoFrame src = child->GetFrame(n, env); // run the GetFrame chain
76
77 env->PlanarChromaAlignment(oldmode); // reset the PLANAR alignement mode
78
79 return src;
80 }
81
82 1 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env)
83 {
84
7/16
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 18 not taken.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 18 not taken.
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 17 not taken.
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 17 not taken.
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 15 not taken.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 15 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 1 time.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 20 not taken.
3 return new PlanarLegacyAlignment(args[0].AsClip(), args[1].AsBool(), env);
85 }
86
87 };
88
89
90
91 /***********************************************
92 ******* Echo Filter *******
93 ******* Call GetFrame on all source clips*****
94 ***********************************************/
95
96 class Echo : public GenericVideoFilter
97 {
98 private:
99 const int ClipCount;
100 PClip *clips;
101
102 public:
103 Echo( PClip _child, const AVSValue _clips, IScriptEnvironment* env )
104 : GenericVideoFilter(_child), ClipCount(_clips.ArraySize()) {
105 AVS_UNUSED(env);
106
107 clips = new PClip[ClipCount];
108 for (int i=0; i < ClipCount; i++)
109 clips[i] = _clips[i].AsClip();
110 }
111
112 ~Echo() {
113 delete[] clips;
114 clips = 0;
115 }
116
117 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {
118
119 PVideoFrame src = child->GetFrame(n, env);
120
121 for (int i=0; i < ClipCount; i++)
122 clips[i]->GetFrame(n, env); // run the GetFrame chains
123
124 return src;
125 }
126
127 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {
128 return new Echo(args[0].AsClip(), args[1], env);
129 }
130
131 };
132
133
134
135 /***********************************************
136 ****** Preroll GetFrame/GetAudio Filter ******
137 ***********************************************/
138
139 class Preroll : public GenericVideoFilter
140 {
141 private:
142 const int videopr;
143 const int64_t audiopr;
144
145 int videonext;
146 int64_t audionext;
147
148 public:
149 Preroll( PClip _child, const int _videopr, const double _audiopr, IScriptEnvironment* env )
150 : GenericVideoFilter(_child),
151 videopr(_videopr),
152 audiopr(int64_t(_audiopr*vi.audio_samples_per_second+0.5)),
153 videonext(0),
154 audionext(0) {
155
156 AVS_UNUSED(env);
157 // Force source filter to honour preroll
158 child->SetCacheHints(CACHE_NOTHING, 0); // Disable Video cache
159 child->SetCacheHints(CACHE_AUDIO_NOTHING, 0); // Disable Audio cache
160 }
161
162 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {
163 if (n != videonext) {
164 int i = n - videopr;
165 if (i < 0) i = 0;
166
167 // Optimise if n is within pr frames of last
168 if (i < videonext && n > videonext) i = videonext;
169
170 while (i < n) {
171 child->GetFrame(i, env);
172 i += 1;
173 }
174 }
175
176 videonext = n+1;
177 return child->GetFrame(n, env);
178 }
179
180 void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {
181 if (start != audionext) {
182 int64_t s = start - audiopr;
183 if (s < 0) s = 0;
184
185 // Optimise if start is within pr sample of last
186 if (s < audionext && start > audionext) s = audionext;
187
188 while (s < start) {
189 int64_t c = start - s;
190 if (c > count) c = count;
191
192 child->GetAudio(buf, s, c, env);
193 s += c;
194 }
195 }
196
197 audionext = start+count;
198 child->GetAudio(buf, start, count, env);
199 }
200
201 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {
202 return new Preroll(args[0].AsClip(), args[1].AsInt(0), (float)args[2].AsDblDef(0.0), env);
203 }
204
205 };
206
207
208
209 /********************************************************************
210 ***** Declare index of new filters for Avisynth's filter engine *****
211 ********************************************************************/
212
213 extern const AVSFunction Debug_filters[] = {
214 { "Null", BUILTIN_FUNC_PREFIX, "c[copy]s", Null::Create }, // clip, copy
215 { "SetPlanarLegacyAlignment", BUILTIN_FUNC_PREFIX, "cb", PlanarLegacyAlignment::Create }, // clip, legacy alignment
216 { "Echo", BUILTIN_FUNC_PREFIX, "cc+", Echo::Create },
217 { "Preroll", BUILTIN_FUNC_PREFIX, "c[video]i[audio]f", Preroll::Create },
218 { NULL }
219 };
220
221
222
223 /*******************************
224 ******* Null Filter *******
225 ******* for debugging *******
226 ******************************/
227
228 1 Null::Null(PClip _child, const char * _copy, IScriptEnvironment* env)
229
2/4
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 8 not taken.
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 6 not taken.
1 : GenericVideoFilter(_child), copy(_copy)
230 {
231 AVS_UNUSED(env);
232 1 }
233
234 1 Null::~Null()
235 {
236 1 }
237
238
239 1 PVideoFrame __stdcall Null::GetFrame(int n, IScriptEnvironment* env)
240 {
241
1/2
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 82 not taken.
1 PVideoFrame src = child->GetFrame(n, env);
242
243
1/2
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 80 not taken.
1 BYTE * foo = new BYTE[256];
244
1/2
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 80 not taken.
1 BYTE * bar = new BYTE[256];
245
1/2
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 80 not taken.
1 MemDebug md;
246
247
1/2
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 78 not taken.
1 md.randomFill(foo, 8, 8, 8);
248
1/2
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 78 not taken.
1 env->BitBlt(bar, 8, foo, 8, 8, 8);
249
250 1 md.reset();
251
1/2
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 78 not taken.
1 int i = md.randomCheck(bar, 9, 8, 8);
252
253
1/2
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 13 not taken.
1 if (i)
254
1/2
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 78 taken 1 time.
1 env->ThrowError("bug found");
255
256 delete [] foo;
257 delete [] bar;
258
259 if (!lstrcmpi(copy, "makewritable"))
260 {
261 env->MakeWritable(&src);
262 return src;
263 }
264
265 // TODO: no support for planar formats!
266 if (!lstrcmpi(copy, "memcopy"))
267 {
268 PVideoFrame dst = env->NewVideoFrame(child->GetVideoInfo(), 16);
269 if (dst->IsWritable() == false)
270 env->ThrowError("new frame not writable"); // honestly don't know whether to expect this condition
271
272 memcpy( dst->GetWritePtr(), src->GetReadPtr(), src->GetPitch() * src->GetHeight() );
273 return dst;
274 }
275
276 if (!lstrcmpi(copy, "bitblt"))
277 {
278 PVideoFrame dst = env->NewVideoFrame(child->GetVideoInfo(), 16);
279 if (dst->IsWritable() == false)
280 env->ThrowError("new frame not writable"); // honestly don't know whether to expect this condition
281
282 env->BitBlt( dst->GetWritePtr(), src->GetPitch(), src->GetReadPtr(), src->GetPitch(),
283 src->GetRowSize(), src->GetHeight() );
284 return dst;
285 }
286
287 //if (!lstrcmpi(copy, "none"))
288 // do nothing
289 return src;
290 2 }
291
292 AVSValue __cdecl Null::Create(AVSValue args, void*, IScriptEnvironment* env)
293 {
294 return new Null(args[0].AsClip(), args[1].AsString("none"), env);
295 }
296
297
298
299
300 1 MemDebug::MemDebug() : mask(0xff)
301 {
302 1 reset();
303 1 }
304
305
306 1 MemDebug::~MemDebug()
307 {
308 1 }
309
310
311 // fills a buffer with "random" (the same every time) data we can
312 // test for after some manipulation (e.g. BitBlt)
313 1 void MemDebug::randomFill(BYTE* const buf, const int pitch, const int row_size, const int height)
314 {
315
2/2
✓ Branch 8 → 3 taken 8 times.
✓ Branch 8 → 9 taken 1 time.
9 for(int x=0; x<height; ++x)
316 {
317
2/2
✓ Branch 6 → 4 taken 64 times.
✓ Branch 6 → 7 taken 8 times.
72 for(int y=0; y<row_size; ++y)
318 {
319 64 buf[x*pitch + y] = nextNum();
320 }
321 }
322 1 }
323
324
325 // checks a buffer to see if "random" data is intact or copied correctly
326 // return value == offset of first discrepancy, or 0 if all's well
327 1 int MemDebug::randomCheck(BYTE* const buf, const int pitch, const int row_size, const int height)
328 {
329
1/2
✓ Branch 10 → 3 taken 1 time.
✗ Branch 10 → 11 not taken.
1 for(int x=0; x<height; ++x)
330 {
331
1/2
✓ Branch 8 → 4 taken 2 times.
✗ Branch 8 → 9 not taken.
2 for(int y=0; y<row_size; ++y)
332 {
333 2 int n = nextNum();
334
2/2
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 1 time.
2 if (buf[x*pitch + y] != n) return x*pitch + y;
335 }
336 }
337
338 return 0;
339 }
340
341
342 66 char MemDebug::nextNum()
343 {
344 66 ++whichByte;
345 66 whichByte &= 3;
346
2/2
✓ Branch 2 → 3 taken 17 times.
✓ Branch 2 → 4 taken 49 times.
66 if (whichByte == 0)
347 {
348 17 randNum *= 0x41c64e6d;
349 17 randNum += 0x3039;
350 }
351
352 66 return char((randNum & (mask << (whichByte * 8))) >> (whichByte * 8));
353 }
354
355
356 2 void MemDebug::reset()
357 {
358 2 randNum = -591377182; // pulled out of my ass
359 2 whichByte = 3;
360 2 }
361