Home | History | Annotate | Download | only in call
      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