OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/base_paths.h" | |
6 #include "base/cpu.h" | |
7 #include "base/file_util.h" | |
8 #include "base/logging.h" | |
9 #include "base/path_service.h" | |
10 #include "base/time/time.h" | |
11 #include "media/base/simd/convert_yuv_to_rgb.h" | |
12 #include "media/base/yuv_convert.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 #include "testing/perf/perf_test.h" | |
15 | |
16 namespace media { | |
17 #if !defined(ARCH_CPU_ARM_FAMILY) && !defined(ARCH_CPU_MIPS_FAMILY) | |
18 // Size of raw image. | |
19 static const int kSourceWidth = 640; | |
20 static const int kSourceHeight = 360; | |
21 static const int kSourceYSize = kSourceWidth * kSourceHeight; | |
22 static const int kSourceUOffset = kSourceYSize; | |
23 static const int kSourceVOffset = kSourceYSize * 5 / 4; | |
24 static const int kBpp = 4; | |
25 | |
26 // Width of the row to convert. Odd so that we exercise the ending | |
27 // one-pixel-leftover case. | |
28 static const int kWidth = 639; | |
29 | |
30 // Surface sizes for various test files. | |
31 static const int kYUV12Size = kSourceYSize * 12 / 8; | |
32 static const int kRGBSize = kSourceYSize * kBpp; | |
33 | |
34 static const int kPerfTestIterations = 2000; | |
35 | |
36 class YUVConvertPerfTest : public testing::Test { | |
37 public: | |
38 YUVConvertPerfTest() | |
39 : yuv_bytes_(new uint8[kYUV12Size]), | |
40 rgb_bytes_converted_(new uint8[kRGBSize]) { | |
41 base::FilePath path; | |
42 CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &path)); | |
43 path = path.Append(FILE_PATH_LITERAL("media")) | |
44 .Append(FILE_PATH_LITERAL("test")) | |
45 .Append(FILE_PATH_LITERAL("data")) | |
46 .Append("bali_640x360_P420.yuv"); | |
47 | |
48 // Verify file size is correct. | |
49 int64 actual_size = 0; | |
50 base::GetFileSize(path, &actual_size); | |
51 CHECK_EQ(actual_size, kYUV12Size); | |
52 | |
53 // Verify bytes read are correct. | |
54 int bytes_read = base::ReadFile( | |
55 path, reinterpret_cast<char*>(yuv_bytes_.get()), kYUV12Size); | |
56 | |
57 CHECK_EQ(bytes_read, kYUV12Size); | |
58 } | |
59 | |
60 scoped_ptr<uint8[]> yuv_bytes_; | |
61 scoped_ptr<uint8[]> rgb_bytes_converted_; | |
62 | |
63 private: | |
64 DISALLOW_COPY_AND_ASSIGN(YUVConvertPerfTest); | |
65 }; | |
66 | |
67 TEST_F(YUVConvertPerfTest, ConvertYUVToRGB32Row_MMX) { | |
68 ASSERT_TRUE(base::CPU().has_mmx()); | |
69 | |
70 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
71 for (int i = 0; i < kPerfTestIterations; ++i) { | |
72 for (int row = 0; row < kSourceHeight; ++row) { | |
73 int chroma_row = row / 2; | |
74 ConvertYUVToRGB32Row_MMX( | |
75 yuv_bytes_.get() + row * kSourceWidth, | |
76 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
77 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
78 rgb_bytes_converted_.get(), | |
79 kWidth); | |
80 } | |
81 } | |
82 double total_time_seconds = | |
83 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
84 perf_test::PrintResult( | |
85 "yuv_convert_perftest", "", "ConvertYUVToRGB32Row_MMX", | |
86 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
87 | |
88 media::EmptyRegisterState(); | |
89 } | |
90 | |
91 TEST_F(YUVConvertPerfTest, ConvertYUVToRGB32Row_SSE) { | |
92 ASSERT_TRUE(base::CPU().has_sse()); | |
93 | |
94 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
95 for (int i = 0; i < kPerfTestIterations; ++i) { | |
96 for (int row = 0; row < kSourceHeight; ++row) { | |
97 int chroma_row = row / 2; | |
98 ConvertYUVToRGB32Row_SSE( | |
99 yuv_bytes_.get() + row * kSourceWidth, | |
100 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
101 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
102 rgb_bytes_converted_.get(), | |
103 kWidth); | |
104 } | |
105 } | |
106 double total_time_seconds = | |
107 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
108 perf_test::PrintResult( | |
109 "yuv_convert_perftest", "", "ConvertYUVToRGB32Row_SSE", | |
110 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
111 media::EmptyRegisterState(); | |
112 } | |
113 | |
114 TEST_F(YUVConvertPerfTest, ScaleYUVToRGB32Row_MMX) { | |
115 ASSERT_TRUE(base::CPU().has_mmx()); | |
116 | |
117 const int kSourceDx = 80000; // This value means a scale down. | |
118 | |
119 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
120 for (int i = 0; i < kPerfTestIterations; ++i) { | |
121 for (int row = 0; row < kSourceHeight; ++row) { | |
122 int chroma_row = row / 2; | |
123 ScaleYUVToRGB32Row_MMX( | |
124 yuv_bytes_.get() + row * kSourceWidth, | |
125 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
126 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
127 rgb_bytes_converted_.get(), | |
128 kWidth, | |
129 kSourceDx); | |
130 } | |
131 } | |
132 double total_time_seconds = | |
133 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
134 perf_test::PrintResult( | |
135 "yuv_convert_perftest", "", "ScaleYUVToRGB32Row_MMX", | |
136 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
137 media::EmptyRegisterState(); | |
138 } | |
139 | |
140 TEST_F(YUVConvertPerfTest, ScaleYUVToRGB32Row_SSE) { | |
141 ASSERT_TRUE(base::CPU().has_sse()); | |
142 | |
143 const int kSourceDx = 80000; // This value means a scale down. | |
144 | |
145 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
146 for (int i = 0; i < kPerfTestIterations; ++i) { | |
147 for (int row = 0; row < kSourceHeight; ++row) { | |
148 int chroma_row = row / 2; | |
149 ScaleYUVToRGB32Row_SSE( | |
150 yuv_bytes_.get() + row * kSourceWidth, | |
151 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
152 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
153 rgb_bytes_converted_.get(), | |
154 kWidth, | |
155 kSourceDx); | |
156 } | |
157 } | |
158 double total_time_seconds = | |
159 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
160 perf_test::PrintResult( | |
161 "yuv_convert_perftest", "", "ScaleYUVToRGB32Row_SSE", | |
162 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
163 media::EmptyRegisterState(); | |
164 } | |
165 | |
166 TEST_F(YUVConvertPerfTest, LinearScaleYUVToRGB32Row_MMX) { | |
167 ASSERT_TRUE(base::CPU().has_mmx()); | |
168 | |
169 const int kSourceDx = 80000; // This value means a scale down. | |
170 | |
171 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
172 for (int i = 0; i < kPerfTestIterations; ++i) { | |
173 for (int row = 0; row < kSourceHeight; ++row) { | |
174 int chroma_row = row / 2; | |
175 LinearScaleYUVToRGB32Row_MMX( | |
176 yuv_bytes_.get() + row * kSourceWidth, | |
177 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
178 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
179 rgb_bytes_converted_.get(), | |
180 kWidth, | |
181 kSourceDx); | |
182 } | |
183 } | |
184 double total_time_seconds = | |
185 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
186 perf_test::PrintResult( | |
187 "yuv_convert_perftest", "", "LinearScaleYUVToRGB32Row_MMX", | |
188 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
189 media::EmptyRegisterState(); | |
190 } | |
191 | |
192 TEST_F(YUVConvertPerfTest, LinearScaleYUVToRGB32Row_SSE) { | |
193 ASSERT_TRUE(base::CPU().has_sse()); | |
194 | |
195 const int kSourceDx = 80000; // This value means a scale down. | |
196 | |
197 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
198 for (int i = 0; i < kPerfTestIterations; ++i) { | |
199 for (int row = 0; row < kSourceHeight; ++row) { | |
200 int chroma_row = row / 2; | |
201 LinearScaleYUVToRGB32Row_SSE( | |
202 yuv_bytes_.get() + row * kSourceWidth, | |
203 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
204 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
205 rgb_bytes_converted_.get(), | |
206 kWidth, | |
207 kSourceDx); | |
208 } | |
209 } | |
210 double total_time_seconds = | |
211 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
212 perf_test::PrintResult( | |
213 "yuv_convert_perftest", "", "LinearScaleYUVToRGB32Row_SSE", | |
214 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
215 media::EmptyRegisterState(); | |
216 } | |
217 | |
218 #endif // !defined(ARCH_CPU_ARM_FAMILY) && !defined(ARCH_CPU_MIPS_FAMILY) | |
219 | |
220 } // namespace media | |
OLD | NEW |