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