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