FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/tests/checkasm/sw_yuv2rgb.c
Date: 2024-09-07 18:49:03
Exec Total Coverage
Lines: 103 116 88.8%
Functions: 5 5 100.0%
Branches: 65 88 73.9%

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 <string.h>
20
21 #include "libavutil/common.h"
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/mem_internal.h"
24 #include "libavutil/pixdesc.h"
25
26 #include "libswscale/swscale.h"
27 #include "libswscale/swscale_internal.h"
28
29 #include "checkasm.h"
30
31 #define randomize_buffers(buf, size) \
32 do { \
33 for (int j = 0; j < size; j += 4) \
34 AV_WN32(buf + j, rnd()); \
35 } while (0)
36
37 static const int dst_fmts[] = {
38 // AV_PIX_FMT_BGR48BE,
39 // AV_PIX_FMT_BGR48LE,
40 // AV_PIX_FMT_RGB48BE,
41 // AV_PIX_FMT_RGB48LE,
42 AV_PIX_FMT_ARGB,
43 AV_PIX_FMT_ABGR,
44 AV_PIX_FMT_RGBA,
45 AV_PIX_FMT_BGRA,
46 AV_PIX_FMT_RGB24,
47 AV_PIX_FMT_BGR24,
48 AV_PIX_FMT_RGB565,
49 AV_PIX_FMT_BGR565,
50 AV_PIX_FMT_RGB555,
51 AV_PIX_FMT_BGR555,
52 // AV_PIX_FMT_RGB444,
53 // AV_PIX_FMT_BGR444,
54 // AV_PIX_FMT_RGB8,
55 // AV_PIX_FMT_BGR8,
56 // AV_PIX_FMT_RGB4,
57 // AV_PIX_FMT_BGR4,
58 // AV_PIX_FMT_RGB4_BYTE,
59 // AV_PIX_FMT_BGR4_BYTE,
60 // AV_PIX_FMT_MONOBLACK,
61 AV_PIX_FMT_GBRP,
62 };
63
64 384 static int cmp_off_by_n(const uint8_t *ref, const uint8_t *test, size_t n, int accuracy)
65 {
66
2/2
✓ Branch 0 taken 790272 times.
✓ Branch 1 taken 384 times.
790656 for (size_t i = 0; i < n; i++) {
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 790272 times.
790272 if (abs(ref[i] - test[i]) > accuracy)
68 return 1;
69 }
70 384 return 0;
71 }
72
73 72 static int cmp_555_by_n(const uint8_t *ref, const uint8_t *test, size_t n, int accuracy)
74 {
75 72 const uint16_t *ref16 = (const uint16_t *) ref;
76 72 const uint16_t *test16 = (const uint16_t *) test;
77
2/2
✓ Branch 0 taken 56448 times.
✓ Branch 1 taken 72 times.
56520 for (size_t i = 0; i < n; i++) {
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56448 times.
56448 if (abs(( ref16[i] & 0x1f) - ( test16[i] & 0x1f)) > accuracy)
79 return 1;
80
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56448 times.
56448 if (abs(((ref16[i] >> 5) & 0x1f) - ((test16[i] >> 5) & 0x1f)) > accuracy)
81 return 1;
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56448 times.
56448 if (abs(((ref16[i] >> 10) & 0x1f) - ((test16[i] >> 10) & 0x1f)) > accuracy)
83 return 1;
84 }
85 72 return 0;
86 }
87
88 72 static int cmp_565_by_n(const uint8_t *ref, const uint8_t *test, size_t n, int accuracy)
89 {
90 72 const uint16_t *ref16 = (const uint16_t *) ref;
91 72 const uint16_t *test16 = (const uint16_t *) test;
92
2/2
✓ Branch 0 taken 56448 times.
✓ Branch 1 taken 72 times.
56520 for (size_t i = 0; i < n; i++) {
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56448 times.
56448 if (abs(( ref16[i] & 0x1f) - ( test16[i] & 0x1f)) > accuracy)
94 return 1;
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56448 times.
56448 if (abs(((ref16[i] >> 5) & 0x3f) - ((test16[i] >> 5) & 0x3f)) > accuracy)
96 return 1;
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56448 times.
56448 if (abs(((ref16[i] >> 11) & 0x1f) - ((test16[i] >> 11) & 0x1f)) > accuracy)
98 return 1;
99 }
100 72 return 0;
101 }
102
103 39 static void check_yuv2rgb(int src_pix_fmt)
104 {
105 39 const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt);
106 #define MAX_LINE_SIZE 1920
107 static const int input_sizes[] = {8, 128, 1080, MAX_LINE_SIZE};
108
109
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 3 times.
39 declare_func_emms(AV_CPU_FLAG_MMX | AV_CPU_FLAG_MMXEXT,
110 int, SwsContext *c, const uint8_t *src[],
111 int srcStride[], int srcSliceY, int srcSliceH,
112 uint8_t *dst[], int dstStride[]);
113
114 39 LOCAL_ALIGNED_8(uint8_t, src_y, [MAX_LINE_SIZE * 2]);
115 39 LOCAL_ALIGNED_8(uint8_t, src_u, [MAX_LINE_SIZE]);
116 39 LOCAL_ALIGNED_8(uint8_t, src_v, [MAX_LINE_SIZE]);
117 39 LOCAL_ALIGNED_8(uint8_t, src_a, [MAX_LINE_SIZE * 2]);
118 39 const uint8_t *src[4] = { src_y, src_u, src_v, src_a };
119
120 39 LOCAL_ALIGNED_8(uint8_t, dst0_0, [2 * MAX_LINE_SIZE * 6]);
121 39 LOCAL_ALIGNED_8(uint8_t, dst0_1, [2 * MAX_LINE_SIZE]);
122 39 LOCAL_ALIGNED_8(uint8_t, dst0_2, [2 * MAX_LINE_SIZE]);
123 39 uint8_t *dst0[4] = { dst0_0, dst0_1, dst0_2 };
124 39 uint8_t *lines0[4][2] = {
125 39 { dst0_0, dst0_0 + MAX_LINE_SIZE * 6 },
126 39 { dst0_1, dst0_1 + MAX_LINE_SIZE },
127 39 { dst0_2, dst0_2 + MAX_LINE_SIZE }
128 };
129
130 39 LOCAL_ALIGNED_8(uint8_t, dst1_0, [2 * MAX_LINE_SIZE * 6]);
131 39 LOCAL_ALIGNED_8(uint8_t, dst1_1, [2 * MAX_LINE_SIZE]);
132 39 LOCAL_ALIGNED_8(uint8_t, dst1_2, [2 * MAX_LINE_SIZE]);
133 39 uint8_t *dst1[4] = { dst1_0, dst1_1, dst1_2 };
134 39 uint8_t *lines1[4][2] = {
135 39 { dst1_0, dst1_0 + MAX_LINE_SIZE * 6 },
136 39 { dst1_1, dst1_1 + MAX_LINE_SIZE },
137 39 { dst1_2, dst1_2 + MAX_LINE_SIZE }
138 };
139
140
2/2
✓ Branch 1 taken 37440 times.
✓ Branch 2 taken 39 times.
37479 randomize_buffers(src_y, MAX_LINE_SIZE * 2);
141
2/2
✓ Branch 1 taken 18720 times.
✓ Branch 2 taken 39 times.
18759 randomize_buffers(src_u, MAX_LINE_SIZE);
142
2/2
✓ Branch 1 taken 18720 times.
✓ Branch 2 taken 39 times.
18759 randomize_buffers(src_v, MAX_LINE_SIZE);
143
2/2
✓ Branch 1 taken 37440 times.
✓ Branch 2 taken 39 times.
37479 randomize_buffers(src_a, MAX_LINE_SIZE * 2);
144
145
2/2
✓ Branch 0 taken 429 times.
✓ Branch 1 taken 39 times.
468 for (int dfi = 0; dfi < FF_ARRAY_ELEMS(dst_fmts); dfi++) {
146 429 int dst_pix_fmt = dst_fmts[dfi];
147 429 const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt);
148 429 int sample_size = av_get_padded_bits_per_pixel(dst_desc) >> 3;
149
2/2
✓ Branch 0 taken 1716 times.
✓ Branch 1 taken 429 times.
2145 for (int isi = 0; isi < FF_ARRAY_ELEMS(input_sizes); isi++) {
150 struct SwsContext *ctx;
151 int log_level;
152 1716 int width = input_sizes[isi];
153 1716 int srcSliceY = 0;
154 1716 int srcSliceH = 2;
155 1716 int srcStride[4] = {
156 width,
157 1716 width >> src_desc->log2_chroma_w,
158 1716 width >> src_desc->log2_chroma_w,
159 width,
160 };
161 1716 int dstStride[4] = {
162 MAX_LINE_SIZE * 6,
163 MAX_LINE_SIZE,
164 MAX_LINE_SIZE,
165 };
166
167 // override log level to prevent spamming of the message
168 // "No accelerated colorspace conversion found from %s to %s"
169 1716 log_level = av_log_get_level();
170 1716 av_log_set_level(AV_LOG_ERROR);
171 1716 ctx = sws_getContext(width, srcSliceH, src_pix_fmt,
172 width, srcSliceH, dst_pix_fmt,
173 0, NULL, NULL, NULL);
174 1716 av_log_set_level(log_level);
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1716 times.
1716 if (!ctx)
176 fail();
177
178
2/2
✓ Branch 3 taken 216 times.
✓ Branch 4 taken 1500 times.
1716 if (check_func(ctx->convert_unscaled, "%s_%s_%d", src_desc->name, dst_desc->name, width)) {
179 216 memset(dst0_0, 0xFF, 2 * MAX_LINE_SIZE * 6);
180 216 memset(dst1_0, 0xFF, 2 * MAX_LINE_SIZE * 6);
181
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 192 times.
216 if (dst_pix_fmt == AV_PIX_FMT_GBRP) {
182 24 memset(dst0_1, 0xFF, MAX_LINE_SIZE);
183 24 memset(dst0_2, 0xFF, MAX_LINE_SIZE);
184 24 memset(dst1_1, 0xFF, MAX_LINE_SIZE);
185 24 memset(dst1_2, 0xFF, MAX_LINE_SIZE);
186 }
187
188 216 call_ref(ctx, src, srcStride, srcSliceY,
189 srcSliceH, dst0, dstStride);
190 216 call_new(ctx, src, srcStride, srcSliceY,
191 srcSliceH, dst1, dstStride);
192
193
4/4
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 192 times.
✓ Branch 3 taken 12 times.
216 if (dst_pix_fmt == AV_PIX_FMT_ARGB ||
194
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 24 times.
192 dst_pix_fmt == AV_PIX_FMT_ABGR ||
195
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 24 times.
168 dst_pix_fmt == AV_PIX_FMT_RGBA ||
196
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 24 times.
144 dst_pix_fmt == AV_PIX_FMT_BGRA ||
197
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 96 times.
120 dst_pix_fmt == AV_PIX_FMT_RGB24 ||
198 dst_pix_fmt == AV_PIX_FMT_BGR24) {
199
1/2
✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
240 if (cmp_off_by_n(lines0[0][0], lines1[0][0], width * sample_size, 3) ||
200
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
120 cmp_off_by_n(lines0[0][1], lines1[0][1], width * sample_size, 3))
201 fail();
202
4/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 60 times.
96 } else if (dst_pix_fmt == AV_PIX_FMT_RGB565 ||
203 dst_pix_fmt == AV_PIX_FMT_BGR565) {
204
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
72 if (cmp_565_by_n(lines0[0][0], lines1[0][0], width, 2) ||
205
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
36 cmp_565_by_n(lines0[0][1], lines1[0][1], width, 2))
206 fail();
207
4/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 24 times.
60 } else if (dst_pix_fmt == AV_PIX_FMT_RGB555 ||
208 dst_pix_fmt == AV_PIX_FMT_BGR555) {
209
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
72 if (cmp_555_by_n(lines0[0][0], lines1[0][0], width, 2) ||
210
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
36 cmp_555_by_n(lines0[0][1], lines1[0][1], width, 2))
211 fail();
212
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 } else if (dst_pix_fmt == AV_PIX_FMT_GBRP) {
213
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 24 times.
96 for (int p = 0; p < 3; p++)
214
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 72 times.
216 for (int l = 0; l < 2; l++)
215
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
144 if (cmp_off_by_n(lines0[p][l], lines1[p][l], width, 3))
216 fail();
217 } else {
218 fail();
219 }
220
221
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 216 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.
216 bench_new(ctx, src, srcStride, srcSliceY,
222 srcSliceH, dst0, dstStride);
223 }
224 1716 sws_freeContext(ctx);
225 }
226 }
227 39 }
228
229 #undef MAX_LINE_SIZE
230
231 13 void checkasm_check_sw_yuv2rgb(void)
232 {
233 13 check_yuv2rgb(AV_PIX_FMT_YUV420P);
234 13 report("yuv420p");
235 13 check_yuv2rgb(AV_PIX_FMT_YUV422P);
236 13 report("yuv422p");
237 13 check_yuv2rgb(AV_PIX_FMT_YUVA420P);
238 13 report("yuva420p");
239 13 }
240