• 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 #include <time.h>
13 
14 #include "libyuv/cpu_id.h"
15 #include "libyuv/rotate.h"
16 #include "libyuv/row.h"
17 #include "../unit_test/unit_test.h"
18 
19 namespace libyuv {
20 
I420TestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int benchmark_iterations)21 static void I420TestRotate(int src_width, int src_height,
22                            int dst_width, int dst_height,
23                            libyuv::RotationMode mode,
24                            int benchmark_iterations) {
25   if (src_width < 1) {
26     src_width = 1;
27   }
28   if (src_height < 1) {
29     src_height = 1;
30   }
31   if (dst_width < 1) {
32     dst_width = 1;
33   }
34   if (dst_height < 1) {
35     dst_height = 1;
36   }
37   int src_i420_y_size = src_width * src_height;
38   int src_i420_uv_size = ((src_width + 1) / 2) * ((src_height + 1) / 2);
39   int src_i420_size = src_i420_y_size + src_i420_uv_size * 2;
40   align_buffer_64(src_i420, src_i420_size);
41   for (int i = 0; i < src_i420_size; ++i) {
42     src_i420[i] = random() & 0xff;
43   }
44 
45   int dst_i420_y_size = dst_width * dst_height;
46   int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
47   int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
48   align_buffer_64(dst_i420_c, dst_i420_size);
49   align_buffer_64(dst_i420_opt, dst_i420_size);
50   memset(dst_i420_c, 2, dst_i420_size);
51   memset(dst_i420_opt, 3, dst_i420_size);
52 
53   MaskCpuFlags(0);  // Disable all CPU optimization.
54   I420Rotate(src_i420, src_width,
55              src_i420 + src_i420_y_size, (src_width + 1) / 2,
56              src_i420 + src_i420_y_size + src_i420_uv_size, (src_width + 1) / 2,
57              dst_i420_c, dst_width,
58              dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
59              dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
60                (dst_width + 1) / 2,
61              src_width, src_height, mode);
62 
63   MaskCpuFlags(-1);  // Enable all CPU optimization.
64   for (int i = 0; i < benchmark_iterations; ++i) {
65     I420Rotate(src_i420, src_width,
66                src_i420 + src_i420_y_size, (src_width + 1) / 2,
67                src_i420 + src_i420_y_size + src_i420_uv_size,
68                  (src_width + 1) / 2,
69                dst_i420_opt, dst_width,
70                dst_i420_opt + dst_i420_y_size, (dst_width + 1) / 2,
71                dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
72                  (dst_width + 1) / 2,
73                src_width, src_height, mode);
74   }
75 
76   // Rotation should be exact.
77   for (int i = 0; i < dst_i420_size; ++i) {
78     EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
79   }
80 
81   free_aligned_buffer_64(dst_i420_c);
82   free_aligned_buffer_64(dst_i420_opt);
83   free_aligned_buffer_64(src_i420);
84 }
85 
TEST_F(libyuvTest,I420Rotate0)86 TEST_F(libyuvTest, I420Rotate0) {
87   I420TestRotate(benchmark_width_, benchmark_height_,
88                  benchmark_width_, benchmark_height_,
89                  kRotate0, benchmark_iterations_);
90 }
91 
TEST_F(libyuvTest,I420Rotate90)92 TEST_F(libyuvTest, I420Rotate90) {
93   I420TestRotate(benchmark_width_, benchmark_height_,
94                  benchmark_height_, benchmark_width_,
95                  kRotate90, benchmark_iterations_);
96 }
97 
TEST_F(libyuvTest,I420Rotate180)98 TEST_F(libyuvTest, I420Rotate180) {
99   I420TestRotate(benchmark_width_, benchmark_height_,
100                  benchmark_width_, benchmark_height_,
101                  kRotate180, benchmark_iterations_);
102 }
103 
TEST_F(libyuvTest,I420Rotate270)104 TEST_F(libyuvTest, I420Rotate270) {
105   I420TestRotate(benchmark_width_, benchmark_height_,
106                  benchmark_height_, benchmark_width_,
107                  kRotate270, benchmark_iterations_);
108 }
109 
TEST_F(libyuvTest,I420Rotate0_Odd)110 TEST_F(libyuvTest, I420Rotate0_Odd) {
111   I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
112                  benchmark_width_ - 3, benchmark_height_ - 1,
113                  kRotate0, benchmark_iterations_);
114 }
115 
TEST_F(libyuvTest,I420Rotate90_Odd)116 TEST_F(libyuvTest, I420Rotate90_Odd) {
117   I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
118                  benchmark_height_ - 1, benchmark_width_ - 3,
119                  kRotate90, benchmark_iterations_);
120 }
121 
TEST_F(libyuvTest,I420Rotate180_Odd)122 TEST_F(libyuvTest, I420Rotate180_Odd) {
123   I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
124                  benchmark_width_ - 3, benchmark_height_ - 1,
125                  kRotate180, benchmark_iterations_);
126 }
127 
TEST_F(libyuvTest,I420Rotate270_Odd)128 TEST_F(libyuvTest, I420Rotate270_Odd) {
129   I420TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
130                  benchmark_height_ - 1, benchmark_width_ - 3,
131                  kRotate270, benchmark_iterations_);
132 }
133 
NV12TestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int benchmark_iterations)134 static void NV12TestRotate(int src_width, int src_height,
135                            int dst_width, int dst_height,
136                            libyuv::RotationMode mode,
137                            int benchmark_iterations) {
138   if (src_width < 1) {
139     src_width = 1;
140   }
141   if (src_height < 1) {
142     src_height = 1;
143   }
144   if (dst_width < 1) {
145     dst_width = 1;
146   }
147   if (dst_height < 1) {
148     dst_height = 1;
149   }
150   int src_nv12_y_size = src_width * src_height;
151   int src_nv12_uv_size = ((src_width + 1) / 2) * ((src_height + 1) / 2) * 2;
152   int src_nv12_size = src_nv12_y_size + src_nv12_uv_size;
153   align_buffer_64(src_nv12, src_nv12_size);
154   for (int i = 0; i < src_nv12_size; ++i) {
155     src_nv12[i] = random() & 0xff;
156   }
157 
158   int dst_i420_y_size = dst_width * dst_height;
159   int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
160   int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
161   align_buffer_64(dst_i420_c, dst_i420_size);
162   align_buffer_64(dst_i420_opt, dst_i420_size);
163   memset(dst_i420_c, 2, dst_i420_size);
164   memset(dst_i420_opt, 3, dst_i420_size);
165 
166   MaskCpuFlags(0);  // Disable all CPU optimization.
167   NV12ToI420Rotate(src_nv12, src_width,
168                    src_nv12 + src_nv12_y_size, (src_width + 1) & ~1,
169                    dst_i420_c, dst_width,
170                    dst_i420_c + dst_i420_y_size, (dst_width + 1) / 2,
171                    dst_i420_c + dst_i420_y_size + dst_i420_uv_size,
172                      (dst_width + 1) / 2,
173                    src_width, src_height, mode);
174 
175   MaskCpuFlags(-1);  // Enable all CPU optimization.
176   for (int i = 0; i < benchmark_iterations; ++i) {
177     NV12ToI420Rotate(src_nv12, src_width,
178                      src_nv12 + src_nv12_y_size, (src_width + 1) & ~1,
179                      dst_i420_opt, dst_width,
180                      dst_i420_opt + dst_i420_y_size, (dst_width + 1) / 2,
181                      dst_i420_opt + dst_i420_y_size + dst_i420_uv_size,
182                        (dst_width + 1) / 2,
183                      src_width, src_height, mode);
184   }
185 
186   // Rotation should be exact.
187   for (int i = 0; i < dst_i420_size; ++i) {
188     EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
189   }
190 
191   free_aligned_buffer_64(dst_i420_c);
192   free_aligned_buffer_64(dst_i420_opt);
193   free_aligned_buffer_64(src_nv12);
194 }
195 
TEST_F(libyuvTest,NV12Rotate0)196 TEST_F(libyuvTest, NV12Rotate0) {
197   NV12TestRotate(benchmark_width_, benchmark_height_,
198                  benchmark_width_, benchmark_height_,
199                  kRotate0, benchmark_iterations_);
200 }
201 
TEST_F(libyuvTest,NV12Rotate90)202 TEST_F(libyuvTest, NV12Rotate90) {
203   NV12TestRotate(benchmark_width_, benchmark_height_,
204                  benchmark_height_, benchmark_width_,
205                  kRotate90, benchmark_iterations_);
206 }
207 
TEST_F(libyuvTest,NV12Rotate180)208 TEST_F(libyuvTest, NV12Rotate180) {
209   NV12TestRotate(benchmark_width_, benchmark_height_,
210                  benchmark_width_, benchmark_height_,
211                  kRotate180, benchmark_iterations_);
212 }
213 
TEST_F(libyuvTest,NV12Rotate270)214 TEST_F(libyuvTest, NV12Rotate270) {
215   NV12TestRotate(benchmark_width_, benchmark_height_,
216                  benchmark_height_, benchmark_width_,
217                  kRotate270, benchmark_iterations_);
218 }
219 
TEST_F(libyuvTest,NV12Rotate0_Odd)220 TEST_F(libyuvTest, NV12Rotate0_Odd) {
221   NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
222                  benchmark_width_ - 3, benchmark_height_ - 1,
223                  kRotate0, benchmark_iterations_);
224 }
225 
TEST_F(libyuvTest,NV12Rotate90_Odd)226 TEST_F(libyuvTest, NV12Rotate90_Odd) {
227   NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
228                  benchmark_height_ - 1, benchmark_width_ - 3,
229                  kRotate90, benchmark_iterations_);
230 }
231 
TEST_F(libyuvTest,NV12Rotate180_Odd)232 TEST_F(libyuvTest, NV12Rotate180_Odd) {
233   NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
234                  benchmark_width_ - 3, benchmark_height_ - 1,
235                  kRotate180, benchmark_iterations_);
236 }
237 
TEST_F(libyuvTest,NV12Rotate270_Odd)238 TEST_F(libyuvTest, NV12Rotate270_Odd) {
239   NV12TestRotate(benchmark_width_ - 3, benchmark_height_ - 1,
240                  benchmark_height_ - 1, benchmark_width_ - 3,
241                  kRotate270, benchmark_iterations_);
242 }
243 
244 }  // namespace libyuv
245