FFmpeg
Loading...
Searching...
No Matches
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"
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
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}
av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth)
Definition bwdifdsp.c:208
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
#define declare_func
Definition test.h:489
#define fail
Definition test.h:479
#define bench_new
Definition test.h:487
#define check_func
Definition test.h:481
#define call_new
Definition test.h:486
#define call_ref
Definition test.h:485
#define report
Definition test.h:480
#define WIDTH
Definition c93.c:45
uint8_t w
Definition llvidencdsp.c:39
static const uint16_t mask[17]
Definition lzw.c:38
#define LOCAL_ALIGNED_16(t, v,...)
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
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
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
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
#define stride
#define randomize_overflow_check(buf0, buf1, mask, count)
Definition vf_bwdif.c:30
#define randomize_buffers(buf0, buf1, mask, count)
Definition vf_bwdif.c:26
void checkasm_check_vf_bwdif(void)
Definition vf_bwdif.c:72
#define BODY(type, depth)
Definition vf_bwdif.c:34
mcdeint parity
Definition vf_mcdeint.c:293