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