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 |