OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
6 #include "base/strings/string_number_conversions.h" | 6 #include "base/strings/string_number_conversions.h" |
7 #include "base/strings/string_split.h" | 7 #include "base/strings/string_split.h" |
8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "media/filters/video_cadence_estimator.h" | 9 #include "media/filters/video_cadence_estimator.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 base::SplitString(cadence.substr(1, cadence.length() - 2), | 33 base::SplitString(cadence.substr(1, cadence.length() - 2), |
34 ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { | 34 ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { |
35 int cadence_value = 0; | 35 int cadence_value = 0; |
36 CHECK(base::StringToInt(token, &cadence_value)) << token; | 36 CHECK(base::StringToInt(token, &cadence_value)) << token; |
37 result.push_back(cadence_value); | 37 result.push_back(cadence_value); |
38 } | 38 } |
39 | 39 |
40 return result; | 40 return result; |
41 } | 41 } |
42 | 42 |
43 static void VerifyCadenceVectorWithCustomDrift( | 43 static void VerifyCadenceVectorWithCustomDeviationAndDrift( |
44 VideoCadenceEstimator* estimator, | 44 VideoCadenceEstimator* estimator, |
45 double frame_hertz, | 45 double frame_hertz, |
46 double render_hertz, | 46 double render_hertz, |
| 47 base::TimeDelta deviation, |
47 base::TimeDelta acceptable_drift, | 48 base::TimeDelta acceptable_drift, |
48 const std::string& expected_cadence) { | 49 const std::string& expected_cadence) { |
49 SCOPED_TRACE(base::StringPrintf("Checking %.03f fps into %0.03f", frame_hertz, | 50 SCOPED_TRACE(base::StringPrintf("Checking %.03f fps into %0.03f", frame_hertz, |
50 render_hertz)); | 51 render_hertz)); |
51 | 52 |
52 const std::vector<int> expected_cadence_vector = | 53 const std::vector<int> expected_cadence_vector = |
53 CreateCadenceFromString(expected_cadence); | 54 CreateCadenceFromString(expected_cadence); |
54 | 55 |
55 estimator->Reset(); | 56 estimator->Reset(); |
56 const bool cadence_changed = estimator->UpdateCadenceEstimate( | 57 const bool cadence_changed = estimator->UpdateCadenceEstimate( |
57 Interval(render_hertz), Interval(frame_hertz), acceptable_drift); | 58 Interval(render_hertz), Interval(frame_hertz), deviation, |
| 59 acceptable_drift); |
58 EXPECT_EQ(cadence_changed, estimator->has_cadence()); | 60 EXPECT_EQ(cadence_changed, estimator->has_cadence()); |
59 EXPECT_EQ(expected_cadence_vector.empty(), !estimator->has_cadence()); | 61 EXPECT_EQ(expected_cadence_vector.empty(), !estimator->has_cadence()); |
60 | 62 |
61 // Nothing further to test. | 63 // Nothing further to test. |
62 if (expected_cadence_vector.empty() || !estimator->has_cadence()) | 64 if (expected_cadence_vector.empty() || !estimator->has_cadence()) |
63 return; | 65 return; |
64 | 66 |
65 EXPECT_EQ(expected_cadence_vector.size(), | 67 EXPECT_EQ(expected_cadence_vector.size(), |
66 estimator->cadence_size_for_testing()); | 68 estimator->cadence_size_for_testing()); |
67 | 69 |
68 // Spot two cycles of the cadence. | 70 // Spot two cycles of the cadence. |
69 for (size_t i = 0; i < expected_cadence_vector.size() * 2; ++i) { | 71 for (size_t i = 0; i < expected_cadence_vector.size() * 2; ++i) { |
70 ASSERT_EQ(expected_cadence_vector[i % expected_cadence_vector.size()], | 72 ASSERT_EQ(expected_cadence_vector[i % expected_cadence_vector.size()], |
71 estimator->GetCadenceForFrame(i)); | 73 estimator->GetCadenceForFrame(i)); |
72 } | 74 } |
73 } | 75 } |
74 | 76 |
| 77 static void VerifyCadenceVectorWithCustomDrift( |
| 78 VideoCadenceEstimator* estimator, |
| 79 double frame_hertz, |
| 80 double render_hertz, |
| 81 base::TimeDelta acceptable_drift, |
| 82 const std::string& expected_cadence) { |
| 83 VerifyCadenceVectorWithCustomDeviationAndDrift( |
| 84 estimator, frame_hertz, render_hertz, base::TimeDelta(), acceptable_drift, |
| 85 expected_cadence); |
| 86 } |
| 87 |
| 88 static void VerifyCadenceVectorWithCustomDeviation( |
| 89 VideoCadenceEstimator* estimator, |
| 90 double frame_hertz, |
| 91 double render_hertz, |
| 92 base::TimeDelta deviation, |
| 93 const std::string& expected_cadence) { |
| 94 const base::TimeDelta acceptable_drift = |
| 95 std::max(Interval(frame_hertz) / 2, Interval(render_hertz)); |
| 96 VerifyCadenceVectorWithCustomDeviationAndDrift( |
| 97 estimator, frame_hertz, render_hertz, deviation, acceptable_drift, |
| 98 expected_cadence); |
| 99 } |
| 100 |
75 static void VerifyCadenceVector(VideoCadenceEstimator* estimator, | 101 static void VerifyCadenceVector(VideoCadenceEstimator* estimator, |
76 double frame_hertz, | 102 double frame_hertz, |
77 double render_hertz, | 103 double render_hertz, |
78 const std::string& expected_cadence) { | 104 const std::string& expected_cadence) { |
79 const base::TimeDelta acceptable_drift = | 105 const base::TimeDelta acceptable_drift = |
80 std::max(Interval(frame_hertz) / 2, Interval(render_hertz)); | 106 std::max(Interval(frame_hertz) / 2, Interval(render_hertz)); |
81 VerifyCadenceVectorWithCustomDrift(estimator, frame_hertz, render_hertz, | 107 VerifyCadenceVectorWithCustomDeviationAndDrift( |
82 acceptable_drift, expected_cadence); | 108 estimator, frame_hertz, render_hertz, base::TimeDelta(), acceptable_drift, |
| 109 expected_cadence); |
83 } | 110 } |
84 | 111 |
85 // Spot check common display and frame rate pairs for correctness. | 112 // Spot check common display and frame rate pairs for correctness. |
86 TEST(VideoCadenceEstimatorTest, CadenceCalculations) { | 113 TEST(VideoCadenceEstimatorTest, CadenceCalculations) { |
87 VideoCadenceEstimator estimator( | 114 VideoCadenceEstimator estimator( |
88 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs)); | 115 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs)); |
89 estimator.set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); | 116 estimator.set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); |
90 | 117 |
91 const std::string kEmptyCadence = "[]"; | 118 const std::string kEmptyCadence = "[]"; |
92 VerifyCadenceVector(&estimator, 1, NTSC(60), "[60]"); | 119 VerifyCadenceVector(&estimator, 1, NTSC(60), "[60]"); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 VerifyCadenceVectorWithCustomDrift(&estimator, NTSC(25), 60, drift, "[2]"); | 180 VerifyCadenceVectorWithCustomDrift(&estimator, NTSC(25), 60, drift, "[2]"); |
154 VerifyCadenceVectorWithCustomDrift(&estimator, 25, NTSC(60), drift, "[2]"); | 181 VerifyCadenceVectorWithCustomDrift(&estimator, 25, NTSC(60), drift, "[2]"); |
155 | 182 |
156 // Test cases for cadence below 1. | 183 // Test cases for cadence below 1. |
157 VerifyCadenceVectorWithCustomDrift(&estimator, 120, 24, drift, "[1]"); | 184 VerifyCadenceVectorWithCustomDrift(&estimator, 120, 24, drift, "[1]"); |
158 VerifyCadenceVectorWithCustomDrift(&estimator, 120, 48, drift, "[1]"); | 185 VerifyCadenceVectorWithCustomDrift(&estimator, 120, 48, drift, "[1]"); |
159 VerifyCadenceVectorWithCustomDrift(&estimator, 120, 72, drift, "[1]"); | 186 VerifyCadenceVectorWithCustomDrift(&estimator, 120, 72, drift, "[1]"); |
160 VerifyCadenceVectorWithCustomDrift(&estimator, 90, 60, drift, "[1]"); | 187 VerifyCadenceVectorWithCustomDrift(&estimator, 90, 60, drift, "[1]"); |
161 } | 188 } |
162 | 189 |
| 190 // Check the case that the estimator excludes variable FPS case from Cadence. |
| 191 TEST(VideoCadenceEstimatorTest, CadenceCalculationWithLargeDeviation) { |
| 192 VideoCadenceEstimator estimator( |
| 193 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs)); |
| 194 estimator.set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); |
| 195 |
| 196 const base::TimeDelta deviation = base::TimeDelta::FromMilliseconds(30); |
| 197 VerifyCadenceVectorWithCustomDeviation(&estimator, 1, 60, deviation, "[]"); |
| 198 VerifyCadenceVectorWithCustomDeviation(&estimator, 30, 60, deviation, "[]"); |
| 199 VerifyCadenceVectorWithCustomDeviation(&estimator, 25, 60, deviation, "[]"); |
| 200 |
| 201 // Test cases for cadence with low refresh rate. |
| 202 VerifyCadenceVectorWithCustomDeviation(&estimator, 60, 12, deviation, |
| 203 "[1:0:0:0:0]"); |
| 204 } |
| 205 |
163 TEST(VideoCadenceEstimatorTest, CadenceVariesWithAcceptableDrift) { | 206 TEST(VideoCadenceEstimatorTest, CadenceVariesWithAcceptableDrift) { |
164 VideoCadenceEstimator estimator( | 207 VideoCadenceEstimator estimator( |
165 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs)); | 208 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs)); |
166 estimator.set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); | 209 estimator.set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); |
167 | 210 |
168 const base::TimeDelta render_interval = Interval(NTSC(60)); | 211 const base::TimeDelta render_interval = Interval(NTSC(60)); |
169 const base::TimeDelta frame_interval = Interval(120); | 212 const base::TimeDelta frame_interval = Interval(120); |
170 | 213 |
171 base::TimeDelta acceptable_drift = frame_interval / 2; | 214 base::TimeDelta acceptable_drift = frame_interval / 2; |
172 EXPECT_FALSE(estimator.UpdateCadenceEstimate(render_interval, frame_interval, | 215 EXPECT_FALSE(estimator.UpdateCadenceEstimate( |
173 acceptable_drift)); | 216 render_interval, frame_interval, base::TimeDelta(), acceptable_drift)); |
174 EXPECT_FALSE(estimator.has_cadence()); | 217 EXPECT_FALSE(estimator.has_cadence()); |
175 | 218 |
176 // Increasing the acceptable drift should be result in more permissive | 219 // Increasing the acceptable drift should be result in more permissive |
177 // detection of cadence. | 220 // detection of cadence. |
178 acceptable_drift = render_interval; | 221 acceptable_drift = render_interval; |
179 EXPECT_TRUE(estimator.UpdateCadenceEstimate(render_interval, frame_interval, | 222 EXPECT_TRUE(estimator.UpdateCadenceEstimate( |
180 acceptable_drift)); | 223 render_interval, frame_interval, base::TimeDelta(), acceptable_drift)); |
181 EXPECT_TRUE(estimator.has_cadence()); | 224 EXPECT_TRUE(estimator.has_cadence()); |
182 EXPECT_EQ("[1:0]", estimator.GetCadenceForTesting()); | 225 EXPECT_EQ("[1:0]", estimator.GetCadenceForTesting()); |
183 } | 226 } |
184 | 227 |
185 TEST(VideoCadenceEstimatorTest, CadenceVariesWithAcceptableGlitchTime) { | 228 TEST(VideoCadenceEstimatorTest, CadenceVariesWithAcceptableGlitchTime) { |
186 scoped_ptr<VideoCadenceEstimator> estimator(new VideoCadenceEstimator( | 229 scoped_ptr<VideoCadenceEstimator> estimator(new VideoCadenceEstimator( |
187 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs))); | 230 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs))); |
188 estimator->set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); | 231 estimator->set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); |
189 | 232 |
190 const base::TimeDelta render_interval = Interval(NTSC(60)); | 233 const base::TimeDelta render_interval = Interval(NTSC(60)); |
191 const base::TimeDelta frame_interval = Interval(120); | 234 const base::TimeDelta frame_interval = Interval(120); |
192 const base::TimeDelta acceptable_drift = frame_interval / 2; | 235 const base::TimeDelta acceptable_drift = frame_interval / 2; |
193 | 236 |
194 EXPECT_FALSE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, | 237 EXPECT_FALSE(estimator->UpdateCadenceEstimate( |
195 acceptable_drift)); | 238 render_interval, frame_interval, base::TimeDelta(), acceptable_drift)); |
196 EXPECT_FALSE(estimator->has_cadence()); | 239 EXPECT_FALSE(estimator->has_cadence()); |
197 | 240 |
198 // Decreasing the acceptable glitch time should be result in more permissive | 241 // Decreasing the acceptable glitch time should be result in more permissive |
199 // detection of cadence. | 242 // detection of cadence. |
200 estimator.reset(new VideoCadenceEstimator(base::TimeDelta::FromSeconds( | 243 estimator.reset(new VideoCadenceEstimator(base::TimeDelta::FromSeconds( |
201 kMinimumAcceptableTimeBetweenGlitchesSecs / 2))); | 244 kMinimumAcceptableTimeBetweenGlitchesSecs / 2))); |
202 estimator->set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); | 245 estimator->set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); |
203 EXPECT_TRUE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, | 246 EXPECT_TRUE(estimator->UpdateCadenceEstimate( |
204 acceptable_drift)); | 247 render_interval, frame_interval, base::TimeDelta(), acceptable_drift)); |
205 EXPECT_TRUE(estimator->has_cadence()); | 248 EXPECT_TRUE(estimator->has_cadence()); |
206 EXPECT_EQ("[1:0]", estimator->GetCadenceForTesting()); | 249 EXPECT_EQ("[1:0]", estimator->GetCadenceForTesting()); |
207 } | 250 } |
208 | 251 |
209 TEST(VideoCadenceEstimatorTest, CadenceHystersisPreventsOscillation) { | 252 TEST(VideoCadenceEstimatorTest, CadenceHystersisPreventsOscillation) { |
210 scoped_ptr<VideoCadenceEstimator> estimator(new VideoCadenceEstimator( | 253 scoped_ptr<VideoCadenceEstimator> estimator(new VideoCadenceEstimator( |
211 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs))); | 254 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs))); |
212 | 255 |
213 const base::TimeDelta render_interval = Interval(30); | 256 const base::TimeDelta render_interval = Interval(30); |
214 const base::TimeDelta frame_interval = Interval(60); | 257 const base::TimeDelta frame_interval = Interval(60); |
215 const base::TimeDelta acceptable_drift = frame_interval / 2; | 258 const base::TimeDelta acceptable_drift = frame_interval / 2; |
216 estimator->set_cadence_hysteresis_threshold_for_testing(render_interval * 2); | 259 estimator->set_cadence_hysteresis_threshold_for_testing(render_interval * 2); |
217 | 260 |
218 // Cadence hysteresis should prevent the cadence from taking effect yet. | 261 // Cadence hysteresis should prevent the cadence from taking effect yet. |
219 EXPECT_FALSE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, | 262 EXPECT_FALSE(estimator->UpdateCadenceEstimate( |
220 acceptable_drift)); | 263 render_interval, frame_interval, base::TimeDelta(), acceptable_drift)); |
221 EXPECT_FALSE(estimator->has_cadence()); | 264 EXPECT_FALSE(estimator->has_cadence()); |
222 | 265 |
223 // A second call should exceed cadence hysteresis and take into effect. | 266 // A second call should exceed cadence hysteresis and take into effect. |
224 EXPECT_TRUE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, | 267 EXPECT_TRUE(estimator->UpdateCadenceEstimate( |
225 acceptable_drift)); | 268 render_interval, frame_interval, base::TimeDelta(), acceptable_drift)); |
226 EXPECT_TRUE(estimator->has_cadence()); | 269 EXPECT_TRUE(estimator->has_cadence()); |
227 | 270 |
228 // One bad interval shouldn't cause cadence to drop | 271 // One bad interval shouldn't cause cadence to drop |
229 EXPECT_FALSE(estimator->UpdateCadenceEstimate( | 272 EXPECT_FALSE( |
230 render_interval, frame_interval * 0.75, acceptable_drift)); | 273 estimator->UpdateCadenceEstimate(render_interval, frame_interval * 0.75, |
| 274 base::TimeDelta(), acceptable_drift)); |
231 EXPECT_TRUE(estimator->has_cadence()); | 275 EXPECT_TRUE(estimator->has_cadence()); |
232 | 276 |
233 // Resumption of cadence should clear bad interval count. | 277 // Resumption of cadence should clear bad interval count. |
234 EXPECT_FALSE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, | 278 EXPECT_FALSE(estimator->UpdateCadenceEstimate( |
235 acceptable_drift)); | 279 render_interval, frame_interval, base::TimeDelta(), acceptable_drift)); |
236 EXPECT_TRUE(estimator->has_cadence()); | 280 EXPECT_TRUE(estimator->has_cadence()); |
237 | 281 |
238 // So one more bad interval shouldn't cause cadence to drop | 282 // So one more bad interval shouldn't cause cadence to drop |
239 EXPECT_FALSE(estimator->UpdateCadenceEstimate( | 283 EXPECT_FALSE( |
240 render_interval, frame_interval * 0.75, acceptable_drift)); | 284 estimator->UpdateCadenceEstimate(render_interval, frame_interval * 0.75, |
| 285 base::TimeDelta(), acceptable_drift)); |
241 EXPECT_TRUE(estimator->has_cadence()); | 286 EXPECT_TRUE(estimator->has_cadence()); |
242 | 287 |
243 // Two bad intervals should. | 288 // Two bad intervals should. |
244 EXPECT_TRUE(estimator->UpdateCadenceEstimate( | 289 EXPECT_TRUE( |
245 render_interval, frame_interval * 0.75, acceptable_drift)); | 290 estimator->UpdateCadenceEstimate(render_interval, frame_interval * 0.75, |
| 291 base::TimeDelta(), acceptable_drift)); |
246 EXPECT_FALSE(estimator->has_cadence()); | 292 EXPECT_FALSE(estimator->has_cadence()); |
247 } | 293 } |
248 | 294 |
249 } // namespace media | 295 } // namespace media |
OLD | NEW |