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" | |
23 #include "webrtc/modules/utility/include/process_thread.h" | 22 #include "webrtc/modules/utility/include/process_thread.h" |
24 #include "webrtc/rtc_base/checks.h" | 23 #include "webrtc/rtc_base/checks.h" |
25 #include "webrtc/rtc_base/logging.h" | 24 #include "webrtc/rtc_base/logging.h" |
26 #include "webrtc/system_wrappers/include/clock.h" | 25 #include "webrtc/system_wrappers/include/clock.h" |
27 #include "webrtc/system_wrappers/include/field_trial.h" | 26 #include "webrtc/system_wrappers/include/field_trial.h" |
28 | 27 |
29 namespace { | 28 namespace { |
30 // Time limit in milliseconds between packet bursts. | 29 // Time limit in milliseconds between packet bursts. |
31 const int64_t kMinPacketLimitMs = 5; | 30 const int64_t kMinPacketLimitMs = 5; |
32 const int64_t kPausedPacketIntervalMs = 500; | 31 const int64_t kPausedPacketIntervalMs = 500; |
33 | 32 |
34 // 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 |
35 // time. | 34 // time. |
36 const int64_t kMaxIntervalTimeMs = 30; | 35 const int64_t kMaxIntervalTimeMs = 30; |
37 | 36 |
38 } // namespace | 37 } // namespace |
39 | 38 |
40 // TODO(sprang): Move at least PacketQueue out to separate | 39 // TODO(sprang): Move at least PacketQueue and MediaBudget out to separate |
41 // files, so that we can more easily test them. | 40 // files, so that we can more easily test them. |
42 | 41 |
43 namespace webrtc { | 42 namespace webrtc { |
44 namespace paced_sender { | 43 namespace paced_sender { |
45 struct Packet { | 44 struct Packet { |
46 Packet(RtpPacketSender::Priority priority, | 45 Packet(RtpPacketSender::Priority priority, |
47 uint32_t ssrc, | 46 uint32_t ssrc, |
48 uint16_t seq_number, | 47 uint16_t seq_number, |
49 int64_t capture_time_ms, | 48 int64_t capture_time_ms, |
50 int64_t enqueue_time_ms, | 49 int64_t enqueue_time_ms, |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 uint64_t bytes_; | 223 uint64_t bytes_; |
225 // Map<ssrc, std::set<seq_no> >, for checking duplicates. | 224 // Map<ssrc, std::set<seq_no> >, for checking duplicates. |
226 typedef std::map<uint32_t, std::set<uint16_t> > SsrcSeqNoMap; | 225 typedef std::map<uint32_t, std::set<uint16_t> > SsrcSeqNoMap; |
227 SsrcSeqNoMap dupe_map_; | 226 SsrcSeqNoMap dupe_map_; |
228 const Clock* const clock_; | 227 const Clock* const clock_; |
229 int64_t queue_time_sum_; | 228 int64_t queue_time_sum_; |
230 int64_t time_last_updated_; | 229 int64_t time_last_updated_; |
231 bool paused_; | 230 bool paused_; |
232 }; | 231 }; |
233 | 232 |
| 233 class IntervalBudget { |
| 234 public: |
| 235 explicit IntervalBudget(int initial_target_rate_kbps) |
| 236 : target_rate_kbps_(initial_target_rate_kbps), bytes_remaining_(0) {} |
| 237 |
| 238 void set_target_rate_kbps(int target_rate_kbps) { |
| 239 target_rate_kbps_ = target_rate_kbps; |
| 240 bytes_remaining_ = |
| 241 std::max(-kWindowMs * target_rate_kbps_ / 8, bytes_remaining_); |
| 242 } |
| 243 |
| 244 void IncreaseBudget(int64_t delta_time_ms) { |
| 245 int64_t bytes = target_rate_kbps_ * delta_time_ms / 8; |
| 246 if (bytes_remaining_ < 0) { |
| 247 // We overused last interval, compensate this interval. |
| 248 bytes_remaining_ = bytes_remaining_ + bytes; |
| 249 } else { |
| 250 // If we underused last interval we can't use it this interval. |
| 251 bytes_remaining_ = bytes; |
| 252 } |
| 253 } |
| 254 |
| 255 void UseBudget(size_t bytes) { |
| 256 bytes_remaining_ = std::max(bytes_remaining_ - static_cast<int>(bytes), |
| 257 -kWindowMs * target_rate_kbps_ / 8); |
| 258 } |
| 259 |
| 260 size_t bytes_remaining() const { |
| 261 return static_cast<size_t>(std::max(0, bytes_remaining_)); |
| 262 } |
| 263 |
| 264 int target_rate_kbps() const { return target_rate_kbps_; } |
| 265 |
| 266 private: |
| 267 static const int kWindowMs = 500; |
| 268 |
| 269 int target_rate_kbps_; |
| 270 int bytes_remaining_; |
| 271 }; |
234 } // namespace paced_sender | 272 } // namespace paced_sender |
235 | 273 |
236 const int64_t PacedSender::kMaxQueueLengthMs = 2000; | 274 const int64_t PacedSender::kMaxQueueLengthMs = 2000; |
237 const float PacedSender::kDefaultPaceMultiplier = 2.5f; | 275 const float PacedSender::kDefaultPaceMultiplier = 2.5f; |
238 | 276 |
239 PacedSender::PacedSender(const Clock* clock, | 277 PacedSender::PacedSender(const Clock* clock, |
240 PacketSender* packet_sender, | 278 PacketSender* packet_sender, |
241 RtcEventLog* event_log) | 279 RtcEventLog* event_log) |
242 : clock_(clock), | 280 : clock_(clock), |
243 packet_sender_(packet_sender), | 281 packet_sender_(packet_sender), |
244 alr_detector_(new AlrDetector()), | 282 alr_detector_(new AlrDetector()), |
245 paused_(false), | 283 paused_(false), |
246 media_budget_(new IntervalBudget(0)), | 284 media_budget_(new paced_sender::IntervalBudget(0)), |
247 padding_budget_(new IntervalBudget(0)), | 285 padding_budget_(new paced_sender::IntervalBudget(0)), |
248 prober_(new BitrateProber(event_log)), | 286 prober_(new BitrateProber(event_log)), |
249 probing_send_failure_(false), | 287 probing_send_failure_(false), |
250 estimated_bitrate_bps_(0), | 288 estimated_bitrate_bps_(0), |
251 min_send_bitrate_kbps_(0u), | 289 min_send_bitrate_kbps_(0u), |
252 max_padding_bitrate_kbps_(0u), | 290 max_padding_bitrate_kbps_(0u), |
253 pacing_bitrate_kbps_(0), | 291 pacing_bitrate_kbps_(0), |
254 time_last_update_us_(clock->TimeInMicroseconds()), | 292 time_last_update_us_(clock->TimeInMicroseconds()), |
255 first_sent_packet_ms_(-1), | 293 first_sent_packet_ms_(-1), |
256 packets_(new paced_sender::PacketQueue(clock)), | 294 packets_(new paced_sender::PacketQueue(clock)), |
257 packet_counter_(0), | 295 packet_counter_(0) { |
258 pacing_factor_(kDefaultPaceMultiplier), | |
259 queue_time_limit(kMaxQueueLengthMs) { | |
260 UpdateBudgetWithElapsedTime(kMinPacketLimitMs); | 296 UpdateBudgetWithElapsedTime(kMinPacketLimitMs); |
261 } | 297 } |
262 | 298 |
263 PacedSender::~PacedSender() {} | 299 PacedSender::~PacedSender() {} |
264 | 300 |
265 void PacedSender::CreateProbeCluster(int bitrate_bps) { | 301 void PacedSender::CreateProbeCluster(int bitrate_bps) { |
266 rtc::CritScope cs(&critsect_); | 302 rtc::CritScope cs(&critsect_); |
267 prober_->CreateProbeCluster(bitrate_bps, clock_->TimeInMilliseconds()); | 303 prober_->CreateProbeCluster(bitrate_bps, clock_->TimeInMilliseconds()); |
268 } | 304 } |
269 | 305 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 | 339 |
304 void PacedSender::SetEstimatedBitrate(uint32_t bitrate_bps) { | 340 void PacedSender::SetEstimatedBitrate(uint32_t bitrate_bps) { |
305 if (bitrate_bps == 0) | 341 if (bitrate_bps == 0) |
306 LOG(LS_ERROR) << "PacedSender is not designed to handle 0 bitrate."; | 342 LOG(LS_ERROR) << "PacedSender is not designed to handle 0 bitrate."; |
307 rtc::CritScope cs(&critsect_); | 343 rtc::CritScope cs(&critsect_); |
308 estimated_bitrate_bps_ = bitrate_bps; | 344 estimated_bitrate_bps_ = bitrate_bps; |
309 padding_budget_->set_target_rate_kbps( | 345 padding_budget_->set_target_rate_kbps( |
310 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); | 346 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); |
311 pacing_bitrate_kbps_ = | 347 pacing_bitrate_kbps_ = |
312 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * | 348 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * |
313 pacing_factor_; | 349 kDefaultPaceMultiplier; |
314 alr_detector_->SetEstimatedBitrate(bitrate_bps); | 350 alr_detector_->SetEstimatedBitrate(bitrate_bps); |
315 } | 351 } |
316 | 352 |
317 void PacedSender::SetSendBitrateLimits(int min_send_bitrate_bps, | 353 void PacedSender::SetSendBitrateLimits(int min_send_bitrate_bps, |
318 int padding_bitrate) { | 354 int padding_bitrate) { |
319 rtc::CritScope cs(&critsect_); | 355 rtc::CritScope cs(&critsect_); |
320 min_send_bitrate_kbps_ = min_send_bitrate_bps / 1000; | 356 min_send_bitrate_kbps_ = min_send_bitrate_bps / 1000; |
321 pacing_bitrate_kbps_ = | 357 pacing_bitrate_kbps_ = |
322 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * | 358 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * |
323 pacing_factor_; | 359 kDefaultPaceMultiplier; |
324 max_padding_bitrate_kbps_ = padding_bitrate / 1000; | 360 max_padding_bitrate_kbps_ = padding_bitrate / 1000; |
325 padding_budget_->set_target_rate_kbps( | 361 padding_budget_->set_target_rate_kbps( |
326 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); | 362 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); |
327 } | 363 } |
328 | 364 |
329 void PacedSender::InsertPacket(RtpPacketSender::Priority priority, | 365 void PacedSender::InsertPacket(RtpPacketSender::Priority priority, |
330 uint32_t ssrc, | 366 uint32_t ssrc, |
331 uint16_t sequence_number, | 367 uint16_t sequence_number, |
332 int64_t capture_time_ms, | 368 int64_t capture_time_ms, |
333 size_t bytes, | 369 size_t bytes, |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 } | 458 } |
423 | 459 |
424 if (elapsed_time_ms > 0) { | 460 if (elapsed_time_ms > 0) { |
425 size_t queue_size_bytes = packets_->SizeInBytes(); | 461 size_t queue_size_bytes = packets_->SizeInBytes(); |
426 if (queue_size_bytes > 0) { | 462 if (queue_size_bytes > 0) { |
427 // Assuming equal size packets and input/output rate, the average packet | 463 // Assuming equal size packets and input/output rate, the average packet |
428 // has avg_time_left_ms left to get queue_size_bytes out of the queue, if | 464 // has avg_time_left_ms left to get queue_size_bytes out of the queue, if |
429 // time constraint shall be met. Determine bitrate needed for that. | 465 // time constraint shall be met. Determine bitrate needed for that. |
430 packets_->UpdateQueueTime(clock_->TimeInMilliseconds()); | 466 packets_->UpdateQueueTime(clock_->TimeInMilliseconds()); |
431 int64_t avg_time_left_ms = std::max<int64_t>( | 467 int64_t avg_time_left_ms = std::max<int64_t>( |
432 1, queue_time_limit - packets_->AverageQueueTimeMs()); | 468 1, kMaxQueueLengthMs - packets_->AverageQueueTimeMs()); |
433 int min_bitrate_needed_kbps = | 469 int min_bitrate_needed_kbps = |
434 static_cast<int>(queue_size_bytes * 8 / avg_time_left_ms); | 470 static_cast<int>(queue_size_bytes * 8 / avg_time_left_ms); |
435 if (min_bitrate_needed_kbps > target_bitrate_kbps) | 471 if (min_bitrate_needed_kbps > target_bitrate_kbps) |
436 target_bitrate_kbps = min_bitrate_needed_kbps; | 472 target_bitrate_kbps = min_bitrate_needed_kbps; |
437 } | 473 } |
438 | 474 |
439 media_budget_->set_target_rate_kbps(target_bitrate_kbps); | 475 media_budget_->set_target_rate_kbps(target_bitrate_kbps); |
440 | 476 |
441 elapsed_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms); | 477 elapsed_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms); |
442 UpdateBudgetWithElapsedTime(elapsed_time_ms); | 478 UpdateBudgetWithElapsedTime(elapsed_time_ms); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 : padding_budget_->bytes_remaining()); | 518 : padding_budget_->bytes_remaining()); |
483 if (padding_needed > 0) | 519 if (padding_needed > 0) |
484 bytes_sent += SendPadding(padding_needed, pacing_info); | 520 bytes_sent += SendPadding(padding_needed, pacing_info); |
485 } | 521 } |
486 } | 522 } |
487 if (is_probing) { | 523 if (is_probing) { |
488 probing_send_failure_ = bytes_sent == 0; | 524 probing_send_failure_ = bytes_sent == 0; |
489 if (!probing_send_failure_) | 525 if (!probing_send_failure_) |
490 prober_->ProbeSent(clock_->TimeInMilliseconds(), bytes_sent); | 526 prober_->ProbeSent(clock_->TimeInMilliseconds(), bytes_sent); |
491 } | 527 } |
492 alr_detector_->OnBytesSent(bytes_sent, elapsed_time_ms); | 528 alr_detector_->OnBytesSent(bytes_sent, now_us / 1000); |
493 } | 529 } |
494 | 530 |
495 void PacedSender::ProcessThreadAttached(ProcessThread* process_thread) { | 531 void PacedSender::ProcessThreadAttached(ProcessThread* process_thread) { |
496 LOG(LS_INFO) << "ProcessThreadAttached 0x" << std::hex << process_thread; | 532 LOG(LS_INFO) << "ProcessThreadAttached 0x" << std::hex << process_thread; |
497 process_thread_ = process_thread; | 533 process_thread_ = process_thread; |
498 } | 534 } |
499 | 535 |
500 bool PacedSender::SendPacket(const paced_sender::Packet& packet, | 536 bool PacedSender::SendPacket(const paced_sender::Packet& packet, |
501 const PacedPacketInfo& pacing_info) { | 537 const PacedPacketInfo& pacing_info) { |
502 RTC_DCHECK(!paused_); | 538 RTC_DCHECK(!paused_); |
503 if (media_budget_->bytes_remaining() == 0 && | 539 if (media_budget_->bytes_remaining() == 0 && |
504 pacing_info.probe_cluster_id == PacedPacketInfo::kNotAProbe) { | 540 pacing_info.probe_cluster_id == PacedPacketInfo::kNotAProbe) { |
505 return false; | 541 return false; |
506 } | 542 } |
507 | 543 |
508 critsect_.Leave(); | 544 critsect_.Leave(); |
509 const bool success = packet_sender_->TimeToSendPacket( | 545 const bool success = packet_sender_->TimeToSendPacket( |
510 packet.ssrc, packet.sequence_number, packet.capture_time_ms, | 546 packet.ssrc, packet.sequence_number, packet.capture_time_ms, |
511 packet.retransmission, pacing_info); | 547 packet.retransmission, pacing_info); |
512 critsect_.Enter(); | 548 critsect_.Enter(); |
513 | 549 |
514 if (success) { | 550 if (success) { |
515 // TODO(holmer): High priority packets should only be accounted for if we | 551 // TODO(holmer): High priority packets should only be accounted for if we |
516 // are allocating bandwidth for audio. | 552 // are allocating bandwidth for audio. |
517 if (packet.priority != kHighPriority) { | 553 if (packet.priority != kHighPriority) { |
518 // Update media bytes sent. | 554 // Update media bytes sent. |
519 // TODO(eladalon): TimeToSendPacket() can also return |true| in some | |
520 // situations where nothing actually ended up being sent to the network, | |
521 // and we probably don't want to update the budget in such cases. | |
522 // https://bugs.chromium.org/p/webrtc/issues/detail?id=8052 | |
523 UpdateBudgetWithBytesSent(packet.bytes); | 555 UpdateBudgetWithBytesSent(packet.bytes); |
524 } | 556 } |
525 } | 557 } |
526 | 558 |
527 return success; | 559 return success; |
528 } | 560 } |
529 | 561 |
530 size_t PacedSender::SendPadding(size_t padding_needed, | 562 size_t PacedSender::SendPadding(size_t padding_needed, |
531 const PacedPacketInfo& pacing_info) { | 563 const PacedPacketInfo& pacing_info) { |
532 RTC_DCHECK_GT(packet_counter_, 0); | 564 RTC_DCHECK_GT(packet_counter_, 0); |
(...skipping 10 matching lines...) Expand all Loading... |
543 | 575 |
544 void PacedSender::UpdateBudgetWithElapsedTime(int64_t delta_time_ms) { | 576 void PacedSender::UpdateBudgetWithElapsedTime(int64_t delta_time_ms) { |
545 media_budget_->IncreaseBudget(delta_time_ms); | 577 media_budget_->IncreaseBudget(delta_time_ms); |
546 padding_budget_->IncreaseBudget(delta_time_ms); | 578 padding_budget_->IncreaseBudget(delta_time_ms); |
547 } | 579 } |
548 | 580 |
549 void PacedSender::UpdateBudgetWithBytesSent(size_t bytes_sent) { | 581 void PacedSender::UpdateBudgetWithBytesSent(size_t bytes_sent) { |
550 media_budget_->UseBudget(bytes_sent); | 582 media_budget_->UseBudget(bytes_sent); |
551 padding_budget_->UseBudget(bytes_sent); | 583 padding_budget_->UseBudget(bytes_sent); |
552 } | 584 } |
553 | |
554 void PacedSender::SetPacingFactor(float pacing_factor) { | |
555 rtc::CritScope cs(&critsect_); | |
556 pacing_factor_ = pacing_factor; | |
557 } | |
558 | |
559 void PacedSender::SetQueueTimeLimit(int limit_ms) { | |
560 rtc::CritScope cs(&critsect_); | |
561 queue_time_limit = limit_ms; | |
562 } | |
563 | |
564 } // namespace webrtc | 585 } // namespace webrtc |
OLD | NEW |