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 "media/filters/video_cadence_estimator.h" | 5 #include "media/filters/video_cadence_estimator.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <iterator> | 9 #include <iterator> |
10 #include <limits> | 10 #include <limits> |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
14 | 14 |
15 namespace media { | 15 namespace media { |
16 | 16 |
17 // To prevent oscillation in and out of cadence or between cadence values, we | 17 // To prevent oscillation in and out of cadence or between cadence values, we |
18 // require some time to elapse before a cadence switch is accepted. | 18 // require some time to elapse before a cadence switch is accepted. |
19 const int kMinimumCadenceDurationMs = 100; | 19 const int kMinimumCadenceDurationMs = 100; |
20 | 20 |
| 21 // The numbers are used to decide whether the current video is variable FPS or |
| 22 // constant FPS. If ratio of the sample deviation and the render length is |
| 23 // above |kVariableFPSFactor|, then it is recognized as a variable FPS, and if |
| 24 // the ratio is below |kConstantFPSFactor|, then it is recognized as a constant |
| 25 // FPS, and if the ratio is in between the two factors, then we do not change |
| 26 // previous recognition. |
| 27 const double kVariableFPSFactor = 0.55; |
| 28 const double kConstantFPSFactor = 0.45; |
| 29 |
21 // Records the number of cadence changes to UMA. | 30 // Records the number of cadence changes to UMA. |
22 static void HistogramCadenceChangeCount(int cadence_changes) { | 31 static void HistogramCadenceChangeCount(int cadence_changes) { |
23 const int kCadenceChangeMax = 10; | 32 const int kCadenceChangeMax = 10; |
24 UMA_HISTOGRAM_CUSTOM_COUNTS("Media.VideoRenderer.CadenceChanges", | 33 UMA_HISTOGRAM_CUSTOM_COUNTS("Media.VideoRenderer.CadenceChanges", |
25 cadence_changes, 0, kCadenceChangeMax, | 34 cadence_changes, 0, kCadenceChangeMax, |
26 kCadenceChangeMax); | 35 kCadenceChangeMax); |
27 } | 36 } |
28 | 37 |
29 // Construct a Cadence vector, a vector of integers satisfying the following | 38 // Construct a Cadence vector, a vector of integers satisfying the following |
30 // conditions: | 39 // conditions: |
(...skipping 28 matching lines...) Expand all Loading... |
59 actual_accumulate += output[i] * n; | 68 actual_accumulate += output[i] * n; |
60 } | 69 } |
61 | 70 |
62 return output; | 71 return output; |
63 } | 72 } |
64 | 73 |
65 VideoCadenceEstimator::VideoCadenceEstimator( | 74 VideoCadenceEstimator::VideoCadenceEstimator( |
66 base::TimeDelta minimum_time_until_max_drift) | 75 base::TimeDelta minimum_time_until_max_drift) |
67 : cadence_hysteresis_threshold_( | 76 : cadence_hysteresis_threshold_( |
68 base::TimeDelta::FromMilliseconds(kMinimumCadenceDurationMs)), | 77 base::TimeDelta::FromMilliseconds(kMinimumCadenceDurationMs)), |
69 minimum_time_until_max_drift_(minimum_time_until_max_drift) { | 78 minimum_time_until_max_drift_(minimum_time_until_max_drift), |
| 79 is_variable_frame_rate_(false) { |
70 Reset(); | 80 Reset(); |
71 } | 81 } |
72 | 82 |
73 VideoCadenceEstimator::~VideoCadenceEstimator() { | 83 VideoCadenceEstimator::~VideoCadenceEstimator() { |
74 } | 84 } |
75 | 85 |
76 void VideoCadenceEstimator::Reset() { | 86 void VideoCadenceEstimator::Reset() { |
77 cadence_.clear(); | 87 cadence_.clear(); |
78 pending_cadence_.clear(); | 88 pending_cadence_.clear(); |
79 cadence_changes_ = render_intervals_cadence_held_ = 0; | 89 cadence_changes_ = render_intervals_cadence_held_ = 0; |
80 first_update_call_ = true; | 90 first_update_call_ = true; |
81 } | 91 } |
82 | 92 |
83 bool VideoCadenceEstimator::UpdateCadenceEstimate( | 93 bool VideoCadenceEstimator::UpdateCadenceEstimate( |
84 base::TimeDelta render_interval, | 94 base::TimeDelta render_interval, |
85 base::TimeDelta frame_duration, | 95 base::TimeDelta frame_duration, |
| 96 base::TimeDelta frame_duration_deviation, |
86 base::TimeDelta max_acceptable_drift) { | 97 base::TimeDelta max_acceptable_drift) { |
87 DCHECK_GT(render_interval, base::TimeDelta()); | 98 DCHECK_GT(render_interval, base::TimeDelta()); |
88 DCHECK_GT(frame_duration, base::TimeDelta()); | 99 DCHECK_GT(frame_duration, base::TimeDelta()); |
89 | 100 |
| 101 if (frame_duration_deviation > kVariableFPSFactor * render_interval) { |
| 102 is_variable_frame_rate_ = true; |
| 103 } else if (frame_duration_deviation < kConstantFPSFactor * render_interval) { |
| 104 is_variable_frame_rate_ = false; |
| 105 } |
| 106 |
| 107 // Variable FPS detected, turn off Cadence by force. |
| 108 if (is_variable_frame_rate_) { |
| 109 render_intervals_cadence_held_ = 0; |
| 110 if (!cadence_.empty()) { |
| 111 cadence_.clear(); |
| 112 return true; |
| 113 } |
| 114 return false; |
| 115 } |
| 116 |
90 base::TimeDelta time_until_max_drift; | 117 base::TimeDelta time_until_max_drift; |
91 | 118 |
92 // See if we can find a cadence which fits the data. | 119 // See if we can find a cadence which fits the data. |
93 Cadence new_cadence = | 120 Cadence new_cadence = |
94 CalculateCadence(render_interval, frame_duration, max_acceptable_drift, | 121 CalculateCadence(render_interval, frame_duration, max_acceptable_drift, |
95 &time_until_max_drift); | 122 &time_until_max_drift); |
96 | 123 |
97 // If this is the first time UpdateCadenceEstimate() has been called, | 124 // If this is the first time UpdateCadenceEstimate() has been called, |
98 // initialize the histogram with a zero count for cadence changes; this | 125 // initialize the histogram with a zero count for cadence changes; this |
99 // allows us to track the number of playbacks which have cadence at all. | 126 // allows us to track the number of playbacks which have cadence at all. |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 | 252 |
226 std::ostringstream os; | 253 std::ostringstream os; |
227 os << "["; | 254 os << "["; |
228 std::copy(cadence.begin(), cadence.end() - 1, | 255 std::copy(cadence.begin(), cadence.end() - 1, |
229 std::ostream_iterator<int>(os, ":")); | 256 std::ostream_iterator<int>(os, ":")); |
230 os << cadence.back() << "]"; | 257 os << cadence.back() << "]"; |
231 return os.str(); | 258 return os.str(); |
232 } | 259 } |
233 | 260 |
234 } // namespace media | 261 } // namespace media |
OLD | NEW |