FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/tests/checkasm/vc1dsp.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 185 208 88.9%
Functions: 12 12 100.0%
Branches: 146 208 70.2%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2022 Ben Avison
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <string.h>
22
23 #include "checkasm.h"
24
25 #include "libavcodec/vc1dsp.h"
26
27 #include "libavutil/common.h"
28 #include "libavutil/internal.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/mem_internal.h"
32
33 #define VC1DSP_TEST(func) { #func, offsetof(VC1DSPContext, func) },
34 #define VC1DSP_SIZED_TEST(func, width, height) { #func, offsetof(VC1DSPContext, func), width, height },
35
36 typedef struct {
37 const char *name;
38 size_t offset;
39 int width;
40 int height;
41 } test;
42
43 typedef struct matrix {
44 size_t width;
45 size_t height;
46 float d[];
47 } matrix;
48
49 static const matrix T8 = { 8, 8, {
50 12, 12, 12, 12, 12, 12, 12, 12,
51 16, 15, 9, 4, -4, -9, -15, -16,
52 16, 6, -6, -16, -16, -6, 6, 16,
53 15, -4, -16, -9, 9, 16, 4, -15,
54 12, -12, -12, 12, 12, -12, -12, 12,
55 9, -16, 4, 15, -15, -4, 16, -9,
56 6, -16, 16, -6, -6, 16, -16, 6,
57 4, -9, 15, -16, 16, -15, 9, -4
58 } };
59
60 static const matrix T4 = { 4, 4, {
61 17, 17, 17, 17,
62 22, 10, -10, -22,
63 17, -17, -17, 17,
64 10, -22, 22, -10
65 } };
66
67 static const matrix T8t = { 8, 8, {
68 12, 16, 16, 15, 12, 9, 6, 4,
69 12, 15, 6, -4, -12, -16, -16, -9,
70 12, 9, -6, -16, -12, 4, 16, 15,
71 12, 4, -16, -9, 12, 15, -6, -16,
72 12, -4, -16, 9, 12, -15, -6, 16,
73 12, -9, -6, 16, -12, -4, 16, -15,
74 12, -15, 6, 4, -12, 16, -16, 9,
75 12, -16, 16, -15, 12, -9, 6, -4
76 } };
77
78 static const matrix T4t = { 4, 4, {
79 17, 22, 17, 10,
80 17, 10, -17, -22,
81 17, -10, -17, 22,
82 17, -22, 17, -10
83 } };
84
85 60 static matrix *new_matrix(size_t width, size_t height)
86 {
87 60 matrix *out = av_mallocz(sizeof (matrix) + height * width * sizeof (float));
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if (out == NULL) {
89 fprintf(stderr, "Memory allocation failure\n");
90 exit(EXIT_FAILURE);
91 }
92 60 out->width = width;
93 60 out->height = height;
94 60 return out;
95 }
96
97 48 static matrix *multiply(const matrix *a, const matrix *b)
98 {
99 matrix *out;
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (a->width != b->height) {
101 fprintf(stderr, "Incompatible multiplication\n");
102 exit(EXIT_FAILURE);
103 }
104 48 out = new_matrix(b->width, a->height);
105
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 48 times.
336 for (int j = 0; j < out->height; ++j)
106
2/2
✓ Branch 0 taken 1728 times.
✓ Branch 1 taken 288 times.
2016 for (int i = 0; i < out->width; ++i) {
107 1728 float sum = 0;
108
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 1728 times.
13248 for (int k = 0; k < a->width; ++k)
109 11520 sum += a->d[j * a->width + k] * b->d[k * b->width + i];
110 1728 out->d[j * out->width + i] = sum;
111 }
112 48 return out;
113 }
114
115 12 static void normalise(matrix *a)
116 {
117
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 12 times.
84 for (int j = 0; j < a->height; ++j)
118
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 72 times.
504 for (int i = 0; i < a->width; ++i) {
119 432 float *p = a->d + j * a->width + i;
120 432 *p *= 64;
121
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 288 times.
432 if (a->height == 4)
122 144 *p /= (const unsigned[]) { 289, 292, 289, 292 } [j];
123 else
124 288 *p /= (const unsigned[]) { 288, 289, 292, 289, 288, 289, 292, 289 } [j];
125
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 288 times.
432 if (a->width == 4)
126 144 *p /= (const unsigned[]) { 289, 292, 289, 292 } [i];
127 else
128 288 *p /= (const unsigned[]) { 288, 289, 292, 289, 288, 289, 292, 289 } [i];
129 }
130 12 }
131
132 36 static void divide_and_round_nearest(matrix *a, float by)
133 {
134
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 36 times.
252 for (int j = 0; j < a->height; ++j)
135
2/2
✓ Branch 0 taken 1296 times.
✓ Branch 1 taken 216 times.
1512 for (int i = 0; i < a->width; ++i) {
136 1296 float *p = a->d + j * a->width + i;
137 1296 *p = rintf(*p / by);
138 }
139 36 }
140
141 12 static void tweak(matrix *a)
142 {
143
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 for (int j = 4; j < a->height; ++j)
144
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 24 times.
168 for (int i = 0; i < a->width; ++i) {
145 144 float *p = a->d + j * a->width + i;
146 144 *p += 1;
147 }
148 12 }
149
150 /* The VC-1 spec places restrictions on the values permitted at three
151 * different stages:
152 * - D: the input coefficients in frequency domain
153 * - E: the intermediate coefficients, inverse-transformed only horizontally
154 * - R: the fully inverse-transformed coefficients
155 *
156 * To fully cater for the ranges specified requires various intermediate
157 * values to be held to 17-bit precision; yet these conditions do not appear
158 * to be utilised in real-world streams. At least some assembly
159 * implementations have chosen to restrict these values to 16-bit precision,
160 * to accelerate the decoding of real-world streams at the cost of strict
161 * adherence to the spec. To avoid our test marking these as failures,
162 * reduce our random inputs.
163 */
164 #define ATTENUATION 4
165
166 12 static matrix *generate_inverse_quantized_transform_coefficients(size_t width, size_t height)
167 {
168 matrix *raw, *tmp, *D, *E, *R;
169 12 raw = new_matrix(width, height);
170
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 12 times.
444 for (int i = 0; i < width * height; ++i)
171 432 raw->d[i] = (int) (rnd() % (1024/ATTENUATION)) - 512/ATTENUATION;
172
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 tmp = multiply(height == 8 ? &T8 : &T4, raw);
173
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 D = multiply(tmp, width == 8 ? &T8t : &T4t);
174 12 normalise(D);
175 12 divide_and_round_nearest(D, 1);
176
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 12 times.
444 for (int i = 0; i < width * height; ++i) {
177
2/4
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 432 times.
432 if (D->d[i] < -2048/ATTENUATION || D->d[i] > 2048/ATTENUATION-1) {
178 /* Rare, so simply try again */
179 av_free(raw);
180 av_free(tmp);
181 av_free(D);
182 return generate_inverse_quantized_transform_coefficients(width, height);
183 }
184 }
185
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 E = multiply(D, width == 8 ? &T8 : &T4);
186 12 divide_and_round_nearest(E, 8);
187
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 12 times.
444 for (int i = 0; i < width * height; ++i)
188
2/4
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 432 times.
432 if (E->d[i] < -4096/ATTENUATION || E->d[i] > 4096/ATTENUATION-1) {
189 /* Rare, so simply try again */
190 av_free(raw);
191 av_free(tmp);
192 av_free(D);
193 av_free(E);
194 return generate_inverse_quantized_transform_coefficients(width, height);
195 }
196
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 R = multiply(height == 8 ? &T8t : &T4t, E);
197 12 tweak(R);
198 12 divide_and_round_nearest(R, 128);
199
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 12 times.
444 for (int i = 0; i < width * height; ++i)
200
2/4
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 432 times.
432 if (R->d[i] < -512/ATTENUATION || R->d[i] > 512/ATTENUATION-1) {
201 /* Rare, so simply try again */
202 av_free(raw);
203 av_free(tmp);
204 av_free(D);
205 av_free(E);
206 av_free(R);
207 return generate_inverse_quantized_transform_coefficients(width, height);
208 }
209 12 av_free(raw);
210 12 av_free(tmp);
211 12 av_free(E);
212 12 av_free(R);
213 12 return D;
214 }
215
216 #define RANDOMIZE_BUFFER16(name, size) \
217 do { \
218 int i; \
219 for (i = 0; i < size; ++i) { \
220 uint16_t r = rnd(); \
221 AV_WN16A(name##0 + i, r); \
222 AV_WN16A(name##1 + i, r); \
223 } \
224 } while (0)
225
226 #define RANDOMIZE_BUFFER8(name, size) \
227 do { \
228 int i; \
229 for (i = 0; i < size; ++i) { \
230 uint8_t r = rnd(); \
231 name##0[i] = r; \
232 name##1[i] = r; \
233 } \
234 } while (0)
235
236 #define RANDOMIZE_BUFFER8_MID_WEIGHTED(name, size) \
237 do { \
238 uint8_t *p##0 = name##0, *p##1 = name##1; \
239 int i = (size); \
240 while (i-- > 0) { \
241 int x = 0x80 | (rnd() & 0x7F); \
242 x >>= rnd() % 9; \
243 if (rnd() & 1) \
244 x = -x; \
245 *p##1++ = *p##0++ = 0x80 + x; \
246 } \
247 } while (0)
248
249 13 static void check_inv_trans_inplace(void)
250 {
251 /* Inverse transform input coefficients are stored in a 16-bit buffer
252 * with row stride of 8 coefficients irrespective of transform size.
253 * vc1_inv_trans_8x8 differs from the others in two ways: coefficients
254 * are stored in column-major order, and the outputs are written back
255 * to the input buffer, so we oversize it slightly to catch overruns. */
256 13 LOCAL_ALIGNED_16(int16_t, inv_trans_in0, [10 * 8]);
257 13 LOCAL_ALIGNED_16(int16_t, inv_trans_in1, [10 * 8]);
258
259 VC1DSPContext h;
260
261 13 ff_vc1dsp_init(&h);
262
263
2/2
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 12 times.
13 if (check_func(h.vc1_inv_trans_8x8, "vc1dsp.vc1_inv_trans_8x8")) {
264 matrix *coeffs;
265 1 declare_func(void, int16_t *);
266
2/2
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 1 times.
81 RANDOMIZE_BUFFER16(inv_trans_in, 10 * 8);
267 1 coeffs = generate_inverse_quantized_transform_coefficients(8, 8);
268
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 for (int j = 0; j < 8; ++j)
269
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 8 times.
72 for (int i = 0; i < 8; ++i) {
270 64 int idx = 8 + i * 8 + j;
271 64 inv_trans_in1[idx] = inv_trans_in0[idx] = coeffs->d[j * 8 + i];
272 }
273 1 call_ref(inv_trans_in0 + 8);
274 1 call_new(inv_trans_in1 + 8);
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (memcmp(inv_trans_in0, inv_trans_in1, 10 * 8 * sizeof (int16_t)))
276 fail();
277
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
1 bench_new(inv_trans_in1 + 8);
278 1 av_free(coeffs);
279 }
280 13 }
281
282 13 static void check_inv_trans_adding(void)
283 {
284 /* Inverse transform input coefficients are stored in a 16-bit buffer
285 * with row stride of 8 coefficients irrespective of transform size. */
286 13 LOCAL_ALIGNED_16(int16_t, inv_trans_in0, [8 * 8]);
287 13 LOCAL_ALIGNED_16(int16_t, inv_trans_in1, [8 * 8]);
288
289 /* For all but vc1_inv_trans_8x8, the inverse transform is narrowed and
290 * added with saturation to an array of unsigned 8-bit values. Oversize
291 * this by 8 samples left and right and one row above and below. */
292 13 LOCAL_ALIGNED_8(uint8_t, inv_trans_out0, [10 * 24]);
293 13 LOCAL_ALIGNED_8(uint8_t, inv_trans_out1, [10 * 24]);
294
295 VC1DSPContext h;
296
297 13 const test tests[] = {
298 VC1DSP_SIZED_TEST(vc1_inv_trans_8x4, 8, 4)
299 VC1DSP_SIZED_TEST(vc1_inv_trans_4x8, 4, 8)
300 VC1DSP_SIZED_TEST(vc1_inv_trans_4x4, 4, 4)
301 VC1DSP_SIZED_TEST(vc1_inv_trans_8x8_dc, 8, 8)
302 VC1DSP_SIZED_TEST(vc1_inv_trans_8x4_dc, 8, 4)
303 VC1DSP_SIZED_TEST(vc1_inv_trans_4x8_dc, 4, 8)
304 VC1DSP_SIZED_TEST(vc1_inv_trans_4x4_dc, 4, 4)
305 };
306
307 13 ff_vc1dsp_init(&h);
308
309
2/2
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 13 times.
104 for (size_t t = 0; t < FF_ARRAY_ELEMS(tests); ++t) {
310 91 void (*func)(uint8_t *, ptrdiff_t, int16_t *) = *(void **)((intptr_t) &h + tests[t].offset);
311
2/2
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 80 times.
91 if (check_func(func, "vc1dsp.%s", tests[t].name)) {
312 matrix *coeffs;
313
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 7 times.
11 declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, ptrdiff_t, int16_t *);
314
2/2
✓ Branch 1 taken 704 times.
✓ Branch 2 taken 11 times.
715 RANDOMIZE_BUFFER16(inv_trans_in, 8 * 8);
315
2/2
✓ Branch 1 taken 2640 times.
✓ Branch 2 taken 11 times.
2651 RANDOMIZE_BUFFER8(inv_trans_out, 10 * 24);
316 11 coeffs = generate_inverse_quantized_transform_coefficients(tests[t].width, tests[t].height);
317
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 11 times.
75 for (int j = 0; j < tests[t].height; ++j)
318
2/2
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 64 times.
432 for (int i = 0; i < tests[t].width; ++i) {
319 368 int idx = j * 8 + i;
320 368 inv_trans_in1[idx] = inv_trans_in0[idx] = coeffs->d[j * tests[t].width + i];
321 }
322 11 call_ref(inv_trans_out0 + 24 + 8, 24, inv_trans_in0);
323 11 call_new(inv_trans_out1 + 24 + 8, 24, inv_trans_in1);
324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (memcmp(inv_trans_out0, inv_trans_out1, 10 * 24))
325 fail();
326
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
11 bench_new(inv_trans_out1 + 24 + 8, 24, inv_trans_in1 + 8);
327 11 av_free(coeffs);
328 }
329 }
330 13 }
331
332 13 static void check_loop_filter(void)
333 {
334 /* Deblocking filter buffers are big enough to hold a 16x16 block,
335 * plus 16 columns left and 4 rows above to hold filter inputs
336 * (depending on whether v or h neighbouring block edge, oversized
337 * horizontally to maintain 16-byte alignment) plus 16 columns and
338 * 4 rows below to catch write overflows */
339 13 LOCAL_ALIGNED_16(uint8_t, filter_buf0, [24 * 48]);
340 13 LOCAL_ALIGNED_16(uint8_t, filter_buf1, [24 * 48]);
341
342 VC1DSPContext h;
343
344 13 const test tests[] = {
345 VC1DSP_TEST(vc1_v_loop_filter4)
346 VC1DSP_TEST(vc1_h_loop_filter4)
347 VC1DSP_TEST(vc1_v_loop_filter8)
348 VC1DSP_TEST(vc1_h_loop_filter8)
349 VC1DSP_TEST(vc1_v_loop_filter16)
350 VC1DSP_TEST(vc1_h_loop_filter16)
351 };
352
353 13 ff_vc1dsp_init(&h);
354
355
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 13 times.
91 for (size_t t = 0; t < FF_ARRAY_ELEMS(tests); ++t) {
356 78 void (*func)(uint8_t *, ptrdiff_t, int) = *(void **)((intptr_t) &h + tests[t].offset);
357
2/2
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 6 times.
78 declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, ptrdiff_t, int);
358
2/2
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 58 times.
78 if (check_func(func, "vc1dsp.%s", tests[t].name)) {
359
2/2
✓ Branch 0 taken 20000 times.
✓ Branch 1 taken 20 times.
20020 for (int count = 1000; count > 0; --count) {
360 20000 int pq = rnd() % 31 + 1;
361
4/4
✓ Branch 3 taken 11523781 times.
✓ Branch 4 taken 11516219 times.
✓ Branch 5 taken 23040000 times.
✓ Branch 6 taken 20000 times.
23060000 RANDOMIZE_BUFFER8_MID_WEIGHTED(filter_buf, 24 * 48);
362 20000 call_ref(filter_buf0 + 4 * 48 + 16, 48, pq);
363 20000 call_new(filter_buf1 + 4 * 48 + 16, 48, pq);
364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20000 times.
20000 if (memcmp(filter_buf0, filter_buf1, 24 * 48))
365 fail();
366 }
367 }
368
2/2
✓ Branch 0 taken 1872 times.
✓ Branch 1 taken 78 times.
1950 for (int j = 0; j < 24; ++j)
369
2/2
✓ Branch 0 taken 89856 times.
✓ Branch 1 taken 1872 times.
91728 for (int i = 0; i < 48; ++i)
370
4/4
✓ Branch 0 taken 59904 times.
✓ Branch 1 taken 29952 times.
✓ Branch 2 taken 49920 times.
✓ Branch 3 taken 9984 times.
89856 filter_buf1[j * 48 + i] = 0x60 + 0x40 * (i >= 16 && j >= 4);
371
2/2
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 58 times.
78 if (check_func(func, "vc1dsp.%s_bestcase", tests[t].name))
372
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
20 bench_new(filter_buf1 + 4 * 48 + 16, 48, 1);
373
2/2
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 58 times.
78 if (check_func(func, "vc1dsp.%s_worstcase", tests[t].name))
374
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
20 bench_new(filter_buf1 + 4 * 48 + 16, 48, 31);
375 }
376 13 }
377
378 #define TEST_UNESCAPE \
379 do { \
380 for (int count = 100; count > 0; --count) { \
381 escaped_offset = rnd() & 7; \
382 unescaped_offset = rnd() & 7; \
383 escaped_len = (1u << (rnd() % 8) + 3) - (rnd() & 7); \
384 RANDOMIZE_BUFFER8(unescaped, UNESCAPE_BUF_SIZE); \
385 len0 = call_ref(escaped0 + escaped_offset, escaped_len, unescaped0 + unescaped_offset); \
386 len1 = call_new(escaped1 + escaped_offset, escaped_len, unescaped1 + unescaped_offset); \
387 if (len0 != len1 || memcmp(unescaped0, unescaped1, UNESCAPE_BUF_SIZE)) \
388 fail(); \
389 } \
390 } while (0)
391
392 13 static void check_unescape(void)
393 {
394 /* This appears to be a typical length of buffer in use */
395 #define LOG2_UNESCAPE_BUF_SIZE 17
396 #define UNESCAPE_BUF_SIZE (1u<<LOG2_UNESCAPE_BUF_SIZE)
397 13 LOCAL_ALIGNED_8(uint8_t, escaped0, [UNESCAPE_BUF_SIZE]);
398 13 LOCAL_ALIGNED_8(uint8_t, escaped1, [UNESCAPE_BUF_SIZE]);
399 13 LOCAL_ALIGNED_8(uint8_t, unescaped0, [UNESCAPE_BUF_SIZE]);
400 13 LOCAL_ALIGNED_8(uint8_t, unescaped1, [UNESCAPE_BUF_SIZE]);
401
402 VC1DSPContext h;
403
404 13 ff_vc1dsp_init(&h);
405
406
2/2
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 12 times.
13 if (check_func(h.vc1_unescape_buffer, "vc1dsp.vc1_unescape_buffer")) {
407 int len0, len1, escaped_offset, unescaped_offset, escaped_len;
408 1 declare_func(int, const uint8_t *, int, uint8_t *);
409
410 /* Test data which consists of escapes sequences packed as tightly as possible */
411
2/2
✓ Branch 0 taken 131072 times.
✓ Branch 1 taken 1 times.
131073 for (int x = 0; x < UNESCAPE_BUF_SIZE; ++x)
412
2/2
✓ Branch 0 taken 43691 times.
✓ Branch 1 taken 87381 times.
131072 escaped1[x] = escaped0[x] = 3 * (x % 3 == 0);
413
6/8
✓ Branch 5 taken 13107200 times.
✓ Branch 6 taken 100 times.
✓ Branch 14 taken 100 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 100 times.
✓ Branch 20 taken 100 times.
✓ Branch 21 taken 1 times.
13107301 TEST_UNESCAPE;
414
415 /* Test random data */
416
2/2
✓ Branch 1 taken 131072 times.
✓ Branch 2 taken 1 times.
131073 RANDOMIZE_BUFFER8(escaped, UNESCAPE_BUF_SIZE);
417
6/8
✓ Branch 5 taken 13107200 times.
✓ Branch 6 taken 100 times.
✓ Branch 14 taken 100 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 100 times.
✓ Branch 20 taken 100 times.
✓ Branch 21 taken 1 times.
13107301 TEST_UNESCAPE;
418
419 /* Test data with escape sequences at random intervals */
420
2/2
✓ Branch 0 taken 1445 times.
✓ Branch 1 taken 1 times.
1446 for (int x = 0; x <= UNESCAPE_BUF_SIZE - 4;) {
421 int gap, gap_msb;
422 1445 escaped1[x+0] = escaped0[x+0] = 0;
423 1445 escaped1[x+1] = escaped0[x+1] = 0;
424 1445 escaped1[x+2] = escaped0[x+2] = 3;
425 1445 escaped1[x+3] = escaped0[x+3] = rnd() & 3;
426 1445 gap_msb = 2u << (rnd() % 8);
427 1445 gap = (rnd() &~ -gap_msb) | gap_msb;
428 1445 x += gap;
429 }
430
6/8
✓ Branch 5 taken 13107200 times.
✓ Branch 6 taken 100 times.
✓ Branch 14 taken 100 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 100 times.
✓ Branch 20 taken 100 times.
✓ Branch 21 taken 1 times.
13107301 TEST_UNESCAPE;
431
432 /* Test data which is known to contain no escape sequences */
433 1 memset(escaped0, 0xFF, UNESCAPE_BUF_SIZE);
434 1 memset(escaped1, 0xFF, UNESCAPE_BUF_SIZE);
435
6/8
✓ Branch 5 taken 13107200 times.
✓ Branch 6 taken 100 times.
✓ Branch 14 taken 100 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 100 times.
✓ Branch 20 taken 100 times.
✓ Branch 21 taken 1 times.
13107301 TEST_UNESCAPE;
436
437 /* Benchmark the no-escape-sequences case */
438
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
1 bench_new(escaped1, UNESCAPE_BUF_SIZE, unescaped1);
439 }
440 13 }
441
442 13 static void check_mspel_pixels(void)
443 {
444 13 LOCAL_ALIGNED_16(uint8_t, src0, [32 * 32]);
445 13 LOCAL_ALIGNED_16(uint8_t, src1, [32 * 32]);
446 13 LOCAL_ALIGNED_16(uint8_t, dst0, [32 * 32]);
447 13 LOCAL_ALIGNED_16(uint8_t, dst1, [32 * 32]);
448
449 VC1DSPContext h;
450
451 13 const test tests[] = {
452 VC1DSP_SIZED_TEST(put_vc1_mspel_pixels_tab[0][0], 16, 16)
453 VC1DSP_SIZED_TEST(put_vc1_mspel_pixels_tab[1][0], 8, 8)
454 VC1DSP_SIZED_TEST(avg_vc1_mspel_pixels_tab[0][0], 16, 16)
455 VC1DSP_SIZED_TEST(avg_vc1_mspel_pixels_tab[1][0], 8, 8)
456 };
457
458 13 ff_vc1dsp_init(&h);
459
460
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 13 times.
65 for (size_t t = 0; t < FF_ARRAY_ELEMS(tests); ++t) {
461 52 void (*func)(uint8_t *, const uint8_t*, ptrdiff_t, int) = *(void **)((intptr_t) &h + tests[t].offset);
462
2/2
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 44 times.
52 if (check_func(func, "vc1dsp.%s", tests[t].name)) {
463
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, const uint8_t*, ptrdiff_t, int);
464
2/2
✓ Branch 1 taken 8192 times.
✓ Branch 2 taken 8 times.
8200 RANDOMIZE_BUFFER8(dst, 32 * 32);
465
2/2
✓ Branch 1 taken 8192 times.
✓ Branch 2 taken 8 times.
8200 RANDOMIZE_BUFFER8(src, 32 * 32);
466 8 call_ref(dst0, src0, 32, 0);
467 8 call_new(dst1, src1, 32, 0);
468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (memcmp(dst0, dst1, 32 * 32)) {
469 fail();
470 }
471
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
8 bench_new(dst1, src0, 32, 0);
472 }
473 }
474 13 }
475
476 13 void checkasm_check_vc1dsp(void)
477 {
478 13 check_inv_trans_inplace();
479 13 check_inv_trans_adding();
480 13 report("inv_trans");
481
482 13 check_loop_filter();
483 13 report("loop_filter");
484
485 13 check_unescape();
486 13 report("unescape_buffer");
487
488 13 check_mspel_pixels();
489 13 report("mspel_pixels");
490 13 }
491