| 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 |
| 11 #include "webrtc/modules/pacing/paced_sender.h" | 11 #include "webrtc/modules/pacing/paced_sender.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <map> | 14 #include <map> |
| 15 #include <queue> | 15 #include <queue> |
| 16 #include <set> | 16 #include <set> |
| 17 #include <vector> | 17 #include <vector> |
| 18 | 18 |
| 19 #include "webrtc/modules/include/module_common_types.h" | 19 #include "webrtc/modules/include/module_common_types.h" |
| 20 #include "webrtc/modules/pacing/alr_detector.h" | 20 #include "webrtc/modules/pacing/alr_detector.h" |
| 21 #include "webrtc/modules/pacing/bitrate_prober.h" | 21 #include "webrtc/modules/pacing/bitrate_prober.h" |
| 22 #include "webrtc/modules/pacing/interval_budget.h" |
| 22 #include "webrtc/modules/utility/include/process_thread.h" | 23 #include "webrtc/modules/utility/include/process_thread.h" |
| 23 #include "webrtc/rtc_base/checks.h" | 24 #include "webrtc/rtc_base/checks.h" |
| 24 #include "webrtc/rtc_base/logging.h" | 25 #include "webrtc/rtc_base/logging.h" |
| 25 #include "webrtc/system_wrappers/include/clock.h" | 26 #include "webrtc/system_wrappers/include/clock.h" |
| 26 #include "webrtc/system_wrappers/include/field_trial.h" | 27 #include "webrtc/system_wrappers/include/field_trial.h" |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 // Time limit in milliseconds between packet bursts. | 30 // Time limit in milliseconds between packet bursts. |
| 30 const int64_t kMinPacketLimitMs = 5; | 31 const int64_t kMinPacketLimitMs = 5; |
| 31 | 32 |
| 32 // Upper cap on process interval, in case process has not been called in a long | 33 // Upper cap on process interval, in case process has not been called in a long |
| 33 // time. | 34 // time. |
| 34 const int64_t kMaxIntervalTimeMs = 30; | 35 const int64_t kMaxIntervalTimeMs = 30; |
| 35 | 36 |
| 36 } // namespace | 37 } // namespace |
| 37 | 38 |
| 38 // TODO(sprang): Move at least PacketQueue and MediaBudget out to separate | 39 // TODO(sprang): Move at least PacketQueue out to separate |
| 39 // files, so that we can more easily test them. | 40 // files, so that we can more easily test them. |
| 40 | 41 |
| 41 namespace webrtc { | 42 namespace webrtc { |
| 42 namespace paced_sender { | 43 namespace paced_sender { |
| 43 struct Packet { | 44 struct Packet { |
| 44 Packet(RtpPacketSender::Priority priority, | 45 Packet(RtpPacketSender::Priority priority, |
| 45 uint32_t ssrc, | 46 uint32_t ssrc, |
| 46 uint16_t seq_number, | 47 uint16_t seq_number, |
| 47 int64_t capture_time_ms, | 48 int64_t capture_time_ms, |
| 48 int64_t enqueue_time_ms, | 49 int64_t enqueue_time_ms, |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 // Total number of bytes in the queue. | 195 // Total number of bytes in the queue. |
| 195 uint64_t bytes_; | 196 uint64_t bytes_; |
| 196 // Map<ssrc, std::set<seq_no> >, for checking duplicates. | 197 // Map<ssrc, std::set<seq_no> >, for checking duplicates. |
| 197 typedef std::map<uint32_t, std::set<uint16_t> > SsrcSeqNoMap; | 198 typedef std::map<uint32_t, std::set<uint16_t> > SsrcSeqNoMap; |
| 198 SsrcSeqNoMap dupe_map_; | 199 SsrcSeqNoMap dupe_map_; |
| 199 const Clock* const clock_; | 200 const Clock* const clock_; |
| 200 int64_t queue_time_sum_; | 201 int64_t queue_time_sum_; |
| 201 int64_t time_last_updated_; | 202 int64_t time_last_updated_; |
| 202 }; | 203 }; |
| 203 | 204 |
| 204 class IntervalBudget { | |
| 205 public: | |
| 206 explicit IntervalBudget(int initial_target_rate_kbps) | |
| 207 : target_rate_kbps_(initial_target_rate_kbps), | |
| 208 bytes_remaining_(0) {} | |
| 209 | |
| 210 void set_target_rate_kbps(int target_rate_kbps) { | |
| 211 target_rate_kbps_ = target_rate_kbps; | |
| 212 bytes_remaining_ = | |
| 213 std::max(-kWindowMs * target_rate_kbps_ / 8, bytes_remaining_); | |
| 214 } | |
| 215 | |
| 216 void IncreaseBudget(int64_t delta_time_ms) { | |
| 217 int64_t bytes = target_rate_kbps_ * delta_time_ms / 8; | |
| 218 if (bytes_remaining_ < 0) { | |
| 219 // We overused last interval, compensate this interval. | |
| 220 bytes_remaining_ = bytes_remaining_ + bytes; | |
| 221 } else { | |
| 222 // If we underused last interval we can't use it this interval. | |
| 223 bytes_remaining_ = bytes; | |
| 224 } | |
| 225 } | |
| 226 | |
| 227 void UseBudget(size_t bytes) { | |
| 228 bytes_remaining_ = std::max(bytes_remaining_ - static_cast<int>(bytes), | |
| 229 -kWindowMs * target_rate_kbps_ / 8); | |
| 230 } | |
| 231 | |
| 232 size_t bytes_remaining() const { | |
| 233 return static_cast<size_t>(std::max(0, bytes_remaining_)); | |
| 234 } | |
| 235 | |
| 236 int target_rate_kbps() const { return target_rate_kbps_; } | |
| 237 | |
| 238 private: | |
| 239 static const int kWindowMs = 500; | |
| 240 | |
| 241 int target_rate_kbps_; | |
| 242 int bytes_remaining_; | |
| 243 }; | |
| 244 } // namespace paced_sender | 205 } // namespace paced_sender |
| 245 | 206 |
| 246 const int64_t PacedSender::kMaxQueueLengthMs = 2000; | 207 const int64_t PacedSender::kMaxQueueLengthMs = 2000; |
| 247 const float PacedSender::kDefaultPaceMultiplier = 2.5f; | 208 const float PacedSender::kDefaultPaceMultiplier = 2.5f; |
| 248 | 209 |
| 249 PacedSender::PacedSender(const Clock* clock, | 210 PacedSender::PacedSender(const Clock* clock, |
| 250 PacketSender* packet_sender, | 211 PacketSender* packet_sender, |
| 251 RtcEventLog* event_log) | 212 RtcEventLog* event_log) |
| 252 : clock_(clock), | 213 : clock_(clock), |
| 253 packet_sender_(packet_sender), | 214 packet_sender_(packet_sender), |
| 254 alr_detector_(new AlrDetector()), | 215 alr_detector_(new AlrDetector()), |
| 255 paused_(false), | 216 paused_(false), |
| 256 media_budget_(new paced_sender::IntervalBudget(0)), | 217 media_budget_(new IntervalBudget(0)), |
| 257 padding_budget_(new paced_sender::IntervalBudget(0)), | 218 padding_budget_(new IntervalBudget(0)), |
| 258 prober_(new BitrateProber(event_log)), | 219 prober_(new BitrateProber(event_log)), |
| 259 probing_send_failure_(false), | 220 probing_send_failure_(false), |
| 260 estimated_bitrate_bps_(0), | 221 estimated_bitrate_bps_(0), |
| 261 min_send_bitrate_kbps_(0u), | 222 min_send_bitrate_kbps_(0u), |
| 262 max_padding_bitrate_kbps_(0u), | 223 max_padding_bitrate_kbps_(0u), |
| 263 pacing_bitrate_kbps_(0), | 224 pacing_bitrate_kbps_(0), |
| 264 time_last_update_us_(clock->TimeInMicroseconds()), | 225 time_last_update_us_(clock->TimeInMicroseconds()), |
| 265 first_sent_packet_ms_(-1), | 226 first_sent_packet_ms_(-1), |
| 266 packets_(new paced_sender::PacketQueue(clock)), | 227 packets_(new paced_sender::PacketQueue(clock)), |
| 267 packet_counter_(0), | 228 packet_counter_(0), |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 | 434 |
| 474 if (padding_needed > 0) | 435 if (padding_needed > 0) |
| 475 bytes_sent += SendPadding(padding_needed, pacing_info); | 436 bytes_sent += SendPadding(padding_needed, pacing_info); |
| 476 } | 437 } |
| 477 } | 438 } |
| 478 if (is_probing) { | 439 if (is_probing) { |
| 479 probing_send_failure_ = bytes_sent == 0; | 440 probing_send_failure_ = bytes_sent == 0; |
| 480 if (!probing_send_failure_) | 441 if (!probing_send_failure_) |
| 481 prober_->ProbeSent(clock_->TimeInMilliseconds(), bytes_sent); | 442 prober_->ProbeSent(clock_->TimeInMilliseconds(), bytes_sent); |
| 482 } | 443 } |
| 483 alr_detector_->OnBytesSent(bytes_sent, now_us / 1000); | 444 alr_detector_->OnBytesSent(bytes_sent, elapsed_time_ms); |
| 484 } | 445 } |
| 485 | 446 |
| 486 void PacedSender::ProcessThreadAttached(ProcessThread* process_thread) { | 447 void PacedSender::ProcessThreadAttached(ProcessThread* process_thread) { |
| 487 LOG(LS_INFO) << "ProcessThreadAttached 0x" << std::hex << process_thread; | 448 LOG(LS_INFO) << "ProcessThreadAttached 0x" << std::hex << process_thread; |
| 488 process_thread_ = process_thread; | 449 process_thread_ = process_thread; |
| 489 } | 450 } |
| 490 | 451 |
| 491 bool PacedSender::SendPacket(const paced_sender::Packet& packet, | 452 bool PacedSender::SendPacket(const paced_sender::Packet& packet, |
| 492 const PacedPacketInfo& pacing_info) { | 453 const PacedPacketInfo& pacing_info) { |
| 493 if (paused_) | 454 if (paused_) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 rtc::CritScope cs(&critsect_); | 503 rtc::CritScope cs(&critsect_); |
| 543 pacing_factor_ = pacing_factor; | 504 pacing_factor_ = pacing_factor; |
| 544 } | 505 } |
| 545 | 506 |
| 546 void PacedSender::SetQueueTimeLimit(int limit_ms) { | 507 void PacedSender::SetQueueTimeLimit(int limit_ms) { |
| 547 rtc::CritScope cs(&critsect_); | 508 rtc::CritScope cs(&critsect_); |
| 548 queue_time_limit = limit_ms; | 509 queue_time_limit = limit_ms; |
| 549 } | 510 } |
| 550 | 511 |
| 551 } // namespace webrtc | 512 } // namespace webrtc |
| OLD | NEW |