FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/tests/checkasm/vf_fspp.c
Date: 2026-04-21 03:24:50
Exec Total Coverage
Lines: 68 71 95.8%
Functions: 4 4 100.0%
Branches: 37 62 59.7%

Line Branch Exec Source
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 <stddef.h>
20 #include <stdint.h>
21
22 #include "checkasm.h"
23 #include "libavfilter/vf_fsppdsp.h"
24 #include "libavcodec/mathops.h"
25 #include "libavutil/mem_internal.h"
26
27 #define randomize_buffers(buf) \
28 do { \
29 for (size_t j = 0; j < FF_ARRAY_ELEMS(buf); ++j) \
30 buf[j] = rnd(); \
31 } while (0)
32
33 #define randomize_mask_buffers(buf, buf2, nb_elems, nb_bits)\
34 do { \
35 for (size_t j = 0; j < nb_elems; ++j) \
36 buf[j] = buf2[j] = sign_extend(rnd(), nb_bits); \
37 } while (0)
38
39 #define randomize_buffer_range(buf, min, max) \
40 do { \
41 for (size_t j = 0; j < FF_ARRAY_ELEMS(buf); ++j) \
42 buf[j] = min + rnd() % (max - min + 1); \
43 } while (0)
44
45 14 static void check_store_slice(void)
46 {
47 enum {
48 MAX_WIDTH = 256,
49 /// in elements, not in bytes; 32 is arbitrary
50 MAX_STRIDE = MAX_WIDTH + 32,
51 MAX_HEIGHT = 8,
52 };
53 FSPPDSPContext fspp;
54 14 ff_fsppdsp_init(&fspp);
55 14 declare_func(void, uint8_t *dst, int16_t *src,
56 ptrdiff_t dst_stride, ptrdiff_t src_stride,
57 ptrdiff_t width, ptrdiff_t height, ptrdiff_t log2_scale);
58
59
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
42 for (int i = 0; i < 2; ++i) {
60
6/6
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 14 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 24 times.
28 if (check_func(i ? fspp.store_slice2 : fspp.store_slice, "store_slice%s", i ? "2" : "")) {
61 // store slice resets the row eight lines above the current one
62 DECLARE_ALIGNED(16, int16_t, src_ref1)[MAX_STRIDE * ( 8 + MAX_HEIGHT - 1) + MAX_WIDTH];
63 DECLARE_ALIGNED(16, int16_t, src_new1)[MAX_STRIDE * ( 8 + MAX_HEIGHT - 1) + MAX_WIDTH];
64 // store_slice2 resets the row 16 lines below the current one
65 DECLARE_ALIGNED(16, int16_t, src_ref2)[MAX_STRIDE * (16 + MAX_HEIGHT - 1) + MAX_WIDTH];
66 DECLARE_ALIGNED(16, int16_t, src_new2)[MAX_STRIDE * (16 + MAX_HEIGHT - 1) + MAX_WIDTH];
67 uint8_t dstbuf_new[MAX_STRIDE * (MAX_HEIGHT - 1) + MAX_WIDTH], dstbuf_ref[MAX_STRIDE * (MAX_HEIGHT - 1) + MAX_WIDTH];
68 4 uint8_t *dst_new = dstbuf_new, *dst_ref = dstbuf_ref;
69 int16_t *src_ref, *src_new, *or_src_ref, *or_src_new;
70 4 ptrdiff_t width = 1 + rnd() % MAX_WIDTH;
71 4 ptrdiff_t src_stride = FFALIGN(width + 1 + rnd() % (MAX_STRIDE - MAX_WIDTH), 8);
72 4 ptrdiff_t dst_stride = FFALIGN(width + 1 + rnd() % (MAX_STRIDE - MAX_WIDTH), 8);
73 4 ptrdiff_t height = 1 + rnd() % 8;
74 size_t nb_elems;
75
76
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (i) {
77 2 src_ref = src_ref2;
78 2 src_new = src_new2;
79 2 or_src_ref = src_ref2;
80 2 or_src_new = src_new2;
81 2 nb_elems = FF_ARRAY_ELEMS(src_ref2);
82 } else {
83 2 src_ref = src_ref1 + 8 * src_stride;
84 2 src_new = src_new1 + 8 * src_stride;
85 2 or_src_ref = src_ref1;
86 2 or_src_new = src_new1;
87 2 nb_elems = FF_ARRAY_ELEMS(src_ref1);
88 }
89
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 if (rnd() & 1) {
90 2 dst_ref += dst_stride * (height - 1);
91 2 dst_new += dst_stride * (height - 1);
92 2 dst_stride *= -1;
93 }
94
2/2
✓ Branch 1 taken 9088 times.
✓ Branch 2 taken 4 times.
9092 randomize_buffers(dstbuf_new);
95 4 memcpy(dstbuf_ref, dstbuf_new, sizeof(dstbuf_ref));
96
2/2
✓ Branch 1 taken 22912 times.
✓ Branch 2 taken 4 times.
22916 randomize_mask_buffers(or_src_ref, or_src_new, nb_elems, 14);
97
98 4 ptrdiff_t log2_scale = rnd() & 1;
99 4 call_ref(dst_ref, src_ref, dst_stride, src_stride, width, height, log2_scale);
100 4 call_new(dst_new, src_new, dst_stride, src_stride, width, height, log2_scale);
101
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (memcmp(dstbuf_new, dstbuf_ref, sizeof(dstbuf_ref)) ||
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 memcmp(or_src_ref, or_src_new, sizeof(*or_src_new) * nb_elems))
103 fail();
104 // don't use random parameters for benchmarks
105
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 src_ref = or_src_ref + !i * 8 * MAX_STRIDE;
106
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
4 bench_new(dstbuf_new, src_ref,
107 MAX_STRIDE, MAX_STRIDE, MAX_WIDTH, 8, 1);
108 }
109 }
110 14 }
111
112 14 static void check_mul_thrmat(void)
113 {
114 FSPPDSPContext fspp;
115 DECLARE_ALIGNED(16, int16_t, src)[64];
116 DECLARE_ALIGNED(16, int16_t, dst_ref)[64];
117 DECLARE_ALIGNED(16, int16_t, dst_new)[64];
118 14 const int q = (uint8_t)rnd();
119 14 declare_func(void, const int16_t *thr_adr_noq, int16_t *thr_adr, int q);
120
121 14 ff_fsppdsp_init(&fspp);
122
123
2/2
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 12 times.
14 if (check_func(fspp.mul_thrmat, "mul_thrmat")) {
124
2/2
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 2 times.
130 randomize_buffers(src);
125 2 call_ref(src, dst_ref, q);
126 2 call_new(src, dst_new, q);
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (memcmp(dst_ref, dst_new, sizeof(dst_ref)))
128 fail();
129
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
2 bench_new(src, dst_new, q);
130 }
131 14 }
132
133 14 static void check_column_fidct(void)
134 {
135 enum {
136 NB_BLOCKS = 8, ///< arbitrary
137 };
138 FSPPDSPContext fspp;
139 14 declare_func(void, const int16_t *thr_adr, const int16_t *data,
140 int16_t *output, int cnt);
141
142 14 ff_fsppdsp_init(&fspp);
143
144
2/2
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 12 times.
14 if (check_func(fspp.column_fidct, "column_fidct")) {
145 DECLARE_ALIGNED(16, int16_t, threshold)[64];
146 DECLARE_ALIGNED(16, int16_t, src)[8*(8*NB_BLOCKS + 6)];
147 DECLARE_ALIGNED(16, int16_t, dst_new)[8*(8*NB_BLOCKS + 6)];
148 DECLARE_ALIGNED(16, int16_t, dst_ref)[8*(8*NB_BLOCKS + 6)];
149
150
2/2
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 2 times.
130 randomize_buffer_range(threshold, 0, INT16_MAX);
151
2/2
✓ Branch 1 taken 1120 times.
✓ Branch 2 taken 2 times.
1122 randomize_buffer_range(src, -1284, 1284);
152
2/2
✓ Branch 1 taken 1120 times.
✓ Branch 2 taken 2 times.
1122 randomize_buffers(dst_new);
153 2 memcpy(dst_ref, dst_new, sizeof(dst_ref));
154
155 2 call_ref(threshold, src, dst_ref, NB_BLOCKS * 8);
156 2 call_new(threshold, src, dst_new, NB_BLOCKS * 8);
157
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (memcmp(dst_new, dst_ref, sizeof(dst_new)))
159 fail();
160
161
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
2 bench_new(threshold, src, dst_new, NB_BLOCKS * 8);
162 }
163 14 }
164
165 14 void checkasm_check_vf_fspp(void)
166 {
167 14 check_store_slice();
168 14 report("store_slice");
169 14 check_mul_thrmat();
170 14 report("mul_thrmat");
171 14 check_column_fidct();
172 14 report("column_fidct");
173 14 }
174