OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 |
(...skipping 28 matching lines...) Expand all Loading... |
39 user_frame_rate_(0), | 39 user_frame_rate_(0), |
40 frame_dropper_(new FrameDropper), | 40 frame_dropper_(new FrameDropper), |
41 fraction_lost_(0), | 41 fraction_lost_(0), |
42 send_statistics_zero_encode_(0), | 42 send_statistics_zero_encode_(0), |
43 max_payload_size_(1460), | 43 max_payload_size_(1460), |
44 video_target_bitrate_(0), | 44 video_target_bitrate_(0), |
45 incoming_frame_rate_(0), | 45 incoming_frame_rate_(0), |
46 encoded_frame_samples_(), | 46 encoded_frame_samples_(), |
47 avg_sent_bit_rate_bps_(0), | 47 avg_sent_bit_rate_bps_(0), |
48 avg_sent_framerate_(0), | 48 avg_sent_framerate_(0), |
49 num_layers_(0), | 49 num_layers_(0) { |
50 suspension_enabled_(false), | |
51 video_suspended_(false), | |
52 suspension_threshold_bps_(0), | |
53 suspension_window_bps_(0) { | |
54 memset(send_statistics_, 0, sizeof(send_statistics_)); | 50 memset(send_statistics_, 0, sizeof(send_statistics_)); |
55 memset(incoming_frame_times_, -1, sizeof(incoming_frame_times_)); | 51 memset(incoming_frame_times_, -1, sizeof(incoming_frame_times_)); |
56 } | 52 } |
57 | 53 |
58 MediaOptimization::~MediaOptimization(void) { | 54 MediaOptimization::~MediaOptimization(void) { |
59 } | 55 } |
60 | 56 |
61 void MediaOptimization::Reset() { | 57 void MediaOptimization::Reset() { |
62 CriticalSectionScoped lock(crit_sect_.get()); | 58 CriticalSectionScoped lock(crit_sect_.get()); |
63 SetEncodingDataInternal(0, 0, 0, 0, 0, 0, max_payload_size_); | 59 SetEncodingDataInternal(0, 0, 0, 0, 0, 0, max_payload_size_); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 // Cap target video bitrate to codec maximum. | 125 // Cap target video bitrate to codec maximum. |
130 if (max_bit_rate_ > 0 && video_target_bitrate_ > max_bit_rate_) { | 126 if (max_bit_rate_ > 0 && video_target_bitrate_ > max_bit_rate_) { |
131 video_target_bitrate_ = max_bit_rate_; | 127 video_target_bitrate_ = max_bit_rate_; |
132 } | 128 } |
133 | 129 |
134 // Update encoding rates following protection settings. | 130 // Update encoding rates following protection settings. |
135 float target_video_bitrate_kbps = | 131 float target_video_bitrate_kbps = |
136 static_cast<float>(video_target_bitrate_) / 1000.0f; | 132 static_cast<float>(video_target_bitrate_) / 1000.0f; |
137 frame_dropper_->SetRates(target_video_bitrate_kbps, incoming_frame_rate_); | 133 frame_dropper_->SetRates(target_video_bitrate_kbps, incoming_frame_rate_); |
138 | 134 |
139 CheckSuspendConditions(); | |
140 | |
141 return video_target_bitrate_; | 135 return video_target_bitrate_; |
142 } | 136 } |
143 | 137 |
144 uint32_t MediaOptimization::InputFrameRate() { | 138 uint32_t MediaOptimization::InputFrameRate() { |
145 CriticalSectionScoped lock(crit_sect_.get()); | 139 CriticalSectionScoped lock(crit_sect_.get()); |
146 return InputFrameRateInternal(); | 140 return InputFrameRateInternal(); |
147 } | 141 } |
148 | 142 |
149 uint32_t MediaOptimization::InputFrameRateInternal() { | 143 uint32_t MediaOptimization::InputFrameRateInternal() { |
150 ProcessIncomingFrameRate(clock_->TimeInMilliseconds()); | 144 ProcessIncomingFrameRate(clock_->TimeInMilliseconds()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 } | 190 } |
197 | 191 |
198 return VCM_OK; | 192 return VCM_OK; |
199 } | 193 } |
200 | 194 |
201 void MediaOptimization::EnableFrameDropper(bool enable) { | 195 void MediaOptimization::EnableFrameDropper(bool enable) { |
202 CriticalSectionScoped lock(crit_sect_.get()); | 196 CriticalSectionScoped lock(crit_sect_.get()); |
203 frame_dropper_->Enable(enable); | 197 frame_dropper_->Enable(enable); |
204 } | 198 } |
205 | 199 |
206 void MediaOptimization::SuspendBelowMinBitrate(int threshold_bps, | |
207 int window_bps) { | |
208 CriticalSectionScoped lock(crit_sect_.get()); | |
209 assert(threshold_bps > 0 && window_bps >= 0); | |
210 suspension_threshold_bps_ = threshold_bps; | |
211 suspension_window_bps_ = window_bps; | |
212 suspension_enabled_ = true; | |
213 video_suspended_ = false; | |
214 } | |
215 | |
216 bool MediaOptimization::IsVideoSuspended() const { | |
217 CriticalSectionScoped lock(crit_sect_.get()); | |
218 return video_suspended_; | |
219 } | |
220 | |
221 bool MediaOptimization::DropFrame() { | 200 bool MediaOptimization::DropFrame() { |
222 CriticalSectionScoped lock(crit_sect_.get()); | 201 CriticalSectionScoped lock(crit_sect_.get()); |
223 UpdateIncomingFrameRate(); | 202 UpdateIncomingFrameRate(); |
224 // Leak appropriate number of bytes. | 203 // Leak appropriate number of bytes. |
225 frame_dropper_->Leak((uint32_t)(InputFrameRateInternal() + 0.5f)); | 204 frame_dropper_->Leak((uint32_t)(InputFrameRateInternal() + 0.5f)); |
226 if (video_suspended_) { | |
227 return true; // Drop all frames when muted. | |
228 } | |
229 return frame_dropper_->DropFrame(); | 205 return frame_dropper_->DropFrame(); |
230 } | 206 } |
231 | 207 |
232 void MediaOptimization::UpdateIncomingFrameRate() { | 208 void MediaOptimization::UpdateIncomingFrameRate() { |
233 int64_t now = clock_->TimeInMilliseconds(); | 209 int64_t now = clock_->TimeInMilliseconds(); |
234 if (incoming_frame_times_[0] == 0) { | 210 if (incoming_frame_times_[0] == 0) { |
235 // No shifting if this is the first time. | 211 // No shifting if this is the first time. |
236 } else { | 212 } else { |
237 // Shift all times one step. | 213 // Shift all times one step. |
238 for (int32_t i = (kFrameCountHistorySize - 2); i >= 0; i--) { | 214 for (int32_t i = (kFrameCountHistorySize - 2); i >= 0; i--) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 } | 280 } |
305 if (num > 1) { | 281 if (num > 1) { |
306 const int64_t diff = | 282 const int64_t diff = |
307 incoming_frame_times_[0] - incoming_frame_times_[num - 1]; | 283 incoming_frame_times_[0] - incoming_frame_times_[num - 1]; |
308 incoming_frame_rate_ = 0.0; // No frame rate estimate available. | 284 incoming_frame_rate_ = 0.0; // No frame rate estimate available. |
309 if (diff > 0) { | 285 if (diff > 0) { |
310 incoming_frame_rate_ = nr_of_frames * 1000.0f / static_cast<float>(diff); | 286 incoming_frame_rate_ = nr_of_frames * 1000.0f / static_cast<float>(diff); |
311 } | 287 } |
312 } | 288 } |
313 } | 289 } |
314 | |
315 void MediaOptimization::CheckSuspendConditions() { | |
316 // Check conditions for SuspendBelowMinBitrate. |video_target_bitrate_| is in | |
317 // bps. | |
318 if (suspension_enabled_) { | |
319 if (!video_suspended_) { | |
320 // Check if we just went below the threshold. | |
321 if (video_target_bitrate_ < suspension_threshold_bps_) { | |
322 video_suspended_ = true; | |
323 } | |
324 } else { | |
325 // Video is already suspended. Check if we just went over the threshold | |
326 // with a margin. | |
327 if (video_target_bitrate_ > | |
328 suspension_threshold_bps_ + suspension_window_bps_) { | |
329 video_suspended_ = false; | |
330 } | |
331 } | |
332 } | |
333 } | |
334 | |
335 } // namespace media_optimization | 290 } // namespace media_optimization |
336 } // namespace webrtc | 291 } // namespace webrtc |
OLD | NEW |