OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/video_coding/utility/frame_dropper.h" | 11 #include "webrtc/modules/video_coding/utility/frame_dropper.h" |
12 | 12 |
13 #include <algorithm> | |
14 | |
15 #include "webrtc/base/logging.h" | |
13 #include "webrtc/system_wrappers/include/trace.h" | 16 #include "webrtc/system_wrappers/include/trace.h" |
14 | 17 |
15 namespace webrtc { | 18 namespace webrtc { |
16 | 19 |
17 const float kDefaultKeyFrameSizeAvgKBits = 0.9f; | 20 namespace { |
18 const float kDefaultKeyFrameRatio = 0.99f; | 21 |
22 const float kDefaultFrameSizeAlpha = 0.9f; | |
23 const float kDefaultKeyFrameRatioAlpha = 0.99f; | |
24 // 1 key frame every 10th second in 30 fps. | |
25 const float kDefaultKeyFrameRatioValue = 1 / 300.0f; | |
26 | |
19 const float kDefaultDropRatioAlpha = 0.9f; | 27 const float kDefaultDropRatioAlpha = 0.9f; |
20 const float kDefaultDropRatioMax = 0.96f; | 28 const float kDefaultDropRatioValue = 0.96f; |
21 const float kDefaultMaxTimeToDropFrames = 4.0f; // In seconds. | 29 // Maximum duration over which frames are continuously dropped. |
30 const float kDefaultMaxDropDurationSecs = 4.0f; | |
31 | |
32 // Default target bitrate. | |
33 // TODO(isheriff): Should this be higher to avoid dropping too many packets when | |
34 // the bandwidth is unknown at the start ? | |
35 const float kDefaultTargetBitrateKbps = 300.0f; | |
36 const float kDefaultIncomingFrameRate = 30; | |
37 const float kLeakyBucketSizeSeconds = 0.5f; | |
38 | |
39 // Cap on the frame size accumulator to prevent excessive drops. | |
40 const float kAccumulatorCapBufferSizeSecs = 3.0f; | |
41 } // namespace | |
22 | 42 |
23 FrameDropper::FrameDropper() | 43 FrameDropper::FrameDropper() |
24 : _keyFrameSizeAvgKbits(kDefaultKeyFrameSizeAvgKBits), | 44 : key_frame_size_avg_kbits_(kDefaultFrameSizeAlpha), |
25 _keyFrameRatio(kDefaultKeyFrameRatio), | 45 key_frame_ratio_(kDefaultKeyFrameRatioAlpha), |
26 _dropRatio(kDefaultDropRatioAlpha, kDefaultDropRatioMax), | 46 delta_frame_size_avg_kbits_(kDefaultFrameSizeAlpha), |
27 _enabled(true), | 47 drop_ratio_(kDefaultDropRatioAlpha, kDefaultDropRatioValue), |
28 _max_time_drops(kDefaultMaxTimeToDropFrames) { | 48 enabled_(true), |
49 max_drop_duration_secs_(kDefaultMaxDropDurationSecs) { | |
29 Reset(); | 50 Reset(); |
30 } | 51 } |
31 | 52 |
32 FrameDropper::FrameDropper(float max_time_drops) | 53 FrameDropper::FrameDropper(float max_drop_duration_secs) |
33 : _keyFrameSizeAvgKbits(kDefaultKeyFrameSizeAvgKBits), | 54 : key_frame_size_avg_kbits_(kDefaultFrameSizeAlpha), |
34 _keyFrameRatio(kDefaultKeyFrameRatio), | 55 key_frame_ratio_(kDefaultKeyFrameRatioAlpha), |
35 _dropRatio(kDefaultDropRatioAlpha, kDefaultDropRatioMax), | 56 delta_frame_size_avg_kbits_(kDefaultFrameSizeAlpha), |
36 _enabled(true), | 57 drop_ratio_(kDefaultDropRatioAlpha, kDefaultDropRatioValue), |
37 _max_time_drops(max_time_drops) { | 58 enabled_(true), |
59 max_drop_duration_secs_(max_drop_duration_secs) { | |
38 Reset(); | 60 Reset(); |
39 } | 61 } |
40 | 62 |
41 void FrameDropper::Reset() { | 63 void FrameDropper::Reset() { |
42 _keyFrameRatio.Reset(0.99f); | 64 key_frame_ratio_.Reset(kDefaultKeyFrameRatioAlpha); |
43 _keyFrameRatio.Apply( | 65 key_frame_ratio_.Apply(1.0f, kDefaultKeyFrameRatioValue); |
44 1.0f, 1.0f / 300.0f); // 1 key frame every 10th second in 30 fps | 66 key_frame_size_avg_kbits_.Reset(kDefaultFrameSizeAlpha); |
45 _keyFrameSizeAvgKbits.Reset(0.9f); | 67 delta_frame_size_avg_kbits_.Reset(kDefaultFrameSizeAlpha); |
46 _keyFrameCount = 0; | 68 |
47 _accumulator = 0.0f; | 69 accumulator_ = 0.0f; |
48 _accumulatorMax = 150.0f; // assume 300 kb/s and 0.5 s window | 70 accumulator_max_ = kDefaultTargetBitrateKbps / 2; |
49 _targetBitRate = 300.0f; | 71 target_bitrate_ = kDefaultTargetBitrateKbps; |
50 _incoming_frame_rate = 30; | 72 incoming_frame_rate_ = kDefaultIncomingFrameRate; |
51 _keyFrameSpreadFrames = 0.5f * _incoming_frame_rate; | 73 |
52 _dropNext = false; | 74 large_frame_accumulation_count_ = 0; |
53 _dropRatio.Reset(0.9f); | 75 large_frame_accumulation_spread_ = 0.5 * kDefaultIncomingFrameRate; |
54 _dropRatio.Apply(0.0f, 0.0f); // Initialize to 0 | 76 |
55 _dropCount = 0; | 77 drop_next_ = false; |
56 _windowSize = 0.5f; | 78 drop_ratio_.Reset(0.9f); |
57 _wasBelowMax = true; | 79 drop_ratio_.Apply(0.0f, 0.0f); |
58 _fastMode = false; // start with normal (non-aggressive) mode | 80 drop_count_ = 0; |
59 // Cap for the encoder buffer level/accumulator, in secs. | 81 was_below_max_ = true; |
60 _cap_buffer_size = 3.0f; | |
61 // Cap on maximum amount of dropped frames between kept frames, in secs. | |
62 _max_time_drops = 4.0f; | |
63 } | 82 } |
64 | 83 |
65 void FrameDropper::Enable(bool enable) { | 84 void FrameDropper::Enable(bool enable) { |
66 _enabled = enable; | 85 enabled_ = enable; |
67 } | 86 } |
68 | 87 |
69 void FrameDropper::Fill(size_t frameSizeBytes, bool deltaFrame) { | 88 void FrameDropper::Fill(size_t framesize_bytes, bool delta_frame) { |
70 if (!_enabled) { | 89 if (!enabled_) { |
71 return; | 90 return; |
72 } | 91 } |
73 float frameSizeKbits = 8.0f * static_cast<float>(frameSizeBytes) / 1000.0f; | 92 float framesize_kbits = 8.0f * static_cast<float>(framesize_bytes) / 1000.0f; |
74 if (!deltaFrame && | 93 if (!delta_frame) { |
75 !_fastMode) { // fast mode does not treat key-frames any different | 94 key_frame_size_avg_kbits_.Apply(1, framesize_kbits); |
76 _keyFrameSizeAvgKbits.Apply(1, frameSizeKbits); | 95 key_frame_ratio_.Apply(1.0, 1.0); |
77 _keyFrameRatio.Apply(1.0, 1.0); | 96 if (framesize_kbits > key_frame_size_avg_kbits_.filtered()) { |
78 if (frameSizeKbits > _keyFrameSizeAvgKbits.filtered()) { | |
79 // Remove the average key frame size since we | 97 // Remove the average key frame size since we |
80 // compensate for key frames when adding delta | 98 // compensate for key frames when adding delta |
81 // frames. | 99 // frames. |
82 frameSizeKbits -= _keyFrameSizeAvgKbits.filtered(); | 100 framesize_kbits -= key_frame_size_avg_kbits_.filtered(); |
83 } else { | 101 } else { |
84 // Shouldn't be negative, so zero is the lower bound. | 102 // Shouldn't be negative, so zero is the lower bound. |
85 frameSizeKbits = 0; | 103 framesize_kbits = 0; |
86 } | 104 } |
87 if (_keyFrameRatio.filtered() > 1e-5 && | 105 if (key_frame_ratio_.filtered() > 1e-5 && |
88 1 / _keyFrameRatio.filtered() < _keyFrameSpreadFrames) { | 106 1 / key_frame_ratio_.filtered() < large_frame_accumulation_spread_) { |
89 // We are sending key frames more often than our upper bound for | 107 large_frame_accumulation_count_ = |
90 // how much we allow the key frame compensation to be spread | 108 static_cast<int32_t>(1 / key_frame_ratio_.filtered() + 0.5); |
91 // out in time. Therefor we must use the key frame ratio rather | 109 } else { |
92 // than keyFrameSpreadFrames. | 110 large_frame_accumulation_count_ = |
93 _keyFrameCount = | 111 static_cast<int32_t>(large_frame_accumulation_spread_ + 0.5); |
94 static_cast<int32_t>(1 / _keyFrameRatio.filtered() + 0.5); | 112 } |
95 } else { | 113 large_frame_accumulation_chunk_size_ = |
96 // Compensate for the key frame the following frames | 114 key_frame_size_avg_kbits_.filtered() / large_frame_accumulation_count_; |
97 _keyFrameCount = static_cast<int32_t>(_keyFrameSpreadFrames + 0.5); | |
98 } | |
99 } else { | 115 } else { |
100 // Decrease the keyFrameRatio | 116 // Identify if it is a unusually large delta frame and spread accumulation |
101 _keyFrameRatio.Apply(1.0, 0.0); | 117 // if that is the case. |
118 if (delta_frame_size_avg_kbits_.filtered() != -1 && | |
119 framesize_kbits > 3 * delta_frame_size_avg_kbits_.filtered() && | |
sprang_webrtc
2016/03/03 11:50:26
Named constant for 3.
| |
120 large_frame_accumulation_count_ == 0) { | |
121 large_frame_accumulation_count_ = | |
122 static_cast<int32_t>(large_frame_accumulation_spread_ + 0.5); | |
123 large_frame_accumulation_chunk_size_ = | |
124 framesize_kbits / large_frame_accumulation_count_; | |
125 framesize_kbits = 0; | |
126 } else { | |
127 delta_frame_size_avg_kbits_.Apply(1, framesize_kbits); | |
128 key_frame_ratio_.Apply(1.0, 0.0); | |
129 } | |
102 } | 130 } |
103 // Change the level of the accumulator (bucket) | 131 // Change the level of the accumulator (bucket) |
104 _accumulator += frameSizeKbits; | 132 accumulator_ += framesize_kbits; |
105 CapAccumulator(); | 133 CapAccumulator(); |
106 } | 134 LOG(LS_VERBOSE) << "FILL acc " << accumulator_ << " max " << accumulator_max_ |
107 | 135 << " count " << large_frame_accumulation_count_ << " chunk " |
108 void FrameDropper::Leak(uint32_t inputFrameRate) { | 136 << large_frame_accumulation_chunk_size_ << " spread " |
109 if (!_enabled) { | 137 << large_frame_accumulation_spread_ << " key avg " |
110 return; | 138 << key_frame_size_avg_kbits_.filtered() << " delta avg " |
111 } | 139 << delta_frame_size_avg_kbits_.filtered() << " SIZE " |
112 if (inputFrameRate < 1) { | 140 << framesize_kbits; |
113 return; | 141 } |
114 } | 142 |
115 if (_targetBitRate < 0.0f) { | 143 void FrameDropper::Leak(uint32_t input_framerate) { |
116 return; | 144 if (!enabled_) { |
117 } | 145 return; |
118 _keyFrameSpreadFrames = 0.5f * inputFrameRate; | 146 } |
119 // T is the expected bits per frame (target). If all frames were the same | 147 if (input_framerate < 1) { |
120 // size, | 148 return; |
121 // we would get T bits per frame. Notice that T is also weighted to be able to | 149 } |
122 // force a lower frame rate if wanted. | 150 if (target_bitrate_ < 0.0f) { |
123 float T = _targetBitRate / inputFrameRate; | 151 return; |
124 if (_keyFrameCount > 0) { | 152 } |
125 // Perform the key frame compensation | 153 // Add lower bound for large frame accumulation spread. |
126 if (_keyFrameRatio.filtered() > 0 && | 154 large_frame_accumulation_spread_ = std::max(0.5 * input_framerate, 5.0); |
127 1 / _keyFrameRatio.filtered() < _keyFrameSpreadFrames) { | 155 // Expected bits per frame based on current input frame rate. |
128 T -= _keyFrameSizeAvgKbits.filtered() * _keyFrameRatio.filtered(); | 156 float expected_bits_per_frame = target_bitrate_ / input_framerate; |
129 } else { | 157 if (large_frame_accumulation_count_ > 0) { |
130 T -= _keyFrameSizeAvgKbits.filtered() / _keyFrameSpreadFrames; | 158 expected_bits_per_frame -= large_frame_accumulation_chunk_size_; |
131 } | 159 large_frame_accumulation_count_--; |
stefan-webrtc
2016/03/01 15:14:34
--large_frame...;
Irfan
2016/03/04 07:58:49
Done.
| |
132 _keyFrameCount--; | 160 } |
133 } | 161 accumulator_ -= expected_bits_per_frame; |
134 _accumulator -= T; | 162 if (accumulator_ < 0.0f) { |
135 if (_accumulator < 0.0f) { | 163 accumulator_ = 0.0f; |
136 _accumulator = 0.0f; | 164 } |
137 } | 165 LOG(LS_VERBOSE) << " LEAK acc " << accumulator_ << " max " << accumulator_max_ |
stefan-webrtc
2016/03/01 15:14:34
Remove space before LEAK
Irfan
2016/03/04 07:58:49
Done.
| |
166 << " count " << large_frame_accumulation_count_ << " spread " | |
167 << large_frame_accumulation_spread_ << " key avg " | |
168 << key_frame_size_avg_kbits_.filtered() << " delta avg " | |
169 << delta_frame_size_avg_kbits_.filtered(); | |
138 UpdateRatio(); | 170 UpdateRatio(); |
139 } | 171 } |
140 | 172 |
141 void FrameDropper::UpdateNack(uint32_t nackBytes) { | |
142 if (!_enabled) { | |
143 return; | |
144 } | |
145 _accumulator += static_cast<float>(nackBytes) * 8.0f / 1000.0f; | |
146 } | |
147 | |
148 void FrameDropper::FillBucket(float inKbits, float outKbits) { | |
149 _accumulator += (inKbits - outKbits); | |
150 } | |
151 | |
152 void FrameDropper::UpdateRatio() { | 173 void FrameDropper::UpdateRatio() { |
153 if (_accumulator > 1.3f * _accumulatorMax) { | 174 if (accumulator_ > 1.3f * accumulator_max_) { |
154 // Too far above accumulator max, react faster | 175 // Too far above accumulator max, react faster |
155 _dropRatio.UpdateBase(0.8f); | 176 drop_ratio_.UpdateBase(0.8f); |
156 } else { | 177 } else { |
157 // Go back to normal reaction | 178 // Go back to normal reaction |
158 _dropRatio.UpdateBase(0.9f); | 179 drop_ratio_.UpdateBase(0.9f); |
159 } | 180 } |
160 if (_accumulator > _accumulatorMax) { | 181 if (accumulator_ > accumulator_max_) { |
161 // We are above accumulator max, and should ideally | 182 // We are above accumulator max, and should ideally |
162 // drop a frame. Increase the dropRatio and drop | 183 // drop a frame. Increase the dropRatio and drop |
163 // the frame later. | 184 // the frame later. |
164 if (_wasBelowMax) { | 185 if (was_below_max_) { |
165 _dropNext = true; | 186 drop_next_ = true; |
166 } | 187 } |
167 if (_fastMode) { | 188 drop_ratio_.Apply(1.0f, 1.0f); |
168 // always drop in aggressive mode | 189 drop_ratio_.UpdateBase(0.9f); |
169 _dropNext = true; | |
170 } | |
171 | |
172 _dropRatio.Apply(1.0f, 1.0f); | |
173 _dropRatio.UpdateBase(0.9f); | |
174 } else { | 190 } else { |
175 _dropRatio.Apply(1.0f, 0.0f); | 191 drop_ratio_.Apply(1.0f, 0.0f); |
176 } | 192 } |
177 _wasBelowMax = _accumulator < _accumulatorMax; | 193 was_below_max_ = accumulator_ < accumulator_max_; |
178 } | 194 } |
179 | 195 |
180 // This function signals when to drop frames to the caller. It makes use of the | 196 // This function signals when to drop frames to the caller. It makes use of the |
181 // dropRatio | 197 // dropRatio |
182 // to smooth out the drops over time. | 198 // to smooth out the drops over time. |
183 bool FrameDropper::DropFrame() { | 199 bool FrameDropper::DropFrame() { |
184 if (!_enabled) { | 200 if (!enabled_) { |
185 return false; | 201 return false; |
186 } | 202 } |
187 if (_dropNext) { | 203 if (drop_next_) { |
188 _dropNext = false; | 204 drop_next_ = false; |
189 _dropCount = 0; | 205 drop_count_ = 0; |
190 } | 206 } |
191 | 207 LOG(LS_VERBOSE) << " drop_ratio_ " << drop_ratio_.filtered() |
192 if (_dropRatio.filtered() >= 0.5f) { // Drops per keep | 208 << " drop_count_ " << drop_count_; |
209 | |
210 if (drop_ratio_.filtered() >= 0.5f) { // Drops per keep | |
193 // limit is the number of frames we should drop between each kept frame | 211 // limit is the number of frames we should drop between each kept frame |
194 // to keep our drop ratio. limit is positive in this case. | 212 // to keep our drop ratio. limit is positive in this case. |
195 float denom = 1.0f - _dropRatio.filtered(); | 213 float denom = 1.0f - drop_ratio_.filtered(); |
196 if (denom < 1e-5) { | 214 if (denom < 1e-5) { |
197 denom = 1e-5f; | 215 denom = 1e-5f; |
198 } | 216 } |
199 int32_t limit = static_cast<int32_t>(1.0f / denom - 1.0f + 0.5f); | 217 int32_t limit = static_cast<int32_t>(1.0f / denom - 1.0f + 0.5f); |
200 // Put a bound on the max amount of dropped frames between each kept | 218 // Put a bound on the max amount of dropped frames between each kept |
201 // frame, in terms of frame rate and window size (secs). | 219 // frame, in terms of frame rate and window size (secs). |
202 int max_limit = static_cast<int>(_incoming_frame_rate * _max_time_drops); | 220 int max_limit = |
221 static_cast<int>(incoming_frame_rate_ * max_drop_duration_secs_); | |
203 if (limit > max_limit) { | 222 if (limit > max_limit) { |
204 limit = max_limit; | 223 limit = max_limit; |
205 } | 224 } |
206 if (_dropCount < 0) { | 225 if (drop_count_ < 0) { |
207 // Reset the _dropCount since it was negative and should be positive. | 226 // Reset the drop_count_ since it was negative and should be positive. |
208 if (_dropRatio.filtered() > 0.4f) { | 227 drop_count_ = -drop_count_; |
209 _dropCount = -_dropCount; | 228 } |
210 } else { | 229 if (drop_count_ < limit) { |
211 _dropCount = 0; | |
212 } | |
213 } | |
214 if (_dropCount < limit) { | |
215 // As long we are below the limit we should drop frames. | 230 // As long we are below the limit we should drop frames. |
216 _dropCount++; | 231 drop_count_++; |
217 return true; | 232 return true; |
218 } else { | 233 } else { |
219 // Only when we reset _dropCount a frame should be kept. | 234 // Only when we reset drop_count_ a frame should be kept. |
220 _dropCount = 0; | 235 drop_count_ = 0; |
221 return false; | 236 return false; |
222 } | 237 } |
223 } else if (_dropRatio.filtered() > 0.0f && | 238 } else if (drop_ratio_.filtered() > 0.0f && |
224 _dropRatio.filtered() < 0.5f) { // Keeps per drop | 239 drop_ratio_.filtered() < 0.5f) { // Keeps per drop |
225 // limit is the number of frames we should keep between each drop | 240 // limit is the number of frames we should keep between each drop |
226 // in order to keep the drop ratio. limit is negative in this case, | 241 // in order to keep the drop ratio. limit is negative in this case, |
227 // and the _dropCount is also negative. | 242 // and the drop_count_ is also negative. |
228 float denom = _dropRatio.filtered(); | 243 float denom = drop_ratio_.filtered(); |
229 if (denom < 1e-5) { | 244 if (denom < 1e-5) { |
230 denom = 1e-5f; | 245 denom = 1e-5f; |
231 } | 246 } |
232 int32_t limit = -static_cast<int32_t>(1.0f / denom - 1.0f + 0.5f); | 247 int32_t limit = -static_cast<int32_t>(1.0f / denom - 1.0f + 0.5f); |
233 if (_dropCount > 0) { | 248 if (drop_count_ > 0) { |
234 // Reset the _dropCount since we have a positive | 249 // Reset the drop_count_ since we have a positive |
235 // _dropCount, and it should be negative. | 250 // drop_count_, and it should be negative. |
236 if (_dropRatio.filtered() < 0.6f) { | 251 drop_count_ = -drop_count_; |
237 _dropCount = -_dropCount; | 252 } |
238 } else { | 253 if (drop_count_ > limit) { |
239 _dropCount = 0; | 254 if (drop_count_ == 0) { |
240 } | 255 // Drop frames when we reset drop_count_. |
241 } | 256 drop_count_--; |
242 if (_dropCount > limit) { | |
243 if (_dropCount == 0) { | |
244 // Drop frames when we reset _dropCount. | |
245 _dropCount--; | |
246 return true; | 257 return true; |
247 } else { | 258 } else { |
248 // Keep frames as long as we haven't reached limit. | 259 // Keep frames as long as we haven't reached limit. |
249 _dropCount--; | 260 drop_count_--; |
250 return false; | 261 return false; |
251 } | 262 } |
252 } else { | 263 } else { |
253 _dropCount = 0; | 264 drop_count_ = 0; |
254 return false; | 265 return false; |
255 } | 266 } |
256 } | 267 } |
257 _dropCount = 0; | 268 drop_count_ = 0; |
258 return false; | 269 return false; |
259 | 270 } |
260 // A simpler version, unfiltered and quicker | 271 |
261 // bool dropNext = _dropNext; | 272 void FrameDropper::SetRates(float bitrate, float incoming_frame_rate) { |
262 // _dropNext = false; | |
263 // return dropNext; | |
264 } | |
265 | |
266 void FrameDropper::SetRates(float bitRate, float incoming_frame_rate) { | |
267 // Bit rate of -1 means infinite bandwidth. | 273 // Bit rate of -1 means infinite bandwidth. |
268 _accumulatorMax = bitRate * _windowSize; // bitRate * windowSize (in seconds) | 274 accumulator_max_ = bitrate * kLeakyBucketSizeSeconds; |
269 if (_targetBitRate > 0.0f && bitRate < _targetBitRate && | 275 if (target_bitrate_ > 0.0f && bitrate < target_bitrate_ && |
270 _accumulator > _accumulatorMax) { | 276 accumulator_ > accumulator_max_) { |
271 // Rescale the accumulator level if the accumulator max decreases | 277 // Rescale the accumulator level if the accumulator max decreases |
272 _accumulator = bitRate / _targetBitRate * _accumulator; | 278 accumulator_ = bitrate / target_bitrate_ * accumulator_; |
273 } | 279 } |
274 _targetBitRate = bitRate; | 280 target_bitrate_ = bitrate; |
275 CapAccumulator(); | 281 CapAccumulator(); |
276 _incoming_frame_rate = incoming_frame_rate; | 282 incoming_frame_rate_ = incoming_frame_rate; |
277 } | |
278 | |
279 float FrameDropper::ActualFrameRate(uint32_t inputFrameRate) const { | |
280 if (!_enabled) { | |
281 return static_cast<float>(inputFrameRate); | |
282 } | |
283 return inputFrameRate * (1.0f - _dropRatio.filtered()); | |
284 } | 283 } |
285 | 284 |
286 // Put a cap on the accumulator, i.e., don't let it grow beyond some level. | 285 // Put a cap on the accumulator, i.e., don't let it grow beyond some level. |
287 // This is a temporary fix for screencasting where very large frames from | 286 // This is a temporary fix for screencasting where very large frames from |
288 // encoder will cause very slow response (too many frame drops). | 287 // encoder will cause very slow response (too many frame drops). |
288 // TODO(isheriff): Remove this now that large delta frames are also spread out ? | |
289 void FrameDropper::CapAccumulator() { | 289 void FrameDropper::CapAccumulator() { |
290 float max_accumulator = _targetBitRate * _cap_buffer_size; | 290 float max_accumulator = target_bitrate_ * kAccumulatorCapBufferSizeSecs; |
291 if (_accumulator > max_accumulator) { | 291 if (accumulator_ > max_accumulator) { |
292 _accumulator = max_accumulator; | 292 accumulator_ = max_accumulator; |
293 } | 293 } |
294 } | 294 } |
295 } // namespace webrtc | 295 } // namespace webrtc |
OLD | NEW |