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