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: 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 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 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 199 void ChannelGroup::AddChannel(int channel_id) { 200 channels_.insert(channel_id); 201 } 202 203 void ChannelGroup::RemoveChannel(int channel_id, unsigned int ssrc) { 204 channels_.erase(channel_id); 205 remote_bitrate_estimator_->RemoveStream(ssrc); 206 } 207 208 bool ChannelGroup::HasChannel(int channel_id) { 209 return channels_.find(channel_id) != channels_.end(); 210 } 211 212 bool ChannelGroup::Empty() { 213 return channels_.empty(); 214 } 215 216 BitrateController* ChannelGroup::GetBitrateController() { 217 return bitrate_controller_.get(); 218 } 219 220 RemoteBitrateEstimator* ChannelGroup::GetRemoteBitrateEstimator() { 221 return remote_bitrate_estimator_.get(); 222 } 223 224 CallStats* ChannelGroup::GetCallStats() { 225 return call_stats_.get(); 226 } 227 228 EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() { 229 return encoder_state_feedback_.get(); 230 } 231 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 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