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 "modules/pacing/packet_router.h"
14 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
15 #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
16 #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
17 #include "rtc_base/logging.h"
18
19 namespace webrtc {
20
21 namespace {
22 static const uint32_t kTimeOffsetSwitchThreshold = 30;
23 } // namespace
24
25 ReceiveSideCongestionController::WrappingBitrateEstimator::
WrappingBitrateEstimator(RemoteBitrateObserver * observer,Clock * clock)26 WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock)
27 : observer_(observer),
28 clock_(clock),
29 rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)),
30 using_absolute_send_time_(false),
31 packets_since_absolute_send_time_(0),
32 min_bitrate_bps_(congestion_controller::GetMinBitrateBps()) {}
33
34 ReceiveSideCongestionController::WrappingBitrateEstimator::
35 ~WrappingBitrateEstimator() = default;
36
IncomingPacket(int64_t arrival_time_ms,size_t payload_size,const RTPHeader & header)37 void ReceiveSideCongestionController::WrappingBitrateEstimator::IncomingPacket(
38 int64_t arrival_time_ms,
39 size_t payload_size,
40 const RTPHeader& header) {
41 MutexLock lock(&mutex_);
42 PickEstimatorFromHeader(header);
43 rbe_->IncomingPacket(arrival_time_ms, payload_size, header);
44 }
45
Process()46 void ReceiveSideCongestionController::WrappingBitrateEstimator::Process() {
47 MutexLock lock(&mutex_);
48 rbe_->Process();
49 }
50
51 int64_t ReceiveSideCongestionController::WrappingBitrateEstimator::
TimeUntilNextProcess()52 TimeUntilNextProcess() {
53 MutexLock lock(&mutex_);
54 return rbe_->TimeUntilNextProcess();
55 }
56
OnRttUpdate(int64_t avg_rtt_ms,int64_t max_rtt_ms)57 void ReceiveSideCongestionController::WrappingBitrateEstimator::OnRttUpdate(
58 int64_t avg_rtt_ms,
59 int64_t max_rtt_ms) {
60 MutexLock lock(&mutex_);
61 rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
62 }
63
RemoveStream(unsigned int ssrc)64 void ReceiveSideCongestionController::WrappingBitrateEstimator::RemoveStream(
65 unsigned int ssrc) {
66 MutexLock lock(&mutex_);
67 rbe_->RemoveStream(ssrc);
68 }
69
LatestEstimate(std::vector<unsigned int> * ssrcs,unsigned int * bitrate_bps) const70 bool ReceiveSideCongestionController::WrappingBitrateEstimator::LatestEstimate(
71 std::vector<unsigned int>* ssrcs,
72 unsigned int* bitrate_bps) const {
73 MutexLock lock(&mutex_);
74 return rbe_->LatestEstimate(ssrcs, bitrate_bps);
75 }
76
SetMinBitrate(int min_bitrate_bps)77 void ReceiveSideCongestionController::WrappingBitrateEstimator::SetMinBitrate(
78 int min_bitrate_bps) {
79 MutexLock lock(&mutex_);
80 rbe_->SetMinBitrate(min_bitrate_bps);
81 min_bitrate_bps_ = min_bitrate_bps;
82 }
83
84 void ReceiveSideCongestionController::WrappingBitrateEstimator::
PickEstimatorFromHeader(const RTPHeader & header)85 PickEstimatorFromHeader(const RTPHeader& header) {
86 if (header.extension.hasAbsoluteSendTime) {
87 // If we see AST in header, switch RBE strategy immediately.
88 if (!using_absolute_send_time_) {
89 RTC_LOG(LS_INFO)
90 << "WrappingBitrateEstimator: Switching to absolute send time RBE.";
91 using_absolute_send_time_ = true;
92 PickEstimator();
93 }
94 packets_since_absolute_send_time_ = 0;
95 } else {
96 // When we don't see AST, wait for a few packets before going back to TOF.
97 if (using_absolute_send_time_) {
98 ++packets_since_absolute_send_time_;
99 if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
100 RTC_LOG(LS_INFO)
101 << "WrappingBitrateEstimator: Switching to transmission "
102 "time offset RBE.";
103 using_absolute_send_time_ = false;
104 PickEstimator();
105 }
106 }
107 }
108 }
109
110 // Instantiate RBE for Time Offset or Absolute Send Time extensions.
111 void ReceiveSideCongestionController::WrappingBitrateEstimator::
PickEstimator()112 PickEstimator() {
113 if (using_absolute_send_time_) {
114 rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_));
115 } else {
116 rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_));
117 }
118 rbe_->SetMinBitrate(min_bitrate_bps_);
119 }
120
ReceiveSideCongestionController(Clock * clock,PacketRouter * packet_router)121 ReceiveSideCongestionController::ReceiveSideCongestionController(
122 Clock* clock,
123 PacketRouter* packet_router)
124 : ReceiveSideCongestionController(clock, packet_router, nullptr) {}
125
ReceiveSideCongestionController(Clock * clock,PacketRouter * packet_router,NetworkStateEstimator * network_state_estimator)126 ReceiveSideCongestionController::ReceiveSideCongestionController(
127 Clock* clock,
128 PacketRouter* packet_router,
129 NetworkStateEstimator* network_state_estimator)
130 : remote_bitrate_estimator_(packet_router, clock),
131 remote_estimator_proxy_(clock,
132 packet_router,
133 &field_trial_config_,
134 network_state_estimator) {}
135
OnReceivedPacket(int64_t arrival_time_ms,size_t payload_size,const RTPHeader & header)136 void ReceiveSideCongestionController::OnReceivedPacket(
137 int64_t arrival_time_ms,
138 size_t payload_size,
139 const RTPHeader& header) {
140 remote_estimator_proxy_.IncomingPacket(arrival_time_ms, payload_size, header);
141 if (!header.extension.hasTransportSequenceNumber) {
142 // Receive-side BWE.
143 remote_bitrate_estimator_.IncomingPacket(arrival_time_ms, payload_size,
144 header);
145 }
146 }
147
SetSendPeriodicFeedback(bool send_periodic_feedback)148 void ReceiveSideCongestionController::SetSendPeriodicFeedback(
149 bool send_periodic_feedback) {
150 remote_estimator_proxy_.SetSendPeriodicFeedback(send_periodic_feedback);
151 }
152
153 RemoteBitrateEstimator*
GetRemoteBitrateEstimator(bool send_side_bwe)154 ReceiveSideCongestionController::GetRemoteBitrateEstimator(bool send_side_bwe) {
155 if (send_side_bwe) {
156 return &remote_estimator_proxy_;
157 } else {
158 return &remote_bitrate_estimator_;
159 }
160 }
161
162 const RemoteBitrateEstimator*
GetRemoteBitrateEstimator(bool send_side_bwe) const163 ReceiveSideCongestionController::GetRemoteBitrateEstimator(
164 bool send_side_bwe) const {
165 if (send_side_bwe) {
166 return &remote_estimator_proxy_;
167 } else {
168 return &remote_bitrate_estimator_;
169 }
170 }
171
OnRttUpdate(int64_t avg_rtt_ms,int64_t max_rtt_ms)172 void ReceiveSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms,
173 int64_t max_rtt_ms) {
174 remote_bitrate_estimator_.OnRttUpdate(avg_rtt_ms, max_rtt_ms);
175 }
176
OnBitrateChanged(int bitrate_bps)177 void ReceiveSideCongestionController::OnBitrateChanged(int bitrate_bps) {
178 remote_estimator_proxy_.OnBitrateChanged(bitrate_bps);
179 }
180
TimeUntilNextProcess()181 int64_t ReceiveSideCongestionController::TimeUntilNextProcess() {
182 return remote_bitrate_estimator_.TimeUntilNextProcess();
183 }
184
Process()185 void ReceiveSideCongestionController::Process() {
186 remote_bitrate_estimator_.Process();
187 }
188
189 } // namespace webrtc
190