media/libyuv/unit_test/convert_test.cc

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:21eec9fd48b0
1 /*
2 * Copyright 2011 The LibYuv Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <stdlib.h>
12 #include <time.h>
13
14 #include "libyuv/compare.h"
15 #include "libyuv/convert.h"
16 #include "libyuv/convert_argb.h"
17 #include "libyuv/convert_from.h"
18 #include "libyuv/convert_from_argb.h"
19 #include "libyuv/cpu_id.h"
20 #include "libyuv/format_conversion.h"
21 #ifdef HAVE_JPEG
22 #include "libyuv/mjpeg_decoder.h"
23 #endif
24 #include "libyuv/planar_functions.h"
25 #include "libyuv/rotate.h"
26 #include "libyuv/row.h"
27 #include "../unit_test/unit_test.h"
28
29 #if defined(_MSC_VER)
30 #define SIMD_ALIGNED(var) __declspec(align(16)) var
31 #else // __GNUC__
32 #define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
33 #endif
34
35 namespace libyuv {
36
37 #define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
38
39 #define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
40 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \
41 TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \
42 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
43 const int kHeight = benchmark_height_; \
44 align_buffer_64(src_y, kWidth * kHeight + OFF); \
45 align_buffer_64(src_u, \
46 SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \
47 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \
48 align_buffer_64(src_v, \
49 SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \
50 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \
51 align_buffer_64(dst_y_c, kWidth * kHeight); \
52 align_buffer_64(dst_u_c, \
53 SUBSAMPLE(kWidth, SUBSAMP_X) * \
54 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
55 align_buffer_64(dst_v_c, \
56 SUBSAMPLE(kWidth, SUBSAMP_X) * \
57 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
58 align_buffer_64(dst_y_opt, kWidth * kHeight); \
59 align_buffer_64(dst_u_opt, \
60 SUBSAMPLE(kWidth, SUBSAMP_X) * \
61 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
62 align_buffer_64(dst_v_opt, \
63 SUBSAMPLE(kWidth, SUBSAMP_X) * \
64 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
65 srandom(time(NULL)); \
66 for (int i = 0; i < kHeight; ++i) \
67 for (int j = 0; j < kWidth; ++j) \
68 src_y[(i * kWidth) + j + OFF] = (random() & 0xff); \
69 for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \
70 for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \
71 src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \
72 (random() & 0xff); \
73 src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \
74 (random() & 0xff); \
75 } \
76 } \
77 memset(dst_y_c, 1, kWidth * kHeight); \
78 memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * \
79 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
80 memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) * \
81 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
82 memset(dst_y_opt, 101, kWidth * kHeight); \
83 memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * \
84 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
85 memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) * \
86 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
87 MaskCpuFlags(0); \
88 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \
89 src_u + OFF, \
90 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
91 src_v + OFF, \
92 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
93 dst_y_c, kWidth, \
94 dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \
95 dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \
96 kWidth, NEG kHeight); \
97 MaskCpuFlags(-1); \
98 for (int i = 0; i < benchmark_iterations_; ++i) { \
99 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \
100 src_u + OFF, \
101 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
102 src_v + OFF, \
103 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
104 dst_y_opt, kWidth, \
105 dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
106 dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
107 kWidth, NEG kHeight); \
108 } \
109 int max_diff = 0; \
110 for (int i = 0; i < kHeight; ++i) { \
111 for (int j = 0; j < kWidth; ++j) { \
112 int abs_diff = \
113 abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
114 static_cast<int>(dst_y_opt[i * kWidth + j])); \
115 if (abs_diff > max_diff) { \
116 max_diff = abs_diff; \
117 } \
118 } \
119 } \
120 EXPECT_LE(max_diff, 0); \
121 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
122 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
123 int abs_diff = \
124 abs(static_cast<int>(dst_u_c[i * \
125 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
126 static_cast<int>(dst_u_opt[i * \
127 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
128 if (abs_diff > max_diff) { \
129 max_diff = abs_diff; \
130 } \
131 } \
132 } \
133 EXPECT_LE(max_diff, 3); \
134 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
135 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
136 int abs_diff = \
137 abs(static_cast<int>(dst_v_c[i * \
138 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
139 static_cast<int>(dst_v_opt[i * \
140 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
141 if (abs_diff > max_diff) { \
142 max_diff = abs_diff; \
143 } \
144 } \
145 } \
146 EXPECT_LE(max_diff, 3); \
147 free_aligned_buffer_64(dst_y_c); \
148 free_aligned_buffer_64(dst_u_c); \
149 free_aligned_buffer_64(dst_v_c); \
150 free_aligned_buffer_64(dst_y_opt); \
151 free_aligned_buffer_64(dst_u_opt); \
152 free_aligned_buffer_64(dst_v_opt); \
153 free_aligned_buffer_64(src_y); \
154 free_aligned_buffer_64(src_u); \
155 free_aligned_buffer_64(src_v); \
156 }
157
158 #define TESTPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
159 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
160 TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
161 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
162 benchmark_width_ - 4, _Any, +, 0) \
163 TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
164 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
165 benchmark_width_, _Unaligned, +, 1) \
166 TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
167 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
168 benchmark_width_, _Invert, -, 0) \
169 TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
170 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
171 benchmark_width_, _Opt, +, 0)
172
173 TESTPLANARTOP(I420, 2, 2, I420, 2, 2)
174 TESTPLANARTOP(I422, 2, 1, I420, 2, 2)
175 TESTPLANARTOP(I444, 1, 1, I420, 2, 2)
176 TESTPLANARTOP(I411, 4, 1, I420, 2, 2)
177 TESTPLANARTOP(I420, 2, 2, I422, 2, 1)
178 TESTPLANARTOP(I420, 2, 2, I444, 1, 1)
179 TESTPLANARTOP(I420, 2, 2, I411, 4, 1)
180 TESTPLANARTOP(I420, 2, 2, I420Mirror, 2, 2)
181 TESTPLANARTOP(I422, 2, 1, I422, 2, 1)
182 TESTPLANARTOP(I444, 1, 1, I444, 1, 1)
183
184 #define TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
185 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \
186 TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \
187 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
188 const int kHeight = benchmark_height_; \
189 align_buffer_64(src_y, kWidth * kHeight + OFF); \
190 align_buffer_64(src_u, \
191 SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \
192 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \
193 align_buffer_64(src_v, \
194 SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \
195 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \
196 align_buffer_64(dst_y_c, kWidth * kHeight); \
197 align_buffer_64(dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \
198 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
199 align_buffer_64(dst_y_opt, kWidth * kHeight); \
200 align_buffer_64(dst_uv_opt, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \
201 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
202 srandom(time(NULL)); \
203 for (int i = 0; i < kHeight; ++i) \
204 for (int j = 0; j < kWidth; ++j) \
205 src_y[(i * kWidth) + j + OFF] = (random() & 0xff); \
206 for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \
207 for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \
208 src_u[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \
209 (random() & 0xff); \
210 src_v[(i * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \
211 (random() & 0xff); \
212 } \
213 } \
214 memset(dst_y_c, 1, kWidth * kHeight); \
215 memset(dst_uv_c, 2, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \
216 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
217 memset(dst_y_opt, 101, kWidth * kHeight); \
218 memset(dst_uv_opt, 102, SUBSAMPLE(kWidth * 2, SUBSAMP_X) * \
219 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
220 MaskCpuFlags(0); \
221 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \
222 src_u + OFF, \
223 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
224 src_v + OFF, \
225 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
226 dst_y_c, kWidth, \
227 dst_uv_c, SUBSAMPLE(kWidth * 2, SUBSAMP_X), \
228 kWidth, NEG kHeight); \
229 MaskCpuFlags(-1); \
230 for (int i = 0; i < benchmark_iterations_; ++i) { \
231 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \
232 src_u + OFF, \
233 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
234 src_v + OFF, \
235 SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
236 dst_y_opt, kWidth, \
237 dst_uv_opt, \
238 SUBSAMPLE(kWidth * 2, SUBSAMP_X), \
239 kWidth, NEG kHeight); \
240 } \
241 int max_diff = 0; \
242 for (int i = 0; i < kHeight; ++i) { \
243 for (int j = 0; j < kWidth; ++j) { \
244 int abs_diff = \
245 abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
246 static_cast<int>(dst_y_opt[i * kWidth + j])); \
247 if (abs_diff > max_diff) { \
248 max_diff = abs_diff; \
249 } \
250 } \
251 } \
252 EXPECT_LE(max_diff, 1); \
253 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
254 for (int j = 0; j < SUBSAMPLE(kWidth * 2, SUBSAMP_X); ++j) { \
255 int abs_diff = \
256 abs(static_cast<int>(dst_uv_c[i * \
257 SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j]) - \
258 static_cast<int>(dst_uv_opt[i * \
259 SUBSAMPLE(kWidth * 2, SUBSAMP_X) + j])); \
260 if (abs_diff > max_diff) { \
261 max_diff = abs_diff; \
262 } \
263 } \
264 } \
265 EXPECT_LE(max_diff, 1); \
266 free_aligned_buffer_64(dst_y_c); \
267 free_aligned_buffer_64(dst_uv_c); \
268 free_aligned_buffer_64(dst_y_opt); \
269 free_aligned_buffer_64(dst_uv_opt); \
270 free_aligned_buffer_64(src_y); \
271 free_aligned_buffer_64(src_u); \
272 free_aligned_buffer_64(src_v); \
273 }
274
275 #define TESTPLANARTOBP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
276 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
277 TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
278 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
279 benchmark_width_ - 4, _Any, +, 0) \
280 TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
281 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
282 benchmark_width_, _Unaligned, +, 1) \
283 TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
284 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
285 benchmark_width_, _Invert, -, 0) \
286 TESTPLANARTOBPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
287 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
288 benchmark_width_, _Opt, +, 0)
289
290 TESTPLANARTOBP(I420, 2, 2, NV12, 2, 2)
291 TESTPLANARTOBP(I420, 2, 2, NV21, 2, 2)
292
293 #define TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
294 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, W1280, N, NEG, OFF) \
295 TEST_F(libyuvTest, SRC_FMT_PLANAR##To##FMT_PLANAR##N) { \
296 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
297 const int kHeight = benchmark_height_; \
298 align_buffer_64(src_y, kWidth * kHeight + OFF); \
299 align_buffer_64(src_uv, 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * \
300 SUBSAMPLE(kHeight, SRC_SUBSAMP_Y) + OFF); \
301 align_buffer_64(dst_y_c, kWidth * kHeight); \
302 align_buffer_64(dst_u_c, \
303 SUBSAMPLE(kWidth, SUBSAMP_X) * \
304 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
305 align_buffer_64(dst_v_c, \
306 SUBSAMPLE(kWidth, SUBSAMP_X) * \
307 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
308 align_buffer_64(dst_y_opt, kWidth * kHeight); \
309 align_buffer_64(dst_u_opt, \
310 SUBSAMPLE(kWidth, SUBSAMP_X) * \
311 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
312 align_buffer_64(dst_v_opt, \
313 SUBSAMPLE(kWidth, SUBSAMP_X) * \
314 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
315 srandom(time(NULL)); \
316 for (int i = 0; i < kHeight; ++i) \
317 for (int j = 0; j < kWidth; ++j) \
318 src_y[(i * kWidth) + j + OFF] = (random() & 0xff); \
319 for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \
320 for (int j = 0; j < 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \
321 src_uv[(i * 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X)) + j + OFF] = \
322 (random() & 0xff); \
323 } \
324 } \
325 memset(dst_y_c, 1, kWidth * kHeight); \
326 memset(dst_u_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * \
327 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
328 memset(dst_v_c, 3, SUBSAMPLE(kWidth, SUBSAMP_X) * \
329 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
330 memset(dst_y_opt, 101, kWidth * kHeight); \
331 memset(dst_u_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * \
332 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
333 memset(dst_v_opt, 103, SUBSAMPLE(kWidth, SUBSAMP_X) * \
334 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
335 MaskCpuFlags(0); \
336 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \
337 src_uv + OFF, \
338 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
339 dst_y_c, kWidth, \
340 dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \
341 dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \
342 kWidth, NEG kHeight); \
343 MaskCpuFlags(-1); \
344 for (int i = 0; i < benchmark_iterations_; ++i) { \
345 SRC_FMT_PLANAR##To##FMT_PLANAR(src_y + OFF, kWidth, \
346 src_uv + OFF, \
347 2 * SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
348 dst_y_opt, kWidth, \
349 dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
350 dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
351 kWidth, NEG kHeight); \
352 } \
353 int max_diff = 0; \
354 for (int i = 0; i < kHeight; ++i) { \
355 for (int j = 0; j < kWidth; ++j) { \
356 int abs_diff = \
357 abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
358 static_cast<int>(dst_y_opt[i * kWidth + j])); \
359 if (abs_diff > max_diff) { \
360 max_diff = abs_diff; \
361 } \
362 } \
363 } \
364 EXPECT_LE(max_diff, 1); \
365 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
366 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
367 int abs_diff = \
368 abs(static_cast<int>(dst_u_c[i * \
369 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
370 static_cast<int>(dst_u_opt[i * \
371 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
372 if (abs_diff > max_diff) { \
373 max_diff = abs_diff; \
374 } \
375 } \
376 } \
377 EXPECT_LE(max_diff, 1); \
378 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
379 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
380 int abs_diff = \
381 abs(static_cast<int>(dst_v_c[i * \
382 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
383 static_cast<int>(dst_v_opt[i * \
384 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
385 if (abs_diff > max_diff) { \
386 max_diff = abs_diff; \
387 } \
388 } \
389 } \
390 EXPECT_LE(max_diff, 1); \
391 free_aligned_buffer_64(dst_y_c); \
392 free_aligned_buffer_64(dst_u_c); \
393 free_aligned_buffer_64(dst_v_c); \
394 free_aligned_buffer_64(dst_y_opt); \
395 free_aligned_buffer_64(dst_u_opt); \
396 free_aligned_buffer_64(dst_v_opt); \
397 free_aligned_buffer_64(src_y); \
398 free_aligned_buffer_64(src_uv); \
399 }
400
401 #define TESTBIPLANARTOP(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
402 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
403 TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
404 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
405 benchmark_width_ - 4, _Any, +, 0) \
406 TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
407 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
408 benchmark_width_, _Unaligned, +, 1) \
409 TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
410 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
411 benchmark_width_, _Invert, -, 0) \
412 TESTBIPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
413 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
414 benchmark_width_, _Opt, +, 0)
415
416 TESTBIPLANARTOP(NV12, 2, 2, I420, 2, 2)
417 TESTBIPLANARTOP(NV21, 2, 2, I420, 2, 2)
418
419 #define ALIGNINT(V, ALIGN) (((V) + (ALIGN) - 1) / (ALIGN) * (ALIGN))
420
421 #define TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
422 YALIGN, W1280, DIFF, N, NEG, OFF, FMT_C, BPP_C) \
423 TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) { \
424 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
425 const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \
426 const int kStrideB = ALIGNINT(kWidth * BPP_B, ALIGN); \
427 const int kSizeUV = \
428 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y); \
429 align_buffer_64(src_y, kWidth * kHeight + OFF); \
430 align_buffer_64(src_u, kSizeUV + OFF); \
431 align_buffer_64(src_v, kSizeUV + OFF); \
432 align_buffer_64(dst_argb_c, kStrideB * kHeight); \
433 align_buffer_64(dst_argb_opt, kStrideB * kHeight); \
434 srandom(time(NULL)); \
435 for (int i = 0; i < kWidth * kHeight; ++i) { \
436 src_y[i + OFF] = (random() & 0xff); \
437 } \
438 for (int i = 0; i < kSizeUV; ++i) { \
439 src_u[i + OFF] = (random() & 0xff); \
440 src_v[i + OFF] = (random() & 0xff); \
441 } \
442 memset(dst_argb_c, 1, kStrideB * kHeight); \
443 memset(dst_argb_opt, 101, kStrideB * kHeight); \
444 MaskCpuFlags(0); \
445 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \
446 src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \
447 src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \
448 dst_argb_c, kStrideB, \
449 kWidth, NEG kHeight); \
450 MaskCpuFlags(-1); \
451 for (int i = 0; i < benchmark_iterations_; ++i) { \
452 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \
453 src_u + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \
454 src_v + OFF, SUBSAMPLE(kWidth, SUBSAMP_X), \
455 dst_argb_opt, kStrideB, \
456 kWidth, NEG kHeight); \
457 } \
458 int max_diff = 0; \
459 /* Convert to ARGB so 565 is expanded to bytes that can be compared. */ \
460 align_buffer_64(dst_argb32_c, kWidth * BPP_C * kHeight); \
461 align_buffer_64(dst_argb32_opt, kWidth * BPP_C * kHeight); \
462 memset(dst_argb32_c, 2, kWidth * BPP_C * kHeight); \
463 memset(dst_argb32_opt, 102, kWidth * BPP_C * kHeight); \
464 FMT_B##To##FMT_C(dst_argb_c, kStrideB, \
465 dst_argb32_c, kWidth * BPP_C , \
466 kWidth, kHeight); \
467 FMT_B##To##FMT_C(dst_argb_opt, kStrideB, \
468 dst_argb32_opt, kWidth * BPP_C , \
469 kWidth, kHeight); \
470 for (int i = 0; i < kWidth * BPP_C * kHeight; ++i) { \
471 int abs_diff = \
472 abs(static_cast<int>(dst_argb32_c[i]) - \
473 static_cast<int>(dst_argb32_opt[i])); \
474 if (abs_diff > max_diff) { \
475 max_diff = abs_diff; \
476 } \
477 } \
478 EXPECT_LE(max_diff, DIFF); \
479 free_aligned_buffer_64(src_y); \
480 free_aligned_buffer_64(src_u); \
481 free_aligned_buffer_64(src_v); \
482 free_aligned_buffer_64(dst_argb_c); \
483 free_aligned_buffer_64(dst_argb_opt); \
484 free_aligned_buffer_64(dst_argb32_c); \
485 free_aligned_buffer_64(dst_argb32_opt); \
486 }
487
488 #define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
489 YALIGN, DIFF, FMT_C, BPP_C) \
490 TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
491 YALIGN, benchmark_width_ - 4, DIFF, _Any, +, 0, FMT_C, BPP_C) \
492 TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
493 YALIGN, benchmark_width_, DIFF, _Unaligned, +, 1, FMT_C, BPP_C) \
494 TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
495 YALIGN, benchmark_width_, DIFF, _Invert, -, 0, FMT_C, BPP_C) \
496 TESTPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
497 YALIGN, benchmark_width_, DIFF, _Opt, +, 0, FMT_C, BPP_C)
498
499 // TODO(fbarchard): Make vertical alignment unnecessary on bayer.
500 TESTPLANARTOB(I420, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4)
501 TESTPLANARTOB(I420, 2, 2, BGRA, 4, 4, 1, 2, ARGB, 4)
502 TESTPLANARTOB(I420, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4)
503 TESTPLANARTOB(I420, 2, 2, RGBA, 4, 4, 1, 2, ARGB, 4)
504 TESTPLANARTOB(I420, 2, 2, RAW, 3, 3, 1, 2, ARGB, 4)
505 TESTPLANARTOB(I420, 2, 2, RGB24, 3, 3, 1, 2, ARGB, 4)
506 TESTPLANARTOB(I420, 2, 2, RGB565, 2, 2, 1, 9, ARGB, 4)
507 TESTPLANARTOB(I420, 2, 2, ARGB1555, 2, 2, 1, 9, ARGB, 4)
508 TESTPLANARTOB(I420, 2, 2, ARGB4444, 2, 2, 1, 17, ARGB, 4)
509 TESTPLANARTOB(I422, 2, 1, ARGB, 4, 4, 1, 2, ARGB, 4)
510 TESTPLANARTOB(I422, 2, 1, BGRA, 4, 4, 1, 2, ARGB, 4)
511 TESTPLANARTOB(I422, 2, 1, ABGR, 4, 4, 1, 2, ARGB, 4)
512 TESTPLANARTOB(I422, 2, 1, RGBA, 4, 4, 1, 2, ARGB, 4)
513 TESTPLANARTOB(I411, 4, 1, ARGB, 4, 4, 1, 2, ARGB, 4)
514 TESTPLANARTOB(I444, 1, 1, ARGB, 4, 4, 1, 2, ARGB, 4)
515 TESTPLANARTOB(I420, 2, 2, YUY2, 2, 4, 1, 1, ARGB, 4)
516 TESTPLANARTOB(I420, 2, 2, UYVY, 2, 4, 1, 1, ARGB, 4)
517 TESTPLANARTOB(I422, 2, 1, YUY2, 2, 4, 1, 0, ARGB, 4)
518 TESTPLANARTOB(I422, 2, 1, UYVY, 2, 4, 1, 0, ARGB, 4)
519 TESTPLANARTOB(I420, 2, 2, I400, 1, 1, 1, 0, ARGB, 4)
520 TESTPLANARTOB(I420, 2, 2, BayerBGGR, 1, 2, 2, 2, ARGB, 4)
521 TESTPLANARTOB(I420, 2, 2, BayerRGGB, 1, 2, 2, 2, ARGB, 4)
522 TESTPLANARTOB(I420, 2, 2, BayerGBRG, 1, 2, 2, 2, ARGB, 4)
523 TESTPLANARTOB(I420, 2, 2, BayerGRBG, 1, 2, 2, 2, ARGB, 4)
524
525 #define TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
526 W1280, DIFF, N, NEG, OFF) \
527 TEST_F(libyuvTest, FMT_PLANAR##To##FMT_B##N) { \
528 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
529 const int kHeight = benchmark_height_; \
530 const int kStrideB = kWidth * BPP_B; \
531 align_buffer_64(src_y, kWidth * kHeight + OFF); \
532 align_buffer_64(src_uv, \
533 SUBSAMPLE(kWidth, SUBSAMP_X) * \
534 SUBSAMPLE(kHeight, SUBSAMP_Y) * 2 + OFF); \
535 align_buffer_64(dst_argb_c, kStrideB * kHeight); \
536 align_buffer_64(dst_argb_opt, kStrideB * kHeight); \
537 srandom(time(NULL)); \
538 for (int i = 0; i < kHeight; ++i) \
539 for (int j = 0; j < kWidth; ++j) \
540 src_y[(i * kWidth) + j + OFF] = (random() & 0xff); \
541 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
542 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X) * 2; ++j) { \
543 src_uv[(i * SUBSAMPLE(kWidth, SUBSAMP_X)) * 2 + j + OFF] = \
544 (random() & 0xff); \
545 } \
546 } \
547 memset(dst_argb_c, 1, kStrideB * kHeight); \
548 memset(dst_argb_opt, 101, kStrideB * kHeight); \
549 MaskCpuFlags(0); \
550 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \
551 src_uv + OFF, SUBSAMPLE(kWidth, SUBSAMP_X) * 2, \
552 dst_argb_c, kWidth * BPP_B, \
553 kWidth, NEG kHeight); \
554 MaskCpuFlags(-1); \
555 for (int i = 0; i < benchmark_iterations_; ++i) { \
556 FMT_PLANAR##To##FMT_B(src_y + OFF, kWidth, \
557 src_uv + OFF, SUBSAMPLE(kWidth, SUBSAMP_X) * 2, \
558 dst_argb_opt, kWidth * BPP_B, \
559 kWidth, NEG kHeight); \
560 } \
561 /* Convert to ARGB so 565 is expanded to bytes that can be compared. */ \
562 align_buffer_64(dst_argb32_c, kWidth * 4 * kHeight); \
563 align_buffer_64(dst_argb32_opt, kWidth * 4 * kHeight); \
564 memset(dst_argb32_c, 2, kWidth * 4 * kHeight); \
565 memset(dst_argb32_opt, 102, kWidth * 4 * kHeight); \
566 FMT_B##ToARGB(dst_argb_c, kStrideB, \
567 dst_argb32_c, kWidth * 4, \
568 kWidth, kHeight); \
569 FMT_B##ToARGB(dst_argb_opt, kStrideB, \
570 dst_argb32_opt, kWidth * 4, \
571 kWidth, kHeight); \
572 int max_diff = 0; \
573 for (int i = 0; i < kHeight; ++i) { \
574 for (int j = 0; j < kWidth * 4; ++j) { \
575 int abs_diff = \
576 abs(static_cast<int>(dst_argb32_c[i * kWidth * 4 + j]) - \
577 static_cast<int>(dst_argb32_opt[i * kWidth * 4 + j])); \
578 if (abs_diff > max_diff) { \
579 max_diff = abs_diff; \
580 } \
581 } \
582 } \
583 EXPECT_LE(max_diff, DIFF); \
584 free_aligned_buffer_64(src_y); \
585 free_aligned_buffer_64(src_uv); \
586 free_aligned_buffer_64(dst_argb_c); \
587 free_aligned_buffer_64(dst_argb_opt); \
588 free_aligned_buffer_64(dst_argb32_c); \
589 free_aligned_buffer_64(dst_argb32_opt); \
590 }
591
592 #define TESTBIPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, DIFF) \
593 TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
594 benchmark_width_ - 4, DIFF, _Any, +, 0) \
595 TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
596 benchmark_width_, DIFF, _Unaligned, +, 1) \
597 TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
598 benchmark_width_, DIFF, _Invert, -, 0) \
599 TESTBIPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
600 benchmark_width_, DIFF, _Opt, +, 0)
601
602 TESTBIPLANARTOB(NV12, 2, 2, ARGB, 4, 2)
603 TESTBIPLANARTOB(NV21, 2, 2, ARGB, 4, 2)
604 TESTBIPLANARTOB(NV12, 2, 2, RGB565, 2, 9)
605 TESTBIPLANARTOB(NV21, 2, 2, RGB565, 2, 9)
606
607 #define TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
608 W1280, DIFF, N, NEG, OFF) \
609 TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) { \
610 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
611 const int kHeight = ALIGNINT(benchmark_height_, YALIGN); \
612 const int kStride = \
613 (SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMP_X * 8 * BPP_A + 7) / 8; \
614 align_buffer_64(src_argb, kStride * kHeight + OFF); \
615 align_buffer_64(dst_y_c, kWidth * kHeight); \
616 align_buffer_64(dst_u_c, \
617 SUBSAMPLE(kWidth, SUBSAMP_X) * \
618 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
619 align_buffer_64(dst_v_c, \
620 SUBSAMPLE(kWidth, SUBSAMP_X) * \
621 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
622 align_buffer_64(dst_y_opt, kWidth * kHeight); \
623 align_buffer_64(dst_u_opt, \
624 SUBSAMPLE(kWidth, SUBSAMP_X) * \
625 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
626 align_buffer_64(dst_v_opt, \
627 SUBSAMPLE(kWidth, SUBSAMP_X) * \
628 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
629 memset(dst_y_c, 1, kWidth * kHeight); \
630 memset(dst_u_c, 2, \
631 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
632 memset(dst_v_c, 3, \
633 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
634 memset(dst_y_opt, 101, kWidth * kHeight); \
635 memset(dst_u_opt, 102, \
636 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
637 memset(dst_v_opt, 103, \
638 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
639 srandom(time(NULL)); \
640 for (int i = 0; i < kHeight; ++i) \
641 for (int j = 0; j < kStride; ++j) \
642 src_argb[(i * kStride) + j + OFF] = (random() & 0xff); \
643 MaskCpuFlags(0); \
644 FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \
645 dst_y_c, kWidth, \
646 dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), \
647 dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X), \
648 kWidth, NEG kHeight); \
649 MaskCpuFlags(-1); \
650 for (int i = 0; i < benchmark_iterations_; ++i) { \
651 FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \
652 dst_y_opt, kWidth, \
653 dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
654 dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
655 kWidth, NEG kHeight); \
656 } \
657 int max_diff = 0; \
658 for (int i = 0; i < kHeight; ++i) { \
659 for (int j = 0; j < kWidth; ++j) { \
660 int abs_diff = \
661 abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
662 static_cast<int>(dst_y_opt[i * kWidth + j])); \
663 if (abs_diff > max_diff) { \
664 max_diff = abs_diff; \
665 } \
666 } \
667 } \
668 EXPECT_LE(max_diff, DIFF); \
669 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
670 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
671 int abs_diff = \
672 abs(static_cast<int>(dst_u_c[i * \
673 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
674 static_cast<int>(dst_u_opt[i * \
675 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
676 if (abs_diff > max_diff) { \
677 max_diff = abs_diff; \
678 } \
679 } \
680 } \
681 EXPECT_LE(max_diff, DIFF); \
682 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
683 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
684 int abs_diff = \
685 abs(static_cast<int>(dst_v_c[i * \
686 SUBSAMPLE(kWidth, SUBSAMP_X) + j]) - \
687 static_cast<int>(dst_v_opt[i * \
688 SUBSAMPLE(kWidth, SUBSAMP_X) + j])); \
689 if (abs_diff > max_diff) { \
690 max_diff = abs_diff; \
691 } \
692 } \
693 } \
694 EXPECT_LE(max_diff, DIFF); \
695 free_aligned_buffer_64(dst_y_c); \
696 free_aligned_buffer_64(dst_u_c); \
697 free_aligned_buffer_64(dst_v_c); \
698 free_aligned_buffer_64(dst_y_opt); \
699 free_aligned_buffer_64(dst_u_opt); \
700 free_aligned_buffer_64(dst_v_opt); \
701 free_aligned_buffer_64(src_argb); \
702 }
703
704 #define TESTATOPLANAR(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
705 DIFF) \
706 TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
707 benchmark_width_ - 4, DIFF, _Any, +, 0) \
708 TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
709 benchmark_width_, DIFF, _Unaligned, +, 1) \
710 TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
711 benchmark_width_, DIFF, _Invert, -, 0) \
712 TESTATOPLANARI(FMT_A, BPP_A, YALIGN, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
713 benchmark_width_, DIFF, _Opt, +, 0)
714
715 TESTATOPLANAR(ARGB, 4, 1, I420, 2, 2, 4)
716 #ifdef __arm__
717 TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 4)
718 #else
719 TESTATOPLANAR(ARGB, 4, 1, J420, 2, 2, 0)
720 #endif
721 TESTATOPLANAR(BGRA, 4, 1, I420, 2, 2, 4)
722 TESTATOPLANAR(ABGR, 4, 1, I420, 2, 2, 4)
723 TESTATOPLANAR(RGBA, 4, 1, I420, 2, 2, 4)
724 TESTATOPLANAR(RAW, 3, 1, I420, 2, 2, 4)
725 TESTATOPLANAR(RGB24, 3, 1, I420, 2, 2, 4)
726 TESTATOPLANAR(RGB565, 2, 1, I420, 2, 2, 5)
727 // TODO(fbarchard): Make 1555 neon work same as C code, reduce to diff 9.
728 TESTATOPLANAR(ARGB1555, 2, 1, I420, 2, 2, 15)
729 TESTATOPLANAR(ARGB4444, 2, 1, I420, 2, 2, 17)
730 TESTATOPLANAR(ARGB, 4, 1, I411, 4, 1, 4)
731 TESTATOPLANAR(ARGB, 4, 1, I422, 2, 1, 2)
732 TESTATOPLANAR(ARGB, 4, 1, I444, 1, 1, 2)
733 TESTATOPLANAR(YUY2, 2, 1, I420, 2, 2, 2)
734 TESTATOPLANAR(UYVY, 2, 1, I420, 2, 2, 2)
735 TESTATOPLANAR(YUY2, 2, 1, I422, 2, 1, 2)
736 TESTATOPLANAR(UYVY, 2, 1, I422, 2, 1, 2)
737 TESTATOPLANAR(I400, 1, 1, I420, 2, 2, 2)
738 TESTATOPLANAR(BayerBGGR, 1, 2, I420, 2, 2, 4)
739 TESTATOPLANAR(BayerRGGB, 1, 2, I420, 2, 2, 4)
740 TESTATOPLANAR(BayerGBRG, 1, 2, I420, 2, 2, 4)
741 TESTATOPLANAR(BayerGRBG, 1, 2, I420, 2, 2, 4)
742
743 #define TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
744 W1280, N, NEG, OFF) \
745 TEST_F(libyuvTest, FMT_A##To##FMT_PLANAR##N) { \
746 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
747 const int kHeight = benchmark_height_; \
748 const int kStride = (kWidth * 8 * BPP_A + 7) / 8; \
749 align_buffer_64(src_argb, kStride * kHeight + OFF); \
750 align_buffer_64(dst_y_c, kWidth * kHeight); \
751 align_buffer_64(dst_uv_c, \
752 SUBSAMPLE(kWidth, SUBSAMP_X) * 2 * \
753 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
754 align_buffer_64(dst_y_opt, kWidth * kHeight); \
755 align_buffer_64(dst_uv_opt, \
756 SUBSAMPLE(kWidth, SUBSAMP_X) * 2 * \
757 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
758 srandom(time(NULL)); \
759 for (int i = 0; i < kHeight; ++i) \
760 for (int j = 0; j < kStride; ++j) \
761 src_argb[(i * kStride) + j + OFF] = (random() & 0xff); \
762 memset(dst_y_c, 1, kWidth * kHeight); \
763 memset(dst_uv_c, 2, SUBSAMPLE(kWidth, SUBSAMP_X) * 2 * \
764 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
765 memset(dst_y_opt, 101, kWidth * kHeight); \
766 memset(dst_uv_opt, 102, SUBSAMPLE(kWidth, SUBSAMP_X) * 2 * \
767 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
768 MaskCpuFlags(0); \
769 FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \
770 dst_y_c, kWidth, \
771 dst_uv_c, SUBSAMPLE(kWidth, SUBSAMP_X) * 2, \
772 kWidth, NEG kHeight); \
773 MaskCpuFlags(-1); \
774 for (int i = 0; i < benchmark_iterations_; ++i) { \
775 FMT_A##To##FMT_PLANAR(src_argb + OFF, kStride, \
776 dst_y_opt, kWidth, \
777 dst_uv_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * 2, \
778 kWidth, NEG kHeight); \
779 } \
780 int max_diff = 0; \
781 for (int i = 0; i < kHeight; ++i) { \
782 for (int j = 0; j < kWidth; ++j) { \
783 int abs_diff = \
784 abs(static_cast<int>(dst_y_c[i * kWidth + j]) - \
785 static_cast<int>(dst_y_opt[i * kWidth + j])); \
786 if (abs_diff > max_diff) { \
787 max_diff = abs_diff; \
788 } \
789 } \
790 } \
791 EXPECT_LE(max_diff, 4); \
792 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
793 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X) * 2; ++j) { \
794 int abs_diff = \
795 abs(static_cast<int>(dst_uv_c[i * \
796 SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j]) - \
797 static_cast<int>(dst_uv_opt[i * \
798 SUBSAMPLE(kWidth, SUBSAMP_X) * 2 + j])); \
799 if (abs_diff > max_diff) { \
800 max_diff = abs_diff; \
801 } \
802 } \
803 } \
804 EXPECT_LE(max_diff, 4); \
805 free_aligned_buffer_64(dst_y_c); \
806 free_aligned_buffer_64(dst_uv_c); \
807 free_aligned_buffer_64(dst_y_opt); \
808 free_aligned_buffer_64(dst_uv_opt); \
809 free_aligned_buffer_64(src_argb); \
810 }
811
812 #define TESTATOBIPLANAR(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
813 TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
814 benchmark_width_ - 4, _Any, +, 0) \
815 TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
816 benchmark_width_, _Unaligned, +, 1) \
817 TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
818 benchmark_width_, _Invert, -, 0) \
819 TESTATOBIPLANARI(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
820 benchmark_width_, _Opt, +, 0)
821
822 TESTATOBIPLANAR(ARGB, 4, NV12, 2, 2)
823 TESTATOBIPLANAR(ARGB, 4, NV21, 2, 2)
824
825 #define TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
826 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \
827 W1280, DIFF, N, NEG, OFF) \
828 TEST_F(libyuvTest, FMT_A##To##FMT_B##N) { \
829 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
830 const int kHeight = benchmark_height_; \
831 const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A; \
832 const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B; \
833 const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \
834 const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B; \
835 align_buffer_64(src_argb, kStrideA * kHeightA + OFF); \
836 align_buffer_64(dst_argb_c, kStrideB * kHeightB); \
837 align_buffer_64(dst_argb_opt, kStrideB * kHeightB); \
838 srandom(time(NULL)); \
839 for (int i = 0; i < kStrideA * kHeightA; ++i) { \
840 src_argb[i + OFF] = (random() & 0xff); \
841 } \
842 memset(dst_argb_c, 1, kStrideB * kHeightB); \
843 memset(dst_argb_opt, 101, kStrideB * kHeightB); \
844 MaskCpuFlags(0); \
845 FMT_A##To##FMT_B(src_argb + OFF, kStrideA, \
846 dst_argb_c, kStrideB, \
847 kWidth, NEG kHeight); \
848 MaskCpuFlags(-1); \
849 for (int i = 0; i < benchmark_iterations_; ++i) { \
850 FMT_A##To##FMT_B(src_argb + OFF, kStrideA, \
851 dst_argb_opt, kStrideB, \
852 kWidth, NEG kHeight); \
853 } \
854 int max_diff = 0; \
855 for (int i = 0; i < kStrideB * kHeightB; ++i) { \
856 int abs_diff = \
857 abs(static_cast<int>(dst_argb_c[i]) - \
858 static_cast<int>(dst_argb_opt[i])); \
859 if (abs_diff > max_diff) { \
860 max_diff = abs_diff; \
861 } \
862 } \
863 EXPECT_LE(max_diff, DIFF); \
864 free_aligned_buffer_64(src_argb); \
865 free_aligned_buffer_64(dst_argb_c); \
866 free_aligned_buffer_64(dst_argb_opt); \
867 }
868
869 #define TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
870 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) \
871 TEST_F(libyuvTest, FMT_A##To##FMT_B##_Random) { \
872 srandom(time(NULL)); \
873 for (int times = 0; times < benchmark_iterations_; ++times) { \
874 const int kWidth = (random() & 63) + 1; \
875 const int kHeight = (random() & 31) + 1; \
876 const int kHeightA = (kHeight + HEIGHT_A - 1) / HEIGHT_A * HEIGHT_A; \
877 const int kHeightB = (kHeight + HEIGHT_B - 1) / HEIGHT_B * HEIGHT_B; \
878 const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A;\
879 const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B;\
880 align_buffer_page_end(src_argb, kStrideA * kHeightA); \
881 align_buffer_page_end(dst_argb_c, kStrideB * kHeightB); \
882 align_buffer_page_end(dst_argb_opt, kStrideB * kHeightB); \
883 for (int i = 0; i < kStrideA * kHeightA; ++i) { \
884 src_argb[i] = (random() & 0xff); \
885 } \
886 memset(dst_argb_c, 123, kStrideB * kHeightB); \
887 memset(dst_argb_opt, 123, kStrideB * kHeightB); \
888 MaskCpuFlags(0); \
889 FMT_A##To##FMT_B(src_argb, kStrideA, \
890 dst_argb_c, kStrideB, \
891 kWidth, kHeight); \
892 MaskCpuFlags(-1); \
893 FMT_A##To##FMT_B(src_argb, kStrideA, \
894 dst_argb_opt, kStrideB, \
895 kWidth, kHeight); \
896 int max_diff = 0; \
897 for (int i = 0; i < kStrideB * kHeightB; ++i) { \
898 int abs_diff = \
899 abs(static_cast<int>(dst_argb_c[i]) - \
900 static_cast<int>(dst_argb_opt[i])); \
901 if (abs_diff > max_diff) { \
902 max_diff = abs_diff; \
903 } \
904 } \
905 EXPECT_LE(max_diff, DIFF); \
906 free_aligned_buffer_page_end(src_argb); \
907 free_aligned_buffer_page_end(dst_argb_c); \
908 free_aligned_buffer_page_end(dst_argb_opt); \
909 } \
910 }
911
912 #define TESTATOB(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
913 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF) \
914 TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
915 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \
916 benchmark_width_ - 4, DIFF, _Any, +, 0) \
917 TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
918 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \
919 benchmark_width_, DIFF, _Unaligned, +, 1) \
920 TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
921 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \
922 benchmark_width_, DIFF, _Invert, -, 0) \
923 TESTATOBI(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
924 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, \
925 benchmark_width_, DIFF, _Opt, +, 0) \
926 TESTATOBRANDOM(FMT_A, BPP_A, STRIDE_A, HEIGHT_A, \
927 FMT_B, BPP_B, STRIDE_B, HEIGHT_B, DIFF)
928
929 TESTATOB(ARGB, 4, 4, 1, ARGB, 4, 4, 1, 0)
930 TESTATOB(ARGB, 4, 4, 1, BGRA, 4, 4, 1, 0)
931 TESTATOB(ARGB, 4, 4, 1, ABGR, 4, 4, 1, 0)
932 TESTATOB(ARGB, 4, 4, 1, RGBA, 4, 4, 1, 0)
933 TESTATOB(ARGB, 4, 4, 1, RAW, 3, 3, 1, 0)
934 TESTATOB(ARGB, 4, 4, 1, RGB24, 3, 3, 1, 0)
935 TESTATOB(ARGB, 4, 4, 1, RGB565, 2, 2, 1, 0)
936 TESTATOB(ARGB, 4, 4, 1, ARGB1555, 2, 2, 1, 0)
937 TESTATOB(ARGB, 4, 4, 1, ARGB4444, 2, 2, 1, 0)
938 TESTATOB(ARGB, 4, 4, 1, BayerBGGR, 1, 1, 1, 0)
939 TESTATOB(ARGB, 4, 4, 1, BayerRGGB, 1, 1, 1, 0)
940 TESTATOB(ARGB, 4, 4, 1, BayerGBRG, 1, 1, 1, 0)
941 TESTATOB(ARGB, 4, 4, 1, BayerGRBG, 1, 1, 1, 0)
942 TESTATOB(ARGB, 4, 4, 1, YUY2, 2, 4, 1, 4)
943 TESTATOB(ARGB, 4, 4, 1, UYVY, 2, 4, 1, 4)
944 TESTATOB(ARGB, 4, 4, 1, I400, 1, 1, 1, 2)
945 TESTATOB(ARGB, 4, 4, 1, J400, 1, 1, 1, 2)
946 TESTATOB(BGRA, 4, 4, 1, ARGB, 4, 4, 1, 0)
947 TESTATOB(ABGR, 4, 4, 1, ARGB, 4, 4, 1, 0)
948 TESTATOB(RGBA, 4, 4, 1, ARGB, 4, 4, 1, 0)
949 TESTATOB(RAW, 3, 3, 1, ARGB, 4, 4, 1, 0)
950 TESTATOB(RGB24, 3, 3, 1, ARGB, 4, 4, 1, 0)
951 TESTATOB(RGB565, 2, 2, 1, ARGB, 4, 4, 1, 0)
952 TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1, 0)
953 TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1, 0)
954 TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, 4)
955 TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, 4)
956 TESTATOB(BayerBGGR, 1, 2, 2, ARGB, 4, 4, 1, 0)
957 TESTATOB(BayerRGGB, 1, 2, 2, ARGB, 4, 4, 1, 0)
958 TESTATOB(BayerGBRG, 1, 2, 2, ARGB, 4, 4, 1, 0)
959 TESTATOB(BayerGRBG, 1, 2, 2, ARGB, 4, 4, 1, 0)
960 TESTATOB(I400, 1, 1, 1, ARGB, 4, 4, 1, 0)
961 TESTATOB(I400, 1, 1, 1, I400, 1, 1, 1, 0)
962 TESTATOB(I400, 1, 1, 1, I400Mirror, 1, 1, 1, 0)
963 TESTATOB(Y, 1, 1, 1, ARGB, 4, 4, 1, 0)
964 TESTATOB(ARGB, 4, 4, 1, ARGBMirror, 4, 4, 1, 0)
965
966 TEST_F(libyuvTest, Test565) {
967 SIMD_ALIGNED(uint8 orig_pixels[256][4]);
968 SIMD_ALIGNED(uint8 pixels565[256][2]);
969
970 for (int i = 0; i < 256; ++i) {
971 for (int j = 0; j < 4; ++j) {
972 orig_pixels[i][j] = i;
973 }
974 }
975 ARGBToRGB565(&orig_pixels[0][0], 0, &pixels565[0][0], 0, 256, 1);
976 uint32 checksum = HashDjb2(&pixels565[0][0], sizeof(pixels565), 5381);
977 EXPECT_EQ(610919429u, checksum);
978 }
979
980 #ifdef HAVE_JPEG
981 TEST_F(libyuvTest, ValidateJpeg) {
982 const int kOff = 10;
983 const int kMinJpeg = 64;
984 const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ?
985 benchmark_width_ * benchmark_height_ : kMinJpeg;
986 const int kSize = kImageSize + kOff;
987 align_buffer_64(orig_pixels, kSize);
988
989 // No SOI or EOI. Expect fail.
990 memset(orig_pixels, 0, kSize);
991
992 // EOI, SOI. Expect pass.
993 orig_pixels[0] = 0xff;
994 orig_pixels[1] = 0xd8; // SOI.
995 orig_pixels[kSize - kOff + 0] = 0xff;
996 orig_pixels[kSize - kOff + 1] = 0xd9; // EOI.
997 for (int times = 0; times < benchmark_iterations_; ++times) {
998 EXPECT_TRUE(ValidateJpeg(orig_pixels, kSize));
999 }
1000 free_aligned_buffer_page_end(orig_pixels);
1001 }
1002
1003 TEST_F(libyuvTest, InvalidateJpeg) {
1004 const int kOff = 10;
1005 const int kMinJpeg = 64;
1006 const int kImageSize = benchmark_width_ * benchmark_height_ >= kMinJpeg ?
1007 benchmark_width_ * benchmark_height_ : kMinJpeg;
1008 const int kSize = kImageSize + kOff;
1009 align_buffer_64(orig_pixels, kSize);
1010
1011 // No SOI or EOI. Expect fail.
1012 memset(orig_pixels, 0, kSize);
1013 EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
1014
1015 // SOI but no EOI. Expect fail.
1016 orig_pixels[0] = 0xff;
1017 orig_pixels[1] = 0xd8; // SOI.
1018 for (int times = 0; times < benchmark_iterations_; ++times) {
1019 EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
1020 }
1021 // EOI but no SOI. Expect fail.
1022 orig_pixels[0] = 0;
1023 orig_pixels[1] = 0;
1024 orig_pixels[kSize - kOff + 0] = 0xff;
1025 orig_pixels[kSize - kOff + 1] = 0xd9; // EOI.
1026 EXPECT_FALSE(ValidateJpeg(orig_pixels, kSize));
1027
1028 free_aligned_buffer_page_end(orig_pixels);
1029 }
1030
1031 #endif
1032
1033 } // namespace libyuv

mercurial