2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/video_engine/vie_channel_group.h"
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"
31 static const uint32_t kTimeOffsetSwitchThreshold = 30;
33 class WrappingBitrateEstimator : public RemoteBitrateEstimator {
35 WrappingBitrateEstimator(int engine_id,
36 RemoteBitrateObserver* observer,
39 : observer_(observer),
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_,
49 using_absolute_send_time_(false),
50 packets_since_absolute_send_time_(0) {
53 virtual ~WrappingBitrateEstimator() {}
55 virtual void IncomingPacket(int64_t arrival_time_ms,
57 const RTPHeader& header) OVERRIDE {
58 CriticalSectionScoped cs(crit_sect_.get());
59 PickEstimatorFromHeader(header);
60 rbe_->IncomingPacket(arrival_time_ms, payload_size, header);
63 virtual int32_t Process() OVERRIDE {
64 CriticalSectionScoped cs(crit_sect_.get());
65 return rbe_->Process();
68 virtual int32_t TimeUntilNextProcess() OVERRIDE {
69 CriticalSectionScoped cs(crit_sect_.get());
70 return rbe_->TimeUntilNextProcess();
73 virtual void OnRttUpdate(uint32_t rtt) OVERRIDE {
74 CriticalSectionScoped cs(crit_sect_.get());
75 rbe_->OnRttUpdate(rtt);
78 virtual void RemoveStream(unsigned int ssrc) OVERRIDE {
79 CriticalSectionScoped cs(crit_sect_.get());
80 rbe_->RemoveStream(ssrc);
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);
89 virtual bool GetStats(ReceiveBandwidthEstimatorStats* output) const OVERRIDE {
90 CriticalSectionScoped cs(crit_sect_.get());
91 return rbe_->GetStats(output);
94 void SetConfig(const webrtc::Config& config) {
95 CriticalSectionScoped cs(crit_sect_.get());
96 RateControlType new_control_type =
97 config.Get<AimdRemoteRateControl>().enabled ? kAimdControl :
99 if (new_control_type != rate_control_type_) {
100 rate_control_type_ = new_control_type;
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_) {
112 "WrappingBitrateEstimator: Switching to absolute send time RBE.";
113 using_absolute_send_time_ = true;
116 packets_since_absolute_send_time_ = 0;
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;
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_));
137 rbe_.reset(RemoteBitrateEstimatorFactory().Create(
138 observer_, clock_, rate_control_type_, min_bitrate_bps_));
142 RemoteBitrateObserver* observer_;
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_;
152 DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator);
156 ChannelGroup::ChannelGroup(int engine_id,
157 ProcessThread* process_thread,
158 const Config* config)
159 : remb_(new VieRemb()),
161 BitrateController::CreateBitrateController(Clock::GetRealTimeClock(),
163 call_stats_(new CallStats()),
164 encoder_state_feedback_(new EncoderStateFeedback()),
167 process_thread_(process_thread) {
169 own_config_.reset(new Config);
170 config_ = own_config_.get();
172 assert(config_); // Must have a valid config pointer here.
174 remote_bitrate_estimator_.reset(
175 new WrappingBitrateEstimator(engine_id,
177 Clock::GetRealTimeClock(),
180 call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get());
182 process_thread->RegisterModule(remote_bitrate_estimator_.get());
183 process_thread->RegisterModule(call_stats_.get());
184 process_thread->RegisterModule(bitrate_controller_.get());
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());
196 void ChannelGroup::AddChannel(int channel_id) {
197 channels_.insert(channel_id);
200 void ChannelGroup::RemoveChannel(int channel_id, unsigned int ssrc) {
201 channels_.erase(channel_id);
202 remote_bitrate_estimator_->RemoveStream(ssrc);
205 bool ChannelGroup::HasChannel(int channel_id) {
206 return channels_.find(channel_id) != channels_.end();
209 bool ChannelGroup::Empty() {
210 return channels_.empty();
213 BitrateController* ChannelGroup::GetBitrateController() {
214 return bitrate_controller_.get();
217 RemoteBitrateEstimator* ChannelGroup::GetRemoteBitrateEstimator() {
218 return remote_bitrate_estimator_.get();
221 CallStats* ChannelGroup::GetCallStats() {
222 return call_stats_.get();
225 EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() {
226 return encoder_state_feedback_.get();
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)) {
237 channel->EnableRemb(false);
239 // Update the REMB instance with necessary RTP modules.
240 RtpRtcp* rtp_module = channel->rtp_rtcp();
242 remb_->AddRembSender(rtp_module);
244 remb_->RemoveRembSender(rtp_module);
247 remb_->AddReceiveChannel(rtp_module);
249 remb_->RemoveReceiveChannel(rtp_module);
254 void ChannelGroup::SetBandwidthEstimationConfig(const webrtc::Config& config) {
255 WrappingBitrateEstimator* estimator =
256 static_cast<WrappingBitrateEstimator*>(remote_bitrate_estimator_.get());
257 estimator->SetConfig(config);
259 } // namespace webrtc