Home | History | Annotate | Download | only in video_engine
      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/video_engine/vie_channel_group.h"
     12 
     13 #include "webrtc/base/thread_annotations.h"
     14 #include "webrtc/common.h"
     15 #include "webrtc/experiments.h"
     16 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
     17 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
     18 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
     19 #include "webrtc/modules/utility/interface/process_thread.h"
     20 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     21 #include "webrtc/system_wrappers/interface/logging.h"
     22 #include "webrtc/video_engine/call_stats.h"
     23 #include "webrtc/video_engine/encoder_state_feedback.h"
     24 #include "webrtc/video_engine/vie_channel.h"
     25 #include "webrtc/video_engine/vie_encoder.h"
     26 #include "webrtc/video_engine/vie_remb.h"
     27 
     28 namespace webrtc {
     29 namespace {
     30 
     31 static const uint32_t kTimeOffsetSwitchThreshold = 30;
     32 
     33 class WrappingBitrateEstimator : public RemoteBitrateEstimator {
     34  public:
     35   WrappingBitrateEstimator(int engine_id,
     36                            RemoteBitrateObserver* observer,
     37                            Clock* clock,
     38                            const Config& config)
     39       : observer_(observer),
     40         clock_(clock),
     41         crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
     42         engine_id_(engine_id),
     43         min_bitrate_bps_(config.Get<RemoteBitrateEstimatorMinRate>().min_rate),
     44         rate_control_type_(kMimdControl),
     45         rbe_(RemoteBitrateEstimatorFactory().Create(observer_,
     46                                                     clock_,
     47                                                     rate_control_type_,
     48                                                     min_bitrate_bps_)),
     49         using_absolute_send_time_(false),
     50         packets_since_absolute_send_time_(0) {
     51   }
     52 
     53   virtual ~WrappingBitrateEstimator() {}
     54 
     55   virtual void IncomingPacket(int64_t arrival_time_ms,
     56                               int payload_size,
     57                               const RTPHeader& header) OVERRIDE {
     58     CriticalSectionScoped cs(crit_sect_.get());
     59     PickEstimatorFromHeader(header);
     60     rbe_->IncomingPacket(arrival_time_ms, payload_size, header);
     61   }
     62 
     63   virtual int32_t Process() OVERRIDE {
     64     CriticalSectionScoped cs(crit_sect_.get());
     65     return rbe_->Process();
     66   }
     67 
     68   virtual int32_t TimeUntilNextProcess() OVERRIDE {
     69     CriticalSectionScoped cs(crit_sect_.get());
     70     return rbe_->TimeUntilNextProcess();
     71   }
     72 
     73   virtual void OnRttUpdate(uint32_t rtt) OVERRIDE {
     74     CriticalSectionScoped cs(crit_sect_.get());
     75     rbe_->OnRttUpdate(rtt);
     76   }
     77 
     78   virtual void RemoveStream(unsigned int ssrc) OVERRIDE {
     79     CriticalSectionScoped cs(crit_sect_.get());
     80     rbe_->RemoveStream(ssrc);
     81   }
     82 
     83   virtual bool LatestEstimate(std::vector<unsigned int>* ssrcs,
     84                               unsigned int* bitrate_bps) const OVERRIDE {
     85     CriticalSectionScoped cs(crit_sect_.get());
     86     return rbe_->LatestEstimate(ssrcs, bitrate_bps);
     87   }
     88 
     89   virtual bool GetStats(ReceiveBandwidthEstimatorStats* output) const OVERRIDE {
     90     CriticalSectionScoped cs(crit_sect_.get());
     91     return rbe_->GetStats(output);
     92   }
     93 
     94   void SetConfig(const webrtc::Config& config) {
     95     CriticalSectionScoped cs(crit_sect_.get());
     96     RateControlType new_control_type =
     97         config.Get<AimdRemoteRateControl>().enabled ? kAimdControl :
     98                                                       kMimdControl;
     99     if (new_control_type != rate_control_type_) {
    100       rate_control_type_ = new_control_type;
    101       PickEstimator();
    102     }
    103   }
    104 
    105  private:
    106   void PickEstimatorFromHeader(const RTPHeader& header)
    107       EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
    108     if (header.extension.hasAbsoluteSendTime) {
    109       // If we see AST in header, switch RBE strategy immediately.
    110       if (!using_absolute_send_time_) {
    111         LOG(LS_INFO) <<
    112             "WrappingBitrateEstimator: Switching to absolute send time RBE.";
    113         using_absolute_send_time_ = true;
    114         PickEstimator();
    115       }
    116       packets_since_absolute_send_time_ = 0;
    117     } else {
    118       // When we don't see AST, wait for a few packets before going back to TOF.
    119       if (using_absolute_send_time_) {
    120         ++packets_since_absolute_send_time_;
    121         if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
    122           LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission "
    123                        << "time offset RBE.";
    124           using_absolute_send_time_ = false;
    125           PickEstimator();
    126         }
    127       }
    128     }
    129   }
    130 
    131   // Instantiate RBE for Time Offset or Absolute Send Time extensions.
    132   void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
    133     if (using_absolute_send_time_) {
    134       rbe_.reset(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create(
    135           observer_, clock_, rate_control_type_, min_bitrate_bps_));
    136     } else {
    137       rbe_.reset(RemoteBitrateEstimatorFactory().Create(
    138           observer_, clock_, rate_control_type_, min_bitrate_bps_));
    139     }
    140   }
    141 
    142   RemoteBitrateObserver* observer_;
    143   Clock* clock_;
    144   scoped_ptr<CriticalSectionWrapper> crit_sect_;
    145   const int engine_id_;
    146   const uint32_t min_bitrate_bps_;
    147   RateControlType rate_control_type_;
    148   scoped_ptr<RemoteBitrateEstimator> rbe_;
    149   bool using_absolute_send_time_;
    150   uint32_t packets_since_absolute_send_time_;
    151 
    152   DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator);
    153 };
    154 }  // namespace
    155 
    156 ChannelGroup::ChannelGroup(int engine_id,
    157                            ProcessThread* process_thread,
    158                            const Config* config)
    159     : remb_(new VieRemb()),
    160       bitrate_controller_(
    161           BitrateController::CreateBitrateController(Clock::GetRealTimeClock(),
    162                                                      true)),
    163       call_stats_(new CallStats()),
    164       encoder_state_feedback_(new EncoderStateFeedback()),
    165       config_(config),
    166       own_config_(),
    167       process_thread_(process_thread) {
    168   if (!config) {
    169     own_config_.reset(new Config);
    170     config_ = own_config_.get();
    171   }
    172   assert(config_);  // Must have a valid config pointer here.
    173 
    174   remote_bitrate_estimator_.reset(
    175       new WrappingBitrateEstimator(engine_id,
    176                                    remb_.get(),
    177                                    Clock::GetRealTimeClock(),
    178                                    *config_));
    179 
    180   call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get());
    181 
    182   process_thread->RegisterModule(remote_bitrate_estimator_.get());
    183   process_thread->RegisterModule(call_stats_.get());
    184   process_thread->RegisterModule(bitrate_controller_.get());
    185 }
    186 
    187 ChannelGroup::~ChannelGroup() {
    188   process_thread_->DeRegisterModule(bitrate_controller_.get());
    189   process_thread_->DeRegisterModule(call_stats_.get());
    190   process_thread_->DeRegisterModule(remote_bitrate_estimator_.get());
    191   call_stats_->DeregisterStatsObserver(remote_bitrate_estimator_.get());
    192   assert(channels_.empty());
    193   assert(!remb_->InUse());
    194 }
    195 
    196 void ChannelGroup::AddChannel(int channel_id) {
    197   channels_.insert(channel_id);
    198 }
    199 
    200 void ChannelGroup::RemoveChannel(int channel_id, unsigned int ssrc) {
    201   channels_.erase(channel_id);
    202   remote_bitrate_estimator_->RemoveStream(ssrc);
    203 }
    204 
    205 bool ChannelGroup::HasChannel(int channel_id) {
    206   return channels_.find(channel_id) != channels_.end();
    207 }
    208 
    209 bool ChannelGroup::Empty() {
    210   return channels_.empty();
    211 }
    212 
    213 BitrateController* ChannelGroup::GetBitrateController() {
    214   return bitrate_controller_.get();
    215 }
    216 
    217 RemoteBitrateEstimator* ChannelGroup::GetRemoteBitrateEstimator() {
    218   return remote_bitrate_estimator_.get();
    219 }
    220 
    221 CallStats* ChannelGroup::GetCallStats() {
    222   return call_stats_.get();
    223 }
    224 
    225 EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() {
    226   return encoder_state_feedback_.get();
    227 }
    228 
    229 bool ChannelGroup::SetChannelRembStatus(int channel_id, bool sender,
    230                                         bool receiver, ViEChannel* channel) {
    231   // Update the channel state.
    232   if (sender || receiver) {
    233     if (!channel->EnableRemb(true)) {
    234       return false;
    235     }
    236   } else {
    237     channel->EnableRemb(false);
    238   }
    239   // Update the REMB instance with necessary RTP modules.
    240   RtpRtcp* rtp_module = channel->rtp_rtcp();
    241   if (sender) {
    242     remb_->AddRembSender(rtp_module);
    243   } else {
    244     remb_->RemoveRembSender(rtp_module);
    245   }
    246   if (receiver) {
    247     remb_->AddReceiveChannel(rtp_module);
    248   } else {
    249     remb_->RemoveReceiveChannel(rtp_module);
    250   }
    251   return true;
    252 }
    253 
    254 void ChannelGroup::SetBandwidthEstimationConfig(const webrtc::Config& config) {
    255   WrappingBitrateEstimator* estimator =
    256       static_cast<WrappingBitrateEstimator*>(remote_bitrate_estimator_.get());
    257   estimator->SetConfig(config);
    258 }
    259 }  // namespace webrtc
    260