blob: 54aef21fd9eafc9133c363e556ebf232c6ed4f37 [file] [log] [blame]
nissecae45d02017-04-24 05:53:20 -07001/*
2 * Copyright (c) 2017 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 */
Sebastian Jansson91bb6672018-02-21 13:02:51 +010010#include <utility>
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020011#include <vector>
nissecae45d02017-04-24 05:53:20 -070012
Karl Wiberg918f50c2018-07-05 11:40:33 +020013#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "call/rtp_transport_controller_send.h"
Sebastian Jansson10211e92018-02-28 16:48:26 +010015#include "modules/congestion_controller/include/send_side_congestion_controller.h"
Sebastian Jansson19bea512018-03-13 19:07:46 +010016#include "modules/congestion_controller/rtp/include/send_side_congestion_controller.h"
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010017#include "rtc_base/location.h"
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010018#include "rtc_base/logging.h"
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020019#include "rtc_base/rate_limiter.h"
Sebastian Jansson19bea512018-03-13 19:07:46 +010020#include "system_wrappers/include/field_trial.h"
nissecae45d02017-04-24 05:53:20 -070021
22namespace webrtc {
Sebastian Jansson19bea512018-03-13 19:07:46 +010023namespace {
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020024static const int64_t kRetransmitWindowSizeMs = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +020025static const size_t kMaxOverheadBytes = 500;
Sebastian Jansson19bea512018-03-13 19:07:46 +010026const char kTaskQueueExperiment[] = "WebRTC-TaskQueueCongestionControl";
27using TaskQueueController = webrtc::webrtc_cc::SendSideCongestionController;
28
29bool TaskQueueExperimentEnabled() {
30 std::string trial = webrtc::field_trial::FindFullName(kTaskQueueExperiment);
31 return trial.find("Enable") == 0;
32}
33
34std::unique_ptr<SendSideCongestionControllerInterface> CreateController(
35 Clock* clock,
Sebastian Janssonbd9fe092018-05-07 16:33:50 +020036 rtc::TaskQueue* task_queue,
Sebastian Jansson19bea512018-03-13 19:07:46 +010037 webrtc::RtcEventLog* event_log,
38 PacedSender* pacer,
39 const BitrateConstraints& bitrate_config,
Sebastian Janssondfce03a2018-05-18 18:05:10 +020040 bool task_queue_controller,
41 NetworkControllerFactoryInterface* controller_factory) {
Sebastian Jansson19bea512018-03-13 19:07:46 +010042 if (task_queue_controller) {
Sebastian Jansson4e140da2018-04-13 13:25:19 +020043 RTC_LOG(LS_INFO) << "Using TaskQueue based SSCC";
Karl Wiberg918f50c2018-07-05 11:40:33 +020044 return absl::make_unique<webrtc::webrtc_cc::SendSideCongestionController>(
Sebastian Janssonbd9fe092018-05-07 16:33:50 +020045 clock, task_queue, event_log, pacer, bitrate_config.start_bitrate_bps,
Sebastian Janssondfce03a2018-05-18 18:05:10 +020046 bitrate_config.min_bitrate_bps, bitrate_config.max_bitrate_bps,
47 controller_factory);
Sebastian Jansson19bea512018-03-13 19:07:46 +010048 }
Sebastian Jansson4e140da2018-04-13 13:25:19 +020049 RTC_LOG(LS_INFO) << "Using Legacy SSCC";
Karl Wiberg918f50c2018-07-05 11:40:33 +020050 auto cc = absl::make_unique<webrtc::SendSideCongestionController>(
Sebastian Jansson19bea512018-03-13 19:07:46 +010051 clock, nullptr /* observer */, event_log, pacer);
52 cc->SignalNetworkState(kNetworkDown);
53 cc->SetBweBitrates(bitrate_config.min_bitrate_bps,
54 bitrate_config.start_bitrate_bps,
55 bitrate_config.max_bitrate_bps);
56 return std::move(cc);
57}
58} // namespace
nissecae45d02017-04-24 05:53:20 -070059
60RtpTransportControllerSend::RtpTransportControllerSend(
61 Clock* clock,
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010062 webrtc::RtcEventLog* event_log,
Sebastian Janssondfce03a2018-05-18 18:05:10 +020063 NetworkControllerFactoryInterface* controller_factory,
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010064 const BitrateConstraints& bitrate_config)
Sebastian Jansson19704ec2018-03-12 15:59:12 +010065 : clock_(clock),
66 pacer_(clock, &packet_router_, event_log),
Sebastian Jansson317a5222018-03-16 15:36:37 +010067 bitrate_configurator_(bitrate_config),
68 process_thread_(ProcessThread::Create("SendControllerThread")),
69 observer_(nullptr),
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020070 retransmission_rate_limiter_(clock, kRetransmitWindowSizeMs),
Sebastian Janssone6256052018-05-04 14:08:15 +020071 task_queue_("rtp_send_controller") {
Sebastian Janssonbd9fe092018-05-07 16:33:50 +020072 // Created after task_queue to be able to post to the task queue internally.
73 send_side_cc_ =
74 CreateController(clock, &task_queue_, event_log, &pacer_, bitrate_config,
Sebastian Janssondfce03a2018-05-18 18:05:10 +020075 TaskQueueExperimentEnabled(), controller_factory);
Sebastian Janssonbd9fe092018-05-07 16:33:50 +020076
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010077 process_thread_->RegisterModule(&pacer_, RTC_FROM_HERE);
Sebastian Jansson10211e92018-02-28 16:48:26 +010078 process_thread_->RegisterModule(send_side_cc_.get(), RTC_FROM_HERE);
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010079 process_thread_->Start();
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010080}
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010081
82RtpTransportControllerSend::~RtpTransportControllerSend() {
83 process_thread_->Stop();
Sebastian Jansson10211e92018-02-28 16:48:26 +010084 process_thread_->DeRegisterModule(send_side_cc_.get());
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010085 process_thread_->DeRegisterModule(&pacer_);
86}
nissecae45d02017-04-24 05:53:20 -070087
Stefan Holmer9416ef82018-07-19 10:34:38 +020088RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender(
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020089 const std::vector<uint32_t>& ssrcs,
90 std::map<uint32_t, RtpState> suspended_ssrcs,
91 const std::map<uint32_t, RtpPayloadState>& states,
92 const RtpConfig& rtp_config,
93 const RtcpConfig& rtcp_config,
94 Transport* send_transport,
95 const RtpSenderObservers& observers,
Stefan Holmer64be7fa2018-10-04 15:21:55 +020096 RtcEventLog* event_log,
97 std::unique_ptr<FecController> fec_controller) {
Stefan Holmer9416ef82018-07-19 10:34:38 +020098 video_rtp_senders_.push_back(absl::make_unique<RtpVideoSender>(
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020099 ssrcs, suspended_ssrcs, states, rtp_config, rtcp_config, send_transport,
100 observers,
101 // TODO(holmer): Remove this circular dependency by injecting
102 // the parts of RtpTransportControllerSendInterface that are really used.
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200103 this, event_log, &retransmission_rate_limiter_,
104 std::move(fec_controller)));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200105 return video_rtp_senders_.back().get();
106}
107
Stefan Holmer9416ef82018-07-19 10:34:38 +0200108void RtpTransportControllerSend::DestroyRtpVideoSender(
109 RtpVideoSenderInterface* rtp_video_sender) {
110 std::vector<std::unique_ptr<RtpVideoSenderInterface>>::iterator it =
Stefan Holmer5ed25af2018-07-18 15:17:14 +0200111 video_rtp_senders_.end();
112 for (it = video_rtp_senders_.begin(); it != video_rtp_senders_.end(); ++it) {
113 if (it->get() == rtp_video_sender) {
114 break;
115 }
116 }
117 RTC_DCHECK(it != video_rtp_senders_.end());
118 video_rtp_senders_.erase(it);
119}
120
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100121void RtpTransportControllerSend::OnNetworkChanged(uint32_t bitrate_bps,
122 uint8_t fraction_loss,
123 int64_t rtt_ms,
124 int64_t probing_interval_ms) {
125 // TODO(srte): Skip this step when old SendSideCongestionController is
126 // deprecated.
127 TargetTransferRate msg;
128 msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
129 msg.target_rate = DataRate::bps(bitrate_bps);
130 msg.network_estimate.at_time = msg.at_time;
131 msg.network_estimate.bwe_period = TimeDelta::ms(probing_interval_ms);
132 uint32_t bandwidth_bps;
Sebastian Janssonbd9fe092018-05-07 16:33:50 +0200133 if (send_side_cc_->AvailableBandwidth(&bandwidth_bps))
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100134 msg.network_estimate.bandwidth = DataRate::bps(bandwidth_bps);
135 msg.network_estimate.loss_rate_ratio = fraction_loss / 255.0;
136 msg.network_estimate.round_trip_time = TimeDelta::ms(rtt_ms);
Sebastian Janssone6256052018-05-04 14:08:15 +0200137
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200138 retransmission_rate_limiter_.SetMaxRate(bandwidth_bps);
139
Sebastian Janssone6256052018-05-04 14:08:15 +0200140 if (!task_queue_.IsCurrent()) {
141 task_queue_.PostTask([this, msg] {
142 rtc::CritScope cs(&observer_crit_);
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200143 // We won't register as observer until we have an observers.
Sebastian Janssone6256052018-05-04 14:08:15 +0200144 RTC_DCHECK(observer_ != nullptr);
145 observer_->OnTargetTransferRate(msg);
146 });
147 } else {
148 rtc::CritScope cs(&observer_crit_);
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200149 // We won't register as observer until we have an observers.
Sebastian Janssone6256052018-05-04 14:08:15 +0200150 RTC_DCHECK(observer_ != nullptr);
151 observer_->OnTargetTransferRate(msg);
152 }
153}
154
155rtc::TaskQueue* RtpTransportControllerSend::GetWorkerQueue() {
156 return &task_queue_;
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100157}
158
nisse76e62b02017-05-31 02:24:52 -0700159PacketRouter* RtpTransportControllerSend::packet_router() {
160 return &packet_router_;
161}
162
nisse76e62b02017-05-31 02:24:52 -0700163TransportFeedbackObserver*
164RtpTransportControllerSend::transport_feedback_observer() {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100165 return send_side_cc_.get();
nisse76e62b02017-05-31 02:24:52 -0700166}
167
168RtpPacketSender* RtpTransportControllerSend::packet_sender() {
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200169 return &pacer_;
nisse76e62b02017-05-31 02:24:52 -0700170}
171
sprangdb2a9fc2017-08-09 06:42:32 -0700172const RtpKeepAliveConfig& RtpTransportControllerSend::keepalive_config() const {
173 return keepalive_;
174}
175
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200176void RtpTransportControllerSend::SetAllocatedSendBitrateLimits(
177 int min_send_bitrate_bps,
philipel832b1c82018-02-28 17:04:18 +0100178 int max_padding_bitrate_bps,
philipeldb4fa4b2018-03-06 18:29:22 +0100179 int max_total_bitrate_bps) {
Sebastian Jansson68ee4652018-03-13 11:40:34 +0100180 send_side_cc_->SetAllocatedSendBitrateLimits(
181 min_send_bitrate_bps, max_padding_bitrate_bps, max_total_bitrate_bps);
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200182}
183
sprangdb2a9fc2017-08-09 06:42:32 -0700184void RtpTransportControllerSend::SetKeepAliveConfig(
185 const RtpKeepAliveConfig& config) {
186 keepalive_ = config;
187}
Sebastian Jansson4c1ffb82018-02-15 16:51:58 +0100188void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) {
Sebastian Jansson68ee4652018-03-13 11:40:34 +0100189 send_side_cc_->SetPacingFactor(pacing_factor);
Sebastian Jansson4c1ffb82018-02-15 16:51:58 +0100190}
191void RtpTransportControllerSend::SetQueueTimeLimit(int limit_ms) {
192 pacer_.SetQueueTimeLimit(limit_ms);
193}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100194CallStatsObserver* RtpTransportControllerSend::GetCallStatsObserver() {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100195 return send_side_cc_.get();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100196}
197void RtpTransportControllerSend::RegisterPacketFeedbackObserver(
198 PacketFeedbackObserver* observer) {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100199 send_side_cc_->RegisterPacketFeedbackObserver(observer);
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100200}
201void RtpTransportControllerSend::DeRegisterPacketFeedbackObserver(
202 PacketFeedbackObserver* observer) {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100203 send_side_cc_->DeRegisterPacketFeedbackObserver(observer);
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100204}
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100205
206void RtpTransportControllerSend::RegisterTargetTransferRateObserver(
207 TargetTransferRateObserver* observer) {
208 {
209 rtc::CritScope cs(&observer_crit_);
210 RTC_DCHECK(observer_ == nullptr);
211 observer_ = observer;
212 }
213 send_side_cc_->RegisterNetworkObserver(this);
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100214}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100215void RtpTransportControllerSend::OnNetworkRouteChanged(
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100216 const std::string& transport_name,
217 const rtc::NetworkRoute& network_route) {
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100218 // Check if the network route is connected.
219 if (!network_route.connected) {
220 RTC_LOG(LS_INFO) << "Transport " << transport_name << " is disconnected";
221 // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and
222 // consider merging these two methods.
223 return;
224 }
225
226 // Check whether the network route has changed on each transport.
227 auto result =
228 network_routes_.insert(std::make_pair(transport_name, network_route));
229 auto kv = result.first;
230 bool inserted = result.second;
231 if (inserted) {
232 // No need to reset BWE if this is the first time the network connects.
233 return;
234 }
235 if (kv->second != network_route) {
236 kv->second = network_route;
237 BitrateConstraints bitrate_config = bitrate_configurator_.GetConfig();
238 RTC_LOG(LS_INFO) << "Network route changed on transport " << transport_name
239 << ": new local network id "
240 << network_route.local_network_id
241 << " new remote network id "
242 << network_route.remote_network_id
243 << " Reset bitrates to min: "
244 << bitrate_config.min_bitrate_bps
245 << " bps, start: " << bitrate_config.start_bitrate_bps
246 << " bps, max: " << bitrate_config.max_bitrate_bps
247 << " bps.";
248 RTC_DCHECK_GT(bitrate_config.start_bitrate_bps, 0);
Sebastian Jansson10211e92018-02-28 16:48:26 +0100249 send_side_cc_->OnNetworkRouteChanged(
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100250 network_route, bitrate_config.start_bitrate_bps,
251 bitrate_config.min_bitrate_bps, bitrate_config.max_bitrate_bps);
252 }
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100253}
254void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100255 send_side_cc_->SignalNetworkState(network_available ? kNetworkUp
256 : kNetworkDown);
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200257 for (auto& rtp_sender : video_rtp_senders_) {
258 rtp_sender->OnNetworkAvailability(network_available);
259 }
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100260}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100261RtcpBandwidthObserver* RtpTransportControllerSend::GetBandwidthObserver() {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100262 return send_side_cc_->GetBandwidthObserver();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100263}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100264int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const {
Sebastian Janssona06e9192018-03-07 18:49:55 +0100265 return pacer_.QueueInMs();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100266}
267int64_t RtpTransportControllerSend::GetFirstPacketTimeMs() const {
Sebastian Janssona06e9192018-03-07 18:49:55 +0100268 return pacer_.FirstSentPacketTimeMs();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100269}
Sebastian Jansson12130bb2018-03-21 12:48:43 +0100270void RtpTransportControllerSend::SetPerPacketFeedbackAvailable(bool available) {
271 send_side_cc_->SetPerPacketFeedbackAvailable(available);
272}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100273void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100274 send_side_cc_->EnablePeriodicAlrProbing(enable);
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100275}
276void RtpTransportControllerSend::OnSentPacket(
277 const rtc::SentPacket& sent_packet) {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100278 send_side_cc_->OnSentPacket(sent_packet);
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100279}
sprangdb2a9fc2017-08-09 06:42:32 -0700280
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100281void RtpTransportControllerSend::SetSdpBitrateParameters(
282 const BitrateConstraints& constraints) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200283 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100284 bitrate_configurator_.UpdateWithSdpParameters(constraints);
285 if (updated.has_value()) {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100286 send_side_cc_->SetBweBitrates(updated->min_bitrate_bps,
287 updated->start_bitrate_bps,
288 updated->max_bitrate_bps);
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100289 } else {
290 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100291 << "WebRTC.RtpTransportControllerSend.SetSdpBitrateParameters: "
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100292 << "nothing to update";
293 }
294}
295
296void RtpTransportControllerSend::SetClientBitratePreferences(
Niels Möller0c4f7be2018-05-07 14:01:37 +0200297 const BitrateSettings& preferences) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200298 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100299 bitrate_configurator_.UpdateWithClientPreferences(preferences);
300 if (updated.has_value()) {
Sebastian Jansson10211e92018-02-28 16:48:26 +0100301 send_side_cc_->SetBweBitrates(updated->min_bitrate_bps,
302 updated->start_bitrate_bps,
303 updated->max_bitrate_bps);
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100304 } else {
305 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100306 << "WebRTC.RtpTransportControllerSend.SetClientBitratePreferences: "
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100307 << "nothing to update";
308 }
309}
Alex Narestbcf91802018-06-25 16:08:36 +0200310
311void RtpTransportControllerSend::SetAllocatedBitrateWithoutFeedback(
312 uint32_t bitrate_bps) {
Sebastian Jansson35fa2802018-10-01 09:16:12 +0200313 // Audio transport feedback will not be reported in this mode, instead update
314 // acknowledged bitrate estimator with the bitrate allocated for audio.
315 if (field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC")) {
316 // TODO(srte): Make sure it's safe to always report this and remove the
317 // field trial check.
318 send_side_cc_->SetAllocatedBitrateWithoutFeedback(bitrate_bps);
319 }
Alex Narestbcf91802018-06-25 16:08:36 +0200320}
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200321
322void RtpTransportControllerSend::OnTransportOverheadChanged(
323 size_t transport_overhead_bytes_per_packet) {
324 if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) {
325 RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes;
326 return;
327 }
328
329 // TODO(holmer): Call AudioRtpSenders when they have been moved to
330 // RtpTransportControllerSend.
331 for (auto& rtp_video_sender : video_rtp_senders_) {
332 rtp_video_sender->OnTransportOverheadChanged(
333 transport_overhead_bytes_per_packet);
334 }
335}
nissecae45d02017-04-24 05:53:20 -0700336} // namespace webrtc