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 "../unit_test/unit_test.h"
15 #include "libyuv/cpu_id.h"
16 #include "libyuv/scale.h"
17
18 #ifdef ENABLE_ROW_TESTS
19 #include "libyuv/scale_row.h" // For ScaleRowDown2Box_Odd_C
20 #endif
21
22 #define STRINGIZE(line) #line
23 #define FILELINESTR(file, line) file ":" STRINGIZE(line)
24
25 #if defined(__riscv) && !defined(__clang__)
26 #define DISABLE_SLOW_TESTS
27 #undef ENABLE_FULL_TESTS
28 #endif
29
30 #if !defined(DISABLE_SLOW_TESTS) || defined(__x86_64__) || defined(__i386__)
31 // SLOW TESTS are those that are unoptimized C code.
32 // FULL TESTS are optimized but test many variations of the same code.
33 #define ENABLE_FULL_TESTS
34 #endif
35
36 namespace libyuv {
37
38 // Test scaling with C vs Opt and return maximum pixel difference. 0 = exact.
I420TestFilter(int src_width,int src_height,int dst_width,int dst_height,FilterMode f,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)39 static int I420TestFilter(int src_width,
40 int src_height,
41 int dst_width,
42 int dst_height,
43 FilterMode f,
44 int benchmark_iterations,
45 int disable_cpu_flags,
46 int benchmark_cpu_info) {
47 if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
48 return 0;
49 }
50
51 int i, j;
52 int src_width_uv = (Abs(src_width) + 1) >> 1;
53 int src_height_uv = (Abs(src_height) + 1) >> 1;
54
55 int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height));
56 int64_t src_uv_plane_size = (src_width_uv) * (src_height_uv);
57
58 int src_stride_y = Abs(src_width);
59 int src_stride_uv = src_width_uv;
60
61 align_buffer_page_end(src_y, src_y_plane_size);
62 align_buffer_page_end(src_u, src_uv_plane_size);
63 align_buffer_page_end(src_v, src_uv_plane_size);
64 if (!src_y || !src_u || !src_v) {
65 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
66 return 0;
67 }
68 MemRandomize(src_y, src_y_plane_size);
69 MemRandomize(src_u, src_uv_plane_size);
70 MemRandomize(src_v, src_uv_plane_size);
71
72 int dst_width_uv = (dst_width + 1) >> 1;
73 int dst_height_uv = (dst_height + 1) >> 1;
74
75 int64_t dst_y_plane_size = (dst_width) * (dst_height);
76 int64_t dst_uv_plane_size = (dst_width_uv) * (dst_height_uv);
77
78 int dst_stride_y = dst_width;
79 int dst_stride_uv = dst_width_uv;
80
81 align_buffer_page_end(dst_y_c, dst_y_plane_size);
82 align_buffer_page_end(dst_u_c, dst_uv_plane_size);
83 align_buffer_page_end(dst_v_c, dst_uv_plane_size);
84 align_buffer_page_end(dst_y_opt, dst_y_plane_size);
85 align_buffer_page_end(dst_u_opt, dst_uv_plane_size);
86 align_buffer_page_end(dst_v_opt, dst_uv_plane_size);
87 if (!dst_y_c || !dst_u_c || !dst_v_c || !dst_y_opt || !dst_u_opt ||
88 !dst_v_opt) {
89 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
90 return 0;
91 }
92
93 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
94 double c_time = get_time();
95 I420Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
96 src_width, src_height, dst_y_c, dst_stride_y, dst_u_c,
97 dst_stride_uv, dst_v_c, dst_stride_uv, dst_width, dst_height, f);
98 c_time = (get_time() - c_time);
99
100 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
101 double opt_time = get_time();
102 for (i = 0; i < benchmark_iterations; ++i) {
103 I420Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
104 src_width, src_height, dst_y_opt, dst_stride_y, dst_u_opt,
105 dst_stride_uv, dst_v_opt, dst_stride_uv, dst_width, dst_height,
106 f);
107 }
108 opt_time = (get_time() - opt_time) / benchmark_iterations;
109 // Report performance of C vs OPT.
110 printf("filter %d - %8d us C - %8d us OPT\n", f,
111 static_cast<int>(c_time * 1e6), static_cast<int>(opt_time * 1e6));
112
113 // C version may be a little off from the optimized. Order of
114 // operations may introduce rounding somewhere. So do a difference
115 // of the buffers and look to see that the max difference is not
116 // over 3.
117 int max_diff = 0;
118 for (i = 0; i < (dst_height); ++i) {
119 for (j = 0; j < (dst_width); ++j) {
120 int abs_diff = Abs(dst_y_c[(i * dst_stride_y) + j] -
121 dst_y_opt[(i * dst_stride_y) + j]);
122 if (abs_diff > max_diff) {
123 max_diff = abs_diff;
124 }
125 }
126 }
127
128 for (i = 0; i < (dst_height_uv); ++i) {
129 for (j = 0; j < (dst_width_uv); ++j) {
130 int abs_diff = Abs(dst_u_c[(i * dst_stride_uv) + j] -
131 dst_u_opt[(i * dst_stride_uv) + j]);
132 if (abs_diff > max_diff) {
133 max_diff = abs_diff;
134 }
135 abs_diff = Abs(dst_v_c[(i * dst_stride_uv) + j] -
136 dst_v_opt[(i * dst_stride_uv) + j]);
137 if (abs_diff > max_diff) {
138 max_diff = abs_diff;
139 }
140 }
141 }
142
143 free_aligned_buffer_page_end(dst_y_c);
144 free_aligned_buffer_page_end(dst_u_c);
145 free_aligned_buffer_page_end(dst_v_c);
146 free_aligned_buffer_page_end(dst_y_opt);
147 free_aligned_buffer_page_end(dst_u_opt);
148 free_aligned_buffer_page_end(dst_v_opt);
149 free_aligned_buffer_page_end(src_y);
150 free_aligned_buffer_page_end(src_u);
151 free_aligned_buffer_page_end(src_v);
152
153 return max_diff;
154 }
155
156 // Test scaling with 8 bit C vs 12 bit C and return maximum pixel difference.
157 // 0 = exact.
I420TestFilter_12(int src_width,int src_height,int dst_width,int dst_height,FilterMode f,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)158 static int I420TestFilter_12(int src_width,
159 int src_height,
160 int dst_width,
161 int dst_height,
162 FilterMode f,
163 int benchmark_iterations,
164 int disable_cpu_flags,
165 int benchmark_cpu_info) {
166 if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
167 return 0;
168 }
169
170 int i;
171 int src_width_uv = (Abs(src_width) + 1) >> 1;
172 int src_height_uv = (Abs(src_height) + 1) >> 1;
173
174 int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height));
175 int64_t src_uv_plane_size = (src_width_uv) * (src_height_uv);
176
177 int src_stride_y = Abs(src_width);
178 int src_stride_uv = src_width_uv;
179
180 align_buffer_page_end(src_y, src_y_plane_size);
181 align_buffer_page_end(src_u, src_uv_plane_size);
182 align_buffer_page_end(src_v, src_uv_plane_size);
183 align_buffer_page_end(src_y_12, src_y_plane_size * 2);
184 align_buffer_page_end(src_u_12, src_uv_plane_size * 2);
185 align_buffer_page_end(src_v_12, src_uv_plane_size * 2);
186 if (!src_y || !src_u || !src_v || !src_y_12 || !src_u_12 || !src_v_12) {
187 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
188 return 0;
189 }
190 uint16_t* p_src_y_12 = reinterpret_cast<uint16_t*>(src_y_12);
191 uint16_t* p_src_u_12 = reinterpret_cast<uint16_t*>(src_u_12);
192 uint16_t* p_src_v_12 = reinterpret_cast<uint16_t*>(src_v_12);
193
194 MemRandomize(src_y, src_y_plane_size);
195 MemRandomize(src_u, src_uv_plane_size);
196 MemRandomize(src_v, src_uv_plane_size);
197
198 for (i = 0; i < src_y_plane_size; ++i) {
199 p_src_y_12[i] = src_y[i];
200 }
201 for (i = 0; i < src_uv_plane_size; ++i) {
202 p_src_u_12[i] = src_u[i];
203 p_src_v_12[i] = src_v[i];
204 }
205
206 int dst_width_uv = (dst_width + 1) >> 1;
207 int dst_height_uv = (dst_height + 1) >> 1;
208
209 int dst_y_plane_size = (dst_width) * (dst_height);
210 int dst_uv_plane_size = (dst_width_uv) * (dst_height_uv);
211
212 int dst_stride_y = dst_width;
213 int dst_stride_uv = dst_width_uv;
214
215 align_buffer_page_end(dst_y_8, dst_y_plane_size);
216 align_buffer_page_end(dst_u_8, dst_uv_plane_size);
217 align_buffer_page_end(dst_v_8, dst_uv_plane_size);
218 align_buffer_page_end(dst_y_12, dst_y_plane_size * 2);
219 align_buffer_page_end(dst_u_12, dst_uv_plane_size * 2);
220 align_buffer_page_end(dst_v_12, dst_uv_plane_size * 2);
221
222 uint16_t* p_dst_y_12 = reinterpret_cast<uint16_t*>(dst_y_12);
223 uint16_t* p_dst_u_12 = reinterpret_cast<uint16_t*>(dst_u_12);
224 uint16_t* p_dst_v_12 = reinterpret_cast<uint16_t*>(dst_v_12);
225
226 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
227 I420Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
228 src_width, src_height, dst_y_8, dst_stride_y, dst_u_8,
229 dst_stride_uv, dst_v_8, dst_stride_uv, dst_width, dst_height, f);
230 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
231 for (i = 0; i < benchmark_iterations; ++i) {
232 I420Scale_12(p_src_y_12, src_stride_y, p_src_u_12, src_stride_uv,
233 p_src_v_12, src_stride_uv, src_width, src_height, p_dst_y_12,
234 dst_stride_y, p_dst_u_12, dst_stride_uv, p_dst_v_12,
235 dst_stride_uv, dst_width, dst_height, f);
236 }
237
238 // Expect an exact match.
239 int max_diff = 0;
240 for (i = 0; i < dst_y_plane_size; ++i) {
241 int abs_diff = Abs(dst_y_8[i] - p_dst_y_12[i]);
242 if (abs_diff > max_diff) {
243 max_diff = abs_diff;
244 }
245 }
246 for (i = 0; i < dst_uv_plane_size; ++i) {
247 int abs_diff = Abs(dst_u_8[i] - p_dst_u_12[i]);
248 if (abs_diff > max_diff) {
249 max_diff = abs_diff;
250 }
251 abs_diff = Abs(dst_v_8[i] - p_dst_v_12[i]);
252 if (abs_diff > max_diff) {
253 max_diff = abs_diff;
254 }
255 }
256
257 free_aligned_buffer_page_end(dst_y_8);
258 free_aligned_buffer_page_end(dst_u_8);
259 free_aligned_buffer_page_end(dst_v_8);
260 free_aligned_buffer_page_end(dst_y_12);
261 free_aligned_buffer_page_end(dst_u_12);
262 free_aligned_buffer_page_end(dst_v_12);
263 free_aligned_buffer_page_end(src_y);
264 free_aligned_buffer_page_end(src_u);
265 free_aligned_buffer_page_end(src_v);
266 free_aligned_buffer_page_end(src_y_12);
267 free_aligned_buffer_page_end(src_u_12);
268 free_aligned_buffer_page_end(src_v_12);
269
270 return max_diff;
271 }
272
273 // Test scaling with 8 bit C vs 16 bit C and return maximum pixel difference.
274 // 0 = exact.
I420TestFilter_16(int src_width,int src_height,int dst_width,int dst_height,FilterMode f,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)275 static int I420TestFilter_16(int src_width,
276 int src_height,
277 int dst_width,
278 int dst_height,
279 FilterMode f,
280 int benchmark_iterations,
281 int disable_cpu_flags,
282 int benchmark_cpu_info) {
283 if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
284 return 0;
285 }
286
287 int i;
288 int src_width_uv = (Abs(src_width) + 1) >> 1;
289 int src_height_uv = (Abs(src_height) + 1) >> 1;
290
291 int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height));
292 int64_t src_uv_plane_size = (src_width_uv) * (src_height_uv);
293
294 int src_stride_y = Abs(src_width);
295 int src_stride_uv = src_width_uv;
296
297 align_buffer_page_end(src_y, src_y_plane_size);
298 align_buffer_page_end(src_u, src_uv_plane_size);
299 align_buffer_page_end(src_v, src_uv_plane_size);
300 align_buffer_page_end(src_y_16, src_y_plane_size * 2);
301 align_buffer_page_end(src_u_16, src_uv_plane_size * 2);
302 align_buffer_page_end(src_v_16, src_uv_plane_size * 2);
303 if (!src_y || !src_u || !src_v || !src_y_16 || !src_u_16 || !src_v_16) {
304 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
305 return 0;
306 }
307 uint16_t* p_src_y_16 = reinterpret_cast<uint16_t*>(src_y_16);
308 uint16_t* p_src_u_16 = reinterpret_cast<uint16_t*>(src_u_16);
309 uint16_t* p_src_v_16 = reinterpret_cast<uint16_t*>(src_v_16);
310
311 MemRandomize(src_y, src_y_plane_size);
312 MemRandomize(src_u, src_uv_plane_size);
313 MemRandomize(src_v, src_uv_plane_size);
314
315 for (i = 0; i < src_y_plane_size; ++i) {
316 p_src_y_16[i] = src_y[i];
317 }
318 for (i = 0; i < src_uv_plane_size; ++i) {
319 p_src_u_16[i] = src_u[i];
320 p_src_v_16[i] = src_v[i];
321 }
322
323 int dst_width_uv = (dst_width + 1) >> 1;
324 int dst_height_uv = (dst_height + 1) >> 1;
325
326 int dst_y_plane_size = (dst_width) * (dst_height);
327 int dst_uv_plane_size = (dst_width_uv) * (dst_height_uv);
328
329 int dst_stride_y = dst_width;
330 int dst_stride_uv = dst_width_uv;
331
332 align_buffer_page_end(dst_y_8, dst_y_plane_size);
333 align_buffer_page_end(dst_u_8, dst_uv_plane_size);
334 align_buffer_page_end(dst_v_8, dst_uv_plane_size);
335 align_buffer_page_end(dst_y_16, dst_y_plane_size * 2);
336 align_buffer_page_end(dst_u_16, dst_uv_plane_size * 2);
337 align_buffer_page_end(dst_v_16, dst_uv_plane_size * 2);
338
339 uint16_t* p_dst_y_16 = reinterpret_cast<uint16_t*>(dst_y_16);
340 uint16_t* p_dst_u_16 = reinterpret_cast<uint16_t*>(dst_u_16);
341 uint16_t* p_dst_v_16 = reinterpret_cast<uint16_t*>(dst_v_16);
342
343 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
344 I420Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
345 src_width, src_height, dst_y_8, dst_stride_y, dst_u_8,
346 dst_stride_uv, dst_v_8, dst_stride_uv, dst_width, dst_height, f);
347 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
348 for (i = 0; i < benchmark_iterations; ++i) {
349 I420Scale_16(p_src_y_16, src_stride_y, p_src_u_16, src_stride_uv,
350 p_src_v_16, src_stride_uv, src_width, src_height, p_dst_y_16,
351 dst_stride_y, p_dst_u_16, dst_stride_uv, p_dst_v_16,
352 dst_stride_uv, dst_width, dst_height, f);
353 }
354
355 // Expect an exact match.
356 int max_diff = 0;
357 for (i = 0; i < dst_y_plane_size; ++i) {
358 int abs_diff = Abs(dst_y_8[i] - p_dst_y_16[i]);
359 if (abs_diff > max_diff) {
360 max_diff = abs_diff;
361 }
362 }
363 for (i = 0; i < dst_uv_plane_size; ++i) {
364 int abs_diff = Abs(dst_u_8[i] - p_dst_u_16[i]);
365 if (abs_diff > max_diff) {
366 max_diff = abs_diff;
367 }
368 abs_diff = Abs(dst_v_8[i] - p_dst_v_16[i]);
369 if (abs_diff > max_diff) {
370 max_diff = abs_diff;
371 }
372 }
373
374 free_aligned_buffer_page_end(dst_y_8);
375 free_aligned_buffer_page_end(dst_u_8);
376 free_aligned_buffer_page_end(dst_v_8);
377 free_aligned_buffer_page_end(dst_y_16);
378 free_aligned_buffer_page_end(dst_u_16);
379 free_aligned_buffer_page_end(dst_v_16);
380 free_aligned_buffer_page_end(src_y);
381 free_aligned_buffer_page_end(src_u);
382 free_aligned_buffer_page_end(src_v);
383 free_aligned_buffer_page_end(src_y_16);
384 free_aligned_buffer_page_end(src_u_16);
385 free_aligned_buffer_page_end(src_v_16);
386
387 return max_diff;
388 }
389
390 // Test scaling with C vs Opt and return maximum pixel difference. 0 = exact.
I444TestFilter(int src_width,int src_height,int dst_width,int dst_height,FilterMode f,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)391 static int I444TestFilter(int src_width,
392 int src_height,
393 int dst_width,
394 int dst_height,
395 FilterMode f,
396 int benchmark_iterations,
397 int disable_cpu_flags,
398 int benchmark_cpu_info) {
399 if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
400 return 0;
401 }
402
403 int i, j;
404 int src_width_uv = Abs(src_width);
405 int src_height_uv = Abs(src_height);
406
407 int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height));
408 int64_t src_uv_plane_size = (src_width_uv) * (src_height_uv);
409
410 int src_stride_y = Abs(src_width);
411 int src_stride_uv = src_width_uv;
412
413 align_buffer_page_end(src_y, src_y_plane_size);
414 align_buffer_page_end(src_u, src_uv_plane_size);
415 align_buffer_page_end(src_v, src_uv_plane_size);
416 if (!src_y || !src_u || !src_v) {
417 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
418 return 0;
419 }
420 MemRandomize(src_y, src_y_plane_size);
421 MemRandomize(src_u, src_uv_plane_size);
422 MemRandomize(src_v, src_uv_plane_size);
423
424 int dst_width_uv = dst_width;
425 int dst_height_uv = dst_height;
426
427 int64_t dst_y_plane_size = (dst_width) * (dst_height);
428 int64_t dst_uv_plane_size = (dst_width_uv) * (dst_height_uv);
429
430 int dst_stride_y = dst_width;
431 int dst_stride_uv = dst_width_uv;
432
433 align_buffer_page_end(dst_y_c, dst_y_plane_size);
434 align_buffer_page_end(dst_u_c, dst_uv_plane_size);
435 align_buffer_page_end(dst_v_c, dst_uv_plane_size);
436 align_buffer_page_end(dst_y_opt, dst_y_plane_size);
437 align_buffer_page_end(dst_u_opt, dst_uv_plane_size);
438 align_buffer_page_end(dst_v_opt, dst_uv_plane_size);
439 if (!dst_y_c || !dst_u_c || !dst_v_c || !dst_y_opt || !dst_u_opt ||
440 !dst_v_opt) {
441 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
442 return 0;
443 }
444
445 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
446 double c_time = get_time();
447 I444Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
448 src_width, src_height, dst_y_c, dst_stride_y, dst_u_c,
449 dst_stride_uv, dst_v_c, dst_stride_uv, dst_width, dst_height, f);
450 c_time = (get_time() - c_time);
451
452 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
453 double opt_time = get_time();
454 for (i = 0; i < benchmark_iterations; ++i) {
455 I444Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
456 src_width, src_height, dst_y_opt, dst_stride_y, dst_u_opt,
457 dst_stride_uv, dst_v_opt, dst_stride_uv, dst_width, dst_height,
458 f);
459 }
460 opt_time = (get_time() - opt_time) / benchmark_iterations;
461 // Report performance of C vs OPT.
462 printf("filter %d - %8d us C - %8d us OPT\n", f,
463 static_cast<int>(c_time * 1e6), static_cast<int>(opt_time * 1e6));
464
465 // C version may be a little off from the optimized. Order of
466 // operations may introduce rounding somewhere. So do a difference
467 // of the buffers and look to see that the max difference is not
468 // over 3.
469 int max_diff = 0;
470 for (i = 0; i < (dst_height); ++i) {
471 for (j = 0; j < (dst_width); ++j) {
472 int abs_diff = Abs(dst_y_c[(i * dst_stride_y) + j] -
473 dst_y_opt[(i * dst_stride_y) + j]);
474 if (abs_diff > max_diff) {
475 max_diff = abs_diff;
476 }
477 }
478 }
479
480 for (i = 0; i < (dst_height_uv); ++i) {
481 for (j = 0; j < (dst_width_uv); ++j) {
482 int abs_diff = Abs(dst_u_c[(i * dst_stride_uv) + j] -
483 dst_u_opt[(i * dst_stride_uv) + j]);
484 if (abs_diff > max_diff) {
485 max_diff = abs_diff;
486 }
487 abs_diff = Abs(dst_v_c[(i * dst_stride_uv) + j] -
488 dst_v_opt[(i * dst_stride_uv) + j]);
489 if (abs_diff > max_diff) {
490 max_diff = abs_diff;
491 }
492 }
493 }
494
495 free_aligned_buffer_page_end(dst_y_c);
496 free_aligned_buffer_page_end(dst_u_c);
497 free_aligned_buffer_page_end(dst_v_c);
498 free_aligned_buffer_page_end(dst_y_opt);
499 free_aligned_buffer_page_end(dst_u_opt);
500 free_aligned_buffer_page_end(dst_v_opt);
501 free_aligned_buffer_page_end(src_y);
502 free_aligned_buffer_page_end(src_u);
503 free_aligned_buffer_page_end(src_v);
504
505 return max_diff;
506 }
507
508 // Test scaling with 8 bit C vs 12 bit C and return maximum pixel difference.
509 // 0 = exact.
I444TestFilter_12(int src_width,int src_height,int dst_width,int dst_height,FilterMode f,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)510 static int I444TestFilter_12(int src_width,
511 int src_height,
512 int dst_width,
513 int dst_height,
514 FilterMode f,
515 int benchmark_iterations,
516 int disable_cpu_flags,
517 int benchmark_cpu_info) {
518 if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
519 return 0;
520 }
521
522 int i;
523 int src_width_uv = Abs(src_width);
524 int src_height_uv = Abs(src_height);
525
526 int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height));
527 int64_t src_uv_plane_size = (src_width_uv) * (src_height_uv);
528
529 int src_stride_y = Abs(src_width);
530 int src_stride_uv = src_width_uv;
531
532 align_buffer_page_end(src_y, src_y_plane_size);
533 align_buffer_page_end(src_u, src_uv_plane_size);
534 align_buffer_page_end(src_v, src_uv_plane_size);
535 align_buffer_page_end(src_y_12, src_y_plane_size * 2);
536 align_buffer_page_end(src_u_12, src_uv_plane_size * 2);
537 align_buffer_page_end(src_v_12, src_uv_plane_size * 2);
538 if (!src_y || !src_u || !src_v || !src_y_12 || !src_u_12 || !src_v_12) {
539 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
540 return 0;
541 }
542 uint16_t* p_src_y_12 = reinterpret_cast<uint16_t*>(src_y_12);
543 uint16_t* p_src_u_12 = reinterpret_cast<uint16_t*>(src_u_12);
544 uint16_t* p_src_v_12 = reinterpret_cast<uint16_t*>(src_v_12);
545
546 MemRandomize(src_y, src_y_plane_size);
547 MemRandomize(src_u, src_uv_plane_size);
548 MemRandomize(src_v, src_uv_plane_size);
549
550 for (i = 0; i < src_y_plane_size; ++i) {
551 p_src_y_12[i] = src_y[i];
552 }
553 for (i = 0; i < src_uv_plane_size; ++i) {
554 p_src_u_12[i] = src_u[i];
555 p_src_v_12[i] = src_v[i];
556 }
557
558 int dst_width_uv = dst_width;
559 int dst_height_uv = dst_height;
560
561 int dst_y_plane_size = (dst_width) * (dst_height);
562 int dst_uv_plane_size = (dst_width_uv) * (dst_height_uv);
563
564 int dst_stride_y = dst_width;
565 int dst_stride_uv = dst_width_uv;
566
567 align_buffer_page_end(dst_y_8, dst_y_plane_size);
568 align_buffer_page_end(dst_u_8, dst_uv_plane_size);
569 align_buffer_page_end(dst_v_8, dst_uv_plane_size);
570 align_buffer_page_end(dst_y_12, dst_y_plane_size * 2);
571 align_buffer_page_end(dst_u_12, dst_uv_plane_size * 2);
572 align_buffer_page_end(dst_v_12, dst_uv_plane_size * 2);
573
574 uint16_t* p_dst_y_12 = reinterpret_cast<uint16_t*>(dst_y_12);
575 uint16_t* p_dst_u_12 = reinterpret_cast<uint16_t*>(dst_u_12);
576 uint16_t* p_dst_v_12 = reinterpret_cast<uint16_t*>(dst_v_12);
577
578 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
579 I444Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
580 src_width, src_height, dst_y_8, dst_stride_y, dst_u_8,
581 dst_stride_uv, dst_v_8, dst_stride_uv, dst_width, dst_height, f);
582 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
583 for (i = 0; i < benchmark_iterations; ++i) {
584 I444Scale_12(p_src_y_12, src_stride_y, p_src_u_12, src_stride_uv,
585 p_src_v_12, src_stride_uv, src_width, src_height, p_dst_y_12,
586 dst_stride_y, p_dst_u_12, dst_stride_uv, p_dst_v_12,
587 dst_stride_uv, dst_width, dst_height, f);
588 }
589
590 // Expect an exact match.
591 int max_diff = 0;
592 for (i = 0; i < dst_y_plane_size; ++i) {
593 int abs_diff = Abs(dst_y_8[i] - p_dst_y_12[i]);
594 if (abs_diff > max_diff) {
595 max_diff = abs_diff;
596 }
597 }
598 for (i = 0; i < dst_uv_plane_size; ++i) {
599 int abs_diff = Abs(dst_u_8[i] - p_dst_u_12[i]);
600 if (abs_diff > max_diff) {
601 max_diff = abs_diff;
602 }
603 abs_diff = Abs(dst_v_8[i] - p_dst_v_12[i]);
604 if (abs_diff > max_diff) {
605 max_diff = abs_diff;
606 }
607 }
608
609 free_aligned_buffer_page_end(dst_y_8);
610 free_aligned_buffer_page_end(dst_u_8);
611 free_aligned_buffer_page_end(dst_v_8);
612 free_aligned_buffer_page_end(dst_y_12);
613 free_aligned_buffer_page_end(dst_u_12);
614 free_aligned_buffer_page_end(dst_v_12);
615 free_aligned_buffer_page_end(src_y);
616 free_aligned_buffer_page_end(src_u);
617 free_aligned_buffer_page_end(src_v);
618 free_aligned_buffer_page_end(src_y_12);
619 free_aligned_buffer_page_end(src_u_12);
620 free_aligned_buffer_page_end(src_v_12);
621
622 return max_diff;
623 }
624
625 // Test scaling with 8 bit C vs 16 bit C and return maximum pixel difference.
626 // 0 = exact.
I444TestFilter_16(int src_width,int src_height,int dst_width,int dst_height,FilterMode f,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)627 static int I444TestFilter_16(int src_width,
628 int src_height,
629 int dst_width,
630 int dst_height,
631 FilterMode f,
632 int benchmark_iterations,
633 int disable_cpu_flags,
634 int benchmark_cpu_info) {
635 if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
636 return 0;
637 }
638
639 int i;
640 int src_width_uv = Abs(src_width);
641 int src_height_uv = Abs(src_height);
642
643 int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height));
644 int64_t src_uv_plane_size = (src_width_uv) * (src_height_uv);
645
646 int src_stride_y = Abs(src_width);
647 int src_stride_uv = src_width_uv;
648
649 align_buffer_page_end(src_y, src_y_plane_size);
650 align_buffer_page_end(src_u, src_uv_plane_size);
651 align_buffer_page_end(src_v, src_uv_plane_size);
652 align_buffer_page_end(src_y_16, src_y_plane_size * 2);
653 align_buffer_page_end(src_u_16, src_uv_plane_size * 2);
654 align_buffer_page_end(src_v_16, src_uv_plane_size * 2);
655 if (!src_y || !src_u || !src_v || !src_y_16 || !src_u_16 || !src_v_16) {
656 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
657 return 0;
658 }
659 uint16_t* p_src_y_16 = reinterpret_cast<uint16_t*>(src_y_16);
660 uint16_t* p_src_u_16 = reinterpret_cast<uint16_t*>(src_u_16);
661 uint16_t* p_src_v_16 = reinterpret_cast<uint16_t*>(src_v_16);
662
663 MemRandomize(src_y, src_y_plane_size);
664 MemRandomize(src_u, src_uv_plane_size);
665 MemRandomize(src_v, src_uv_plane_size);
666
667 for (i = 0; i < src_y_plane_size; ++i) {
668 p_src_y_16[i] = src_y[i];
669 }
670 for (i = 0; i < src_uv_plane_size; ++i) {
671 p_src_u_16[i] = src_u[i];
672 p_src_v_16[i] = src_v[i];
673 }
674
675 int dst_width_uv = dst_width;
676 int dst_height_uv = dst_height;
677
678 int dst_y_plane_size = (dst_width) * (dst_height);
679 int dst_uv_plane_size = (dst_width_uv) * (dst_height_uv);
680
681 int dst_stride_y = dst_width;
682 int dst_stride_uv = dst_width_uv;
683
684 align_buffer_page_end(dst_y_8, dst_y_plane_size);
685 align_buffer_page_end(dst_u_8, dst_uv_plane_size);
686 align_buffer_page_end(dst_v_8, dst_uv_plane_size);
687 align_buffer_page_end(dst_y_16, dst_y_plane_size * 2);
688 align_buffer_page_end(dst_u_16, dst_uv_plane_size * 2);
689 align_buffer_page_end(dst_v_16, dst_uv_plane_size * 2);
690
691 uint16_t* p_dst_y_16 = reinterpret_cast<uint16_t*>(dst_y_16);
692 uint16_t* p_dst_u_16 = reinterpret_cast<uint16_t*>(dst_u_16);
693 uint16_t* p_dst_v_16 = reinterpret_cast<uint16_t*>(dst_v_16);
694
695 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
696 I444Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
697 src_width, src_height, dst_y_8, dst_stride_y, dst_u_8,
698 dst_stride_uv, dst_v_8, dst_stride_uv, dst_width, dst_height, f);
699 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
700 for (i = 0; i < benchmark_iterations; ++i) {
701 I444Scale_16(p_src_y_16, src_stride_y, p_src_u_16, src_stride_uv,
702 p_src_v_16, src_stride_uv, src_width, src_height, p_dst_y_16,
703 dst_stride_y, p_dst_u_16, dst_stride_uv, p_dst_v_16,
704 dst_stride_uv, dst_width, dst_height, f);
705 }
706
707 // Expect an exact match.
708 int max_diff = 0;
709 for (i = 0; i < dst_y_plane_size; ++i) {
710 int abs_diff = Abs(dst_y_8[i] - p_dst_y_16[i]);
711 if (abs_diff > max_diff) {
712 max_diff = abs_diff;
713 }
714 }
715 for (i = 0; i < dst_uv_plane_size; ++i) {
716 int abs_diff = Abs(dst_u_8[i] - p_dst_u_16[i]);
717 if (abs_diff > max_diff) {
718 max_diff = abs_diff;
719 }
720 abs_diff = Abs(dst_v_8[i] - p_dst_v_16[i]);
721 if (abs_diff > max_diff) {
722 max_diff = abs_diff;
723 }
724 }
725
726 free_aligned_buffer_page_end(dst_y_8);
727 free_aligned_buffer_page_end(dst_u_8);
728 free_aligned_buffer_page_end(dst_v_8);
729 free_aligned_buffer_page_end(dst_y_16);
730 free_aligned_buffer_page_end(dst_u_16);
731 free_aligned_buffer_page_end(dst_v_16);
732 free_aligned_buffer_page_end(src_y);
733 free_aligned_buffer_page_end(src_u);
734 free_aligned_buffer_page_end(src_v);
735 free_aligned_buffer_page_end(src_y_16);
736 free_aligned_buffer_page_end(src_u_16);
737 free_aligned_buffer_page_end(src_v_16);
738
739 return max_diff;
740 }
741
742 // Test scaling with C vs Opt and return maximum pixel difference. 0 = exact.
NV12TestFilter(int src_width,int src_height,int dst_width,int dst_height,FilterMode f,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)743 static int NV12TestFilter(int src_width,
744 int src_height,
745 int dst_width,
746 int dst_height,
747 FilterMode f,
748 int benchmark_iterations,
749 int disable_cpu_flags,
750 int benchmark_cpu_info) {
751 if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
752 return 0;
753 }
754
755 int i, j;
756 int src_width_uv = (Abs(src_width) + 1) >> 1;
757 int src_height_uv = (Abs(src_height) + 1) >> 1;
758
759 int64_t src_y_plane_size = (Abs(src_width)) * (Abs(src_height));
760 int64_t src_uv_plane_size = (src_width_uv) * (src_height_uv)*2;
761
762 int src_stride_y = Abs(src_width);
763 int src_stride_uv = src_width_uv * 2;
764
765 align_buffer_page_end(src_y, src_y_plane_size);
766 align_buffer_page_end(src_uv, src_uv_plane_size);
767 if (!src_y || !src_uv) {
768 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
769 return 0;
770 }
771 MemRandomize(src_y, src_y_plane_size);
772 MemRandomize(src_uv, src_uv_plane_size);
773
774 int dst_width_uv = (dst_width + 1) >> 1;
775 int dst_height_uv = (dst_height + 1) >> 1;
776
777 int64_t dst_y_plane_size = (dst_width) * (dst_height);
778 int64_t dst_uv_plane_size = (dst_width_uv) * (dst_height_uv)*2;
779
780 int dst_stride_y = dst_width;
781 int dst_stride_uv = dst_width_uv * 2;
782
783 align_buffer_page_end(dst_y_c, dst_y_plane_size);
784 align_buffer_page_end(dst_uv_c, dst_uv_plane_size);
785 align_buffer_page_end(dst_y_opt, dst_y_plane_size);
786 align_buffer_page_end(dst_uv_opt, dst_uv_plane_size);
787 if (!dst_y_c || !dst_uv_c || !dst_y_opt || !dst_uv_opt) {
788 printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
789 return 0;
790 }
791
792 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
793 double c_time = get_time();
794 NV12Scale(src_y, src_stride_y, src_uv, src_stride_uv, src_width, src_height,
795 dst_y_c, dst_stride_y, dst_uv_c, dst_stride_uv, dst_width,
796 dst_height, f);
797 c_time = (get_time() - c_time);
798
799 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
800 double opt_time = get_time();
801 for (i = 0; i < benchmark_iterations; ++i) {
802 NV12Scale(src_y, src_stride_y, src_uv, src_stride_uv, src_width, src_height,
803 dst_y_opt, dst_stride_y, dst_uv_opt, dst_stride_uv, dst_width,
804 dst_height, f);
805 }
806 opt_time = (get_time() - opt_time) / benchmark_iterations;
807 // Report performance of C vs OPT.
808 printf("filter %d - %8d us C - %8d us OPT\n", f,
809 static_cast<int>(c_time * 1e6), static_cast<int>(opt_time * 1e6));
810
811 // C version may be a little off from the optimized. Order of
812 // operations may introduce rounding somewhere. So do a difference
813 // of the buffers and look to see that the max difference is not
814 // over 3.
815 int max_diff = 0;
816 for (i = 0; i < (dst_height); ++i) {
817 for (j = 0; j < (dst_width); ++j) {
818 int abs_diff = Abs(dst_y_c[(i * dst_stride_y) + j] -
819 dst_y_opt[(i * dst_stride_y) + j]);
820 if (abs_diff > max_diff) {
821 max_diff = abs_diff;
822 }
823 }
824 }
825
826 for (i = 0; i < (dst_height_uv); ++i) {
827 for (j = 0; j < (dst_width_uv * 2); ++j) {
828 int abs_diff = Abs(dst_uv_c[(i * dst_stride_uv) + j] -
829 dst_uv_opt[(i * dst_stride_uv) + j]);
830 if (abs_diff > max_diff) {
831 max_diff = abs_diff;
832 }
833 }
834 }
835
836 free_aligned_buffer_page_end(dst_y_c);
837 free_aligned_buffer_page_end(dst_uv_c);
838 free_aligned_buffer_page_end(dst_y_opt);
839 free_aligned_buffer_page_end(dst_uv_opt);
840 free_aligned_buffer_page_end(src_y);
841 free_aligned_buffer_page_end(src_uv);
842
843 return max_diff;
844 }
845
846 // The following adjustments in dimensions ensure the scale factor will be
847 // exactly achieved.
848 // 2 is chroma subsample.
849 #define DX(x, nom, denom) static_cast<int>(((Abs(x) / nom + 1) / 2) * nom * 2)
850 #define SX(x, nom, denom) static_cast<int>(((x / nom + 1) / 2) * denom * 2)
851
852 #define TEST_FACTOR1(DISABLED_, name, filter, nom, denom, max_diff) \
853 TEST_F(LibYUVScaleTest, I420ScaleDownBy##name##_##filter) { \
854 int diff = I420TestFilter( \
855 SX(benchmark_width_, nom, denom), SX(benchmark_height_, nom, denom), \
856 DX(benchmark_width_, nom, denom), DX(benchmark_height_, nom, denom), \
857 kFilter##filter, benchmark_iterations_, disable_cpu_flags_, \
858 benchmark_cpu_info_); \
859 EXPECT_LE(diff, max_diff); \
860 } \
861 TEST_F(LibYUVScaleTest, I444ScaleDownBy##name##_##filter) { \
862 int diff = I444TestFilter( \
863 SX(benchmark_width_, nom, denom), SX(benchmark_height_, nom, denom), \
864 DX(benchmark_width_, nom, denom), DX(benchmark_height_, nom, denom), \
865 kFilter##filter, benchmark_iterations_, disable_cpu_flags_, \
866 benchmark_cpu_info_); \
867 EXPECT_LE(diff, max_diff); \
868 } \
869 TEST_F(LibYUVScaleTest, DISABLED_##I420ScaleDownBy##name##_##filter##_12) { \
870 int diff = I420TestFilter_12( \
871 SX(benchmark_width_, nom, denom), SX(benchmark_height_, nom, denom), \
872 DX(benchmark_width_, nom, denom), DX(benchmark_height_, nom, denom), \
873 kFilter##filter, benchmark_iterations_, disable_cpu_flags_, \
874 benchmark_cpu_info_); \
875 EXPECT_LE(diff, max_diff); \
876 } \
877 TEST_F(LibYUVScaleTest, DISABLED_##I444ScaleDownBy##name##_##filter##_12) { \
878 int diff = I444TestFilter_12( \
879 SX(benchmark_width_, nom, denom), SX(benchmark_height_, nom, denom), \
880 DX(benchmark_width_, nom, denom), DX(benchmark_height_, nom, denom), \
881 kFilter##filter, benchmark_iterations_, disable_cpu_flags_, \
882 benchmark_cpu_info_); \
883 EXPECT_LE(diff, max_diff); \
884 } \
885 TEST_F(LibYUVScaleTest, NV12ScaleDownBy##name##_##filter) { \
886 int diff = NV12TestFilter( \
887 SX(benchmark_width_, nom, denom), SX(benchmark_height_, nom, denom), \
888 DX(benchmark_width_, nom, denom), DX(benchmark_height_, nom, denom), \
889 kFilter##filter, benchmark_iterations_, disable_cpu_flags_, \
890 benchmark_cpu_info_); \
891 EXPECT_LE(diff, max_diff); \
892 }
893
894 // Test a scale factor with all 4 filters. Expect unfiltered to be exact, but
895 // filtering is different fixed point implementations for SSSE3, Neon and C.
896 #ifndef DISABLE_SLOW_TESTS
897 #define TEST_FACTOR(name, nom, denom, boxdiff) \
898 TEST_FACTOR1(, name, None, nom, denom, 0) \
899 TEST_FACTOR1(, name, Linear, nom, denom, 3) \
900 TEST_FACTOR1(, name, Bilinear, nom, denom, 3) \
901 TEST_FACTOR1(, name, Box, nom, denom, boxdiff)
902 #else
903 #if defined(ENABLE_FULL_TESTS)
904 #define TEST_FACTOR(name, nom, denom, boxdiff) \
905 TEST_FACTOR1(DISABLED_, name, None, nom, denom, 0) \
906 TEST_FACTOR1(DISABLED_, name, Linear, nom, denom, 3) \
907 TEST_FACTOR1(DISABLED_, name, Bilinear, nom, denom, 3) \
908 TEST_FACTOR1(DISABLED_, name, Box, nom, denom, boxdiff)
909 #else
910 #define TEST_FACTOR(name, nom, denom, boxdiff) \
911 TEST_FACTOR1(DISABLED_, name, Bilinear, nom, denom, 3) \
912 TEST_FACTOR1(DISABLED_, name, Box, nom, denom, boxdiff)
913 #endif
914 #endif
915
916 TEST_FACTOR(2, 1, 2, 0)
917 TEST_FACTOR(4, 1, 4, 0)
918 #ifndef DISABLE_SLOW_TESTS
919 TEST_FACTOR(8, 1, 8, 0)
920 #endif
921 TEST_FACTOR(3by4, 3, 4, 1)
922 TEST_FACTOR(3by8, 3, 8, 1)
923 TEST_FACTOR(3, 1, 3, 0)
924 #undef TEST_FACTOR1
925 #undef TEST_FACTOR
926 #undef SX
927 #undef DX
928
929 #define TEST_SCALETO1(DISABLED_, name, width, height, filter, max_diff) \
930 TEST_F(LibYUVScaleTest, I420##name##To##width##x##height##_##filter) { \
931 int diff = I420TestFilter(benchmark_width_, benchmark_height_, width, \
932 height, kFilter##filter, benchmark_iterations_, \
933 disable_cpu_flags_, benchmark_cpu_info_); \
934 EXPECT_LE(diff, max_diff); \
935 } \
936 TEST_F(LibYUVScaleTest, I444##name##To##width##x##height##_##filter) { \
937 int diff = I444TestFilter(benchmark_width_, benchmark_height_, width, \
938 height, kFilter##filter, benchmark_iterations_, \
939 disable_cpu_flags_, benchmark_cpu_info_); \
940 EXPECT_LE(diff, max_diff); \
941 } \
942 TEST_F(LibYUVScaleTest, \
943 DISABLED_##I420##name##To##width##x##height##_##filter##_12) { \
944 int diff = I420TestFilter_12( \
945 benchmark_width_, benchmark_height_, width, height, kFilter##filter, \
946 benchmark_iterations_, disable_cpu_flags_, benchmark_cpu_info_); \
947 EXPECT_LE(diff, max_diff); \
948 } \
949 TEST_F(LibYUVScaleTest, \
950 DISABLED_##I444##name##To##width##x##height##_##filter##_12) { \
951 int diff = I444TestFilter_12( \
952 benchmark_width_, benchmark_height_, width, height, kFilter##filter, \
953 benchmark_iterations_, disable_cpu_flags_, benchmark_cpu_info_); \
954 EXPECT_LE(diff, max_diff); \
955 } \
956 TEST_F(LibYUVScaleTest, \
957 DISABLED_##I420##name##To##width##x##height##_##filter##_16) { \
958 int diff = I420TestFilter_16( \
959 benchmark_width_, benchmark_height_, width, height, kFilter##filter, \
960 benchmark_iterations_, disable_cpu_flags_, benchmark_cpu_info_); \
961 EXPECT_LE(diff, max_diff); \
962 } \
963 TEST_F(LibYUVScaleTest, \
964 DISABLED_##I444##name##To##width##x##height##_##filter##_16) { \
965 int diff = I444TestFilter_16( \
966 benchmark_width_, benchmark_height_, width, height, kFilter##filter, \
967 benchmark_iterations_, disable_cpu_flags_, benchmark_cpu_info_); \
968 EXPECT_LE(diff, max_diff); \
969 } \
970 TEST_F(LibYUVScaleTest, NV12##name##To##width##x##height##_##filter) { \
971 int diff = NV12TestFilter(benchmark_width_, benchmark_height_, width, \
972 height, kFilter##filter, benchmark_iterations_, \
973 disable_cpu_flags_, benchmark_cpu_info_); \
974 EXPECT_LE(diff, max_diff); \
975 } \
976 TEST_F(LibYUVScaleTest, I420##name##From##width##x##height##_##filter) { \
977 int diff = I420TestFilter(width, height, Abs(benchmark_width_), \
978 Abs(benchmark_height_), kFilter##filter, \
979 benchmark_iterations_, disable_cpu_flags_, \
980 benchmark_cpu_info_); \
981 EXPECT_LE(diff, max_diff); \
982 } \
983 TEST_F(LibYUVScaleTest, I444##name##From##width##x##height##_##filter) { \
984 int diff = I444TestFilter(width, height, Abs(benchmark_width_), \
985 Abs(benchmark_height_), kFilter##filter, \
986 benchmark_iterations_, disable_cpu_flags_, \
987 benchmark_cpu_info_); \
988 EXPECT_LE(diff, max_diff); \
989 } \
990 TEST_F(LibYUVScaleTest, \
991 DISABLED_##I420##name##From##width##x##height##_##filter##_12) { \
992 int diff = I420TestFilter_12(width, height, Abs(benchmark_width_), \
993 Abs(benchmark_height_), kFilter##filter, \
994 benchmark_iterations_, disable_cpu_flags_, \
995 benchmark_cpu_info_); \
996 EXPECT_LE(diff, max_diff); \
997 } \
998 TEST_F(LibYUVScaleTest, \
999 DISABLED_##I444##name##From##width##x##height##_##filter##_12) { \
1000 int diff = I444TestFilter_12(width, height, Abs(benchmark_width_), \
1001 Abs(benchmark_height_), kFilter##filter, \
1002 benchmark_iterations_, disable_cpu_flags_, \
1003 benchmark_cpu_info_); \
1004 EXPECT_LE(diff, max_diff); \
1005 } \
1006 TEST_F(LibYUVScaleTest, \
1007 DISABLED_##I420##name##From##width##x##height##_##filter##_16) { \
1008 int diff = I420TestFilter_16(width, height, Abs(benchmark_width_), \
1009 Abs(benchmark_height_), kFilter##filter, \
1010 benchmark_iterations_, disable_cpu_flags_, \
1011 benchmark_cpu_info_); \
1012 EXPECT_LE(diff, max_diff); \
1013 } \
1014 TEST_F(LibYUVScaleTest, \
1015 DISABLED_##I444##name##From##width##x##height##_##filter##_16) { \
1016 int diff = I444TestFilter_16(width, height, Abs(benchmark_width_), \
1017 Abs(benchmark_height_), kFilter##filter, \
1018 benchmark_iterations_, disable_cpu_flags_, \
1019 benchmark_cpu_info_); \
1020 EXPECT_LE(diff, max_diff); \
1021 } \
1022 TEST_F(LibYUVScaleTest, NV12##name##From##width##x##height##_##filter) { \
1023 int diff = NV12TestFilter(width, height, Abs(benchmark_width_), \
1024 Abs(benchmark_height_), kFilter##filter, \
1025 benchmark_iterations_, disable_cpu_flags_, \
1026 benchmark_cpu_info_); \
1027 EXPECT_LE(diff, max_diff); \
1028 }
1029
1030 #ifndef DISABLE_SLOW_TESTS
1031 // Test scale to a specified size with all 4 filters.
1032 #define TEST_SCALETO(name, width, height) \
1033 TEST_SCALETO1(, name, width, height, None, 0) \
1034 TEST_SCALETO1(, name, width, height, Linear, 3) \
1035 TEST_SCALETO1(, name, width, height, Bilinear, 3) \
1036 TEST_SCALETO1(, name, width, height, Box, 3)
1037 #else
1038 #if defined(ENABLE_FULL_TESTS)
1039 #define TEST_SCALETO(name, width, height) \
1040 TEST_SCALETO1(DISABLED_, name, width, height, None, 0) \
1041 TEST_SCALETO1(DISABLED_, name, width, height, Linear, 3) \
1042 TEST_SCALETO1(DISABLED_, name, width, height, Bilinear, 3) \
1043 TEST_SCALETO1(DISABLED_, name, width, height, Box, 3)
1044 #else
1045 #define TEST_SCALETO(name, width, height) \
1046 TEST_SCALETO1(DISABLED_, name, width, height, Bilinear, 3) \
1047 TEST_SCALETO1(DISABLED_, name, width, height, Box, 3)
1048 #endif
1049 #endif
1050
1051 TEST_SCALETO(Scale, 1, 1)
1052 TEST_SCALETO(Scale, 569, 480)
1053 TEST_SCALETO(Scale, 640, 360)
1054 #ifndef DISABLE_SLOW_TESTS
1055 TEST_SCALETO(Scale, 256, 144) /* 128x72 * 2 */
1056 TEST_SCALETO(Scale, 320, 240)
1057 TEST_SCALETO(Scale, 1280, 720)
1058 TEST_SCALETO(Scale, 1920, 1080)
1059 #endif // DISABLE_SLOW_TESTS
1060 #undef TEST_SCALETO1
1061 #undef TEST_SCALETO
1062
1063 #define TEST_SCALESWAPXY1(DISABLED_, name, filter, max_diff) \
1064 TEST_F(LibYUVScaleTest, I420##name##SwapXY_##filter) { \
1065 int diff = I420TestFilter(benchmark_width_, benchmark_height_, \
1066 benchmark_height_, benchmark_width_, \
1067 kFilter##filter, benchmark_iterations_, \
1068 disable_cpu_flags_, benchmark_cpu_info_); \
1069 EXPECT_LE(diff, max_diff); \
1070 } \
1071 TEST_F(LibYUVScaleTest, I444##name##SwapXY_##filter) { \
1072 int diff = I444TestFilter(benchmark_width_, benchmark_height_, \
1073 benchmark_height_, benchmark_width_, \
1074 kFilter##filter, benchmark_iterations_, \
1075 disable_cpu_flags_, benchmark_cpu_info_); \
1076 EXPECT_LE(diff, max_diff); \
1077 } \
1078 TEST_F(LibYUVScaleTest, DISABLED_##I420##name##SwapXY_##filter##_12) { \
1079 int diff = I420TestFilter_12(benchmark_width_, benchmark_height_, \
1080 benchmark_height_, benchmark_width_, \
1081 kFilter##filter, benchmark_iterations_, \
1082 disable_cpu_flags_, benchmark_cpu_info_); \
1083 EXPECT_LE(diff, max_diff); \
1084 } \
1085 TEST_F(LibYUVScaleTest, DISABLED_##I444##name##SwapXY_##filter##_12) { \
1086 int diff = I444TestFilter_12(benchmark_width_, benchmark_height_, \
1087 benchmark_height_, benchmark_width_, \
1088 kFilter##filter, benchmark_iterations_, \
1089 disable_cpu_flags_, benchmark_cpu_info_); \
1090 EXPECT_LE(diff, max_diff); \
1091 } \
1092 TEST_F(LibYUVScaleTest, DISABLED_##I420##name##SwapXY_##filter##_16) { \
1093 int diff = I420TestFilter_16(benchmark_width_, benchmark_height_, \
1094 benchmark_height_, benchmark_width_, \
1095 kFilter##filter, benchmark_iterations_, \
1096 disable_cpu_flags_, benchmark_cpu_info_); \
1097 EXPECT_LE(diff, max_diff); \
1098 } \
1099 TEST_F(LibYUVScaleTest, DISABLED_##I444##name##SwapXY_##filter##_16) { \
1100 int diff = I444TestFilter_16(benchmark_width_, benchmark_height_, \
1101 benchmark_height_, benchmark_width_, \
1102 kFilter##filter, benchmark_iterations_, \
1103 disable_cpu_flags_, benchmark_cpu_info_); \
1104 EXPECT_LE(diff, max_diff); \
1105 } \
1106 TEST_F(LibYUVScaleTest, NV12##name##SwapXY_##filter) { \
1107 int diff = NV12TestFilter(benchmark_width_, benchmark_height_, \
1108 benchmark_height_, benchmark_width_, \
1109 kFilter##filter, benchmark_iterations_, \
1110 disable_cpu_flags_, benchmark_cpu_info_); \
1111 EXPECT_LE(diff, max_diff); \
1112 }
1113
1114 // Test scale to a specified size with all 4 filters.
1115 #ifndef DISABLE_SLOW_TESTS
1116 TEST_SCALESWAPXY1(, Scale, None, 0)
1117 TEST_SCALESWAPXY1(, Scale, Linear, 3)
1118 TEST_SCALESWAPXY1(, Scale, Bilinear, 3)
1119 TEST_SCALESWAPXY1(, Scale, Box, 3)
1120 #else
1121 #if defined(ENABLE_FULL_TESTS)
1122 TEST_SCALESWAPXY1(DISABLED_, Scale, None, 0)
1123 TEST_SCALESWAPXY1(DISABLED_, Scale, Linear, 3)
1124 TEST_SCALESWAPXY1(DISABLED_, Scale, Bilinear, 3)
1125 TEST_SCALESWAPXY1(DISABLED_, Scale, Box, 3)
1126 #else
1127 TEST_SCALESWAPXY1(DISABLED_, Scale, Bilinear, 3)
1128 TEST_SCALESWAPXY1(DISABLED_, Scale, Box, 3)
1129 #endif
1130 #endif
1131 #undef TEST_SCALESWAPXY1
1132
1133 } // namespace libyuv
1134