• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
WrappingBitrateEstimator(int engine_id,RemoteBitrateObserver * observer,Clock * clock,ProcessThread * process_thread,const Config & config)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   }
~WrappingBitrateEstimator()54   virtual ~WrappingBitrateEstimator() {
55     process_thread_->DeRegisterModule(rbe_.get());
56   }
57 
IncomingPacket(int64_t arrival_time_ms,int payload_size,const RTPHeader & header)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 
Process()66   virtual int32_t Process() {
67     assert(false && "Not supposed to register the WrappingBitrateEstimator!");
68     return 0;
69   }
70 
TimeUntilNextProcess()71   virtual int32_t TimeUntilNextProcess() {
72     assert(false && "Not supposed to register the WrappingBitrateEstimator!");
73     return 0;
74   }
75 
OnRttUpdate(uint32_t rtt)76   virtual void OnRttUpdate(uint32_t rtt) {
77     CriticalSectionScoped cs(crit_sect_.get());
78     rbe_->OnRttUpdate(rtt);
79   }
80 
RemoveStream(unsigned int ssrc)81   virtual void RemoveStream(unsigned int ssrc) {
82     CriticalSectionScoped cs(crit_sect_.get());
83     rbe_->RemoveStream(ssrc);
84   }
85 
LatestEstimate(std::vector<unsigned int> * ssrcs,unsigned int * bitrate_bps) const86   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 
GetStats(ReceiveBandwidthEstimatorStats * output) const92   virtual bool GetStats(ReceiveBandwidthEstimatorStats* output) const {
93     CriticalSectionScoped cs(crit_sect_.get());
94     return rbe_->GetStats(output);
95   }
96 
SetConfig(const webrtc::Config & config)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:
PickEstimatorFromHeader(const RTPHeader & header)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.
PickEstimator()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 
ChannelGroup(int engine_id,ProcessThread * process_thread,const Config * config)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 
~ChannelGroup()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 
AddChannel(int channel_id)199 void ChannelGroup::AddChannel(int channel_id) {
200   channels_.insert(channel_id);
201 }
202 
RemoveChannel(int channel_id,unsigned int ssrc)203 void ChannelGroup::RemoveChannel(int channel_id, unsigned int ssrc) {
204   channels_.erase(channel_id);
205   remote_bitrate_estimator_->RemoveStream(ssrc);
206 }
207 
HasChannel(int channel_id)208 bool ChannelGroup::HasChannel(int channel_id) {
209   return channels_.find(channel_id) != channels_.end();
210 }
211 
Empty()212 bool ChannelGroup::Empty() {
213   return channels_.empty();
214 }
215 
GetBitrateController()216 BitrateController* ChannelGroup::GetBitrateController() {
217   return bitrate_controller_.get();
218 }
219 
GetRemoteBitrateEstimator()220 RemoteBitrateEstimator* ChannelGroup::GetRemoteBitrateEstimator() {
221   return remote_bitrate_estimator_.get();
222 }
223 
GetCallStats()224 CallStats* ChannelGroup::GetCallStats() {
225   return call_stats_.get();
226 }
227 
GetEncoderStateFeedback()228 EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() {
229   return encoder_state_feedback_.get();
230 }
231 
SetChannelRembStatus(int channel_id,bool sender,bool receiver,ViEChannel * channel)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 
SetBandwidthEstimationConfig(const webrtc::Config & config)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