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 | |
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 void InitYV12Data(); | |
42 } | |
43 | |
44 void InitYV12Data() { | |
scherkus (not reviewing)
2014/04/23 18:11:21
might as well move this into the ctor / use initia
| |
45 yuv_bytes_.reset(new uint8[kYUV12Size]); | |
46 | |
47 base::FilePath path; | |
48 CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &path)); | |
49 path = path.Append(FILE_PATH_LITERAL("media")) | |
50 .Append(FILE_PATH_LITERAL("test")) | |
51 .Append(FILE_PATH_LITERAL("data")) | |
52 .Append("bali_640x360_P420.yuv"); | |
53 | |
54 // Verify file size is correct. | |
55 int64 actual_size = 0; | |
56 base::GetFileSize(path, &actual_size); | |
57 CHECK_EQ(actual_size, kYUV12Size); | |
58 | |
59 // Verify bytes read are correct. | |
60 int bytes_read = base::ReadFile( | |
61 path, reinterpret_cast<char*>(yuv_bytes_.get()), kYUV12Size); | |
62 | |
63 CHECK_EQ(bytes_read, kYUV12Size); | |
64 } | |
65 | |
66 scoped_ptr<uint8[]> yuv_bytes_; | |
67 scoped_ptr<uint8[]> rgb_bytes_converted_; | |
68 | |
69 DISALLOW_COPY_AND_ASSIGN(YUVConvertPerfTest); | |
scherkus (not reviewing)
2014/04/23 18:11:21
this macro is only useful if it's behind a private
| |
70 }; | |
71 | |
72 #if !defined(ARCH_CPU_ARM_FAMILY) && !defined(ARCH_CPU_MIPS_FAMILY) | |
73 TEST_F(YUVConvertPerfTest, ConvertYUVToRGB32Row_MMX) { | |
74 ASSERT_TRUE(base::CPU().has_mmx()); | |
75 | |
76 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
77 for (int i = 0; i < kPerfTestIterations; ++i) { | |
78 for (int row = 0; row < kSourceHeight; ++row) { | |
79 int chroma_row = row / 2; | |
80 ConvertYUVToRGB32Row_MMX( | |
81 yuv_bytes_.get() + row * kSourceWidth, | |
82 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
83 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
84 rgb_bytes_converted_.get(), | |
85 kWidth); | |
86 } | |
87 } | |
88 double total_time_seconds = | |
89 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
90 perf_test::PrintResult( | |
91 "yuv_convert_perftest", "", "ConvertYUVToRGB32Row_MMX", | |
92 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
93 | |
94 media::EmptyRegisterState(); | |
95 } | |
96 | |
97 TEST_F(YUVConvertPerfTest, ConvertYUVToRGB32Row_SSE) { | |
98 ASSERT_TRUE(base::CPU().has_sse()); | |
99 | |
100 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
101 for (int i = 0; i < kPerfTestIterations; ++i) { | |
102 for (int row = 0; row < kSourceHeight; ++row) { | |
103 int chroma_row = row / 2; | |
104 ConvertYUVToRGB32Row_SSE( | |
105 yuv_bytes_.get() + row * kSourceWidth, | |
106 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
107 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
108 rgb_bytes_converted_.get(), | |
109 kWidth); | |
110 } | |
111 } | |
112 double total_time_seconds = | |
113 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
114 perf_test::PrintResult( | |
115 "yuv_convert_perftest", "", "ConvertYUVToRGB32Row_SSE", | |
116 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
117 media::EmptyRegisterState(); | |
118 } | |
119 | |
120 TEST_F(YUVConvertPerfTest, ScaleYUVToRGB32Row_MMX) { | |
121 ASSERT_TRUE(base::CPU().has_mmx()); | |
122 | |
123 const int kSourceDx = 80000; // This value means a scale down. | |
124 | |
125 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
126 for (int i = 0; i < kPerfTestIterations; ++i) { | |
127 for (int row = 0; row < kSourceHeight; ++row) { | |
128 int chroma_row = row / 2; | |
129 ScaleYUVToRGB32Row_MMX( | |
130 yuv_bytes_.get() + row * kSourceWidth, | |
131 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
132 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
133 rgb_bytes_converted_.get(), | |
134 kWidth, | |
135 kSourceDx); | |
136 } | |
137 } | |
138 double total_time_seconds = | |
139 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
140 perf_test::PrintResult( | |
141 "yuv_convert_perftest", "", "ScaleYUVToRGB32Row_MMX", | |
142 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
143 media::EmptyRegisterState(); | |
144 } | |
145 | |
146 TEST_F(YUVConvertPerfTest, ScaleYUVToRGB32Row_SSE) { | |
147 ASSERT_TRUE(base::CPU().has_sse()); | |
148 | |
149 const int kSourceDx = 80000; // This value means a scale down. | |
150 | |
151 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
152 for (int i = 0; i < kPerfTestIterations; ++i) { | |
153 for (int row = 0; row < kSourceHeight; ++row) { | |
154 int chroma_row = row / 2; | |
155 ScaleYUVToRGB32Row_SSE( | |
156 yuv_bytes_.get() + row * kSourceWidth, | |
157 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
158 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
159 rgb_bytes_converted_.get(), | |
160 kWidth, | |
161 kSourceDx); | |
162 } | |
163 } | |
164 double total_time_seconds = | |
165 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
166 perf_test::PrintResult( | |
167 "yuv_convert_perftest", "", "ScaleYUVToRGB32Row_SSE", | |
168 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
169 media::EmptyRegisterState(); | |
170 } | |
171 | |
172 TEST_F(YUVConvertPerfTest, LinearScaleYUVToRGB32Row_MMX) { | |
173 ASSERT_TRUE(base::CPU().has_mmx()); | |
174 | |
175 const int kSourceDx = 80000; // This value means a scale down. | |
176 | |
177 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
178 for (int i = 0; i < kPerfTestIterations; ++i) { | |
179 for (int row = 0; row < kSourceHeight; ++row) { | |
180 int chroma_row = row / 2; | |
181 LinearScaleYUVToRGB32Row_MMX( | |
182 yuv_bytes_.get() + row * kSourceWidth, | |
183 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
184 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
185 rgb_bytes_converted_.get(), | |
186 kWidth, | |
187 kSourceDx); | |
188 } | |
189 } | |
190 double total_time_seconds = | |
191 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
192 perf_test::PrintResult( | |
193 "yuv_convert_perftest", "", "LinearScaleYUVToRGB32Row_MMX", | |
194 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
195 media::EmptyRegisterState(); | |
196 } | |
197 | |
198 TEST_F(YUVConvertPerfTest, LinearScaleYUVToRGB32Row_SSE) { | |
199 ASSERT_TRUE(base::CPU().has_sse()); | |
200 | |
201 const int kSourceDx = 80000; // This value means a scale down. | |
202 | |
203 base::TimeTicks start = base::TimeTicks::HighResNow(); | |
204 for (int i = 0; i < kPerfTestIterations; ++i) { | |
205 for (int row = 0; row < kSourceHeight; ++row) { | |
206 int chroma_row = row / 2; | |
207 LinearScaleYUVToRGB32Row_SSE( | |
208 yuv_bytes_.get() + row * kSourceWidth, | |
209 yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2), | |
210 yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2), | |
211 rgb_bytes_converted_.get(), | |
212 kWidth, | |
213 kSourceDx); | |
214 } | |
215 } | |
216 double total_time_seconds = | |
217 (base::TimeTicks::HighResNow() - start).InSecondsF(); | |
218 perf_test::PrintResult( | |
219 "yuv_convert_perftest", "", "LinearScaleYUVToRGB32Row_SSE", | |
220 kPerfTestIterations / total_time_seconds, "runs/s", true); | |
221 media::EmptyRegisterState(); | |
222 } | |
223 | |
224 #endif // !defined(ARCH_CPU_ARM_FAMILY) && !defined(ARCH_CPU_MIPS_FAMILY) | |
225 | |
226 } // namespace media | |
OLD | NEW |