congestion_controller.cc revision 5574dacd1f83d8ac83458d27e54be6507f3a06a4
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
28namespace webrtc {
29namespace {
30
31static const uint32_t kTimeOffsetSwitchThreshold = 30;
32
33class 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
162ChannelGroup::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
191ChannelGroup::~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
199void ChannelGroup::AddChannel(int channel_id) {
200  channels_.insert(channel_id);
201}
202
203void ChannelGroup::RemoveChannel(int channel_id, unsigned int ssrc) {
204  channels_.erase(channel_id);
205  remote_bitrate_estimator_->RemoveStream(ssrc);
206}
207
208bool ChannelGroup::HasChannel(int channel_id) {
209  return channels_.find(channel_id) != channels_.end();
210}
211
212bool ChannelGroup::Empty() {
213  return channels_.empty();
214}
215
216BitrateController* ChannelGroup::GetBitrateController() {
217  return bitrate_controller_.get();
218}
219
220RemoteBitrateEstimator* ChannelGroup::GetRemoteBitrateEstimator() {
221  return remote_bitrate_estimator_.get();
222}
223
224CallStats* ChannelGroup::GetCallStats() {
225  return call_stats_.get();
226}
227
228EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() {
229  return encoder_state_feedback_.get();
230}
231
232bool 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
257void 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