1 /* 2 * Copyright (c) 2012 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 "webrtc/call/congestion_controller.h" 12 13 #include "webrtc/base/checks.h" 14 #include "webrtc/base/logging.h" 15 #include "webrtc/base/thread_annotations.h" 16 #include "webrtc/common.h" 17 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" 18 #include "webrtc/modules/pacing/paced_sender.h" 19 #include "webrtc/modules/pacing/packet_router.h" 20 #include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h" 21 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h" 22 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h" 23 #include "webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h" 24 #include "webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h" 25 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 26 #include "webrtc/modules/utility/include/process_thread.h" 27 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 28 #include "webrtc/video/call_stats.h" 29 #include "webrtc/video/payload_router.h" 30 #include "webrtc/video/vie_encoder.h" 31 #include "webrtc/video/vie_remb.h" 32 #include "webrtc/voice_engine/include/voe_video_sync.h" 33 34 namespace webrtc { 35 namespace { 36 37 static const uint32_t kTimeOffsetSwitchThreshold = 30; 38 39 class WrappingBitrateEstimator : public RemoteBitrateEstimator { 40 public: 41 WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock) 42 : observer_(observer), 43 clock_(clock), 44 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), 45 rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)), 46 using_absolute_send_time_(false), 47 packets_since_absolute_send_time_(0), 48 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) {} 49 50 virtual ~WrappingBitrateEstimator() {} 51 52 void IncomingPacket(int64_t arrival_time_ms, 53 size_t payload_size, 54 const RTPHeader& header, 55 bool was_paced) override { 56 CriticalSectionScoped cs(crit_sect_.get()); 57 PickEstimatorFromHeader(header); 58 rbe_->IncomingPacket(arrival_time_ms, payload_size, header, was_paced); 59 } 60 61 int32_t Process() override { 62 CriticalSectionScoped cs(crit_sect_.get()); 63 return rbe_->Process(); 64 } 65 66 int64_t TimeUntilNextProcess() override { 67 CriticalSectionScoped cs(crit_sect_.get()); 68 return rbe_->TimeUntilNextProcess(); 69 } 70 71 void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override { 72 CriticalSectionScoped cs(crit_sect_.get()); 73 rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); 74 } 75 76 void RemoveStream(unsigned int ssrc) override { 77 CriticalSectionScoped cs(crit_sect_.get()); 78 rbe_->RemoveStream(ssrc); 79 } 80 81 bool LatestEstimate(std::vector<unsigned int>* ssrcs, 82 unsigned int* bitrate_bps) const override { 83 CriticalSectionScoped cs(crit_sect_.get()); 84 return rbe_->LatestEstimate(ssrcs, bitrate_bps); 85 } 86 87 bool GetStats(ReceiveBandwidthEstimatorStats* output) const override { 88 CriticalSectionScoped cs(crit_sect_.get()); 89 return rbe_->GetStats(output); 90 } 91 92 void SetMinBitrate(int min_bitrate_bps) { 93 CriticalSectionScoped cs(crit_sect_.get()); 94 rbe_->SetMinBitrate(min_bitrate_bps); 95 min_bitrate_bps_ = min_bitrate_bps; 96 } 97 98 private: 99 void PickEstimatorFromHeader(const RTPHeader& header) 100 EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) { 101 if (header.extension.hasAbsoluteSendTime) { 102 // If we see AST in header, switch RBE strategy immediately. 103 if (!using_absolute_send_time_) { 104 LOG(LS_INFO) << 105 "WrappingBitrateEstimator: Switching to absolute send time RBE."; 106 using_absolute_send_time_ = true; 107 PickEstimator(); 108 } 109 packets_since_absolute_send_time_ = 0; 110 } else { 111 // When we don't see AST, wait for a few packets before going back to TOF. 112 if (using_absolute_send_time_) { 113 ++packets_since_absolute_send_time_; 114 if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) { 115 LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission " 116 << "time offset RBE."; 117 using_absolute_send_time_ = false; 118 PickEstimator(); 119 } 120 } 121 } 122 } 123 124 // Instantiate RBE for Time Offset or Absolute Send Time extensions. 125 void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) { 126 if (using_absolute_send_time_) { 127 rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_)); 128 } else { 129 rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_)); 130 } 131 rbe_->SetMinBitrate(min_bitrate_bps_); 132 } 133 134 RemoteBitrateObserver* observer_; 135 Clock* clock_; 136 rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; 137 rtc::scoped_ptr<RemoteBitrateEstimator> rbe_; 138 bool using_absolute_send_time_; 139 uint32_t packets_since_absolute_send_time_; 140 int min_bitrate_bps_; 141 142 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator); 143 }; 144 145 } // namespace 146 147 CongestionController::CongestionController(ProcessThread* process_thread, 148 CallStats* call_stats, 149 BitrateObserver* bitrate_observer) 150 : remb_(new VieRemb(Clock::GetRealTimeClock())), 151 packet_router_(new PacketRouter()), 152 pacer_(new PacedSender(Clock::GetRealTimeClock(), 153 packet_router_.get(), 154 BitrateController::kDefaultStartBitrateKbps, 155 PacedSender::kDefaultPaceMultiplier * 156 BitrateController::kDefaultStartBitrateKbps, 157 0)), 158 remote_bitrate_estimator_( 159 new WrappingBitrateEstimator(remb_.get(), Clock::GetRealTimeClock())), 160 remote_estimator_proxy_( 161 new RemoteEstimatorProxy(Clock::GetRealTimeClock(), 162 packet_router_.get())), 163 process_thread_(process_thread), 164 call_stats_(call_stats), 165 pacer_thread_(ProcessThread::Create("PacerThread")), 166 // Constructed last as this object calls the provided callback on 167 // construction. 168 bitrate_controller_( 169 BitrateController::CreateBitrateController(Clock::GetRealTimeClock(), 170 bitrate_observer)), 171 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) { 172 call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get()); 173 174 pacer_thread_->RegisterModule(pacer_.get()); 175 pacer_thread_->Start(); 176 177 process_thread->RegisterModule(remote_estimator_proxy_.get()); 178 process_thread->RegisterModule(remote_bitrate_estimator_.get()); 179 process_thread->RegisterModule(bitrate_controller_.get()); 180 } 181 182 CongestionController::~CongestionController() { 183 pacer_thread_->Stop(); 184 pacer_thread_->DeRegisterModule(pacer_.get()); 185 process_thread_->DeRegisterModule(bitrate_controller_.get()); 186 process_thread_->DeRegisterModule(remote_bitrate_estimator_.get()); 187 process_thread_->DeRegisterModule(remote_estimator_proxy_.get()); 188 call_stats_->DeregisterStatsObserver(remote_bitrate_estimator_.get()); 189 if (transport_feedback_adapter_.get()) 190 call_stats_->DeregisterStatsObserver(transport_feedback_adapter_.get()); 191 RTC_DCHECK(!remb_->InUse()); 192 RTC_DCHECK(encoders_.empty()); 193 } 194 195 void CongestionController::AddEncoder(ViEEncoder* encoder) { 196 rtc::CritScope lock(&encoder_crit_); 197 encoders_.push_back(encoder); 198 } 199 200 void CongestionController::RemoveEncoder(ViEEncoder* encoder) { 201 rtc::CritScope lock(&encoder_crit_); 202 for (auto it = encoders_.begin(); it != encoders_.end(); ++it) { 203 if (*it == encoder) { 204 encoders_.erase(it); 205 return; 206 } 207 } 208 } 209 210 void CongestionController::SetBweBitrates(int min_bitrate_bps, 211 int start_bitrate_bps, 212 int max_bitrate_bps) { 213 if (start_bitrate_bps > 0) 214 bitrate_controller_->SetStartBitrate(start_bitrate_bps); 215 bitrate_controller_->SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps); 216 if (remote_bitrate_estimator_.get()) 217 remote_bitrate_estimator_->SetMinBitrate(min_bitrate_bps); 218 if (transport_feedback_adapter_.get()) 219 transport_feedback_adapter_->GetBitrateEstimator()->SetMinBitrate( 220 min_bitrate_bps); 221 min_bitrate_bps_ = min_bitrate_bps; 222 } 223 224 BitrateController* CongestionController::GetBitrateController() const { 225 return bitrate_controller_.get(); 226 } 227 228 RemoteBitrateEstimator* CongestionController::GetRemoteBitrateEstimator( 229 bool send_side_bwe) const { 230 231 if (send_side_bwe) 232 return remote_estimator_proxy_.get(); 233 else 234 return remote_bitrate_estimator_.get(); 235 } 236 237 TransportFeedbackObserver* 238 CongestionController::GetTransportFeedbackObserver() { 239 if (transport_feedback_adapter_.get() == nullptr) { 240 transport_feedback_adapter_.reset(new TransportFeedbackAdapter( 241 bitrate_controller_->CreateRtcpBandwidthObserver(), 242 Clock::GetRealTimeClock(), process_thread_)); 243 transport_feedback_adapter_->SetBitrateEstimator( 244 new RemoteBitrateEstimatorAbsSendTime( 245 transport_feedback_adapter_.get(), Clock::GetRealTimeClock())); 246 transport_feedback_adapter_->GetBitrateEstimator()->SetMinBitrate( 247 min_bitrate_bps_); 248 call_stats_->RegisterStatsObserver(transport_feedback_adapter_.get()); 249 } 250 return transport_feedback_adapter_.get(); 251 } 252 253 void CongestionController::UpdatePacerBitrate(int bitrate_kbps, 254 int max_bitrate_kbps, 255 int min_bitrate_kbps) { 256 pacer_->UpdateBitrate(bitrate_kbps, max_bitrate_kbps, min_bitrate_kbps); 257 } 258 259 int64_t CongestionController::GetPacerQueuingDelayMs() const { 260 return pacer_->QueueInMs(); 261 } 262 263 // TODO(mflodman): Move out of this class. 264 void CongestionController::SetChannelRembStatus(bool sender, 265 bool receiver, 266 RtpRtcp* rtp_module) { 267 rtp_module->SetREMBStatus(sender || receiver); 268 if (sender) { 269 remb_->AddRembSender(rtp_module); 270 } else { 271 remb_->RemoveRembSender(rtp_module); 272 } 273 if (receiver) { 274 remb_->AddReceiveChannel(rtp_module); 275 } else { 276 remb_->RemoveReceiveChannel(rtp_module); 277 } 278 } 279 280 void CongestionController::SignalNetworkState(NetworkState state) { 281 if (state == kNetworkUp) { 282 pacer_->Resume(); 283 } else { 284 pacer_->Pause(); 285 } 286 } 287 288 void CongestionController::OnSentPacket(const rtc::SentPacket& sent_packet) { 289 if (transport_feedback_adapter_) { 290 transport_feedback_adapter_->OnSentPacket(sent_packet.packet_id, 291 sent_packet.send_time_ms); 292 } 293 } 294 } // namespace webrtc 295