Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(879)

Side by Side Diff: webrtc/modules/pacing/paced_sender.cc

Issue 2999073002: Tweaked version of BBR for WebRTC. (Closed)
Patch Set: Rebase. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698