GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 29.5% 23 / 0 / 78
Functions: 28.1% 9 / 0 / 32
Branches: 7.2% 11 / 0 / 152

filters/field.h
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 #ifndef __Field_H__
36 #define __Field_H__
37
38 #include <avisynth.h>
39 #include "../core/internal.h"
40 #include <vector>
41
42
43 /**********************************************************************
44 * Reverse Engineering GetParity
45 * -----------------------------
46 * Notes for self - and hopefully useful to others.
47 *
48 * AviSynth is capable of dealing with both progressive and interlaced
49 * material. The main problem is, that it often doesn't know what it
50 * recieves from source filters.
51 *
52 * The fieldbased property in VideoInfo is made to give guides to
53 * AviSynth on what to expect - unfortunately it is not that easy.
54 *
55 * GetParity is made to distinguish TFF and BFF. When a given frame is
56 * returning true, it means that this frame should be considered
57 * top field.
58 * So an interlaced image always returning true must be interpreted as
59 * TFF.
60 *
61 * SeparateFields splits out Top and Bottom frames. It returns true on
62 * GetParity for Top fields and false for Bottom fields.
63 *
64 **********************************************************************/
65
66
67 class ComplementParity : public NonCachedGenericVideoFilter
68 /**
69 * Class to switch field precedence
70 **/
71 {
72 public:
73 ComplementParity(PClip _child) : NonCachedGenericVideoFilter(_child) {
74 if (vi.IsBFF() && !vi.IsTFF()) {
75 vi.Clear(VideoInfo::IT_BFF);
76 vi.Set(VideoInfo::IT_TFF);
77 } else if (!vi.IsBFF() && vi.IsTFF()) {
78 vi.Set(VideoInfo::IT_BFF);
79 vi.Clear(VideoInfo::IT_TFF);
80 }
81 // else both were set (illegal state) or both were unset (parity unknown)
82 }
83
84 inline bool __stdcall GetParity(int n) {
85 return !child->GetParity(n);
86 }
87
88 inline static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {
89 AVS_UNUSED(env);
90 return new ComplementParity(args[0].AsClip());
91 }
92
93 };
94
95
96 class AssumeParity : public NonCachedGenericVideoFilter
97 /**
98 * Class to assume field precedence, AssumeTFF() & AssumeBFF()
99 **/
100 {
101 public:
102
2/4
✓ Branch 2 → 3 taken 9 times.
✗ Branch 2 → 13 not taken.
✓ Branch 3 → 4 taken 9 times.
✗ Branch 3 → 11 not taken.
9 AssumeParity(PClip _child, bool _parity) : NonCachedGenericVideoFilter(_child), parity(_parity) {
103
2/2
✓ Branch 5 → 6 taken 7 times.
✓ Branch 5 → 8 taken 2 times.
9 if (parity) {
104
1/2
✓ Branch 6 → 7 taken 7 times.
✗ Branch 6 → 14 not taken.
7 vi.Clear(VideoInfo::IT_BFF);
105
1/2
✓ Branch 7 → 10 taken 7 times.
✗ Branch 7 → 14 not taken.
7 vi.Set(VideoInfo::IT_TFF);
106 } else {
107
1/2
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 14 not taken.
2 vi.Set(VideoInfo::IT_BFF);
108
1/2
✓ Branch 9 → 10 taken 2 times.
✗ Branch 9 → 14 not taken.
2 vi.Clear(VideoInfo::IT_TFF);
109 }
110 9 }
111
112 53 inline bool __stdcall GetParity(int n) {
113
1/4
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 53 times.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
53 return parity ^ (vi.IsFieldBased() && (n & 1));
114 }
115
116 inline static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env) {
117 AVS_UNUSED(env);
118 return new AssumeParity(args[0].AsClip(), user_data!=0);
119 }
120
121 private:
122 bool parity;
123 };
124
125 class AssumeFieldBased : public NonCachedGenericVideoFilter
126 /**
127 * Class to assume field-based video
128 **/
129 {
130 public:
131 AssumeFieldBased(PClip _child) : NonCachedGenericVideoFilter(_child)
132 {
133 vi.SetFieldBased(true); vi.Clear(VideoInfo::IT_BFF); vi.Clear(VideoInfo::IT_TFF);
134 }
135
136 inline bool __stdcall GetParity(int n) {
137 return n&1;
138 }
139
140 inline static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {
141 AVS_UNUSED(env);
142 return new AssumeFieldBased(args[0].AsClip());
143 }
144
145 };
146
147
148 class AssumeFrameBased : public NonCachedGenericVideoFilter
149 /**
150 * Class to assume frame-based video
151 **/
152 {
153 public:
154 AssumeFrameBased(PClip _child) : NonCachedGenericVideoFilter(_child)
155 {
156 vi.SetFieldBased(false); vi.Clear(VideoInfo::IT_BFF); vi.Clear(VideoInfo::IT_TFF);
157 }
158
159 inline bool __stdcall GetParity(int n) {
160 AVS_UNUSED(n);
161 return false;
162 }
163
164 inline static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {
165 AVS_UNUSED(env);
166 return new AssumeFrameBased(args[0].AsClip());
167 }
168 };
169
170
171 class SeparateColumns : public GenericVideoFilter
172 /**
173 * Class to separate columns of video
174 **/
175 {
176 private:
177 const int interval;
178
179 public:
180 SeparateColumns(PClip _child, int _interval, IScriptEnvironment* env);
181 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
182
183 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
184 AVS_UNUSED(frame_range);
185 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
186 }
187
188 inline bool __stdcall GetParity(int n) override {
189 return child->GetParity(n/interval);
190 }
191
192 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
193 };
194
195
196 class WeaveColumns : public GenericVideoFilter
197 /**
198 * Class to weave columns of video
199 **/
200 {
201 private:
202 const int period;
203 const int inframes;
204
205 public:
206 WeaveColumns(PClip _child, int _period, IScriptEnvironment* env);
207 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
208
209 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
210 AVS_UNUSED(frame_range);
211 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
212 }
213
214 inline bool __stdcall GetParity(int n) override {
215 return child->GetParity(n*period);
216 }
217
218 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
219 };
220
221
222 class SeparateRows : public NonCachedGenericVideoFilter
223 /**
224 * Class to separate lines of video
225 **/
226 {
227 private:
228 const int interval;
229
230 public:
231 SeparateRows(PClip _child, int _interval, IScriptEnvironment* env);
232 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
233
234 inline bool __stdcall GetParity(int n) {
235 return child->GetParity(n/interval);
236 }
237
238 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
239 };
240
241
242 class WeaveRows : public GenericVideoFilter
243 /**
244 * Class to weave lines of video
245 **/
246 {
247 private:
248 const int period;
249 const int inframes;
250
251 public:
252 WeaveRows(PClip _child, int _period, IScriptEnvironment* env);
253 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
254
255 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
256 AVS_UNUSED(frame_range);
257 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
258 }
259
260 inline bool __stdcall GetParity(int n) override{
261 return child->GetParity(n*period);
262 }
263
264 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
265 };
266
267
268 class SeparateFields : public NonCachedGenericVideoFilter
269 /**
270 * Class to separate fields of interlaced video
271 **/
272 {
273 public:
274 SeparateFields(PClip _child, IScriptEnvironment* env);
275 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
276
277 53 inline bool __stdcall GetParity(int n) {
278 53 return child->GetParity(n>>1) ^ (n&1);
279 }
280
281 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
282 };
283
284
285 class DoubleWeaveFields : public GenericVideoFilter
286 /**
287 * Class to weave fields into an equal number of frames
288 **/
289 {
290 public:
291 DoubleWeaveFields(PClip _child);
292 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
293
294 1 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
295 AVS_UNUSED(frame_range);
296
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
1 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
297 }
298 };
299
300
301 class DoubleWeaveFrames : public GenericVideoFilter
302 /**
303 * Class to double-weave frames
304 **/
305 {
306 public:
307 DoubleWeaveFrames(PClip _child);
308 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;
309
310 4 inline bool __stdcall GetParity(int n) override {
311 4 return child->GetParity(n>>1) ^ (n&1);
312 }
313
314 1 int __stdcall SetCacheHints(int cachehints, int frame_range) override {
315 AVS_UNUSED(frame_range);
316
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
1 return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;
317 }
318 };
319
320 inline int congmod(int a, int b) { // congruent modulus
321 return ((a % b) + b) % b;
322 }
323
324 class Interleave : public IClip
325 /**
326 * Class to interleave several clips frame-by-frame
327 **/
328 {
329 public:
330 Interleave(const std::vector<PClip>&& _child_array, IScriptEnvironment* env);
331
332 2 const VideoInfo& __stdcall GetVideoInfo() override {
333 2 return vi;
334 }
335
336 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override {
337 return child_array[congmod(n, num_children)]->GetFrame(n / num_children, env);
338 }
339
340 void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override {
341 child_array[0]->GetAudio(buf, start, count, env);
342 }
343
344 bool __stdcall GetParity(int n) override {
345 return child_array[n % num_children]->GetParity(n / num_children);
346 }
347
348 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
349
350 int __stdcall SetCacheHints(int cachehints, int frame_range) override;
351
352 private:
353 const int num_children;
354 std::vector<PClip> child_array;
355 VideoInfo vi;
356 int child_devs;
357 };
358
359
360 class SelectEvery : public NonCachedGenericVideoFilter
361 /**
362 * Class to perform generalized pulldown (patterned frame removal)
363 **/
364 {
365 public:
366 SelectEvery(PClip _child, int _every, int _from, IScriptEnvironment* env);
367
368 5 inline PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {
369 5 return child->GetFrame(n*every+from, env);
370 }
371
372 5 inline bool __stdcall GetParity(int n) {
373 5 return child->GetParity(n*every+from);
374 }
375
376 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
377
378 inline static AVSValue __cdecl Create_SelectEven(AVSValue args, void*, IScriptEnvironment* env) {
379 return new SelectEvery(args[0].AsClip(), 2, 0, env);
380 }
381
382 inline static AVSValue __cdecl Create_SelectOdd(AVSValue args, void*, IScriptEnvironment* env) {
383 return new SelectEvery(args[0].AsClip(), 2, 1, env);
384 }
385
386 private:
387 const int every, from;
388 };
389
390
391
392 class Fieldwise : public NonCachedGenericVideoFilter
393 /**
394 * Helper class for Bob filter
395 **/
396 {
397 public:
398 Fieldwise(PClip _child1, PClip _child2);
399 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
400 bool __stdcall GetParity(int n);
401
402 private:
403 PClip child2;
404 };
405
406 class SelectRangeEvery : public NonCachedGenericVideoFilter {
407 int every, length;
408 bool audio;
409 PClip achild;
410 public:
411 SelectRangeEvery(PClip _child, int _every, int _length, int _offset, bool _audio, IScriptEnvironment* env);
412 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
413 bool __stdcall GetParity(int n);
414 static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);
415 void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);
416
417 };
418
419
420 #endif // __Field_H__
421