FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/tests/checkasm/sw_rgb.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 261 268 97.4%
Functions: 9 9 100.0%
Branches: 119 194 61.3%

Line Branch Exec Source
1 /*
2 *
3 * This file is part of FFmpeg.
4 *
5 * FFmpeg is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * FFmpeg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <string.h>
21
22 #include "libavutil/common.h"
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/mem_internal.h"
25 #include "libavutil/pixdesc.h"
26
27 #include "libswscale/rgb2rgb.h"
28 #include "libswscale/swscale.h"
29 #include "libswscale/swscale_internal.h"
30
31 #include "checkasm.h"
32
33 #define randomize_buffers(buf, size) \
34 do { \
35 int j; \
36 for (j = 0; j < size; j+=4) \
37 AV_WN32(buf + j, rnd()); \
38 } while (0)
39
40 static const uint8_t width[] = {12, 16, 20, 32, 36, 128};
41 static const struct {uint8_t w, h, s;} planes[] = {
42 {12,16,12}, {16,16,16}, {20,23,25}, {32,18,48}, {8,128,16}, {128,128,128}
43 };
44
45 #define MAX_STRIDE 128
46 #define MAX_HEIGHT 128
47
48 65 static void check_shuffle_bytes(void * func, const char * report)
49 {
50 int i;
51 65 LOCAL_ALIGNED_32(uint8_t, src0, [MAX_STRIDE]);
52 65 LOCAL_ALIGNED_32(uint8_t, src1, [MAX_STRIDE]);
53 65 LOCAL_ALIGNED_32(uint8_t, dst0, [MAX_STRIDE]);
54 65 LOCAL_ALIGNED_32(uint8_t, dst1, [MAX_STRIDE]);
55
56 65 declare_func(void, const uint8_t *src, uint8_t *dst, int src_size);
57
58 65 memset(dst0, 0, MAX_STRIDE);
59 65 memset(dst1, 0, MAX_STRIDE);
60
2/2
✓ Branch 1 taken 2080 times.
✓ Branch 2 taken 65 times.
2145 randomize_buffers(src0, MAX_STRIDE);
61 65 memcpy(src1, src0, MAX_STRIDE);
62
63
2/2
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 50 times.
65 if (check_func(func, "%s", report)) {
64
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 15 times.
105 for (i = 0; i < 6; i ++) {
65 90 call_ref(src0, dst0, width[i]);
66 90 call_new(src1, dst1, width[i]);
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
90 if (memcmp(dst0, dst1, MAX_STRIDE))
68 fail();
69 }
70
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 15 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.
15 bench_new(src0, dst0, width[5]);
71 }
72 65 }
73
74 13 static void check_uyvy_to_422p(void)
75 {
76 int i;
77
78 13 LOCAL_ALIGNED_32(uint8_t, src0, [MAX_STRIDE * MAX_HEIGHT * 2]);
79 13 LOCAL_ALIGNED_32(uint8_t, src1, [MAX_STRIDE * MAX_HEIGHT * 2]);
80 13 LOCAL_ALIGNED_32(uint8_t, dst_y_0, [MAX_STRIDE * MAX_HEIGHT]);
81 13 LOCAL_ALIGNED_32(uint8_t, dst_y_1, [MAX_STRIDE * MAX_HEIGHT]);
82 13 LOCAL_ALIGNED_32(uint8_t, dst_u_0, [(MAX_STRIDE/2) * MAX_HEIGHT]);
83 13 LOCAL_ALIGNED_32(uint8_t, dst_u_1, [(MAX_STRIDE/2) * MAX_HEIGHT]);
84 13 LOCAL_ALIGNED_32(uint8_t, dst_v_0, [(MAX_STRIDE/2) * MAX_HEIGHT]);
85 13 LOCAL_ALIGNED_32(uint8_t, dst_v_1, [(MAX_STRIDE/2) * MAX_HEIGHT]);
86
87 13 declare_func(void, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
88 const uint8_t *src, int width, int height,
89 int lumStride, int chromStride, int srcStride);
90
91
2/2
✓ Branch 1 taken 106496 times.
✓ Branch 2 taken 13 times.
106509 randomize_buffers(src0, MAX_STRIDE * MAX_HEIGHT * 2);
92 13 memcpy(src1, src0, MAX_STRIDE * MAX_HEIGHT * 2);
93
94
2/2
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 9 times.
13 if (check_func(uyvytoyuv422, "uyvytoyuv422")) {
95
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
28 for (i = 0; i < 6; i ++) {
96 24 memset(dst_y_0, 0, MAX_STRIDE * MAX_HEIGHT);
97 24 memset(dst_y_1, 0, MAX_STRIDE * MAX_HEIGHT);
98 24 memset(dst_u_0, 0, (MAX_STRIDE/2) * MAX_HEIGHT);
99 24 memset(dst_u_1, 0, (MAX_STRIDE/2) * MAX_HEIGHT);
100 24 memset(dst_v_0, 0, (MAX_STRIDE/2) * MAX_HEIGHT);
101 24 memset(dst_v_1, 0, (MAX_STRIDE/2) * MAX_HEIGHT);
102
103 24 call_ref(dst_y_0, dst_u_0, dst_v_0, src0, planes[i].w, planes[i].h,
104 MAX_STRIDE, MAX_STRIDE / 2, planes[i].s);
105 24 call_new(dst_y_1, dst_u_1, dst_v_1, src1, planes[i].w, planes[i].h,
106 MAX_STRIDE, MAX_STRIDE / 2, planes[i].s);
107
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (memcmp(dst_y_0, dst_y_1, MAX_STRIDE * MAX_HEIGHT) ||
108
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 memcmp(dst_u_0, dst_u_1, (MAX_STRIDE/2) * MAX_HEIGHT) ||
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 memcmp(dst_v_0, dst_v_1, (MAX_STRIDE/2) * MAX_HEIGHT))
110 fail();
111 }
112
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 4 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.
4 bench_new(dst_y_1, dst_u_1, dst_v_1, src1, planes[5].w, planes[5].h,
113 MAX_STRIDE, MAX_STRIDE / 2, planes[5].s);
114 }
115 13 }
116
117 #define NUM_LINES 5
118 #define MAX_LINE_SIZE 1920
119 #define BUFSIZE (NUM_LINES * MAX_LINE_SIZE)
120
121 15 static int cmp_off_by_n(const uint8_t *ref, const uint8_t *test, size_t n, int accuracy)
122 {
123
2/2
✓ Branch 0 taken 72000 times.
✓ Branch 1 taken 15 times.
72015 for (size_t i = 0; i < n; i++) {
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72000 times.
72000 if (abs(ref[i] - test[i]) > accuracy)
125 return 1;
126 }
127 15 return 0;
128 }
129
130 13 static void check_rgb24toyv12(SwsInternal *ctx)
131 {
132 static const int input_sizes[] = {16, 128, 512, MAX_LINE_SIZE, -MAX_LINE_SIZE};
133
134 13 LOCAL_ALIGNED_32(uint8_t, src, [BUFSIZE * 3]);
135 13 LOCAL_ALIGNED_32(uint8_t, buf_y_0, [BUFSIZE]);
136 13 LOCAL_ALIGNED_32(uint8_t, buf_y_1, [BUFSIZE]);
137 13 LOCAL_ALIGNED_32(uint8_t, buf_u_0, [BUFSIZE / 4]);
138 13 LOCAL_ALIGNED_32(uint8_t, buf_u_1, [BUFSIZE / 4]);
139 13 LOCAL_ALIGNED_32(uint8_t, buf_v_0, [BUFSIZE / 4]);
140 13 LOCAL_ALIGNED_32(uint8_t, buf_v_1, [BUFSIZE / 4]);
141
142 13 declare_func(void, const uint8_t *src, uint8_t *ydst, uint8_t *udst,
143 uint8_t *vdst, int width, int height, int lumStride,
144 int chromStride, int srcStride, int32_t *rgb2yuv);
145
146
2/2
✓ Branch 1 taken 93600 times.
✓ Branch 2 taken 13 times.
93613 randomize_buffers(src, BUFSIZE * 3);
147
148
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 13 times.
78 for (int isi = 0; isi < FF_ARRAY_ELEMS(input_sizes); isi++) {
149 65 int input_size = input_sizes[isi];
150 65 int negstride = input_size < 0;
151
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 52 times.
65 const char *negstride_str = negstride ? "_negstride" : "";
152 65 int width = FFABS(input_size);
153 65 int linesize = width + 32;
154 /* calculate height based on specified width to use the entire buffer. */
155 65 int height = (BUFSIZE / linesize) & ~1;
156 65 uint8_t *src0 = src;
157 65 uint8_t *src1 = src;
158 65 uint8_t *dst_y_0 = buf_y_0;
159 65 uint8_t *dst_y_1 = buf_y_1;
160 65 uint8_t *dst_u_0 = buf_u_0;
161 65 uint8_t *dst_u_1 = buf_u_1;
162 65 uint8_t *dst_v_0 = buf_v_0;
163 65 uint8_t *dst_v_1 = buf_v_1;
164
165
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 52 times.
65 if (negstride) {
166 13 src0 += (height - 1) * (linesize * 3);
167 13 src1 += (height - 1) * (linesize * 3);
168 13 dst_y_0 += (height - 1) * linesize;
169 13 dst_y_1 += (height - 1) * linesize;
170 13 dst_u_0 += ((height / 2) - 1) * (linesize / 2);
171 13 dst_u_1 += ((height / 2) - 1) * (linesize / 2);
172 13 dst_v_0 += ((height / 2) - 1) * (linesize / 2);
173 13 dst_v_1 += ((height / 2) - 1) * (linesize / 2);
174 13 linesize *= -1;
175 }
176
177
2/2
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 60 times.
65 if (check_func(ff_rgb24toyv12, "rgb24toyv12_%d_%d%s", width, height, negstride_str)) {
178 5 memset(buf_y_0, 0xFF, BUFSIZE);
179 5 memset(buf_y_1, 0xFF, BUFSIZE);
180 5 memset(buf_u_0, 0xFF, BUFSIZE / 4);
181 5 memset(buf_u_1, 0xFF, BUFSIZE / 4);
182 5 memset(buf_v_0, 0xFF, BUFSIZE / 4);
183 5 memset(buf_v_1, 0xFF, BUFSIZE / 4);
184
185 5 call_ref(src0, dst_y_0, dst_u_0, dst_v_0, width, height,
186 linesize, linesize / 2, linesize * 3, ctx->input_rgb2yuv_table);
187 5 call_new(src1, dst_y_1, dst_u_1, dst_v_1, width, height,
188 linesize, linesize / 2, linesize * 3, ctx->input_rgb2yuv_table);
189
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if (cmp_off_by_n(buf_y_0, buf_y_1, BUFSIZE, 1) ||
190
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 cmp_off_by_n(buf_u_0, buf_u_1, BUFSIZE / 4, 1) ||
191
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 cmp_off_by_n(buf_v_0, buf_v_1, BUFSIZE / 4, 1))
192 fail();
193
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 5 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.
5 bench_new(src1, dst_y_1, dst_u_1, dst_v_1, width, height,
194 linesize, linesize / 2, linesize * 3, ctx->input_rgb2yuv_table);
195 }
196 }
197 13 }
198
199 #undef NUM_LINES
200 #undef MAX_LINE_SIZE
201 #undef BUFSIZE
202
203 13 static void check_interleave_bytes(void)
204 {
205 13 LOCAL_ALIGNED_16(uint8_t, src0_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
206 13 LOCAL_ALIGNED_16(uint8_t, src1_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
207 13 LOCAL_ALIGNED_16(uint8_t, dst0_buf, [2*MAX_STRIDE*MAX_HEIGHT+2]);
208 13 LOCAL_ALIGNED_16(uint8_t, dst1_buf, [2*MAX_STRIDE*MAX_HEIGHT+2]);
209 // Intentionally using unaligned buffers, as this function doesn't have
210 // any alignment requirements.
211 13 uint8_t *src0 = src0_buf + 1;
212 13 uint8_t *src1 = src1_buf + 1;
213 13 uint8_t *dst0 = dst0_buf + 2;
214 13 uint8_t *dst1 = dst1_buf + 2;
215
216 13 declare_func(void, const uint8_t *, const uint8_t *,
217 uint8_t *, int, int, int, int, int);
218
219
2/2
✓ Branch 1 taken 53248 times.
✓ Branch 2 taken 13 times.
53261 randomize_buffers(src0, MAX_STRIDE * MAX_HEIGHT);
220
2/2
✓ Branch 1 taken 53248 times.
✓ Branch 2 taken 13 times.
53261 randomize_buffers(src1, MAX_STRIDE * MAX_HEIGHT);
221
222
2/2
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 11 times.
13 if (check_func(interleaveBytes, "interleave_bytes")) {
223
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 2 times.
36 for (int i = 0; i <= 16; i++) {
224 // Try all widths [1,16], and try one random width.
225
226
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 32 times.
34 int w = i > 0 ? i : (1 + (rnd() % (MAX_STRIDE-2)));
227 34 int h = 1 + (rnd() % (MAX_HEIGHT-2));
228
229 34 int src0_offset = 0, src0_stride = MAX_STRIDE;
230 34 int src1_offset = 0, src1_stride = MAX_STRIDE;
231 34 int dst_offset = 0, dst_stride = 2 * MAX_STRIDE;
232
233 34 memset(dst0, 0, 2 * MAX_STRIDE * MAX_HEIGHT);
234 34 memset(dst1, 0, 2 * MAX_STRIDE * MAX_HEIGHT);
235
236 // Try different combinations of negative strides
237
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 18 times.
34 if (i & 1) {
238 16 src0_offset = (h-1)*src0_stride;
239 16 src0_stride = -src0_stride;
240 }
241
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 18 times.
34 if (i & 2) {
242 16 src1_offset = (h-1)*src1_stride;
243 16 src1_stride = -src1_stride;
244 }
245
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 18 times.
34 if (i & 4) {
246 16 dst_offset = (h-1)*dst_stride;
247 16 dst_stride = -dst_stride;
248 }
249
250 34 call_ref(src0 + src0_offset, src1 + src1_offset, dst0 + dst_offset,
251 w, h, src0_stride, src1_stride, dst_stride);
252 34 call_new(src0 + src0_offset, src1 + src1_offset, dst1 + dst_offset,
253 w, h, src0_stride, src1_stride, dst_stride);
254 // Check a one pixel-pair edge around the destination area,
255 // to catch overwrites past the end.
256 34 checkasm_check(uint8_t, dst0, 2*MAX_STRIDE, dst1, 2*MAX_STRIDE,
257 2 * w + 2, h + 1, "dst");
258 }
259
260
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 2 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.
2 bench_new(src0, src1, dst1, 127, MAX_HEIGHT,
261 MAX_STRIDE, MAX_STRIDE, 2*MAX_STRIDE);
262 }
263
2/2
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 11 times.
13 if (check_func(interleaveBytes, "interleave_bytes_aligned")) {
264 // Bench the function in a more typical case, with aligned
265 // buffers and widths.
266
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 2 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.
2 bench_new(src0_buf, src1_buf, dst1_buf, 128, MAX_HEIGHT,
267 MAX_STRIDE, MAX_STRIDE, 2*MAX_STRIDE);
268 }
269 13 }
270
271 13 static void check_deinterleave_bytes(void)
272 {
273 13 LOCAL_ALIGNED_16(uint8_t, src_buf, [2*MAX_STRIDE*MAX_HEIGHT+2]);
274 13 LOCAL_ALIGNED_16(uint8_t, dst0_u_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
275 13 LOCAL_ALIGNED_16(uint8_t, dst0_v_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
276 13 LOCAL_ALIGNED_16(uint8_t, dst1_u_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
277 13 LOCAL_ALIGNED_16(uint8_t, dst1_v_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
278 // Intentionally using unaligned buffers, as this function doesn't have
279 // any alignment requirements.
280 13 uint8_t *src = src_buf + 2;
281 13 uint8_t *dst0_u = dst0_u_buf + 1;
282 13 uint8_t *dst0_v = dst0_v_buf + 1;
283 13 uint8_t *dst1_u = dst1_u_buf + 1;
284 13 uint8_t *dst1_v = dst1_v_buf + 1;
285
286 13 declare_func(void, const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
287 int width, int height, int srcStride,
288 int dst1Stride, int dst2Stride);
289
290
2/2
✓ Branch 1 taken 106496 times.
✓ Branch 2 taken 13 times.
106509 randomize_buffers(src, 2*MAX_STRIDE*MAX_HEIGHT);
291
292
2/2
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 10 times.
13 if (check_func(deinterleaveBytes, "deinterleave_bytes")) {
293
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 3 times.
54 for (int i = 0; i <= 16; i++) {
294 // Try all widths [1,16], and try one random width.
295
296
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 48 times.
51 int w = i > 0 ? i : (1 + (rnd() % (MAX_STRIDE-2)));
297 51 int h = 1 + (rnd() % (MAX_HEIGHT-2));
298
299 51 int src_offset = 0, src_stride = 2 * MAX_STRIDE;
300 51 int dst_u_offset = 0, dst_u_stride = MAX_STRIDE;
301 51 int dst_v_offset = 0, dst_v_stride = MAX_STRIDE;
302
303 51 memset(dst0_u, 0, MAX_STRIDE * MAX_HEIGHT);
304 51 memset(dst0_v, 0, MAX_STRIDE * MAX_HEIGHT);
305 51 memset(dst1_u, 0, MAX_STRIDE * MAX_HEIGHT);
306 51 memset(dst1_v, 0, MAX_STRIDE * MAX_HEIGHT);
307
308 // Try different combinations of negative strides
309
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 27 times.
51 if (i & 1) {
310 24 src_offset = (h-1)*src_stride;
311 24 src_stride = -src_stride;
312 }
313
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 27 times.
51 if (i & 2) {
314 24 dst_u_offset = (h-1)*dst_u_stride;
315 24 dst_u_stride = -dst_u_stride;
316 }
317
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 27 times.
51 if (i & 4) {
318 24 dst_v_offset = (h-1)*dst_v_stride;
319 24 dst_v_stride = -dst_v_stride;
320 }
321
322 51 call_ref(src + src_offset, dst0_u + dst_u_offset, dst0_v + dst_v_offset,
323 w, h, src_stride, dst_u_stride, dst_v_stride);
324 51 call_new(src + src_offset, dst1_u + dst_u_offset, dst1_v + dst_v_offset,
325 w, h, src_stride, dst_u_stride, dst_v_stride);
326 // Check a one pixel-pair edge around the destination area,
327 // to catch overwrites past the end.
328 51 checkasm_check(uint8_t, dst0_u, MAX_STRIDE, dst1_u, MAX_STRIDE,
329 w + 1, h + 1, "dst_u");
330 51 checkasm_check(uint8_t, dst0_v, MAX_STRIDE, dst1_v, MAX_STRIDE,
331 w + 1, h + 1, "dst_v");
332 }
333
334
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 3 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.
3 bench_new(src, dst1_u, dst1_v, 127, MAX_HEIGHT,
335 2*MAX_STRIDE, MAX_STRIDE, MAX_STRIDE);
336 }
337
2/2
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 10 times.
13 if (check_func(deinterleaveBytes, "deinterleave_bytes_aligned")) {
338 // Bench the function in a more typical case, with aligned
339 // buffers and widths.
340
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 3 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.
3 bench_new(src_buf, dst1_u_buf, dst1_v_buf, 128, MAX_HEIGHT,
341 2*MAX_STRIDE, MAX_STRIDE, MAX_STRIDE);
342 }
343 13 }
344
345 #define MAX_LINE_SIZE 1920
346 static const int input_sizes[] = {8, 128, 1080, MAX_LINE_SIZE};
347 static const enum AVPixelFormat rgb_formats[] = {
348 AV_PIX_FMT_RGB24,
349 AV_PIX_FMT_BGR24,
350 AV_PIX_FMT_RGBA,
351 AV_PIX_FMT_BGRA,
352 AV_PIX_FMT_ABGR,
353 AV_PIX_FMT_ARGB,
354 };
355
356 13 static void check_rgb_to_y(SwsInternal *ctx)
357 {
358 13 LOCAL_ALIGNED_16(uint8_t, src24, [MAX_LINE_SIZE * 3]);
359 13 LOCAL_ALIGNED_16(uint8_t, src32, [MAX_LINE_SIZE * 4]);
360 13 LOCAL_ALIGNED_32(uint8_t, dst0_y, [MAX_LINE_SIZE * 2]);
361 13 LOCAL_ALIGNED_32(uint8_t, dst1_y, [MAX_LINE_SIZE * 2]);
362
363 13 declare_func(void, uint8_t *dst, const uint8_t *src,
364 const uint8_t *unused1, const uint8_t *unused2, int width,
365 uint32_t *rgb2yuv, void *opq);
366
367
2/2
✓ Branch 1 taken 18720 times.
✓ Branch 2 taken 13 times.
18733 randomize_buffers(src24, MAX_LINE_SIZE * 3);
368
2/2
✓ Branch 1 taken 24960 times.
✓ Branch 2 taken 13 times.
24973 randomize_buffers(src32, MAX_LINE_SIZE * 4);
369
370
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 13 times.
91 for (int i = 0; i < FF_ARRAY_ELEMS(rgb_formats); i++) {
371 78 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(rgb_formats[i]);
372
373 78 ctx->srcFormat = rgb_formats[i];
374 78 ff_sws_init_scale(ctx);
375
376
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 78 times.
390 for (int j = 0; j < FF_ARRAY_ELEMS(input_sizes); j++) {
377 312 int w = input_sizes[j];
378
379
2/2
✓ Branch 3 taken 104 times.
✓ Branch 4 taken 208 times.
312 if (check_func(ctx->lumToYV12, "%s_to_y_%d", desc->name, w)) {
380
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 64 times.
104 const uint8_t *src = desc->nb_components == 3 ? src24 : src32;
381 104 memset(dst0_y, 0xFA, MAX_LINE_SIZE * 2);
382 104 memset(dst1_y, 0xFA, MAX_LINE_SIZE * 2);
383
384 104 call_ref(dst0_y, src, NULL, NULL, w, ctx->input_rgb2yuv_table, NULL);
385 104 call_new(dst1_y, src, NULL, NULL, w, ctx->input_rgb2yuv_table, NULL);
386
387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
104 if (memcmp(dst0_y, dst1_y, w * 2))
388 fail();
389
390
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 40 times.
104 if (desc->nb_components == 3 ||
391 // only bench native endian formats
392
4/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 32 times.
64 (ctx->srcFormat == AV_PIX_FMT_RGB32 || ctx->srcFormat == AV_PIX_FMT_RGB32_1))
393
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 72 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.
72 bench_new(dst1_y, src, NULL, NULL, w, ctx->input_rgb2yuv_table, NULL);
394 }
395 }
396 }
397 13 }
398
399 13 static void check_rgb_to_uv(SwsInternal *ctx)
400 {
401 13 LOCAL_ALIGNED_16(uint8_t, src24, [MAX_LINE_SIZE * 3]);
402 13 LOCAL_ALIGNED_16(uint8_t, src32, [MAX_LINE_SIZE * 4]);
403 13 LOCAL_ALIGNED_16(uint8_t, dst0_u, [MAX_LINE_SIZE * 2]);
404 13 LOCAL_ALIGNED_16(uint8_t, dst0_v, [MAX_LINE_SIZE * 2]);
405 13 LOCAL_ALIGNED_16(uint8_t, dst1_u, [MAX_LINE_SIZE * 2]);
406 13 LOCAL_ALIGNED_16(uint8_t, dst1_v, [MAX_LINE_SIZE * 2]);
407
408 13 declare_func(void, uint8_t *dstU, uint8_t *dstV,
409 const uint8_t *src1, const uint8_t *src2, const uint8_t *src3,
410 int width, uint32_t *pal, void *opq);
411
412
2/2
✓ Branch 1 taken 18720 times.
✓ Branch 2 taken 13 times.
18733 randomize_buffers(src24, MAX_LINE_SIZE * 3);
413
2/2
✓ Branch 1 taken 24960 times.
✓ Branch 2 taken 13 times.
24973 randomize_buffers(src32, MAX_LINE_SIZE * 4);
414
415
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 13 times.
169 for (int i = 0; i < 2 * FF_ARRAY_ELEMS(rgb_formats); i++) {
416 156 enum AVPixelFormat src_fmt = rgb_formats[i / 2];
417 156 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src_fmt);
418
419 156 ctx->chrSrcHSubSample = (i % 2) ? 0 : 1;
420 156 ctx->srcFormat = src_fmt;
421
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 78 times.
156 ctx->dstFormat = ctx->chrSrcHSubSample ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV444P;
422 156 ff_sws_init_scale(ctx);
423
424
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 156 times.
780 for (int j = 0; j < FF_ARRAY_ELEMS(input_sizes); j++) {
425 624 int w = input_sizes[j] >> ctx->chrSrcHSubSample;
426
427
4/4
✓ Branch 2 taken 312 times.
✓ Branch 3 taken 312 times.
✓ Branch 5 taken 128 times.
✓ Branch 6 taken 496 times.
624 if (check_func(ctx->chrToYV12, "%s_to_uv%s_%d", desc->name,
428 ctx->chrSrcHSubSample ? "_half" : "",
429 input_sizes[j])) {
430
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 80 times.
128 const uint8_t *src = desc->nb_components == 3 ? src24 : src32;
431 128 memset(dst0_u, 0xFF, MAX_LINE_SIZE * 2);
432 128 memset(dst0_v, 0xFF, MAX_LINE_SIZE * 2);
433 128 memset(dst1_u, 0xFF, MAX_LINE_SIZE * 2);
434 128 memset(dst1_v, 0xFF, MAX_LINE_SIZE * 2);
435
436 128 call_ref(dst0_u, dst0_v, NULL, src, src, w, ctx->input_rgb2yuv_table, NULL);
437 128 call_new(dst1_u, dst1_v, NULL, src, src, w, ctx->input_rgb2yuv_table, NULL);
438
439
2/4
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 128 times.
128 if (memcmp(dst0_u, dst1_u, w * 2) || memcmp(dst0_v, dst1_v, w * 2))
440 fail();
441
442
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 48 times.
128 if (desc->nb_components == 3 ||
443 // only bench native endian formats
444
4/4
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 40 times.
80 (ctx->srcFormat == AV_PIX_FMT_RGB32 || ctx->srcFormat == AV_PIX_FMT_RGB32_1))
445
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 88 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.
88 bench_new(dst1_u, dst1_v, NULL, src, src, w, ctx->input_rgb2yuv_table, NULL);
446 }
447 }
448 }
449 13 }
450
451 13 void checkasm_check_sw_rgb(void)
452 {
453 SwsContext *sws;
454 SwsInternal *c;
455
456 13 ff_sws_rgb2rgb_init();
457
458 13 check_shuffle_bytes(shuffle_bytes_2103, "shuffle_bytes_2103");
459 13 report("shuffle_bytes_2103");
460
461 13 check_shuffle_bytes(shuffle_bytes_0321, "shuffle_bytes_0321");
462 13 report("shuffle_bytes_0321");
463
464 13 check_shuffle_bytes(shuffle_bytes_1230, "shuffle_bytes_1230");
465 13 report("shuffle_bytes_1230");
466
467 13 check_shuffle_bytes(shuffle_bytes_3012, "shuffle_bytes_3012");
468 13 report("shuffle_bytes_3012");
469
470 13 check_shuffle_bytes(shuffle_bytes_3210, "shuffle_bytes_3210");
471 13 report("shuffle_bytes_3210");
472
473 13 check_uyvy_to_422p();
474 13 report("uyvytoyuv422");
475
476 13 check_interleave_bytes();
477 13 report("interleave_bytes");
478
479 13 check_deinterleave_bytes();
480 13 report("deinterleave_bytes");
481
482 13 sws = sws_getContext(MAX_LINE_SIZE, MAX_LINE_SIZE, AV_PIX_FMT_RGB24,
483 MAX_LINE_SIZE, MAX_LINE_SIZE, AV_PIX_FMT_YUV420P,
484 SWS_ACCURATE_RND | SWS_BITEXACT, NULL, NULL, NULL);
485
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!sws)
486 fail();
487
488 13 c = sws_internal(sws);
489 13 check_rgb_to_y(c);
490 13 report("rgb_to_y");
491
492 13 check_rgb_to_uv(c);
493 13 report("rgb_to_uv");
494
495 13 check_rgb24toyv12(c);
496 13 report("rgb24toyv12");
497
498 13 sws_freeContext(sws);
499 13 }
500