1 /*
2  *  Copyright (c) 2017 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/include/receive_side_congestion_controller.h"
12 
13 #include "api/units/data_rate.h"
14 #include "modules/pacing/packet_router.h"
15 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
16 #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
17 #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
18 #include "rtc_base/logging.h"
19 
20 namespace webrtc {
21 
22 namespace {
23 static const uint32_t kTimeOffsetSwitchThreshold = 30;
24 }  // namespace
25 
OnRttUpdate(int64_t avg_rtt_ms,int64_t max_rtt_ms)26 void ReceiveSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
27                                                   int64_t max_rtt_ms) {
28   MutexLock lock(&mutex_);
29   rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
30 }
31 
RemoveStream(uint32_t ssrc)32 void ReceiveSideCongestionController::RemoveStream(uint32_t ssrc) {
33   MutexLock lock(&mutex_);
34   rbe_->RemoveStream(ssrc);
35 }
36 
LatestReceiveSideEstimate() const37 DataRate ReceiveSideCongestionController::LatestReceiveSideEstimate() const {
38   MutexLock lock(&mutex_);
39   return rbe_->LatestEstimate();
40 }
41 
PickEstimatorFromHeader(const RTPHeader & header)42 void ReceiveSideCongestionController::PickEstimatorFromHeader(
43     const RTPHeader& header) {
44   if (header.extension.hasAbsoluteSendTime) {
45     // If we see AST in header, switch RBE strategy immediately.
46     if (!using_absolute_send_time_) {
47       RTC_LOG(LS_INFO)
48           << "WrappingBitrateEstimator: Switching to absolute send time RBE.";
49       using_absolute_send_time_ = true;
50       PickEstimator();
51     }
52     packets_since_absolute_send_time_ = 0;
53   } else {
54     // When we don't see AST, wait for a few packets before going back to TOF.
55     if (using_absolute_send_time_) {
56       ++packets_since_absolute_send_time_;
57       if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
58         RTC_LOG(LS_INFO)
59             << "WrappingBitrateEstimator: Switching to transmission "
60                "time offset RBE.";
61         using_absolute_send_time_ = false;
62         PickEstimator();
63       }
64     }
65   }
66 }
67 
68 // Instantiate RBE for Time Offset or Absolute Send Time extensions.
PickEstimator()69 void ReceiveSideCongestionController::PickEstimator() {
70   if (using_absolute_send_time_) {
71     rbe_ = std::make_unique<RemoteBitrateEstimatorAbsSendTime>(&remb_throttler_,
72                                                                &clock_);
73   } else {
74     rbe_ = std::make_unique<RemoteBitrateEstimatorSingleStream>(
75         &remb_throttler_, &clock_);
76   }
77 }
78 
ReceiveSideCongestionController(Clock * clock,RemoteEstimatorProxy::TransportFeedbackSender feedback_sender,RembThrottler::RembSender remb_sender,NetworkStateEstimator * network_state_estimator)79 ReceiveSideCongestionController::ReceiveSideCongestionController(
80     Clock* clock,
81     RemoteEstimatorProxy::TransportFeedbackSender feedback_sender,
82     RembThrottler::RembSender remb_sender,
83     NetworkStateEstimator* network_state_estimator)
84     : clock_(*clock),
85       remb_throttler_(std::move(remb_sender), clock),
86       remote_estimator_proxy_(std::move(feedback_sender),
87                               network_state_estimator),
88       rbe_(new RemoteBitrateEstimatorSingleStream(&remb_throttler_, clock)),
89       using_absolute_send_time_(false),
90       packets_since_absolute_send_time_(0) {}
91 
OnReceivedPacket(int64_t arrival_time_ms,size_t payload_size,const RTPHeader & header)92 void ReceiveSideCongestionController::OnReceivedPacket(
93     int64_t arrival_time_ms,
94     size_t payload_size,
95     const RTPHeader& header) {
96   remote_estimator_proxy_.IncomingPacket(arrival_time_ms, payload_size, header);
97   if (!header.extension.hasTransportSequenceNumber) {
98     // Receive-side BWE.
99     MutexLock lock(&mutex_);
100     PickEstimatorFromHeader(header);
101     rbe_->IncomingPacket(arrival_time_ms, payload_size, header);
102   }
103 }
104 
SetSendPeriodicFeedback(bool send_periodic_feedback)105 void ReceiveSideCongestionController::SetSendPeriodicFeedback(
106     bool send_periodic_feedback) {
107   remote_estimator_proxy_.SetSendPeriodicFeedback(send_periodic_feedback);
108 }
109 
OnBitrateChanged(int bitrate_bps)110 void ReceiveSideCongestionController::OnBitrateChanged(int bitrate_bps) {
111   remote_estimator_proxy_.OnBitrateChanged(bitrate_bps);
112 }
113 
MaybeProcess()114 TimeDelta ReceiveSideCongestionController::MaybeProcess() {
115   Timestamp now = clock_.CurrentTime();
116   mutex_.Lock();
117   TimeDelta time_until_rbe = rbe_->Process();
118   mutex_.Unlock();
119   TimeDelta time_until_rep = remote_estimator_proxy_.Process(now);
120   TimeDelta time_until = std::min(time_until_rbe, time_until_rep);
121   return std::max(time_until, TimeDelta::Zero());
122 }
123 
SetMaxDesiredReceiveBitrate(DataRate bitrate)124 void ReceiveSideCongestionController::SetMaxDesiredReceiveBitrate(
125     DataRate bitrate) {
126   remb_throttler_.SetMaxDesiredReceiveBitrate(bitrate);
127 }
128 
SetTransportOverhead(DataSize overhead_per_packet)129 void ReceiveSideCongestionController::SetTransportOverhead(
130     DataSize overhead_per_packet) {
131   remote_estimator_proxy_.SetTransportOverhead(overhead_per_packet);
132 }
133 
134 }  // namespace webrtc
135