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
24
26
28
29 static const uint32_t
pixel_mask[3] = { 0xffffffff, 0x03ff03ff, 0x0fff0fff };
30
31 #define SIZEOF_PIXEL ((bit_depth + 7) / 8)
32 #define BUF_STRIDE (16 * 2)
33 #define BUF_LINES (16)
34 // large buffer sizes based on high bit depth
35 #define BUF_OFFSET (2 * BUF_STRIDE * BUF_LINES)
36 #define BUF_SIZE (2 * BUF_STRIDE * BUF_LINES + BUF_OFFSET * 2)
37
38 #define randomize_buffers(buf0, buf1, size) \
39 do { \
40 uint32_t mask = pixel_mask[(bit_depth - 8) >> 1]; \
41 int k; \
42 for (k = 0; k < size; k += 4) { \
43 uint32_t r = rnd() & mask; \
44 AV_WN32A(buf0 + k, r); \
45 AV_WN32A(buf1 + k, r); \
46 } \
47 } while (0)
48
50 {
51 // see tctable[] in hevc_filter.c, we check full range
53 // no_p, no_q can only be { 0,0 } for the simpler assembly (non *_c
54 // variant) functions, see deblocking_filter_CTB() in hevc_filter.c
55 uint8_t no_p[2] = {
rnd() &
c,
rnd() &
c };
56 uint8_t no_q[2] = {
rnd() &
c,
rnd() &
c };
59
61 const int32_t *tc,
const uint8_t *no_p,
const uint8_t *no_q);
62
63 if (
check_func(
c ?
h->hevc_h_loop_filter_chroma_c :
h->hevc_h_loop_filter_chroma,
64 "hevc_h_loop_filter_chroma%d%s",
bit_depth,
c ?
"_full" :
""))
65 {
67
73 }
74
75 if (
check_func(
c ?
h->hevc_v_loop_filter_chroma_c :
h->hevc_v_loop_filter_chroma,
76 "hevc_v_loop_filter_chroma%d%s",
bit_depth,
c ?
"_full" :
""))
77 {
79
85 }
86 }
87
88 #define P3 buf[-4 * xstride]
89 #define P2 buf[-3 * xstride]
90 #define P1 buf[-2 * xstride]
91 #define P0 buf[-1 * xstride]
92 #define Q0 buf[0 * xstride]
93 #define Q1 buf[1 * xstride]
94 #define Q2 buf[2 * xstride]
95 #define Q3 buf[3 * xstride]
96
97 #define TC25(x) ((tc[x] * 5 + 1) >> 1)
98 #define MASK(x) (uint16_t)(x & ((1 << (bit_depth)) - 1))
99 #define GET(x) ((SIZEOF_PIXEL == 1) ? *(uint8_t*)(&x) : *(uint16_t*)(&x))
100 #define SET(x, y) do { \
101 uint16_t z = MASK(y); \
102 if (SIZEOF_PIXEL == 1) \
103 *(uint8_t*)(&x) = z; \
104 else \
105 *(uint16_t*)(&x) = z; \
106 } while (0)
107 #define RANDCLIP(x, diff) av_clip(GET(x) - (diff), 0, \
108 (1 << (bit_depth)) - 1) + rnd() % FFMAX(2 * (diff), 1)
109
110 // NOTE: this function doesn't work 'correctly' in that it won't always choose
111 // strong/strong or weak/weak, in most cases it tends to but will sometimes mix
112 // weak/strong or even skip sometimes. This is more useful to test correctness
113 // for these functions, though it does make benching them difficult. The easiest
114 // way to bench these functions is to check an overall decode since there are too
115 // many paths and ways to trigger the deblock: we would have to bench all
116 // permutations of weak/strong/skip/nd_q/nd_p/no_q/no_p and it quickly becomes
117 // too much.
119 uint8_t *buf, ptrdiff_t xstride, ptrdiff_t ystride,
int bit_depth)
120 {
121 int i, j,
b3, tc25, tc25diff, b3diff;
122 // both tc & beta are unscaled inputs
123 // minimum useful value is 1, full range 0-24
124 tc[0] = (
rnd() % 25) + 1;
125 tc[1] = (
rnd() % 25) + 1;
126 // minimum useful value for 8bit is 8
127 *beta = (
rnd() % 57) + 8;
128
130 case 0: // strong
131 for (j = 0; j < 2; j++) {
133 tc25diff =
FFMAX(tc25 - 1, 0);
134 // 4 lines per tc
135 for (
i = 0;
i < 4;
i++) {
137
140
141 // p3 - p0 up to beta3 budget
144 // q3 - q0, reduced budget
147
148 // same concept, budget across 4 pixels
153
154 // extra reduced budget for weighted pixels
159
160 buf += ystride;
161 }
162 }
163 break;
164 case 1: // weak
165 for (j = 0; j < 2; j++) {
167 tc25diff =
FFMAX(tc25 - 1, 0);
168 // 4 lines per tc
169 for (
i = 0;
i < 4;
i++) {
170 // Weak filtering is significantly simpler to activate as
171 // we only need to satisfy d0 + d3 < beta, which
172 // can be simplified to d0 + d0 < beta. Using the above
173 // derivations but substiuting b3 for b1 and ensuring
174 // that P0/Q0 are at least 1/2 tc25diff apart (tending
175 // towards 1/2 range).
177
180 (tc25diff >> 1) * (
P0 < (1 << (
bit_depth - 1))) ? 1 : -1);
181
182 // p3 - p0 up to beta3 budget
185 // q3 - q0, reduced budget
188
189 // same concept, budget across 4 pixels
194
195 // extra reduced budget for weighted pixels
200
201 buf += ystride;
202 }
203 }
204 break;
205 case 2: // none
206 *beta = 0; // ensure skip
207 for (
i = 0;
i < 8;
i++) {
208 // we can just fill with completely random data, nothing should be touched.
211 buf += ystride;
212 }
213 break;
214 }
215 }
216
218 {
220 const char *types[3] = { "strong", "weak", "skip" };
221 int beta;
223 uint8_t no_p[2] = {
rnd() &
c,
rnd() &
c };
224 uint8_t no_q[2] = {
rnd() &
c,
rnd() &
c };
229
231 const int32_t *tc,
const uint8_t *no_p,
const uint8_t *no_q);
233
234 for (int j = 0; j < 3; j++) {
236 if (
check_func(
c ?
h->hevc_h_loop_filter_luma_c :
h->hevc_h_loop_filter_luma,
237 "hevc_h_loop_filter_luma%d_%s%s",
bit_depth,
type,
c ?
"_full" :
""))
238 {
241
247 }
248
249 if (
check_func(
c ?
h->hevc_v_loop_filter_luma_c :
h->hevc_v_loop_filter_luma,
250 "hevc_v_loop_filter_luma%d_%s%s",
bit_depth,
type,
c ?
"_full" :
""))
251 {
254
260 }
261 }
262 }
263
265 {
271 }
276 }
281 }
286 }
288 }