FFmpeg
vf_bwdif.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg 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  * FFmpeg 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 along
15  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include <string.h>
20 #include "checkasm.h"
21 #include "libavfilter/bwdifdsp.h"
22 #include "libavutil/mem_internal.h"
23 
24 #define WIDTH 256
25 
26 #define randomize_buffers(buf0, buf1, mask, count) \
27  for (size_t i = 0; i < count; i++) \
28  buf0[i] = buf1[i] = rnd() & mask
29 
30 #define randomize_overflow_check(buf0, buf1, mask, count) \
31  for (size_t i = 0; i < count; i++) \
32  buf0[i] = buf1[i] = (rnd() & 1) != 0 ? mask : 0;
33 
34 #define BODY(type, depth) \
35  do { \
36  type prev0[9*WIDTH], prev1[9*WIDTH]; \
37  type next0[9*WIDTH], next1[9*WIDTH]; \
38  type cur0[9*WIDTH], cur1[9*WIDTH]; \
39  type dst0[WIDTH], dst1[WIDTH]; \
40  const int stride = WIDTH; \
41  const int mask = (1<<depth)-1; \
42  \
43  declare_func(void, void *dst, const void *prev, const void *cur, const void *next, \
44  int w, int prefs, int mrefs, int prefs2, int mrefs2, \
45  int prefs3, int mrefs3, int prefs4, int mrefs4, \
46  int parity, int clip_max); \
47  \
48  randomize_buffers(prev0, prev1, mask, 9*WIDTH); \
49  randomize_buffers(next0, next1, mask, 9*WIDTH); \
50  randomize_buffers( cur0, cur1, mask, 9*WIDTH); \
51  \
52  call_ref(dst0, prev0 + 4*WIDTH, cur0 + 4*WIDTH, next0 + 4*WIDTH, \
53  WIDTH, stride, -stride, 2*stride, -2*stride, \
54  3*stride, -3*stride, 4*stride, -4*stride, \
55  0, mask); \
56  call_new(dst1, prev1 + 4*WIDTH, cur1 + 4*WIDTH, next1 + 4*WIDTH, \
57  WIDTH, stride, -stride, 2*stride, -2*stride, \
58  3*stride, -3*stride, 4*stride, -4*stride, \
59  0, mask); \
60  \
61  if (memcmp(dst0, dst1, sizeof dst0) \
62  || memcmp(prev0, prev1, sizeof prev0) \
63  || memcmp(next0, next1, sizeof next0) \
64  || memcmp( cur0, cur1, sizeof cur0)) \
65  fail(); \
66  bench_new(dst1, prev1 + 4*WIDTH, cur1 + 4*WIDTH, next1 + 4*WIDTH, \
67  WIDTH, stride, -stride, 2*stride, -2*stride, \
68  3*stride, -3*stride, 4*stride, -4*stride, \
69  0, mask); \
70  } while (0)
71 
73 {
74  BWDIFDSPContext ctx_8, ctx_10;
75 
76  ff_bwdif_init_filter_line(&ctx_8, 8);
77  ff_bwdif_init_filter_line(&ctx_10, 10);
78 
79  if (check_func(ctx_8.filter_line, "bwdif8")) {
80  BODY(uint8_t, 8);
81  report("bwdif8");
82  }
83 
84  if (check_func(ctx_10.filter_line, "bwdif10")) {
85  BODY(uint16_t, 10);
86  report("bwdif10");
87  }
88 
89  if (!ctx_8.filter_line3)
91 
92  {
93  LOCAL_ALIGNED_16(uint8_t, prev0, [11*WIDTH]);
94  LOCAL_ALIGNED_16(uint8_t, prev1, [11*WIDTH]);
95  LOCAL_ALIGNED_16(uint8_t, next0, [11*WIDTH]);
96  LOCAL_ALIGNED_16(uint8_t, next1, [11*WIDTH]);
97  LOCAL_ALIGNED_16(uint8_t, cur0, [11*WIDTH]);
98  LOCAL_ALIGNED_16(uint8_t, cur1, [11*WIDTH]);
99  LOCAL_ALIGNED_16(uint8_t, dst0, [WIDTH*3]);
100  LOCAL_ALIGNED_16(uint8_t, dst1, [WIDTH*3]);
101  const int stride = WIDTH;
102  const int mask = (1<<8)-1;
103  int parity;
104 
105  for (parity = 0; parity != 2; ++parity) {
106  if (check_func(ctx_8.filter_line3, "bwdif8.line3.rnd.p%d", parity)) {
107 
108  declare_func(void, void * dst1, int d_stride,
109  const void * prev1, const void * cur1, const void * next1, int prefs,
110  int w, int parity, int clip_max);
111 
112  randomize_buffers(prev0, prev1, mask, 11*WIDTH);
113  randomize_buffers(next0, next1, mask, 11*WIDTH);
114  randomize_buffers( cur0, cur1, mask, 11*WIDTH);
115 
116  call_ref(dst0, stride,
117  prev0 + stride * 4, cur0 + stride * 4, next0 + stride * 4, stride,
118  WIDTH, parity, mask);
119  call_new(dst1, stride,
120  prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, stride,
121  WIDTH, parity, mask);
122 
123  if (memcmp(dst0, dst1, WIDTH*3)
124  || memcmp(prev0, prev1, WIDTH*11)
125  || memcmp(next0, next1, WIDTH*11)
126  || memcmp( cur0, cur1, WIDTH*11))
127  fail();
128 
129  bench_new(dst1, stride,
130  prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, stride,
131  WIDTH, parity, mask);
132  }
133  }
134 
135  // Use just 0s and ~0s to try to provoke bad cropping or overflow
136  // Parity makes no difference to this test so just test 0
137  if (check_func(ctx_8.filter_line3, "bwdif8.line3.overflow")) {
138 
139  declare_func(void, void * dst1, int d_stride,
140  const void * prev1, const void * cur1, const void * next1, int prefs,
141  int w, int parity, int clip_max);
142 
143  randomize_overflow_check(prev0, prev1, mask, 11*WIDTH);
144  randomize_overflow_check(next0, next1, mask, 11*WIDTH);
145  randomize_overflow_check( cur0, cur1, mask, 11*WIDTH);
146 
147  call_ref(dst0, stride,
148  prev0 + stride * 4, cur0 + stride * 4, next0 + stride * 4, stride,
149  WIDTH, 0, mask);
150  call_new(dst1, stride,
151  prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, stride,
152  WIDTH, 0, mask);
153 
154  if (memcmp(dst0, dst1, WIDTH*3)
155  || memcmp(prev0, prev1, WIDTH*11)
156  || memcmp(next0, next1, WIDTH*11)
157  || memcmp( cur0, cur1, WIDTH*11))
158  fail();
159 
160  // No point to benching
161  }
162 
163  report("bwdif8.line3");
164  }
165 
166  {
167  LOCAL_ALIGNED_16(uint8_t, prev0, [11*WIDTH]);
168  LOCAL_ALIGNED_16(uint8_t, prev1, [11*WIDTH]);
169  LOCAL_ALIGNED_16(uint8_t, next0, [11*WIDTH]);
170  LOCAL_ALIGNED_16(uint8_t, next1, [11*WIDTH]);
171  LOCAL_ALIGNED_16(uint8_t, cur0, [11*WIDTH]);
172  LOCAL_ALIGNED_16(uint8_t, cur1, [11*WIDTH]);
173  LOCAL_ALIGNED_16(uint8_t, dst0, [WIDTH*3]);
174  LOCAL_ALIGNED_16(uint8_t, dst1, [WIDTH*3]);
175  const int stride = WIDTH;
176  const int mask = (1<<8)-1;
177  int spat;
178  int parity;
179 
180  for (spat = 0; spat != 2; ++spat) {
181  for (parity = 0; parity != 2; ++parity) {
182  if (check_func(ctx_8.filter_edge, "bwdif8.edge.s%d.p%d", spat, parity)) {
183 
184  declare_func(void, void *dst1, const void *prev1, const void *cur1, const void *next1,
185  int w, int prefs, int mrefs, int prefs2, int mrefs2,
186  int parity, int clip_max, int spat);
187 
188  randomize_buffers(prev0, prev1, mask, 11*WIDTH);
189  randomize_buffers(next0, next1, mask, 11*WIDTH);
190  randomize_buffers( cur0, cur1, mask, 11*WIDTH);
191  memset(dst0, 0xba, WIDTH * 3);
192  memset(dst1, 0xba, WIDTH * 3);
193 
194  call_ref(dst0 + stride,
195  prev0 + stride * 4, cur0 + stride * 4, next0 + stride * 4, WIDTH,
196  stride, -stride, stride * 2, -stride * 2,
197  parity, mask, spat);
198  call_new(dst1 + stride,
199  prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, WIDTH,
200  stride, -stride, stride * 2, -stride * 2,
201  parity, mask, spat);
202 
203  if (memcmp(dst0, dst1, WIDTH*3)
204  || memcmp(prev0, prev1, WIDTH*11)
205  || memcmp(next0, next1, WIDTH*11)
206  || memcmp( cur0, cur1, WIDTH*11))
207  fail();
208 
209  bench_new(dst1 + stride,
210  prev1 + stride * 4, cur1 + stride * 4, next1 + stride * 4, WIDTH,
211  stride, -stride, stride * 2, -stride * 2,
212  parity, mask, spat);
213  }
214  }
215  }
216 
217  report("bwdif8.edge");
218  }
219 
220  if (check_func(ctx_8.filter_intra, "bwdif8.intra")) {
221  LOCAL_ALIGNED_16(uint8_t, cur0, [11*WIDTH]);
222  LOCAL_ALIGNED_16(uint8_t, cur1, [11*WIDTH]);
223  LOCAL_ALIGNED_16(uint8_t, dst0, [WIDTH*3]);
224  LOCAL_ALIGNED_16(uint8_t, dst1, [WIDTH*3]);
225  const int stride = WIDTH;
226  const int mask = (1<<8)-1;
227 
228  declare_func(void, void *dst1, const void *cur1, int w, int prefs, int mrefs,
229  int prefs3, int mrefs3, int parity, int clip_max);
230 
231  randomize_buffers( cur0, cur1, mask, 11*WIDTH);
232  memset(dst0, 0xba, WIDTH * 3);
233  memset(dst1, 0xba, WIDTH * 3);
234 
235  call_ref(dst0 + stride,
236  cur0 + stride * 4, WIDTH,
237  stride, -stride, stride * 3, -stride * 3,
238  0, mask);
239  call_new(dst1 + stride,
240  cur0 + stride * 4, WIDTH,
241  stride, -stride, stride * 3, -stride * 3,
242  0, mask);
243 
244  if (memcmp(dst0, dst1, WIDTH*3)
245  || memcmp( cur0, cur1, WIDTH*11))
246  fail();
247 
248  bench_new(dst1 + stride,
249  cur0 + stride * 4, WIDTH,
250  stride, -stride, stride * 3, -stride * 3,
251  0, mask);
252 
253  report("bwdif8.intra");
254  }
255 }
ff_bwdif_filter_line3_c
static void ff_bwdif_filter_line3_c(void *dst1, int d_stride, const void *prev1, const void *cur1, const void *next1, int s_stride, int w, int parity, int clip_max)
Definition: bwdifdsp.h:57
mem_internal.h
w
uint8_t w
Definition: llviddspenc.c:38
check_func
#define check_func(func,...)
Definition: checkasm.h:177
BODY
#define BODY(type, depth)
Definition: vf_bwdif.c:34
call_ref
#define call_ref(...)
Definition: checkasm.h:192
ff_bwdif_init_filter_line
av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth)
Definition: bwdifdsp.c:208
fail
#define fail()
Definition: checkasm.h:186
checkasm.h
mask
static const uint16_t mask[17]
Definition: lzw.c:38
randomize_overflow_check
#define randomize_overflow_check(buf0, buf1, mask, count)
Definition: vf_bwdif.c:30
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:150
BWDIFDSPContext::filter_intra
void(* filter_intra)(void *dst1, const void *cur1, int w, int prefs, int mrefs, int prefs3, int mrefs3, int parity, int clip_max)
Definition: bwdifdsp.h:26
WIDTH
#define WIDTH
Definition: vf_bwdif.c:24
call_new
#define call_new(...)
Definition: checkasm.h:295
BWDIFDSPContext
Definition: bwdifdsp.h:25
parity
mcdeint parity
Definition: vf_mcdeint.c:281
report
#define report
Definition: checkasm.h:189
bench_new
#define bench_new(...)
Definition: checkasm.h:366
BWDIFDSPContext::filter_line
void(* filter_line)(void *dst, const void *prev, const void *cur, const void *next, int w, int prefs, int mrefs, int prefs2, int mrefs2, int prefs3, int mrefs3, int prefs4, int mrefs4, int parity, int clip_max)
Definition: bwdifdsp.h:28
stride
#define stride
Definition: h264pred_template.c:537
BWDIFDSPContext::filter_line3
void(* filter_line3)(void *dst, int dstride, const void *prev, const void *cur, const void *next, int prefs, int w, int parity, int clip_max)
Definition: bwdifdsp.h:35
bwdifdsp.h
randomize_buffers
#define randomize_buffers(buf0, buf1, mask, count)
Definition: vf_bwdif.c:26
declare_func
#define declare_func(ret,...)
Definition: checkasm.h:181
BWDIFDSPContext::filter_edge
void(* filter_edge)(void *dst, const void *prev, const void *cur, const void *next, int w, int prefs, int mrefs, int prefs2, int mrefs2, int parity, int clip_max, int spat)
Definition: bwdifdsp.h:32
checkasm_check_vf_bwdif
void checkasm_check_vf_bwdif(void)
Definition: vf_bwdif.c:72