receive_side_congestion_controller.cc (6968B)
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 <algorithm> 14 #include <cstdint> 15 #include <memory> 16 #include <utility> 17 18 #include "api/environment/environment.h" 19 #include "api/media_types.h" 20 #include "api/sequence_checker.h" 21 #include "api/units/data_rate.h" 22 #include "api/units/time_delta.h" 23 #include "api/units/timestamp.h" 24 #include "modules/congestion_controller/remb_throttler.h" 25 #include "modules/remote_bitrate_estimator/congestion_control_feedback_generator.h" 26 #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h" 27 #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h" 28 #include "modules/remote_bitrate_estimator/transport_sequence_number_feedback_generator.h" 29 #include "modules/rtp_rtcp/source/rtp_header_extensions.h" 30 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 31 #include "rtc_base/experiments/field_trial_parser.h" 32 #include "rtc_base/logging.h" 33 #include "rtc_base/synchronization/mutex.h" 34 35 namespace webrtc { 36 37 namespace { 38 const uint32_t kTimeOffsetSwitchThreshold = 30; 39 } // namespace 40 41 void ReceiveSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms, 42 int64_t max_rtt_ms) { 43 MutexLock lock(&mutex_); 44 rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); 45 } 46 47 void ReceiveSideCongestionController::RemoveStream(uint32_t ssrc) { 48 MutexLock lock(&mutex_); 49 rbe_->RemoveStream(ssrc); 50 } 51 52 DataRate ReceiveSideCongestionController::LatestReceiveSideEstimate() const { 53 MutexLock lock(&mutex_); 54 return rbe_->LatestEstimate(); 55 } 56 57 void ReceiveSideCongestionController::PickEstimator( 58 bool has_absolute_send_time) { 59 if (has_absolute_send_time) { 60 // If we see AST in header, switch RBE strategy immediately. 61 if (!using_absolute_send_time_) { 62 RTC_LOG(LS_INFO) 63 << "WrappingBitrateEstimator: Switching to absolute send time RBE."; 64 using_absolute_send_time_ = true; 65 rbe_ = std::make_unique<RemoteBitrateEstimatorAbsSendTime>( 66 env_, &remb_throttler_); 67 } 68 packets_since_absolute_send_time_ = 0; 69 } else { 70 // When we don't see AST, wait for a few packets before going back to TOF. 71 if (using_absolute_send_time_) { 72 ++packets_since_absolute_send_time_; 73 if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) { 74 RTC_LOG(LS_INFO) 75 << "WrappingBitrateEstimator: Switching to transmission " 76 "time offset RBE."; 77 using_absolute_send_time_ = false; 78 rbe_ = std::make_unique<RemoteBitrateEstimatorSingleStream>( 79 env_, &remb_throttler_); 80 } 81 } 82 } 83 } 84 85 ReceiveSideCongestionController::ReceiveSideCongestionController( 86 const Environment& env, 87 TransportSequenceNumberFeedbackGenenerator::RtcpSender feedback_sender, 88 RembThrottler::RembSender remb_sender) 89 : env_(env), 90 remb_throttler_(std::move(remb_sender), &env_.clock()), 91 transport_sequence_number_feedback_generator_(feedback_sender), 92 congestion_control_feedback_generator_(env, feedback_sender), 93 rbe_(std::make_unique<RemoteBitrateEstimatorSingleStream>( 94 env_, 95 &remb_throttler_)), 96 using_absolute_send_time_(false), 97 packets_since_absolute_send_time_(0) { 98 FieldTrialParameter<bool> force_send_rfc8888_feedback("force_send", false); 99 ParseFieldTrial( 100 {&force_send_rfc8888_feedback}, 101 env.field_trials().Lookup("WebRTC-RFC8888CongestionControlFeedback")); 102 if (force_send_rfc8888_feedback) { 103 EnableSendCongestionControlFeedbackAccordingToRfc8888(); 104 } 105 } 106 107 void ReceiveSideCongestionController:: 108 EnableSendCongestionControlFeedbackAccordingToRfc8888() { 109 RTC_DCHECK_RUN_ON(&sequence_checker_); 110 send_rfc8888_congestion_feedback_ = true; 111 } 112 113 void ReceiveSideCongestionController::OnReceivedPacket( 114 const RtpPacketReceived& packet, 115 MediaType media_type) { 116 bool has_transport_sequence_number = 117 packet.HasExtension<TransportSequenceNumber>() || 118 packet.HasExtension<TransportSequenceNumberV2>(); 119 if (send_rfc8888_congestion_feedback_) { 120 RTC_DCHECK_RUN_ON(&sequence_checker_); 121 congestion_control_feedback_generator_.OnReceivedPacket(packet); 122 // TODO(https://bugs.webrtc.org/374197376): Utilize RFC 8888 feedback, which 123 // provides comprehensive details similar to transport-cc. To ensure a 124 // smooth transition, we will continue using transport sequence number 125 // feedback temporarily. Once validation is complete, we will fully 126 // transition to using RFC 8888 feedback exclusively. 127 if (has_transport_sequence_number) { 128 transport_sequence_number_feedback_generator_.OnReceivedPacket(packet); 129 } 130 return; 131 } 132 if (media_type == MediaType::AUDIO && !has_transport_sequence_number) { 133 // For audio, we only support send side BWE. 134 return; 135 } 136 137 if (has_transport_sequence_number) { 138 // Send-side BWE. 139 transport_sequence_number_feedback_generator_.OnReceivedPacket(packet); 140 } else { 141 // Receive-side BWE. 142 MutexLock lock(&mutex_); 143 PickEstimator(packet.HasExtension<AbsoluteSendTime>()); 144 rbe_->IncomingPacket(packet); 145 } 146 } 147 148 void ReceiveSideCongestionController::OnBitrateChanged(int bitrate_bps) { 149 RTC_DCHECK_RUN_ON(&sequence_checker_); 150 DataRate send_bandwidth_estimate = DataRate::BitsPerSec(bitrate_bps); 151 transport_sequence_number_feedback_generator_.OnSendBandwidthEstimateChanged( 152 send_bandwidth_estimate); 153 congestion_control_feedback_generator_.OnSendBandwidthEstimateChanged( 154 send_bandwidth_estimate); 155 } 156 157 TimeDelta ReceiveSideCongestionController::MaybeProcess() { 158 Timestamp now = env_.clock().CurrentTime(); 159 if (send_rfc8888_congestion_feedback_) { 160 RTC_DCHECK_RUN_ON(&sequence_checker_); 161 TimeDelta time_until_cc_rep = 162 congestion_control_feedback_generator_.Process(now); 163 TimeDelta time_until_rep = 164 transport_sequence_number_feedback_generator_.Process(now); 165 TimeDelta time_until = std::min(time_until_cc_rep, time_until_rep); 166 return std::max(time_until, TimeDelta::Zero()); 167 } 168 mutex_.Lock(); 169 TimeDelta time_until_rbe = rbe_->Process(); 170 mutex_.Unlock(); 171 TimeDelta time_until_rep = 172 transport_sequence_number_feedback_generator_.Process(now); 173 TimeDelta time_until = std::min(time_until_rbe, time_until_rep); 174 return std::max(time_until, TimeDelta::Zero()); 175 } 176 177 void ReceiveSideCongestionController::SetMaxDesiredReceiveBitrate( 178 DataRate bitrate) { 179 remb_throttler_.SetMaxDesiredReceiveBitrate(bitrate); 180 } 181 182 } // namespace webrtc