• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "libyuv/cpu_id.h"
14 #include "libyuv/rotate.h"
15 #include "../unit_test/unit_test.h"
16 
17 namespace libyuv {
18 
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)19 static void I420TestRotate(int src_width, int src_height,
20                            int dst_width, int dst_height,
21                            libyuv::RotationMode mode,
22                            int benchmark_iterations,
23                            int disable_cpu_flags, int benchmark_cpu_info) {
24   if (src_width < 1) {
25     src_width = 1;
26   }
27   if (src_height == 0) {
28     src_height = 1;
29   }
30   if (dst_width < 1) {
31     dst_width = 1;
32   }
33   if (dst_height < 1) {
34     dst_height = 1;
35   }
36   int src_i420_y_size = src_width * Abs(src_height);
37   int src_i420_uv_size = ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2);
38   int src_i420_size = src_i420_y_size + src_i420_uv_size * 2;
39   align_buffer_page_end(src_i420, src_i420_size);
40   for (int i = 0; i < src_i420_size; ++i) {
41     src_i420[i] = fastrand() & 0xff;
42   }
43 
44   int dst_i420_y_size = dst_width * dst_height;
45   int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
46   int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
47   align_buffer_page_end(dst_i420_c, dst_i420_size);
48   align_buffer_page_end(dst_i420_opt, dst_i420_size);
49   memset(dst_i420_c, 2, dst_i420_size);
50   memset(dst_i420_opt, 3, dst_i420_size);
51 
52   MaskCpuFlags(disable_cpu_flags);  // Disable all CPU optimization.
53   I420Rotate(src_i420, src_width,
54              src_i420 + src_i420_y_size, (src_width + 1) / 2,
55              src_i420 + src_i420_y_size + src_i420_uv_size, (src_width + 1) / 2,
56              dst_i420_c, dst_width,
57              dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
58              dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
59                (dst_width + 1) / 2,
60              src_width, src_height, mode);
61 
62   MaskCpuFlags(benchmark_cpu_info);  // Enable all CPU optimization.
63   for (int i = 0; i < benchmark_iterations; ++i) {
64     I420Rotate(src_i420, src_width,
65                src_i420 + src_i420_y_size, (src_width + 1) / 2,
66                src_i420 + src_i420_y_size + src_i420_uv_size,
67                  (src_width + 1) / 2,
68                dst_i420_opt, dst_width,
69                dst_i420_opt + dst_i420_y_size, (dst_width + 1) / 2,
70                dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
71                  (dst_width + 1) / 2,
72                src_width, src_height, mode);
73   }
74 
75   // Rotation should be exact.
76   for (int i = 0; i < dst_i420_size; ++i) {
77     EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
78   }
79 
80   free_aligned_buffer_page_end(dst_i420_c);
81   free_aligned_buffer_page_end(dst_i420_opt);
82   free_aligned_buffer_page_end(src_i420);
83 }
84 
TEST_F(LibYUVRotateTest,I420Rotate0_Opt)85 TEST_F(LibYUVRotateTest, I420Rotate0_Opt) {
86   I420TestRotate(benchmark_width_, benchmark_height_,
87                  benchmark_width_, benchmark_height_,
88                  kRotate0, benchmark_iterations_,
89                  disable_cpu_flags_, benchmark_cpu_info_);
90 }
91 
TEST_F(LibYUVRotateTest,I420Rotate90_Opt)92 TEST_F(LibYUVRotateTest, I420Rotate90_Opt) {
93   I420TestRotate(benchmark_width_, benchmark_height_,
94                  benchmark_height_, benchmark_width_,
95                  kRotate90, benchmark_iterations_,
96                  disable_cpu_flags_, benchmark_cpu_info_);
97 }
98 
TEST_F(LibYUVRotateTest,I420Rotate180_Opt)99 TEST_F(LibYUVRotateTest, I420Rotate180_Opt) {
100   I420TestRotate(benchmark_width_, benchmark_height_,
101                  benchmark_width_, benchmark_height_,
102                  kRotate180, benchmark_iterations_,
103                  disable_cpu_flags_, benchmark_cpu_info_);
104 }
105 
TEST_F(LibYUVRotateTest,I420Rotate270_Opt)106 TEST_F(LibYUVRotateTest, I420Rotate270_Opt) {
107   I420TestRotate(benchmark_width_, benchmark_height_,
108                  benchmark_height_, benchmark_width_,
109                  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_ - 3, benchmark_height_ - 1,
118                  benchmark_width_ - 3, benchmark_height_ - 1,
119                  kRotate0, benchmark_iterations_,
120                  disable_cpu_flags_, benchmark_cpu_info_);
121 }
122 
TEST_F(LibYUVRotateTest,DISABLED_I420Rotate90_Odd)123 TEST_F(LibYUVRotateTest, DISABLED_I420Rotate90_Odd) {
124   I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
125                  benchmark_height_ - 1, benchmark_width_ - 3,
126                  kRotate90, benchmark_iterations_,
127                  disable_cpu_flags_, benchmark_cpu_info_);
128 }
129 
TEST_F(LibYUVRotateTest,DISABLED_I420Rotate180_Odd)130 TEST_F(LibYUVRotateTest, DISABLED_I420Rotate180_Odd) {
131   I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
132                  benchmark_width_ - 3, benchmark_height_ - 1,
133                  kRotate180, benchmark_iterations_,
134                  disable_cpu_flags_, benchmark_cpu_info_);
135 }
136 
TEST_F(LibYUVRotateTest,DISABLED_I420Rotate270_Odd)137 TEST_F(LibYUVRotateTest, DISABLED_I420Rotate270_Odd) {
138   I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
139                  benchmark_height_ - 1, benchmark_width_ - 3,
140                  kRotate270, benchmark_iterations_,
141                  disable_cpu_flags_, benchmark_cpu_info_);
142 }
143 
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)144 static void NV12TestRotate(int src_width, int src_height,
145                            int dst_width, int dst_height,
146                            libyuv::RotationMode mode,
147                            int benchmark_iterations,
148                            int disable_cpu_flags, int benchmark_cpu_info) {
149   if (src_width < 1) {
150     src_width = 1;
151   }
152   if (src_height == 0) {  // allow negative for inversion test.
153     src_height = 1;
154   }
155   if (dst_width < 1) {
156     dst_width = 1;
157   }
158   if (dst_height < 1) {
159     dst_height = 1;
160   }
161   int src_nv12_y_size = src_width * Abs(src_height);
162   int src_nv12_uv_size =
163       ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2) * 2;
164   int src_nv12_size = src_nv12_y_size + src_nv12_uv_size;
165   align_buffer_page_end(src_nv12, src_nv12_size);
166   for (int i = 0; i < src_nv12_size; ++i) {
167     src_nv12[i] = fastrand() & 0xff;
168   }
169 
170   int dst_i420_y_size = dst_width * dst_height;
171   int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
172   int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
173   align_buffer_page_end(dst_i420_c, dst_i420_size);
174   align_buffer_page_end(dst_i420_opt, dst_i420_size);
175   memset(dst_i420_c, 2, dst_i420_size);
176   memset(dst_i420_opt, 3, dst_i420_size);
177 
178   MaskCpuFlags(disable_cpu_flags);  // Disable all CPU optimization.
179   NV12ToI420Rotate(src_nv12, src_width,
180                    src_nv12 + src_nv12_y_size, (src_width + 1) & ~1,
181                    dst_i420_c, dst_width,
182                    dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
183                    dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
184                      (dst_width + 1) / 2,
185                    src_width, src_height, mode);
186 
187   MaskCpuFlags(benchmark_cpu_info);  // Enable all CPU optimization.
188   for (int i = 0; i < benchmark_iterations; ++i) {
189     NV12ToI420Rotate(src_nv12, src_width,
190                      src_nv12 + src_nv12_y_size, (src_width + 1) & ~1,
191                      dst_i420_opt, dst_width,
192                      dst_i420_opt + dst_i420_y_size, (dst_width + 1) / 2,
193                      dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
194                        (dst_width + 1) / 2,
195                      src_width, src_height, mode);
196   }
197 
198   // Rotation should be exact.
199   for (int i = 0; i < dst_i420_size; ++i) {
200     EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
201   }
202 
203   free_aligned_buffer_page_end(dst_i420_c);
204   free_aligned_buffer_page_end(dst_i420_opt);
205   free_aligned_buffer_page_end(src_nv12);
206 }
207 
TEST_F(LibYUVRotateTest,NV12Rotate0_Opt)208 TEST_F(LibYUVRotateTest, NV12Rotate0_Opt) {
209   NV12TestRotate(benchmark_width_, benchmark_height_,
210                  benchmark_width_, benchmark_height_,
211                  kRotate0, benchmark_iterations_,
212                  disable_cpu_flags_, benchmark_cpu_info_);
213 }
214 
TEST_F(LibYUVRotateTest,NV12Rotate90_Opt)215 TEST_F(LibYUVRotateTest, NV12Rotate90_Opt) {
216   NV12TestRotate(benchmark_width_, benchmark_height_,
217                  benchmark_height_, benchmark_width_,
218                  kRotate90, benchmark_iterations_,
219                  disable_cpu_flags_, benchmark_cpu_info_);
220 }
221 
TEST_F(LibYUVRotateTest,NV12Rotate180_Opt)222 TEST_F(LibYUVRotateTest, NV12Rotate180_Opt) {
223   NV12TestRotate(benchmark_width_, benchmark_height_,
224                  benchmark_width_, benchmark_height_,
225                  kRotate180, benchmark_iterations_,
226                  disable_cpu_flags_, benchmark_cpu_info_);
227 }
228 
TEST_F(LibYUVRotateTest,NV12Rotate270_Opt)229 TEST_F(LibYUVRotateTest, NV12Rotate270_Opt) {
230   NV12TestRotate(benchmark_width_, benchmark_height_,
231                  benchmark_height_, benchmark_width_,
232                  kRotate270, benchmark_iterations_,
233                  disable_cpu_flags_, benchmark_cpu_info_);
234 }
235 
TEST_F(LibYUVRotateTest,DISABLED_NV12Rotate0_Odd)236 TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate0_Odd) {
237   NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
238                  benchmark_width_ - 3, benchmark_height_ - 1,
239                  kRotate0, benchmark_iterations_,
240                  disable_cpu_flags_, benchmark_cpu_info_);
241 }
242 
TEST_F(LibYUVRotateTest,DISABLED_NV12Rotate90_Odd)243 TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate90_Odd) {
244   NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
245                  benchmark_height_ - 1, benchmark_width_ - 3,
246                  kRotate90, benchmark_iterations_,
247                  disable_cpu_flags_, benchmark_cpu_info_);
248 }
249 
TEST_F(LibYUVRotateTest,DISABLED_NV12Rotate180_Odd)250 TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate180_Odd) {
251   NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
252                  benchmark_width_ - 3, benchmark_height_ - 1,
253                  kRotate180, benchmark_iterations_,
254                  disable_cpu_flags_, benchmark_cpu_info_);
255 }
256 
TEST_F(LibYUVRotateTest,DISABLED_NV12Rotate270_Odd)257 TEST_F(LibYUVRotateTest, DISABLED_NV12Rotate270_Odd) {
258   NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
259                  benchmark_height_ - 1, benchmark_width_ - 3,
260                  kRotate270, benchmark_iterations_,
261                  disable_cpu_flags_, benchmark_cpu_info_);
262 }
263 
TEST_F(LibYUVRotateTest,NV12Rotate0_Invert)264 TEST_F(LibYUVRotateTest, NV12Rotate0_Invert) {
265   NV12TestRotate(benchmark_width_, -benchmark_height_,
266                  benchmark_width_, benchmark_height_,
267                  kRotate0, benchmark_iterations_,
268                  disable_cpu_flags_, benchmark_cpu_info_);
269 }
270 
TEST_F(LibYUVRotateTest,NV12Rotate90_Invert)271 TEST_F(LibYUVRotateTest, NV12Rotate90_Invert) {
272   NV12TestRotate(benchmark_width_, -benchmark_height_,
273                  benchmark_height_, benchmark_width_,
274                  kRotate90, benchmark_iterations_,
275                  disable_cpu_flags_, benchmark_cpu_info_);
276 }
277 
TEST_F(LibYUVRotateTest,NV12Rotate180_Invert)278 TEST_F(LibYUVRotateTest, NV12Rotate180_Invert) {
279   NV12TestRotate(benchmark_width_, -benchmark_height_,
280                  benchmark_width_, benchmark_height_,
281                  kRotate180, benchmark_iterations_,
282                  disable_cpu_flags_, benchmark_cpu_info_);
283 }
284 
TEST_F(LibYUVRotateTest,NV12Rotate270_Invert)285 TEST_F(LibYUVRotateTest, NV12Rotate270_Invert) {
286   NV12TestRotate(benchmark_width_, -benchmark_height_,
287                  benchmark_height_, benchmark_width_,
288                  kRotate270, benchmark_iterations_,
289                  disable_cpu_flags_, benchmark_cpu_info_);
290 }
291 
292 
293 
294 
295 
296 }  // namespace libyuv
297