1 /*
2 * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/congestion_controller/remb_throttler.h"
12
13 #include <algorithm>
14 #include <utility>
15
16 namespace webrtc {
17
18 namespace {
19 constexpr TimeDelta kRembSendInterval = TimeDelta::Millis(200);
20 } // namespace
21
RembThrottler(RembSender remb_sender,Clock * clock)22 RembThrottler::RembThrottler(RembSender remb_sender, Clock* clock)
23 : remb_sender_(std::move(remb_sender)),
24 clock_(clock),
25 last_remb_time_(Timestamp::MinusInfinity()),
26 last_send_remb_bitrate_(DataRate::PlusInfinity()),
27 max_remb_bitrate_(DataRate::PlusInfinity()) {}
28
OnReceiveBitrateChanged(const std::vector<uint32_t> & ssrcs,uint32_t bitrate_bps)29 void RembThrottler::OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs,
30 uint32_t bitrate_bps) {
31 DataRate receive_bitrate = DataRate::BitsPerSec(bitrate_bps);
32 Timestamp now = clock_->CurrentTime();
33 {
34 MutexLock lock(&mutex_);
35 // % threshold for if we should send a new REMB asap.
36 const int64_t kSendThresholdPercent = 103;
37 if (receive_bitrate * kSendThresholdPercent / 100 >
38 last_send_remb_bitrate_ &&
39 now < last_remb_time_ + kRembSendInterval) {
40 return;
41 }
42 last_remb_time_ = now;
43 last_send_remb_bitrate_ = receive_bitrate;
44 receive_bitrate = std::min(last_send_remb_bitrate_, max_remb_bitrate_);
45 }
46 remb_sender_(receive_bitrate.bps(), ssrcs);
47 }
48
SetMaxDesiredReceiveBitrate(DataRate bitrate)49 void RembThrottler::SetMaxDesiredReceiveBitrate(DataRate bitrate) {
50 Timestamp now = clock_->CurrentTime();
51 {
52 MutexLock lock(&mutex_);
53 max_remb_bitrate_ = bitrate;
54 if (now - last_remb_time_ < kRembSendInterval &&
55 !last_send_remb_bitrate_.IsZero() &&
56 last_send_remb_bitrate_ <= max_remb_bitrate_) {
57 return;
58 }
59 }
60 remb_sender_(bitrate.bps(), /*ssrcs=*/{});
61 }
62
63 } // namespace webrtc
64