Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1102)

Side by Side Diff: media/filters/video_cadence_estimator_unittest.cc

Issue 1459923003: Fix Bug: Video with Variable Frame Rate plays at incorrect speed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/filters/video_cadence_estimator.cc ('k') | media/filters/video_renderer_algorithm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « media/filters/video_cadence_estimator.cc ('k') | media/filters/video_renderer_algorithm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698