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 | |||
26 | #include "libswscale/rgb2rgb.h" | ||
27 | |||
28 | #include "checkasm.h" | ||
29 | |||
30 | #define randomize_buffers(buf, size) \ | ||
31 | do { \ | ||
32 | int j; \ | ||
33 | for (j = 0; j < size; j+=4) \ | ||
34 | AV_WN32(buf + j, rnd()); \ | ||
35 | } while (0) | ||
36 | |||
37 | static const uint8_t width[] = {12, 16, 20, 32, 36, 128}; | ||
38 | static const struct {uint8_t w, h, s;} planes[] = { | ||
39 | {12,16,12}, {16,16,16}, {20,23,25}, {32,18,48}, {8,128,16}, {128,128,128} | ||
40 | }; | ||
41 | |||
42 | #define MAX_STRIDE 128 | ||
43 | #define MAX_HEIGHT 128 | ||
44 | |||
45 | 65 | static void check_shuffle_bytes(void * func, const char * report) | |
46 | { | ||
47 | int i; | ||
48 | 65 | LOCAL_ALIGNED_32(uint8_t, src0, [MAX_STRIDE]); | |
49 | 65 | LOCAL_ALIGNED_32(uint8_t, src1, [MAX_STRIDE]); | |
50 | 65 | LOCAL_ALIGNED_32(uint8_t, dst0, [MAX_STRIDE]); | |
51 | 65 | LOCAL_ALIGNED_32(uint8_t, dst1, [MAX_STRIDE]); | |
52 | |||
53 |
2/2✓ Branch 1 taken 60 times.
✓ Branch 2 taken 5 times.
|
65 | declare_func_emms(AV_CPU_FLAG_MMX, void, const uint8_t *src, uint8_t *dst, int src_size); |
54 | |||
55 | 65 | memset(dst0, 0, MAX_STRIDE); | |
56 | 65 | memset(dst1, 0, MAX_STRIDE); | |
57 |
2/2✓ Branch 1 taken 2080 times.
✓ Branch 2 taken 65 times.
|
2145 | randomize_buffers(src0, MAX_STRIDE); |
58 | 65 | memcpy(src1, src0, MAX_STRIDE); | |
59 | |||
60 |
2/2✓ Branch 3 taken 16 times.
✓ Branch 4 taken 49 times.
|
65 | if (check_func(func, "%s", report)) { |
61 |
2/2✓ Branch 0 taken 96 times.
✓ Branch 1 taken 16 times.
|
112 | for (i = 0; i < 6; i ++) { |
62 | 96 | call_ref(src0, dst0, width[i]); | |
63 | 96 | call_new(src1, dst1, width[i]); | |
64 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
|
96 | if (memcmp(dst0, dst1, MAX_STRIDE)) |
65 | ✗ | fail(); | |
66 | } | ||
67 |
1/8✗ Branch 1 not taken.
✓ Branch 2 taken 16 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.
|
16 | bench_new(src0, dst0, width[5]); |
68 | } | ||
69 | 65 | } | |
70 | |||
71 | 13 | static void check_uyvy_to_422p(void) | |
72 | { | ||
73 | int i; | ||
74 | |||
75 | 13 | LOCAL_ALIGNED_32(uint8_t, src0, [MAX_STRIDE * MAX_HEIGHT * 2]); | |
76 | 13 | LOCAL_ALIGNED_32(uint8_t, src1, [MAX_STRIDE * MAX_HEIGHT * 2]); | |
77 | 13 | LOCAL_ALIGNED_32(uint8_t, dst_y_0, [MAX_STRIDE * MAX_HEIGHT]); | |
78 | 13 | LOCAL_ALIGNED_32(uint8_t, dst_y_1, [MAX_STRIDE * MAX_HEIGHT]); | |
79 | 13 | LOCAL_ALIGNED_32(uint8_t, dst_u_0, [(MAX_STRIDE/2) * MAX_HEIGHT]); | |
80 | 13 | LOCAL_ALIGNED_32(uint8_t, dst_u_1, [(MAX_STRIDE/2) * MAX_HEIGHT]); | |
81 | 13 | LOCAL_ALIGNED_32(uint8_t, dst_v_0, [(MAX_STRIDE/2) * MAX_HEIGHT]); | |
82 | 13 | LOCAL_ALIGNED_32(uint8_t, dst_v_1, [(MAX_STRIDE/2) * MAX_HEIGHT]); | |
83 | |||
84 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1 times.
|
13 | declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, |
85 | const uint8_t *src, int width, int height, | ||
86 | int lumStride, int chromStride, int srcStride); | ||
87 | |||
88 |
2/2✓ Branch 1 taken 106496 times.
✓ Branch 2 taken 13 times.
|
106509 | randomize_buffers(src0, MAX_STRIDE * MAX_HEIGHT * 2); |
89 | 13 | memcpy(src1, src0, MAX_STRIDE * MAX_HEIGHT * 2); | |
90 | |||
91 |
2/2✓ Branch 3 taken 3 times.
✓ Branch 4 taken 10 times.
|
13 | if (check_func(uyvytoyuv422, "uyvytoyuv422")) { |
92 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 3 times.
|
21 | for (i = 0; i < 6; i ++) { |
93 | 18 | memset(dst_y_0, 0, MAX_STRIDE * MAX_HEIGHT); | |
94 | 18 | memset(dst_y_1, 0, MAX_STRIDE * MAX_HEIGHT); | |
95 | 18 | memset(dst_u_0, 0, (MAX_STRIDE/2) * MAX_HEIGHT); | |
96 | 18 | memset(dst_u_1, 0, (MAX_STRIDE/2) * MAX_HEIGHT); | |
97 | 18 | memset(dst_v_0, 0, (MAX_STRIDE/2) * MAX_HEIGHT); | |
98 | 18 | memset(dst_v_1, 0, (MAX_STRIDE/2) * MAX_HEIGHT); | |
99 | |||
100 | 18 | call_ref(dst_y_0, dst_u_0, dst_v_0, src0, planes[i].w, planes[i].h, | |
101 | MAX_STRIDE, MAX_STRIDE / 2, planes[i].s); | ||
102 | 18 | call_new(dst_y_1, dst_u_1, dst_v_1, src1, planes[i].w, planes[i].h, | |
103 | MAX_STRIDE, MAX_STRIDE / 2, planes[i].s); | ||
104 |
1/2✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
|
18 | if (memcmp(dst_y_0, dst_y_1, MAX_STRIDE * MAX_HEIGHT) || |
105 |
1/2✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
|
18 | memcmp(dst_u_0, dst_u_1, (MAX_STRIDE/2) * MAX_HEIGHT) || |
106 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
|
18 | memcmp(dst_v_0, dst_v_1, (MAX_STRIDE/2) * MAX_HEIGHT)) |
107 | ✗ | fail(); | |
108 | } | ||
109 |
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(dst_y_1, dst_u_1, dst_v_1, src1, planes[5].w, planes[5].h, |
110 | MAX_STRIDE, MAX_STRIDE / 2, planes[5].s); | ||
111 | } | ||
112 | 13 | } | |
113 | |||
114 | 13 | static void check_interleave_bytes(void) | |
115 | { | ||
116 | 13 | LOCAL_ALIGNED_16(uint8_t, src0_buf, [MAX_STRIDE*MAX_HEIGHT+1]); | |
117 | 13 | LOCAL_ALIGNED_16(uint8_t, src1_buf, [MAX_STRIDE*MAX_HEIGHT+1]); | |
118 | 13 | LOCAL_ALIGNED_16(uint8_t, dst0_buf, [2*MAX_STRIDE*MAX_HEIGHT+2]); | |
119 | 13 | LOCAL_ALIGNED_16(uint8_t, dst1_buf, [2*MAX_STRIDE*MAX_HEIGHT+2]); | |
120 | // Intentionally using unaligned buffers, as this function doesn't have | ||
121 | // any alignment requirements. | ||
122 | 13 | uint8_t *src0 = src0_buf + 1; | |
123 | 13 | uint8_t *src1 = src1_buf + 1; | |
124 | 13 | uint8_t *dst0 = dst0_buf + 2; | |
125 | 13 | uint8_t *dst1 = dst1_buf + 2; | |
126 | |||
127 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1 times.
|
13 | declare_func_emms(AV_CPU_FLAG_MMX, void, const uint8_t *, const uint8_t *, |
128 | uint8_t *, int, int, int, int, int); | ||
129 | |||
130 |
2/2✓ Branch 1 taken 53248 times.
✓ Branch 2 taken 13 times.
|
53261 | randomize_buffers(src0, MAX_STRIDE * MAX_HEIGHT); |
131 |
2/2✓ Branch 1 taken 53248 times.
✓ Branch 2 taken 13 times.
|
53261 | randomize_buffers(src1, MAX_STRIDE * MAX_HEIGHT); |
132 | |||
133 |
2/2✓ Branch 3 taken 2 times.
✓ Branch 4 taken 11 times.
|
13 | if (check_func(interleaveBytes, "interleave_bytes")) { |
134 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 2 times.
|
36 | for (int i = 0; i <= 16; i++) { |
135 | // Try all widths [1,16], and try one random width. | ||
136 | |||
137 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 32 times.
|
34 | int w = i > 0 ? i : (1 + (rnd() % (MAX_STRIDE-2))); |
138 | 34 | int h = 1 + (rnd() % (MAX_HEIGHT-2)); | |
139 | |||
140 | 34 | int src0_offset = 0, src0_stride = MAX_STRIDE; | |
141 | 34 | int src1_offset = 0, src1_stride = MAX_STRIDE; | |
142 | 34 | int dst_offset = 0, dst_stride = 2 * MAX_STRIDE; | |
143 | |||
144 | 34 | memset(dst0, 0, 2 * MAX_STRIDE * MAX_HEIGHT); | |
145 | 34 | memset(dst1, 0, 2 * MAX_STRIDE * MAX_HEIGHT); | |
146 | |||
147 | // Try different combinations of negative strides | ||
148 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 18 times.
|
34 | if (i & 1) { |
149 | 16 | src0_offset = (h-1)*src0_stride; | |
150 | 16 | src0_stride = -src0_stride; | |
151 | } | ||
152 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 18 times.
|
34 | if (i & 2) { |
153 | 16 | src1_offset = (h-1)*src1_stride; | |
154 | 16 | src1_stride = -src1_stride; | |
155 | } | ||
156 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 18 times.
|
34 | if (i & 4) { |
157 | 16 | dst_offset = (h-1)*dst_stride; | |
158 | 16 | dst_stride = -dst_stride; | |
159 | } | ||
160 | |||
161 | 34 | call_ref(src0 + src0_offset, src1 + src1_offset, dst0 + dst_offset, | |
162 | w, h, src0_stride, src1_stride, dst_stride); | ||
163 | 34 | call_new(src0 + src0_offset, src1 + src1_offset, dst1 + dst_offset, | |
164 | w, h, src0_stride, src1_stride, dst_stride); | ||
165 | // Check a one pixel-pair edge around the destination area, | ||
166 | // to catch overwrites past the end. | ||
167 | 34 | checkasm_check(uint8_t, dst0, 2*MAX_STRIDE, dst1, 2*MAX_STRIDE, | |
168 | 2 * w + 2, h + 1, "dst"); | ||
169 | } | ||
170 | |||
171 |
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, |
172 | MAX_STRIDE, MAX_STRIDE, 2*MAX_STRIDE); | ||
173 | } | ||
174 |
2/2✓ Branch 3 taken 2 times.
✓ Branch 4 taken 11 times.
|
13 | if (check_func(interleaveBytes, "interleave_bytes_aligned")) { |
175 | // Bench the function in a more typical case, with aligned | ||
176 | // buffers and widths. | ||
177 |
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, |
178 | MAX_STRIDE, MAX_STRIDE, 2*MAX_STRIDE); | ||
179 | } | ||
180 | 13 | } | |
181 | |||
182 | 13 | void checkasm_check_sw_rgb(void) | |
183 | { | ||
184 | 13 | ff_sws_rgb2rgb_init(); | |
185 | |||
186 | 13 | check_shuffle_bytes(shuffle_bytes_2103, "shuffle_bytes_2103"); | |
187 | 13 | report("shuffle_bytes_2103"); | |
188 | |||
189 | 13 | check_shuffle_bytes(shuffle_bytes_0321, "shuffle_bytes_0321"); | |
190 | 13 | report("shuffle_bytes_0321"); | |
191 | |||
192 | 13 | check_shuffle_bytes(shuffle_bytes_1230, "shuffle_bytes_1230"); | |
193 | 13 | report("shuffle_bytes_1230"); | |
194 | |||
195 | 13 | check_shuffle_bytes(shuffle_bytes_3012, "shuffle_bytes_3012"); | |
196 | 13 | report("shuffle_bytes_3012"); | |
197 | |||
198 | 13 | check_shuffle_bytes(shuffle_bytes_3210, "shuffle_bytes_3210"); | |
199 | 13 | report("shuffle_bytes_3210"); | |
200 | |||
201 | 13 | check_uyvy_to_422p(); | |
202 | 13 | report("uyvytoyuv422"); | |
203 | |||
204 | 13 | check_interleave_bytes(); | |
205 | 13 | report("interleave_bytes"); | |
206 | 13 | } | |
207 |