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