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