OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/memory/scoped_ptr.h" |
| 6 #include "base/strings/stringprintf.h" |
| 7 #include "media/filters/video_cadence_estimator.h" |
| 8 #include "testing/gtest/include/gtest/gtest.h" |
| 9 |
| 10 namespace media { |
| 11 |
| 12 // See VideoCadenceEstimator header for more details. |
| 13 const int kMinimumAcceptableTimeBetweenGlitchesSecs = 8; |
| 14 |
| 15 // Slows down the given |fps| according to NTSC field reduction standards; see |
| 16 // http://en.wikipedia.org/wiki/Frame_rate#Digital_video_and_television |
| 17 static double NTSC(double fps) { |
| 18 return fps / 1.001; |
| 19 } |
| 20 |
| 21 static base::TimeDelta Interval(double hertz) { |
| 22 return base::TimeDelta::FromSecondsD(1.0 / hertz); |
| 23 } |
| 24 |
| 25 static void VerifyCadence(VideoCadenceEstimator* estimator, |
| 26 double frame_hertz, |
| 27 double render_hertz, |
| 28 int expected_cadence) { |
| 29 SCOPED_TRACE(base::StringPrintf("Checking %.03f fps into %0.03f", frame_hertz, |
| 30 render_hertz)); |
| 31 estimator->Reset(); |
| 32 const base::TimeDelta acceptable_drift = Interval(frame_hertz) / 2; |
| 33 const bool cadence_changed = estimator->UpdateCadenceEstimate( |
| 34 Interval(render_hertz), Interval(frame_hertz), acceptable_drift); |
| 35 EXPECT_EQ(cadence_changed, estimator->has_cadence()); |
| 36 EXPECT_EQ(!!expected_cadence, estimator->has_cadence()); |
| 37 |
| 38 // Nothing further to test. |
| 39 if (!expected_cadence) |
| 40 return; |
| 41 |
| 42 // Spot check a few frame indices. |
| 43 if (frame_hertz <= render_hertz) { |
| 44 EXPECT_EQ(expected_cadence, estimator->GetCadenceForFrame(0)); |
| 45 EXPECT_EQ(expected_cadence, estimator->GetCadenceForFrame(1)); |
| 46 EXPECT_EQ(expected_cadence, estimator->GetCadenceForFrame(2)); |
| 47 } else { |
| 48 EXPECT_EQ(1, estimator->GetCadenceForFrame(0)); |
| 49 EXPECT_EQ(0, estimator->GetCadenceForFrame(1)); |
| 50 EXPECT_EQ(1, estimator->GetCadenceForFrame(expected_cadence)); |
| 51 EXPECT_EQ(0, estimator->GetCadenceForFrame(expected_cadence + 1)); |
| 52 } |
| 53 } |
| 54 |
| 55 // Spot check common display and frame rate pairs for correctness. |
| 56 TEST(VideoCadenceEstimatorTest, CadenceCalculations) { |
| 57 VideoCadenceEstimator estimator( |
| 58 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs)); |
| 59 estimator.set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); |
| 60 |
| 61 VerifyCadence(&estimator, 24, 60, 0); |
| 62 VerifyCadence(&estimator, NTSC(24), 60, 0); |
| 63 VerifyCadence(&estimator, 25, 60, 0); |
| 64 VerifyCadence(&estimator, NTSC(30), 60, 2); |
| 65 VerifyCadence(&estimator, 30, 60, 2); |
| 66 VerifyCadence(&estimator, 50, 60, 0); |
| 67 VerifyCadence(&estimator, NTSC(60), 60, 1); |
| 68 VerifyCadence(&estimator, 120, 60, 2); |
| 69 |
| 70 // 50Hz is common in the EU. |
| 71 VerifyCadence(&estimator, NTSC(24), 50, 0); |
| 72 VerifyCadence(&estimator, 24, 50, 0); |
| 73 VerifyCadence(&estimator, NTSC(25), 50, 2); |
| 74 VerifyCadence(&estimator, 25, 50, 2); |
| 75 VerifyCadence(&estimator, NTSC(30), 50, 0); |
| 76 VerifyCadence(&estimator, 30, 50, 0); |
| 77 VerifyCadence(&estimator, NTSC(60), 50, 0); |
| 78 VerifyCadence(&estimator, 60, 50, 0); |
| 79 |
| 80 VerifyCadence(&estimator, 25, NTSC(60), 0); |
| 81 VerifyCadence(&estimator, 120, NTSC(60), 0); |
| 82 VerifyCadence(&estimator, 1, NTSC(60), 60); |
| 83 } |
| 84 |
| 85 TEST(VideoCadenceEstimatorTest, CadenceVariesWithAcceptableDrift) { |
| 86 VideoCadenceEstimator estimator( |
| 87 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs)); |
| 88 estimator.set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); |
| 89 |
| 90 const base::TimeDelta render_interval = Interval(NTSC(60)); |
| 91 const base::TimeDelta frame_interval = Interval(120); |
| 92 |
| 93 base::TimeDelta acceptable_drift = frame_interval / 2; |
| 94 EXPECT_FALSE(estimator.UpdateCadenceEstimate(render_interval, frame_interval, |
| 95 acceptable_drift)); |
| 96 EXPECT_FALSE(estimator.has_cadence()); |
| 97 |
| 98 // Increasing the acceptable drift should be result in more permissive |
| 99 // detection of cadence. |
| 100 acceptable_drift = render_interval; |
| 101 EXPECT_TRUE(estimator.UpdateCadenceEstimate(render_interval, frame_interval, |
| 102 acceptable_drift)); |
| 103 EXPECT_TRUE(estimator.has_cadence()); |
| 104 EXPECT_EQ(2, estimator.get_cadence_for_testing()); |
| 105 } |
| 106 |
| 107 TEST(VideoCadenceEstimatorTest, CadenceVariesWithAcceptableGlitchTime) { |
| 108 scoped_ptr<VideoCadenceEstimator> estimator(new VideoCadenceEstimator( |
| 109 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs))); |
| 110 estimator->set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); |
| 111 |
| 112 const base::TimeDelta render_interval = Interval(NTSC(60)); |
| 113 const base::TimeDelta frame_interval = Interval(120); |
| 114 const base::TimeDelta acceptable_drift = frame_interval / 2; |
| 115 |
| 116 EXPECT_FALSE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, |
| 117 acceptable_drift)); |
| 118 EXPECT_FALSE(estimator->has_cadence()); |
| 119 |
| 120 // Decreasing the acceptable glitch time should be result in more permissive |
| 121 // detection of cadence. |
| 122 estimator.reset(new VideoCadenceEstimator(base::TimeDelta::FromSeconds( |
| 123 kMinimumAcceptableTimeBetweenGlitchesSecs / 2))); |
| 124 estimator->set_cadence_hysteresis_threshold_for_testing(base::TimeDelta()); |
| 125 EXPECT_TRUE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, |
| 126 acceptable_drift)); |
| 127 EXPECT_TRUE(estimator->has_cadence()); |
| 128 EXPECT_EQ(2, estimator->get_cadence_for_testing()); |
| 129 } |
| 130 |
| 131 TEST(VideoCadenceEstimatorTest, CadenceHystersisPreventsOscillation) { |
| 132 scoped_ptr<VideoCadenceEstimator> estimator(new VideoCadenceEstimator( |
| 133 base::TimeDelta::FromSeconds(kMinimumAcceptableTimeBetweenGlitchesSecs))); |
| 134 |
| 135 const base::TimeDelta render_interval = Interval(30); |
| 136 const base::TimeDelta frame_interval = Interval(60); |
| 137 const base::TimeDelta acceptable_drift = frame_interval / 2; |
| 138 estimator->set_cadence_hysteresis_threshold_for_testing(render_interval * 2); |
| 139 |
| 140 // Cadence hysteresis should prevent the cadence from taking effect yet. |
| 141 EXPECT_FALSE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, |
| 142 acceptable_drift)); |
| 143 EXPECT_FALSE(estimator->has_cadence()); |
| 144 |
| 145 // A second call should exceed cadence hysteresis and take into effect. |
| 146 EXPECT_TRUE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, |
| 147 acceptable_drift)); |
| 148 EXPECT_TRUE(estimator->has_cadence()); |
| 149 |
| 150 // One bad interval shouldn't cause cadence to drop |
| 151 EXPECT_FALSE(estimator->UpdateCadenceEstimate( |
| 152 render_interval, frame_interval * 0.75, acceptable_drift)); |
| 153 EXPECT_TRUE(estimator->has_cadence()); |
| 154 |
| 155 // Resumption of cadence should clear bad interval count. |
| 156 EXPECT_FALSE(estimator->UpdateCadenceEstimate(render_interval, frame_interval, |
| 157 acceptable_drift)); |
| 158 EXPECT_TRUE(estimator->has_cadence()); |
| 159 |
| 160 // So one more bad interval shouldn't cause cadence to drop |
| 161 EXPECT_FALSE(estimator->UpdateCadenceEstimate( |
| 162 render_interval, frame_interval * 0.75, acceptable_drift)); |
| 163 EXPECT_TRUE(estimator->has_cadence()); |
| 164 |
| 165 // Two bad intervals should. |
| 166 EXPECT_TRUE(estimator->UpdateCadenceEstimate( |
| 167 render_interval, frame_interval * 0.75, acceptable_drift)); |
| 168 EXPECT_FALSE(estimator->has_cadence()); |
| 169 } |
| 170 |
| 171 } // namespace media |
OLD | NEW |