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 sample average 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.1; | |
DaleCurtis
2015/11/20 23:50:46
Your variable frame rate clip was 0.7? If so it se
qiangchen
2015/11/25 18:06:33
Simply excluding that extreme case may not be opti
DaleCurtis
2015/11/25 21:29:24
Sure, but I think we want to err on the side of ca
qiangchen
2015/12/01 19:37:53
Done.
| |
28 const double kConstantFPSFactor = 0.07; | |
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.InMillisecondsF() > | |
102 kVariableFPSFactor * frame_duration.InMillisecondsF()) { | |
103 is_variable_frame_rate_ = true; | |
104 } else if (frame_duration_deviation.InMillisecondsF() < | |
105 kConstantFPSFactor * frame_duration.InMillisecondsF()) { | |
106 is_variable_frame_rate_ = false; | |
107 } | |
108 | |
109 // Variable FPS detected, turn off Cadence by force. | |
110 if (is_variable_frame_rate_) { | |
111 render_intervals_cadence_held_ = 0; | |
112 if (cadence_ != Cadence()) { | |
DaleCurtis
2015/11/20 23:50:46
if !cadence_.empty() cadence_.clear()
qiangchen
2015/11/25 18:06:33
Done.
| |
113 cadence_ = Cadence(); | |
114 return true; | |
115 } | |
116 return false; | |
117 } | |
118 | |
90 base::TimeDelta time_until_max_drift; | 119 base::TimeDelta time_until_max_drift; |
91 | 120 |
92 // See if we can find a cadence which fits the data. | 121 // See if we can find a cadence which fits the data. |
93 Cadence new_cadence = | 122 Cadence new_cadence = |
94 CalculateCadence(render_interval, frame_duration, max_acceptable_drift, | 123 CalculateCadence(render_interval, frame_duration, max_acceptable_drift, |
95 &time_until_max_drift); | 124 &time_until_max_drift); |
96 | 125 |
97 // If this is the first time UpdateCadenceEstimate() has been called, | 126 // If this is the first time UpdateCadenceEstimate() has been called, |
98 // initialize the histogram with a zero count for cadence changes; this | 127 // 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. | 128 // 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 | 254 |
226 std::ostringstream os; | 255 std::ostringstream os; |
227 os << "["; | 256 os << "["; |
228 std::copy(cadence.begin(), cadence.end() - 1, | 257 std::copy(cadence.begin(), cadence.end() - 1, |
229 std::ostream_iterator<int>(os, ":")); | 258 std::ostream_iterator<int>(os, ":")); |
230 os << cadence.back() << "]"; | 259 os << cadence.back() << "]"; |
231 return os.str(); | 260 return os.str(); |
232 } | 261 } |
233 | 262 |
234 } // namespace media | 263 } // namespace media |
OLD | NEW |