blob: 516833bd6badc73298a569b32de66efa6df5c889 [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +00001/*
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
andresp@webrtc.org04253922013-05-14 12:10:58 +000011#include "webrtc/video_engine/vie_channel_group.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000012
andresp@webrtc.org04253922013-05-14 12:10:58 +000013#include "webrtc/common.h"
henrik.lundin@webrtc.orgd2f95a82014-01-29 08:47:15 +000014#include "webrtc/experiments.h"
andresp@webrtc.org04253922013-05-14 12:10:58 +000015#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"
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000019#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
mflodman@webrtc.org022615b2014-04-07 10:56:31 +000020#include "webrtc/system_wrappers/interface/logging.h"
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +000021#include "webrtc/system_wrappers/interface/thread_annotations.h"
andresp@webrtc.org04253922013-05-14 12:10:58 +000022#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"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000027
28namespace webrtc {
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000029namespace {
30
pbos@webrtc.org46f72882013-12-16 12:24:44 +000031static const uint32_t kTimeOffsetSwitchThreshold = 30;
32
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000033class WrappingBitrateEstimator : public RemoteBitrateEstimator {
34 public:
andresp@webrtc.org65a971a2014-07-02 13:23:19 +000035 WrappingBitrateEstimator(int engine_id,
36 RemoteBitrateObserver* observer,
37 Clock* clock,
henrik.lundin@webrtc.orgd2f95a82014-01-29 08:47:15 +000038 const Config& config)
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000039 : observer_(observer),
40 clock_(clock),
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000041 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
pbos@webrtc.org46f72882013-12-16 12:24:44 +000042 engine_id_(engine_id),
henrik.lundin@webrtc.orgd2f95a82014-01-29 08:47:15 +000043 min_bitrate_bps_(config.Get<RemoteBitrateEstimatorMinRate>().min_rate),
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +000044 rate_control_type_(kMimdControl),
45 rbe_(RemoteBitrateEstimatorFactory().Create(observer_,
46 clock_,
47 rate_control_type_,
henrik.lundin@webrtc.orgc49a3fa2013-12-13 08:42:42 +000048 min_bitrate_bps_)),
pbos@webrtc.org46f72882013-12-16 12:24:44 +000049 using_absolute_send_time_(false),
50 packets_since_absolute_send_time_(0) {
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000051 }
andresp@webrtc.org65a971a2014-07-02 13:23:19 +000052
53 virtual ~WrappingBitrateEstimator() {}
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000054
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000055 virtual void IncomingPacket(int64_t arrival_time_ms,
56 int payload_size,
stefan@webrtc.orgd8ecee52013-06-04 12:15:40 +000057 const RTPHeader& header) {
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000058 CriticalSectionScoped cs(crit_sect_.get());
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +000059 PickEstimatorFromHeader(header);
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000060 rbe_->IncomingPacket(arrival_time_ms, payload_size, header);
61 }
62
63 virtual int32_t Process() {
andresp@webrtc.org65a971a2014-07-02 13:23:19 +000064 CriticalSectionScoped cs(crit_sect_.get());
65 return rbe_->Process();
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000066 }
67
68 virtual int32_t TimeUntilNextProcess() {
andresp@webrtc.org65a971a2014-07-02 13:23:19 +000069 CriticalSectionScoped cs(crit_sect_.get());
70 return rbe_->TimeUntilNextProcess();
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +000071 }
72
73 virtual void OnRttUpdate(uint32_t rtt) {
74 CriticalSectionScoped cs(crit_sect_.get());
75 rbe_->OnRttUpdate(rtt);
76 }
77
78 virtual void RemoveStream(unsigned int ssrc) {
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 {
85 CriticalSectionScoped cs(crit_sect_.get());
86 return rbe_->LatestEstimate(ssrcs, bitrate_bps);
87 }
88
jiayl@webrtc.orgd1e7fac2014-02-10 19:12:14 +000089 virtual bool GetStats(ReceiveBandwidthEstimatorStats* output) const {
90 CriticalSectionScoped cs(crit_sect_.get());
91 return rbe_->GetStats(output);
92 }
93
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +000094 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
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +0000105 private:
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +0000106 void PickEstimatorFromHeader(const RTPHeader& header)
107 EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
pbos@webrtc.org46f72882013-12-16 12:24:44 +0000108 if (header.extension.hasAbsoluteSendTime) {
109 // If we see AST in header, switch RBE strategy immediately.
110 if (!using_absolute_send_time_) {
mflodman@webrtc.org022615b2014-04-07 10:56:31 +0000111 LOG(LS_INFO) <<
112 "WrappingBitrateEstimator: Switching to absolute send time RBE.";
pbos@webrtc.org46f72882013-12-16 12:24:44 +0000113 using_absolute_send_time_ = true;
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +0000114 PickEstimator();
pbos@webrtc.org46f72882013-12-16 12:24:44 +0000115 }
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) {
mflodman@webrtc.org022615b2014-04-07 10:56:31 +0000122 LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission "
123 << "time offset RBE.";
pbos@webrtc.org46f72882013-12-16 12:24:44 +0000124 using_absolute_send_time_ = false;
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +0000125 PickEstimator();
pbos@webrtc.org46f72882013-12-16 12:24:44 +0000126 }
127 }
128 }
129 }
130
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +0000131 // Instantiate RBE for Time Offset or Absolute Send Time extensions.
132 void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +0000133 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 }
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +0000140 }
141
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +0000142 RemoteBitrateObserver* observer_;
143 Clock* clock_;
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +0000144 scoped_ptr<CriticalSectionWrapper> crit_sect_;
pbos@webrtc.org46f72882013-12-16 12:24:44 +0000145 const int engine_id_;
henrik.lundin@webrtc.orgc49a3fa2013-12-13 08:42:42 +0000146 const uint32_t min_bitrate_bps_;
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +0000147 RateControlType rate_control_type_;
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +0000148 scoped_ptr<RemoteBitrateEstimator> rbe_;
pbos@webrtc.org46f72882013-12-16 12:24:44 +0000149 bool using_absolute_send_time_;
150 uint32_t packets_since_absolute_send_time_;
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +0000151
152 DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator);
153};
154} // namespace
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000155
andresp@webrtc.orgd7aa2282014-03-26 21:00:21 +0000156ChannelGroup::ChannelGroup(int engine_id,
157 ProcessThread* process_thread,
henrik.lundin@webrtc.orgd2f95a82014-01-29 08:47:15 +0000158 const Config* config)
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000159 : remb_(new VieRemb()),
andresp@webrtc.orgd7aa2282014-03-26 21:00:21 +0000160 bitrate_controller_(
161 BitrateController::CreateBitrateController(Clock::GetRealTimeClock(),
162 true)),
mflodman@webrtc.org78696d32012-11-26 12:40:15 +0000163 call_stats_(new CallStats()),
mflodman@webrtc.org78696d32012-11-26 12:40:15 +0000164 encoder_state_feedback_(new EncoderStateFeedback()),
henrik.lundin@webrtc.orgd2f95a82014-01-29 08:47:15 +0000165 config_(config),
166 own_config_(),
mflodman@webrtc.org78696d32012-11-26 12:40:15 +0000167 process_thread_(process_thread) {
henrik.lundin@webrtc.orgd2f95a82014-01-29 08:47:15 +0000168 if (!config) {
169 own_config_.reset(new Config);
170 config_ = own_config_.get();
171 }
172 assert(config_); // Must have a valid config pointer here.
andresp@webrtc.org65a971a2014-07-02 13:23:19 +0000173
henrik.lundin@webrtc.orgd2f95a82014-01-29 08:47:15 +0000174 remote_bitrate_estimator_.reset(
andresp@webrtc.orgd7aa2282014-03-26 21:00:21 +0000175 new WrappingBitrateEstimator(engine_id,
176 remb_.get(),
177 Clock::GetRealTimeClock(),
andresp@webrtc.org65a971a2014-07-02 13:23:19 +0000178 *config_));
andresp@webrtc.orgd7aa2282014-03-26 21:00:21 +0000179
andresp@webrtc.org65a971a2014-07-02 13:23:19 +0000180 call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get());
181
182 process_thread->RegisterModule(remote_bitrate_estimator_.get());
mflodman@webrtc.org78696d32012-11-26 12:40:15 +0000183 process_thread->RegisterModule(call_stats_.get());
andresp@webrtc.orgd7aa2282014-03-26 21:00:21 +0000184 process_thread->RegisterModule(bitrate_controller_.get());
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000185}
186
187ChannelGroup::~ChannelGroup() {
andresp@webrtc.orgd7aa2282014-03-26 21:00:21 +0000188 process_thread_->DeRegisterModule(bitrate_controller_.get());
andrew@webrtc.orgca28c292014-03-25 19:42:39 +0000189 process_thread_->DeRegisterModule(call_stats_.get());
andresp@webrtc.org65a971a2014-07-02 13:23:19 +0000190 process_thread_->DeRegisterModule(remote_bitrate_estimator_.get());
andresp@webrtc.orgd7aa2282014-03-26 21:00:21 +0000191 call_stats_->DeregisterStatsObserver(remote_bitrate_estimator_.get());
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000192 assert(channels_.empty());
193 assert(!remb_->InUse());
194}
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +0000195
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000196void 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
mflodman@webrtc.org78696d32012-11-26 12:40:15 +0000221CallStats* ChannelGroup::GetCallStats() {
222 return call_stats_.get();
223}
224
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000225EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() {
226 return encoder_state_feedback_.get();
227}
228
mflodman@webrtc.orgbea854a2013-04-22 12:41:57 +0000229bool ChannelGroup::SetChannelRembStatus(int channel_id, bool sender,
230 bool receiver, ViEChannel* channel) {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000231 // Update the channel state.
232 if (sender || receiver) {
233 if (!channel->EnableRemb(true)) {
234 return false;
235 }
mflodman@webrtc.orgbea854a2013-04-22 12:41:57 +0000236 } else {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000237 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}
stefan@webrtc.org5d8c9542014-03-25 10:37:31 +0000253
254void ChannelGroup::SetBandwidthEstimationConfig(const webrtc::Config& config) {
255 WrappingBitrateEstimator* estimator =
256 static_cast<WrappingBitrateEstimator*>(remote_bitrate_estimator_.get());
257 estimator->SetConfig(config);
258}
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000259} // namespace webrtc