1 /*
2 * Copyright 2012 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
13 #include "../unit_test/unit_test.h"
14 #include "libyuv/cpu_id.h"
15 #include "libyuv/rotate.h"
16
17 #ifdef ENABLE_ROW_TESTS
18 #include "libyuv/rotate_row.h"
19 #endif
20
21 namespace libyuv {
22
23 #define SUBSAMPLE(v, a) ((((v) + (a)-1)) / (a))
24
I420TestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)25 static void I420TestRotate(int src_width,
26 int src_height,
27 int dst_width,
28 int dst_height,
29 libyuv::RotationMode mode,
30 int benchmark_iterations,
31 int disable_cpu_flags,
32 int benchmark_cpu_info) {
33 if (src_width < 1) {
34 src_width = 1;
35 }
36 if (src_height == 0) {
37 src_height = 1;
38 }
39 if (dst_width < 1) {
40 dst_width = 1;
41 }
42 if (dst_height < 1) {
43 dst_height = 1;
44 }
45 int src_i420_y_size = src_width * Abs(src_height);
46 int src_i420_uv_size = ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2);
47 int src_i420_size = src_i420_y_size + src_i420_uv_size * 2;
48 align_buffer_page_end(src_i420, src_i420_size);
49 for (int i = 0; i < src_i420_size; ++i) {
50 src_i420[i] = fastrand() & 0xff;
51 }
52
53 int dst_i420_y_size = dst_width * dst_height;
54 int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
55 int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
56 align_buffer_page_end(dst_i420_c, dst_i420_size);
57 align_buffer_page_end(dst_i420_opt, dst_i420_size);
58 memset(dst_i420_c, 2, dst_i420_size);
59 memset(dst_i420_opt, 3, dst_i420_size);
60
61 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
62 I420Rotate(src_i420, src_width, src_i420 + src_i420_y_size,
63 (src_width + 1) / 2, src_i420 + src_i420_y_size + src_i420_uv_size,
64 (src_width + 1) / 2, dst_i420_c, dst_width,
65 dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
66 dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
67 (dst_width + 1) / 2, src_width, src_height, mode);
68
69 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
70 for (int i = 0; i < benchmark_iterations; ++i) {
71 I420Rotate(
72 src_i420, src_width, src_i420 + src_i420_y_size, (src_width + 1) / 2,
73 src_i420 + src_i420_y_size + src_i420_uv_size, (src_width + 1) / 2,
74 dst_i420_opt, dst_width, dst_i420_opt + dst_i420_y_size,
75 (dst_width + 1) / 2, dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
76 (dst_width + 1) / 2, src_width, src_height, mode);
77 }
78
79 // Rotation should be exact.
80 for (int i = 0; i < dst_i420_size; ++i) {
81 EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
82 }
83
84 free_aligned_buffer_page_end(dst_i420_c);
85 free_aligned_buffer_page_end(dst_i420_opt);
86 free_aligned_buffer_page_end(src_i420);
87 }
88
TEST_F(LibYUVRotateTest,I420Rotate0_Opt)89 TEST_F(LibYUVRotateTest, I420Rotate0_Opt) {
90 I420TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
91 benchmark_height_, kRotate0, benchmark_iterations_,
92 disable_cpu_flags_, benchmark_cpu_info_);
93 }
94
TEST_F(LibYUVRotateTest,I420Rotate90_Opt)95 TEST_F(LibYUVRotateTest, I420Rotate90_Opt) {
96 I420TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
97 benchmark_width_, kRotate90, benchmark_iterations_,
98 disable_cpu_flags_, benchmark_cpu_info_);
99 }
100
TEST_F(LibYUVRotateTest,I420Rotate180_Opt)101 TEST_F(LibYUVRotateTest, I420Rotate180_Opt) {
102 I420TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
103 benchmark_height_, kRotate180, benchmark_iterations_,
104 disable_cpu_flags_, benchmark_cpu_info_);
105 }
106
TEST_F(LibYUVRotateTest,I420Rotate270_Opt)107 TEST_F(LibYUVRotateTest, I420Rotate270_Opt) {
108 I420TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
109 benchmark_width_, kRotate270, benchmark_iterations_,
110 disable_cpu_flags_, benchmark_cpu_info_);
111 }
112
113 // TODO(fbarchard): Remove odd width tests.
114 // Odd width tests work but disabled because they use C code and can be
115 // tested by passing an odd width command line or environment variable.
TEST_F(LibYUVRotateTest,DISABLED_I420Rotate0_Odd)116 TEST_F(LibYUVRotateTest, DISABLED_I420Rotate0_Odd) {
117 I420TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
118 benchmark_width_ + 1, benchmark_height_ + 1, kRotate0,
119 benchmark_iterations_, disable_cpu_flags_,
120 benchmark_cpu_info_);
121 }
122
TEST_F(LibYUVRotateTest,DISABLED_I420Rotate90_Odd)123 TEST_F(LibYUVRotateTest, DISABLED_I420Rotate90_Odd) {
124 I420TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
125 benchmark_height_ + 1, benchmark_width_ + 1, kRotate90,
126 benchmark_iterations_, disable_cpu_flags_,
127 benchmark_cpu_info_);
128 }
129
TEST_F(LibYUVRotateTest,DISABLED_I420Rotate180_Odd)130 TEST_F(LibYUVRotateTest, DISABLED_I420Rotate180_Odd) {
131 I420TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
132 benchmark_width_ + 1, benchmark_height_ + 1, kRotate180,
133 benchmark_iterations_, disable_cpu_flags_,
134 benchmark_cpu_info_);
135 }
136
TEST_F(LibYUVRotateTest,DISABLED_I420Rotate270_Odd)137 TEST_F(LibYUVRotateTest, DISABLED_I420Rotate270_Odd) {
138 I420TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
139 benchmark_height_ + 1, benchmark_width_ + 1, kRotate270,
140 benchmark_iterations_, disable_cpu_flags_,
141 benchmark_cpu_info_);
142 }
143
I422TestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)144 static void I422TestRotate(int src_width,
145 int src_height,
146 int dst_width,
147 int dst_height,
148 libyuv::RotationMode mode,
149 int benchmark_iterations,
150 int disable_cpu_flags,
151 int benchmark_cpu_info) {
152 if (src_width < 1) {
153 src_width = 1;
154 }
155 if (src_height == 0) {
156 src_height = 1;
157 }
158 if (dst_width < 1) {
159 dst_width = 1;
160 }
161 if (dst_height < 1) {
162 dst_height = 1;
163 }
164 int src_i422_y_size = src_width * Abs(src_height);
165 int src_i422_uv_size = ((src_width + 1) / 2) * Abs(src_height);
166 int src_i422_size = src_i422_y_size + src_i422_uv_size * 2;
167 align_buffer_page_end(src_i422, src_i422_size);
168 for (int i = 0; i < src_i422_size; ++i) {
169 src_i422[i] = fastrand() & 0xff;
170 }
171
172 int dst_i422_y_size = dst_width * dst_height;
173 int dst_i422_uv_size = ((dst_width + 1) / 2) * dst_height;
174 int dst_i422_size = dst_i422_y_size + dst_i422_uv_size * 2;
175 align_buffer_page_end(dst_i422_c, dst_i422_size);
176 align_buffer_page_end(dst_i422_opt, dst_i422_size);
177 memset(dst_i422_c, 2, dst_i422_size);
178 memset(dst_i422_opt, 3, dst_i422_size);
179
180 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
181 I422Rotate(src_i422, src_width, src_i422 + src_i422_y_size,
182 (src_width + 1) / 2, src_i422 + src_i422_y_size + src_i422_uv_size,
183 (src_width + 1) / 2, dst_i422_c, dst_width,
184 dst_i422_c + dst_i422_y_size, (dst_width + 1) / 2,
185 dst_i422_c + dst_i422_y_size + dst_i422_uv_size,
186 (dst_width + 1) / 2, src_width, src_height, mode);
187
188 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
189 for (int i = 0; i < benchmark_iterations; ++i) {
190 I422Rotate(
191 src_i422, src_width, src_i422 + src_i422_y_size, (src_width + 1) / 2,
192 src_i422 + src_i422_y_size + src_i422_uv_size, (src_width + 1) / 2,
193 dst_i422_opt, dst_width, dst_i422_opt + dst_i422_y_size,
194 (dst_width + 1) / 2, dst_i422_opt + dst_i422_y_size + dst_i422_uv_size,
195 (dst_width + 1) / 2, src_width, src_height, mode);
196 }
197
198 // Rotation should be exact.
199 for (int i = 0; i < dst_i422_size; ++i) {
200 EXPECT_EQ(dst_i422_c[i], dst_i422_opt[i]);
201 }
202
203 free_aligned_buffer_page_end(dst_i422_c);
204 free_aligned_buffer_page_end(dst_i422_opt);
205 free_aligned_buffer_page_end(src_i422);
206 }
207
TEST_F(LibYUVRotateTest,I422Rotate0_Opt)208 TEST_F(LibYUVRotateTest, I422Rotate0_Opt) {
209 I422TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
210 benchmark_height_, kRotate0, benchmark_iterations_,
211 disable_cpu_flags_, benchmark_cpu_info_);
212 }
213
TEST_F(LibYUVRotateTest,I422Rotate90_Opt)214 TEST_F(LibYUVRotateTest, I422Rotate90_Opt) {
215 I422TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
216 benchmark_width_, kRotate90, benchmark_iterations_,
217 disable_cpu_flags_, benchmark_cpu_info_);
218 }
219
TEST_F(LibYUVRotateTest,I422Rotate180_Opt)220 TEST_F(LibYUVRotateTest, I422Rotate180_Opt) {
221 I422TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
222 benchmark_height_, kRotate180, benchmark_iterations_,
223 disable_cpu_flags_, benchmark_cpu_info_);
224 }
225
TEST_F(LibYUVRotateTest,I422Rotate270_Opt)226 TEST_F(LibYUVRotateTest, I422Rotate270_Opt) {
227 I422TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
228 benchmark_width_, kRotate270, benchmark_iterations_,
229 disable_cpu_flags_, benchmark_cpu_info_);
230 }
231
I444TestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)232 static void I444TestRotate(int src_width,
233 int src_height,
234 int dst_width,
235 int dst_height,
236 libyuv::RotationMode mode,
237 int benchmark_iterations,
238 int disable_cpu_flags,
239 int benchmark_cpu_info) {
240 if (src_width < 1) {
241 src_width = 1;
242 }
243 if (src_height == 0) {
244 src_height = 1;
245 }
246 if (dst_width < 1) {
247 dst_width = 1;
248 }
249 if (dst_height < 1) {
250 dst_height = 1;
251 }
252 int src_i444_y_size = src_width * Abs(src_height);
253 int src_i444_uv_size = src_width * Abs(src_height);
254 int src_i444_size = src_i444_y_size + src_i444_uv_size * 2;
255 align_buffer_page_end(src_i444, src_i444_size);
256 for (int i = 0; i < src_i444_size; ++i) {
257 src_i444[i] = fastrand() & 0xff;
258 }
259
260 int dst_i444_y_size = dst_width * dst_height;
261 int dst_i444_uv_size = dst_width * dst_height;
262 int dst_i444_size = dst_i444_y_size + dst_i444_uv_size * 2;
263 align_buffer_page_end(dst_i444_c, dst_i444_size);
264 align_buffer_page_end(dst_i444_opt, dst_i444_size);
265 memset(dst_i444_c, 2, dst_i444_size);
266 memset(dst_i444_opt, 3, dst_i444_size);
267
268 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
269 I444Rotate(src_i444, src_width, src_i444 + src_i444_y_size, src_width,
270 src_i444 + src_i444_y_size + src_i444_uv_size, src_width,
271 dst_i444_c, dst_width, dst_i444_c + dst_i444_y_size, dst_width,
272 dst_i444_c + dst_i444_y_size + dst_i444_uv_size, dst_width,
273 src_width, src_height, mode);
274
275 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
276 for (int i = 0; i < benchmark_iterations; ++i) {
277 I444Rotate(src_i444, src_width, src_i444 + src_i444_y_size, src_width,
278 src_i444 + src_i444_y_size + src_i444_uv_size, src_width,
279 dst_i444_opt, dst_width, dst_i444_opt + dst_i444_y_size,
280 dst_width, dst_i444_opt + dst_i444_y_size + dst_i444_uv_size,
281 dst_width, src_width, src_height, mode);
282 }
283
284 // Rotation should be exact.
285 for (int i = 0; i < dst_i444_size; ++i) {
286 EXPECT_EQ(dst_i444_c[i], dst_i444_opt[i]);
287 }
288
289 free_aligned_buffer_page_end(dst_i444_c);
290 free_aligned_buffer_page_end(dst_i444_opt);
291 free_aligned_buffer_page_end(src_i444);
292 }
293
TEST_F(LibYUVRotateTest,I444Rotate0_Opt)294 TEST_F(LibYUVRotateTest, I444Rotate0_Opt) {
295 I444TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
296 benchmark_height_, kRotate0, benchmark_iterations_,
297 disable_cpu_flags_, benchmark_cpu_info_);
298 }
299
TEST_F(LibYUVRotateTest,I444Rotate90_Opt)300 TEST_F(LibYUVRotateTest, I444Rotate90_Opt) {
301 I444TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
302 benchmark_width_, kRotate90, benchmark_iterations_,
303 disable_cpu_flags_, benchmark_cpu_info_);
304 }
305
TEST_F(LibYUVRotateTest,I444Rotate180_Opt)306 TEST_F(LibYUVRotateTest, I444Rotate180_Opt) {
307 I444TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
308 benchmark_height_, kRotate180, benchmark_iterations_,
309 disable_cpu_flags_, benchmark_cpu_info_);
310 }
311
TEST_F(LibYUVRotateTest,I444Rotate270_Opt)312 TEST_F(LibYUVRotateTest, I444Rotate270_Opt) {
313 I444TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
314 benchmark_width_, kRotate270, benchmark_iterations_,
315 disable_cpu_flags_, benchmark_cpu_info_);
316 }
317
318 // TODO(fbarchard): Remove odd width tests.
319 // Odd width tests work but disabled because they use C code and can be
320 // tested by passing an odd width command line or environment variable.
TEST_F(LibYUVRotateTest,DISABLED_I444Rotate0_Odd)321 TEST_F(LibYUVRotateTest, DISABLED_I444Rotate0_Odd) {
322 I444TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
323 benchmark_width_ + 1, benchmark_height_ + 1, kRotate0,
324 benchmark_iterations_, disable_cpu_flags_,
325 benchmark_cpu_info_);
326 }
327
TEST_F(LibYUVRotateTest,DISABLED_I444Rotate90_Odd)328 TEST_F(LibYUVRotateTest, DISABLED_I444Rotate90_Odd) {
329 I444TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
330 benchmark_height_ + 1, benchmark_width_ + 1, kRotate90,
331 benchmark_iterations_, disable_cpu_flags_,
332 benchmark_cpu_info_);
333 }
334
TEST_F(LibYUVRotateTest,DISABLED_I444Rotate180_Odd)335 TEST_F(LibYUVRotateTest, DISABLED_I444Rotate180_Odd) {
336 I444TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
337 benchmark_width_ + 1, benchmark_height_ + 1, kRotate180,
338 benchmark_iterations_, disable_cpu_flags_,
339 benchmark_cpu_info_);
340 }
341
TEST_F(LibYUVRotateTest,DISABLED_I444Rotate270_Odd)342 TEST_F(LibYUVRotateTest, DISABLED_I444Rotate270_Odd) {
343 I444TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
344 benchmark_height_ + 1, benchmark_width_ + 1, kRotate270,
345 benchmark_iterations_, disable_cpu_flags_,
346 benchmark_cpu_info_);
347 }
348
NV12TestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)349 static void NV12TestRotate(int src_width,
350 int src_height,
351 int dst_width,
352 int dst_height,
353 libyuv::RotationMode mode,
354 int benchmark_iterations,
355 int disable_cpu_flags,
356 int benchmark_cpu_info) {
357 if (src_width < 1) {
358 src_width = 1;
359 }
360 if (src_height == 0) { // allow negative for inversion test.
361 src_height = 1;
362 }
363 if (dst_width < 1) {
364 dst_width = 1;
365 }
366 if (dst_height < 1) {
367 dst_height = 1;
368 }
369 int src_nv12_y_size = src_width * Abs(src_height);
370 int src_nv12_uv_size =
371 ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2) * 2;
372 int src_nv12_size = src_nv12_y_size + src_nv12_uv_size;
373 align_buffer_page_end(src_nv12, src_nv12_size);
374 for (int i = 0; i < src_nv12_size; ++i) {
375 src_nv12[i] = fastrand() & 0xff;
376 }
377
378 int dst_i420_y_size = dst_width * dst_height;
379 int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
380 int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
381 align_buffer_page_end(dst_i420_c, dst_i420_size);
382 align_buffer_page_end(dst_i420_opt, dst_i420_size);
383 memset(dst_i420_c, 2, dst_i420_size);
384 memset(dst_i420_opt, 3, dst_i420_size);
385
386 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
387 NV12ToI420Rotate(src_nv12, src_width, src_nv12 + src_nv12_y_size,
388 (src_width + 1) & ~1, dst_i420_c, dst_width,
389 dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
390 dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
391 (dst_width + 1) / 2, src_width, src_height, mode);
392
393 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
394 for (int i = 0; i < benchmark_iterations; ++i) {
395 NV12ToI420Rotate(src_nv12, src_width, src_nv12 + src_nv12_y_size,
396 (src_width + 1) & ~1, dst_i420_opt, dst_width,
397 dst_i420_opt + dst_i420_y_size, (dst_width + 1) / 2,
398 dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
399 (dst_width + 1) / 2, src_width, src_height, mode);
400 }
401
402 // Rotation should be exact.
403 for (int i = 0; i < dst_i420_size; ++i) {
404 EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
405 }
406
407 free_aligned_buffer_page_end(dst_i420_c);
408 free_aligned_buffer_page_end(dst_i420_opt);
409 free_aligned_buffer_page_end(src_nv12);
410 }
411
TEST_F(LibYUVRotateTest,NV12Rotate0_Opt)412 TEST_F(LibYUVRotateTest, NV12Rotate0_Opt) {
413 NV12TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
414 benchmark_height_, kRotate0, benchmark_iterations_,
415 disable_cpu_flags_, benchmark_cpu_info_);
416 }
417
TEST_F(LibYUVRotateTest,NV12Rotate90_Opt)418 TEST_F(LibYUVRotateTest, NV12Rotate90_Opt) {
419 NV12TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
420 benchmark_width_, kRotate90, benchmark_iterations_,
421 disable_cpu_flags_, benchmark_cpu_info_);
422 }
423
TEST_F(LibYUVRotateTest,NV12Rotate180_Opt)424 TEST_F(LibYUVRotateTest, NV12Rotate180_Opt) {
425 NV12TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
426 benchmark_height_, kRotate180, benchmark_iterations_,
427 disable_cpu_flags_, benchmark_cpu_info_);
428 }
429
TEST_F(LibYUVRotateTest,NV12Rotate270_Opt)430 TEST_F(LibYUVRotateTest, NV12Rotate270_Opt) {
431 NV12TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
432 benchmark_width_, kRotate270, benchmark_iterations_,
433 disable_cpu_flags_, benchmark_cpu_info_);
434 }
435
TEST_F(LibYUVRotateTest,DISABLED_NV12Rotate0_Odd)436 TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate0_Odd) {
437 NV12TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
438 benchmark_width_ + 1, benchmark_height_ + 1, kRotate0,
439 benchmark_iterations_, disable_cpu_flags_,
440 benchmark_cpu_info_);
441 }
442
TEST_F(LibYUVRotateTest,DISABLED_NV12Rotate90_Odd)443 TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate90_Odd) {
444 NV12TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
445 benchmark_height_ + 1, benchmark_width_ + 1, kRotate90,
446 benchmark_iterations_, disable_cpu_flags_,
447 benchmark_cpu_info_);
448 }
449
TEST_F(LibYUVRotateTest,DISABLED_NV12Rotate180_Odd)450 TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate180_Odd) {
451 NV12TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
452 benchmark_width_ + 1, benchmark_height_ + 1, kRotate180,
453 benchmark_iterations_, disable_cpu_flags_,
454 benchmark_cpu_info_);
455 }
456
TEST_F(LibYUVRotateTest,DISABLED_NV12Rotate270_Odd)457 TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate270_Odd) {
458 NV12TestRotate(benchmark_width_ + 1, benchmark_height_ + 1,
459 benchmark_height_ + 1, benchmark_width_ + 1, kRotate270,
460 benchmark_iterations_, disable_cpu_flags_,
461 benchmark_cpu_info_);
462 }
463
TEST_F(LibYUVRotateTest,NV12Rotate0_Invert)464 TEST_F(LibYUVRotateTest, NV12Rotate0_Invert) {
465 NV12TestRotate(benchmark_width_, -benchmark_height_, benchmark_width_,
466 benchmark_height_, kRotate0, benchmark_iterations_,
467 disable_cpu_flags_, benchmark_cpu_info_);
468 }
469
TEST_F(LibYUVRotateTest,NV12Rotate90_Invert)470 TEST_F(LibYUVRotateTest, NV12Rotate90_Invert) {
471 NV12TestRotate(benchmark_width_, -benchmark_height_, benchmark_height_,
472 benchmark_width_, kRotate90, benchmark_iterations_,
473 disable_cpu_flags_, benchmark_cpu_info_);
474 }
475
TEST_F(LibYUVRotateTest,NV12Rotate180_Invert)476 TEST_F(LibYUVRotateTest, NV12Rotate180_Invert) {
477 NV12TestRotate(benchmark_width_, -benchmark_height_, benchmark_width_,
478 benchmark_height_, kRotate180, benchmark_iterations_,
479 disable_cpu_flags_, benchmark_cpu_info_);
480 }
481
TEST_F(LibYUVRotateTest,NV12Rotate270_Invert)482 TEST_F(LibYUVRotateTest, NV12Rotate270_Invert) {
483 NV12TestRotate(benchmark_width_, -benchmark_height_, benchmark_height_,
484 benchmark_width_, kRotate270, benchmark_iterations_,
485 disable_cpu_flags_, benchmark_cpu_info_);
486 }
487
488 // Test Android 420 to I420 Rotate
489 #define TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, \
490 SRC_SUBSAMP_Y, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, \
491 W1280, N, NEG, OFF, PN, OFF_U, OFF_V, ROT) \
492 TEST_F(LibYUVRotateTest, \
493 SRC_FMT_PLANAR##To##FMT_PLANAR##Rotate##ROT##To##PN##N) { \
494 const int kWidth = W1280; \
495 const int kHeight = benchmark_height_; \
496 const int kSizeUV = \
497 SUBSAMPLE(kWidth, SRC_SUBSAMP_X) * SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); \
498 align_buffer_page_end(src_y, kWidth* kHeight + OFF); \
499 align_buffer_page_end(src_uv, \
500 kSizeUV*((PIXEL_STRIDE == 3) ? 3 : 2) + OFF); \
501 align_buffer_page_end(dst_y_c, kWidth* kHeight); \
502 align_buffer_page_end(dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X) * \
503 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
504 align_buffer_page_end(dst_v_c, SUBSAMPLE(kWidth, SUBSAMP_X) * \
505 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
506 align_buffer_page_end(dst_y_opt, kWidth* kHeight); \
507 align_buffer_page_end(dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * \
508 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
509 align_buffer_page_end(dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X) * \
510 SUBSAMPLE(kHeight, SUBSAMP_Y)); \
511 uint8_t* src_u = src_uv + OFF_U; \
512 uint8_t* src_v = src_uv + (PIXEL_STRIDE == 1 ? kSizeUV : OFF_V); \
513 int src_stride_uv = SUBSAMPLE(kWidth, SUBSAMP_X) * PIXEL_STRIDE; \
514 for (int i = 0; i < kHeight; ++i) \
515 for (int j = 0; j < kWidth; ++j) \
516 src_y[i * kWidth + j + OFF] = (fastrand() & 0xff); \
517 for (int i = 0; i < SUBSAMPLE(kHeight, SRC_SUBSAMP_Y); ++i) { \
518 for (int j = 0; j < SUBSAMPLE(kWidth, SRC_SUBSAMP_X); ++j) { \
519 src_u[(i * src_stride_uv) + j * PIXEL_STRIDE + OFF] = \
520 (fastrand() & 0xff); \
521 src_v[(i * src_stride_uv) + j * PIXEL_STRIDE + OFF] = \
522 (fastrand() & 0xff); \
523 } \
524 } \
525 memset(dst_y_c, 1, kWidth* kHeight); \
526 memset(dst_u_c, 2, \
527 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
528 memset(dst_v_c, 3, \
529 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
530 memset(dst_y_opt, 101, kWidth* kHeight); \
531 memset(dst_u_opt, 102, \
532 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
533 memset(dst_v_opt, 103, \
534 SUBSAMPLE(kWidth, SUBSAMP_X) * SUBSAMPLE(kHeight, SUBSAMP_Y)); \
535 MaskCpuFlags(disable_cpu_flags_); \
536 SRC_FMT_PLANAR##To##FMT_PLANAR##Rotate( \
537 src_y + OFF, kWidth, src_u + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
538 src_v + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), PIXEL_STRIDE, dst_y_c, \
539 kWidth, dst_u_c, SUBSAMPLE(kWidth, SUBSAMP_X), dst_v_c, \
540 SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight, \
541 (libyuv::RotationMode)ROT); \
542 MaskCpuFlags(benchmark_cpu_info_); \
543 for (int i = 0; i < benchmark_iterations_; ++i) { \
544 SRC_FMT_PLANAR##To##FMT_PLANAR##Rotate( \
545 src_y + OFF, kWidth, src_u + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), \
546 src_v + OFF, SUBSAMPLE(kWidth, SRC_SUBSAMP_X), PIXEL_STRIDE, \
547 dst_y_opt, kWidth, dst_u_opt, SUBSAMPLE(kWidth, SUBSAMP_X), \
548 dst_v_opt, SUBSAMPLE(kWidth, SUBSAMP_X), kWidth, NEG kHeight, \
549 (libyuv::RotationMode)ROT); \
550 } \
551 for (int i = 0; i < kHeight; ++i) { \
552 for (int j = 0; j < kWidth; ++j) { \
553 EXPECT_EQ(dst_y_c[i * kWidth + j], dst_y_opt[i * kWidth + j]); \
554 } \
555 } \
556 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
557 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
558 EXPECT_EQ(dst_u_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j], \
559 dst_u_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]); \
560 } \
561 } \
562 for (int i = 0; i < SUBSAMPLE(kHeight, SUBSAMP_Y); ++i) { \
563 for (int j = 0; j < SUBSAMPLE(kWidth, SUBSAMP_X); ++j) { \
564 EXPECT_EQ(dst_v_c[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j], \
565 dst_v_opt[i * SUBSAMPLE(kWidth, SUBSAMP_X) + j]); \
566 } \
567 } \
568 free_aligned_buffer_page_end(dst_y_c); \
569 free_aligned_buffer_page_end(dst_u_c); \
570 free_aligned_buffer_page_end(dst_v_c); \
571 free_aligned_buffer_page_end(dst_y_opt); \
572 free_aligned_buffer_page_end(dst_u_opt); \
573 free_aligned_buffer_page_end(dst_v_opt); \
574 free_aligned_buffer_page_end(src_y); \
575 free_aligned_buffer_page_end(src_uv); \
576 }
577
578 #define TESTAPLANARTOP(SRC_FMT_PLANAR, PN, PIXEL_STRIDE, OFF_U, OFF_V, \
579 SRC_SUBSAMP_X, SRC_SUBSAMP_Y, FMT_PLANAR, SUBSAMP_X, \
580 SUBSAMP_Y) \
581 TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
582 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_ + 1, \
583 _Any, +, 0, PN, OFF_U, OFF_V, 0) \
584 TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
585 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, \
586 _Unaligned, +, 2, PN, OFF_U, OFF_V, 0) \
587 TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
588 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Invert, \
589 -, 0, PN, OFF_U, OFF_V, 0) \
590 TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
591 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Opt, +, \
592 0, PN, OFF_U, OFF_V, 0) \
593 TESTAPLANARTOPI(SRC_FMT_PLANAR, PIXEL_STRIDE, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
594 FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, benchmark_width_, _Opt, +, \
595 0, PN, OFF_U, OFF_V, 180)
596
597 TESTAPLANARTOP(Android420, I420, 1, 0, 0, 2, 2, I420, 2, 2)
598 TESTAPLANARTOP(Android420, NV12, 2, 0, 1, 2, 2, I420, 2, 2)
599 TESTAPLANARTOP(Android420, NV21, 2, 1, 0, 2, 2, I420, 2, 2)
600 #undef TESTAPLANARTOP
601 #undef TESTAPLANARTOPI
602
I010TestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)603 static void I010TestRotate(int src_width,
604 int src_height,
605 int dst_width,
606 int dst_height,
607 libyuv::RotationMode mode,
608 int benchmark_iterations,
609 int disable_cpu_flags,
610 int benchmark_cpu_info) {
611 if (src_width < 1) {
612 src_width = 1;
613 }
614 if (src_height == 0) {
615 src_height = 1;
616 }
617 if (dst_width < 1) {
618 dst_width = 1;
619 }
620 if (dst_height < 1) {
621 dst_height = 1;
622 }
623 int src_i010_y_size = src_width * Abs(src_height);
624 int src_i010_uv_size = ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2);
625 int src_i010_size = src_i010_y_size + src_i010_uv_size * 2;
626 align_buffer_page_end_16(src_i010, src_i010_size);
627 for (int i = 0; i < src_i010_size; ++i) {
628 src_i010[i] = fastrand() & 0x3ff;
629 }
630
631 int dst_i010_y_size = dst_width * dst_height;
632 int dst_i010_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
633 int dst_i010_size = dst_i010_y_size + dst_i010_uv_size * 2;
634 align_buffer_page_end_16(dst_i010_c, dst_i010_size);
635 align_buffer_page_end_16(dst_i010_opt, dst_i010_size);
636 memset(dst_i010_c, 2, dst_i010_size * 2);
637 memset(dst_i010_opt, 3, dst_i010_size * 2);
638
639 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
640 I010Rotate(src_i010, src_width, src_i010 + src_i010_y_size,
641 (src_width + 1) / 2, src_i010 + src_i010_y_size + src_i010_uv_size,
642 (src_width + 1) / 2, dst_i010_c, dst_width,
643 dst_i010_c + dst_i010_y_size, (dst_width + 1) / 2,
644 dst_i010_c + dst_i010_y_size + dst_i010_uv_size,
645 (dst_width + 1) / 2, src_width, src_height, mode);
646
647 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
648 for (int i = 0; i < benchmark_iterations; ++i) {
649 I010Rotate(
650 src_i010, src_width, src_i010 + src_i010_y_size, (src_width + 1) / 2,
651 src_i010 + src_i010_y_size + src_i010_uv_size, (src_width + 1) / 2,
652 dst_i010_opt, dst_width, dst_i010_opt + dst_i010_y_size,
653 (dst_width + 1) / 2, dst_i010_opt + dst_i010_y_size + dst_i010_uv_size,
654 (dst_width + 1) / 2, src_width, src_height, mode);
655 }
656
657 // Rotation should be exact.
658 for (int i = 0; i < dst_i010_size; ++i) {
659 EXPECT_EQ(dst_i010_c[i], dst_i010_opt[i]);
660 }
661
662 free_aligned_buffer_page_end_16(dst_i010_c);
663 free_aligned_buffer_page_end_16(dst_i010_opt);
664 free_aligned_buffer_page_end_16(src_i010);
665 }
666
TEST_F(LibYUVRotateTest,I010Rotate0_Opt)667 TEST_F(LibYUVRotateTest, I010Rotate0_Opt) {
668 I010TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
669 benchmark_height_, kRotate0, benchmark_iterations_,
670 disable_cpu_flags_, benchmark_cpu_info_);
671 }
672
TEST_F(LibYUVRotateTest,I010Rotate90_Opt)673 TEST_F(LibYUVRotateTest, I010Rotate90_Opt) {
674 I010TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
675 benchmark_width_, kRotate90, benchmark_iterations_,
676 disable_cpu_flags_, benchmark_cpu_info_);
677 }
678
TEST_F(LibYUVRotateTest,I010Rotate180_Opt)679 TEST_F(LibYUVRotateTest, I010Rotate180_Opt) {
680 I010TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
681 benchmark_height_, kRotate180, benchmark_iterations_,
682 disable_cpu_flags_, benchmark_cpu_info_);
683 }
684
TEST_F(LibYUVRotateTest,I010Rotate270_Opt)685 TEST_F(LibYUVRotateTest, I010Rotate270_Opt) {
686 I010TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
687 benchmark_width_, kRotate270, benchmark_iterations_,
688 disable_cpu_flags_, benchmark_cpu_info_);
689 }
690
I210TestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)691 static void I210TestRotate(int src_width,
692 int src_height,
693 int dst_width,
694 int dst_height,
695 libyuv::RotationMode mode,
696 int benchmark_iterations,
697 int disable_cpu_flags,
698 int benchmark_cpu_info) {
699 if (src_width < 1) {
700 src_width = 1;
701 }
702 if (src_height == 0) {
703 src_height = 1;
704 }
705 if (dst_width < 1) {
706 dst_width = 1;
707 }
708 if (dst_height < 1) {
709 dst_height = 1;
710 }
711 int src_i210_y_size = src_width * Abs(src_height);
712 int src_i210_uv_size = ((src_width + 1) / 2) * Abs(src_height);
713 int src_i210_size = src_i210_y_size + src_i210_uv_size * 2;
714 align_buffer_page_end_16(src_i210, src_i210_size);
715 for (int i = 0; i < src_i210_size; ++i) {
716 src_i210[i] = fastrand() & 0x3ff;
717 }
718
719 int dst_i210_y_size = dst_width * dst_height;
720 int dst_i210_uv_size = ((dst_width + 1) / 2) * dst_height;
721 int dst_i210_size = dst_i210_y_size + dst_i210_uv_size * 2;
722 align_buffer_page_end_16(dst_i210_c, dst_i210_size);
723 align_buffer_page_end_16(dst_i210_opt, dst_i210_size);
724 memset(dst_i210_c, 2, dst_i210_size * 2);
725 memset(dst_i210_opt, 3, dst_i210_size * 2);
726
727 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
728 I210Rotate(src_i210, src_width, src_i210 + src_i210_y_size,
729 (src_width + 1) / 2, src_i210 + src_i210_y_size + src_i210_uv_size,
730 (src_width + 1) / 2, dst_i210_c, dst_width,
731 dst_i210_c + dst_i210_y_size, (dst_width + 1) / 2,
732 dst_i210_c + dst_i210_y_size + dst_i210_uv_size,
733 (dst_width + 1) / 2, src_width, src_height, mode);
734
735 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
736 for (int i = 0; i < benchmark_iterations; ++i) {
737 I210Rotate(
738 src_i210, src_width, src_i210 + src_i210_y_size, (src_width + 1) / 2,
739 src_i210 + src_i210_y_size + src_i210_uv_size, (src_width + 1) / 2,
740 dst_i210_opt, dst_width, dst_i210_opt + dst_i210_y_size,
741 (dst_width + 1) / 2, dst_i210_opt + dst_i210_y_size + dst_i210_uv_size,
742 (dst_width + 1) / 2, src_width, src_height, mode);
743 }
744
745 // Rotation should be exact.
746 for (int i = 0; i < dst_i210_size; ++i) {
747 EXPECT_EQ(dst_i210_c[i], dst_i210_opt[i]);
748 }
749
750 free_aligned_buffer_page_end_16(dst_i210_c);
751 free_aligned_buffer_page_end_16(dst_i210_opt);
752 free_aligned_buffer_page_end_16(src_i210);
753 }
754
TEST_F(LibYUVRotateTest,I210Rotate0_Opt)755 TEST_F(LibYUVRotateTest, I210Rotate0_Opt) {
756 I210TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
757 benchmark_height_, kRotate0, benchmark_iterations_,
758 disable_cpu_flags_, benchmark_cpu_info_);
759 }
760
TEST_F(LibYUVRotateTest,I210Rotate90_Opt)761 TEST_F(LibYUVRotateTest, I210Rotate90_Opt) {
762 I210TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
763 benchmark_width_, kRotate90, benchmark_iterations_,
764 disable_cpu_flags_, benchmark_cpu_info_);
765 }
766
TEST_F(LibYUVRotateTest,I210Rotate180_Opt)767 TEST_F(LibYUVRotateTest, I210Rotate180_Opt) {
768 I210TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
769 benchmark_height_, kRotate180, benchmark_iterations_,
770 disable_cpu_flags_, benchmark_cpu_info_);
771 }
772
TEST_F(LibYUVRotateTest,I210Rotate270_Opt)773 TEST_F(LibYUVRotateTest, I210Rotate270_Opt) {
774 I210TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
775 benchmark_width_, kRotate270, benchmark_iterations_,
776 disable_cpu_flags_, benchmark_cpu_info_);
777 }
778
I410TestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int benchmark_iterations,int disable_cpu_flags,int benchmark_cpu_info)779 static void I410TestRotate(int src_width,
780 int src_height,
781 int dst_width,
782 int dst_height,
783 libyuv::RotationMode mode,
784 int benchmark_iterations,
785 int disable_cpu_flags,
786 int benchmark_cpu_info) {
787 if (src_width < 1) {
788 src_width = 1;
789 }
790 if (src_height == 0) {
791 src_height = 1;
792 }
793 if (dst_width < 1) {
794 dst_width = 1;
795 }
796 if (dst_height < 1) {
797 dst_height = 1;
798 }
799 int src_i410_y_size = src_width * Abs(src_height);
800 int src_i410_uv_size = src_width * Abs(src_height);
801 int src_i410_size = src_i410_y_size + src_i410_uv_size * 2;
802 align_buffer_page_end_16(src_i410, src_i410_size);
803 for (int i = 0; i < src_i410_size; ++i) {
804 src_i410[i] = fastrand() & 0x3ff;
805 }
806
807 int dst_i410_y_size = dst_width * dst_height;
808 int dst_i410_uv_size = dst_width * dst_height;
809 int dst_i410_size = dst_i410_y_size + dst_i410_uv_size * 2;
810 align_buffer_page_end_16(dst_i410_c, dst_i410_size);
811 align_buffer_page_end_16(dst_i410_opt, dst_i410_size);
812 memset(dst_i410_c, 2, dst_i410_size * 2);
813 memset(dst_i410_opt, 3, dst_i410_size * 2);
814
815 MaskCpuFlags(disable_cpu_flags); // Disable all CPU optimization.
816 I410Rotate(src_i410, src_width, src_i410 + src_i410_y_size, src_width,
817 src_i410 + src_i410_y_size + src_i410_uv_size, src_width,
818 dst_i410_c, dst_width, dst_i410_c + dst_i410_y_size, dst_width,
819 dst_i410_c + dst_i410_y_size + dst_i410_uv_size, dst_width,
820 src_width, src_height, mode);
821
822 MaskCpuFlags(benchmark_cpu_info); // Enable all CPU optimization.
823 for (int i = 0; i < benchmark_iterations; ++i) {
824 I410Rotate(src_i410, src_width, src_i410 + src_i410_y_size, src_width,
825 src_i410 + src_i410_y_size + src_i410_uv_size, src_width,
826 dst_i410_opt, dst_width, dst_i410_opt + dst_i410_y_size,
827 dst_width, dst_i410_opt + dst_i410_y_size + dst_i410_uv_size,
828 dst_width, src_width, src_height, mode);
829 }
830
831 // Rotation should be exact.
832 for (int i = 0; i < dst_i410_size; ++i) {
833 EXPECT_EQ(dst_i410_c[i], dst_i410_opt[i]);
834 }
835
836 free_aligned_buffer_page_end_16(dst_i410_c);
837 free_aligned_buffer_page_end_16(dst_i410_opt);
838 free_aligned_buffer_page_end_16(src_i410);
839 }
840
TEST_F(LibYUVRotateTest,I410Rotate0_Opt)841 TEST_F(LibYUVRotateTest, I410Rotate0_Opt) {
842 I410TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
843 benchmark_height_, kRotate0, benchmark_iterations_,
844 disable_cpu_flags_, benchmark_cpu_info_);
845 }
846
TEST_F(LibYUVRotateTest,I410Rotate90_Opt)847 TEST_F(LibYUVRotateTest, I410Rotate90_Opt) {
848 I410TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
849 benchmark_width_, kRotate90, benchmark_iterations_,
850 disable_cpu_flags_, benchmark_cpu_info_);
851 }
852
TEST_F(LibYUVRotateTest,I410Rotate180_Opt)853 TEST_F(LibYUVRotateTest, I410Rotate180_Opt) {
854 I410TestRotate(benchmark_width_, benchmark_height_, benchmark_width_,
855 benchmark_height_, kRotate180, benchmark_iterations_,
856 disable_cpu_flags_, benchmark_cpu_info_);
857 }
858
TEST_F(LibYUVRotateTest,I410Rotate270_Opt)859 TEST_F(LibYUVRotateTest, I410Rotate270_Opt) {
860 I410TestRotate(benchmark_width_, benchmark_height_, benchmark_height_,
861 benchmark_width_, kRotate270, benchmark_iterations_,
862 disable_cpu_flags_, benchmark_cpu_info_);
863 }
864
865 #if defined(ENABLE_ROW_TESTS)
866
TEST_F(LibYUVRotateTest,Transpose4x4_Test)867 TEST_F(LibYUVRotateTest, Transpose4x4_Test) {
868 // dst width and height
869 const int width = 4;
870 const int height = 4;
871 int src_pixels[4][4];
872 int dst_pixels_c[4][4];
873 int dst_pixels_opt[4][4];
874
875 for (int i = 0; i < 4; ++i) {
876 for (int j = 0; j < 4; ++j) {
877 src_pixels[i][j] = i * 10 + j;
878 }
879 }
880 memset(dst_pixels_c, 1, width * height * 4);
881 memset(dst_pixels_opt, 2, width * height * 4);
882
883 Transpose4x4_32_C((const uint8_t*)src_pixels, height * 4,
884 (uint8_t*)dst_pixels_c, width * 4, width);
885
886 const int benchmark_iterations =
887 (benchmark_iterations_ * benchmark_width_ * benchmark_height_ + 15) /
888 (4 * 4);
889 for (int i = 0; i < benchmark_iterations; ++i) {
890 #if defined(HAS_TRANSPOSE4X4_32_NEON)
891 if (TestCpuFlag(kCpuHasNEON)) {
892 Transpose4x4_32_NEON((const uint8_t*)src_pixels, height * 4,
893 (uint8_t*)dst_pixels_opt, width * 4, width);
894 } else
895 #elif defined(HAS_TRANSPOSE4X4_32_SSE2)
896 if (TestCpuFlag(kCpuHasSSE2)) {
897 Transpose4x4_32_SSE2((const uint8_t*)src_pixels, height * 4,
898 (uint8_t*)dst_pixels_opt, width * 4, width);
899 } else
900 #endif
901 {
902 Transpose4x4_32_C((const uint8_t*)src_pixels, height * 4,
903 (uint8_t*)dst_pixels_opt, width * 4, width);
904 }
905 }
906
907 for (int i = 0; i < 4; ++i) {
908 for (int j = 0; j < 4; ++j) {
909 EXPECT_EQ(dst_pixels_c[i][j], src_pixels[j][i]);
910 EXPECT_EQ(dst_pixels_c[i][j], dst_pixels_opt[i][j]);
911 }
912 }
913 }
914
TEST_F(LibYUVRotateTest,Transpose4x4_Opt)915 TEST_F(LibYUVRotateTest, Transpose4x4_Opt) {
916 // dst width and height
917 const int width = ((benchmark_width_ * benchmark_height_ + 3) / 4 + 3) & ~3;
918 const int height = 4;
919 align_buffer_page_end(src_pixels, height * width * 4);
920 align_buffer_page_end(dst_pixels_c, width * height * 4);
921 align_buffer_page_end(dst_pixels_opt, width * height * 4);
922
923 MemRandomize(src_pixels, height * width * 4);
924 memset(dst_pixels_c, 1, width * height * 4);
925 memset(dst_pixels_opt, 2, width * height * 4);
926
927 Transpose4x4_32_C((const uint8_t*)src_pixels, height * 4,
928 (uint8_t*)dst_pixels_c, width * 4, width);
929
930 for (int i = 0; i < benchmark_iterations_; ++i) {
931 #if defined(HAS_TRANSPOSE4X4_32_NEON)
932 if (TestCpuFlag(kCpuHasNEON)) {
933 Transpose4x4_32_NEON((const uint8_t*)src_pixels, height * 4,
934 (uint8_t*)dst_pixels_opt, width * 4, width);
935 } else
936 #elif defined(HAS_TRANSPOSE4X4_32_AVX2)
937 if (TestCpuFlag(kCpuHasAVX2)) {
938 Transpose4x4_32_AVX2((const uint8_t*)src_pixels, height * 4,
939 (uint8_t*)dst_pixels_opt, width * 4, width);
940 } else if (TestCpuFlag(kCpuHasSSE2)) {
941 Transpose4x4_32_SSE2((const uint8_t*)src_pixels, height * 4,
942 (uint8_t*)dst_pixels_opt, width * 4, width);
943 } else
944 #endif
945 {
946 Transpose4x4_32_C((const uint8_t*)src_pixels, height * 4,
947 (uint8_t*)dst_pixels_opt, width * 4, width);
948 }
949 }
950
951 for (int i = 0; i < width * height; ++i) {
952 EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
953 }
954
955 free_aligned_buffer_page_end(src_pixels);
956 free_aligned_buffer_page_end(dst_pixels_c);
957 free_aligned_buffer_page_end(dst_pixels_opt);
958 }
959
960 #endif // ENABLE_ROW_TESTS
961
962 } // namespace libyuv
963