blob: a86e18bf239794b6122e41cb77bb80c66f50a5d7 [file] [log] [blame]
nissecae45d02017-04-24 12:53:201/*
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 12:02:5110#include <utility>
Stefan Holmerdbdb3a02018-07-17 14:03:4611#include <vector>
nissecae45d02017-04-24 12:53:2012
Karl Wiberg918f50c2018-07-05 09:40:3313#include "absl/memory/memory.h"
Yves Gerey3e707812018-11-28 15:47:4914#include "absl/types/optional.h"
15#include "api/transport/network_types.h"
16#include "api/units/data_rate.h"
17#include "api/units/time_delta.h"
18#include "api/units/timestamp.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3119#include "call/rtp_transport_controller_send.h"
Yves Gerey3e707812018-11-28 15:47:4920#include "call/rtp_video_sender.h"
Sebastian Jansson10211e92018-02-28 15:48:2621#include "modules/congestion_controller/include/send_side_congestion_controller.h"
Sebastian Jansson19bea512018-03-13 18:07:4622#include "modules/congestion_controller/rtp/include/send_side_congestion_controller.h"
Yves Gerey3e707812018-11-28 15:47:4923#include "rtc_base/checks.h"
Sebastian Janssonc33c0fc2018-02-22 10:10:1824#include "rtc_base/location.h"
Sebastian Jansson97f61ea2018-02-21 12:01:5525#include "rtc_base/logging.h"
Stefan Holmerdbdb3a02018-07-17 14:03:4626#include "rtc_base/rate_limiter.h"
Sebastian Jansson19bea512018-03-13 18:07:4627#include "system_wrappers/include/field_trial.h"
nissecae45d02017-04-24 12:53:2028
29namespace webrtc {
Sebastian Jansson19bea512018-03-13 18:07:4630namespace {
Stefan Holmerdbdb3a02018-07-17 14:03:4631static const int64_t kRetransmitWindowSizeMs = 500;
Stefan Holmer64be7fa2018-10-04 13:21:5532static const size_t kMaxOverheadBytes = 500;
Sebastian Jansson19bea512018-03-13 18:07:4633const char kTaskQueueExperiment[] = "WebRTC-TaskQueueCongestionControl";
34using TaskQueueController = webrtc::webrtc_cc::SendSideCongestionController;
35
Sebastian Jansson19bea512018-03-13 18:07:4636std::unique_ptr<SendSideCongestionControllerInterface> CreateController(
37 Clock* clock,
Sebastian Janssonbd9fe092018-05-07 14:33:5038 rtc::TaskQueue* task_queue,
Sebastian Jansson19bea512018-03-13 18:07:4639 webrtc::RtcEventLog* event_log,
40 PacedSender* pacer,
41 const BitrateConstraints& bitrate_config,
Sebastian Janssondfce03a2018-05-18 16:05:1042 bool task_queue_controller,
43 NetworkControllerFactoryInterface* controller_factory) {
Sebastian Jansson19bea512018-03-13 18:07:4644 if (task_queue_controller) {
Sebastian Jansson4e140da2018-04-13 11:25:1945 RTC_LOG(LS_INFO) << "Using TaskQueue based SSCC";
Karl Wiberg918f50c2018-07-05 09:40:3346 return absl::make_unique<webrtc::webrtc_cc::SendSideCongestionController>(
Sebastian Janssonbd9fe092018-05-07 14:33:5047 clock, task_queue, event_log, pacer, bitrate_config.start_bitrate_bps,
Sebastian Janssondfce03a2018-05-18 16:05:1048 bitrate_config.min_bitrate_bps, bitrate_config.max_bitrate_bps,
49 controller_factory);
Sebastian Jansson19bea512018-03-13 18:07:4650 }
Sebastian Jansson4e140da2018-04-13 11:25:1951 RTC_LOG(LS_INFO) << "Using Legacy SSCC";
Karl Wiberg918f50c2018-07-05 09:40:3352 auto cc = absl::make_unique<webrtc::SendSideCongestionController>(
Sebastian Jansson19bea512018-03-13 18:07:4653 clock, nullptr /* observer */, event_log, pacer);
54 cc->SignalNetworkState(kNetworkDown);
55 cc->SetBweBitrates(bitrate_config.min_bitrate_bps,
56 bitrate_config.start_bitrate_bps,
57 bitrate_config.max_bitrate_bps);
58 return std::move(cc);
59}
60} // namespace
nissecae45d02017-04-24 12:53:2061
62RtpTransportControllerSend::RtpTransportControllerSend(
63 Clock* clock,
Sebastian Jansson97f61ea2018-02-21 12:01:5564 webrtc::RtcEventLog* event_log,
Sebastian Janssondfce03a2018-05-18 16:05:1065 NetworkControllerFactoryInterface* controller_factory,
Sebastian Jansson97f61ea2018-02-21 12:01:5566 const BitrateConstraints& bitrate_config)
Sebastian Jansson19704ec2018-03-12 14:59:1267 : clock_(clock),
68 pacer_(clock, &packet_router_, event_log),
Sebastian Jansson317a5222018-03-16 14:36:3769 bitrate_configurator_(bitrate_config),
70 process_thread_(ProcessThread::Create("SendControllerThread")),
71 observer_(nullptr),
Stefan Holmerdbdb3a02018-07-17 14:03:4672 retransmission_rate_limiter_(clock, kRetransmitWindowSizeMs),
Sebastian Janssone6256052018-05-04 12:08:1573 task_queue_("rtp_send_controller") {
Sebastian Janssonbd9fe092018-05-07 14:33:5074 // Created after task_queue to be able to post to the task queue internally.
Sebastian Jansson4ff72142018-10-08 09:15:0475 send_side_cc_ = CreateController(
76 clock, &task_queue_, event_log, &pacer_, bitrate_config,
77 !field_trial::IsDisabled(kTaskQueueExperiment), controller_factory);
Sebastian Janssonbd9fe092018-05-07 14:33:5078
Sebastian Janssonc33c0fc2018-02-22 10:10:1879 process_thread_->RegisterModule(&pacer_, RTC_FROM_HERE);
Sebastian Jansson10211e92018-02-28 15:48:2680 process_thread_->RegisterModule(send_side_cc_.get(), RTC_FROM_HERE);
Sebastian Janssonc33c0fc2018-02-22 10:10:1881 process_thread_->Start();
Sebastian Jansson97f61ea2018-02-21 12:01:5582}
Sebastian Janssonc33c0fc2018-02-22 10:10:1883
84RtpTransportControllerSend::~RtpTransportControllerSend() {
85 process_thread_->Stop();
Sebastian Jansson10211e92018-02-28 15:48:2686 process_thread_->DeRegisterModule(send_side_cc_.get());
Sebastian Janssonc33c0fc2018-02-22 10:10:1887 process_thread_->DeRegisterModule(&pacer_);
88}
nissecae45d02017-04-24 12:53:2089
Stefan Holmer9416ef82018-07-19 08:34:3890RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender(
Stefan Holmerdbdb3a02018-07-17 14:03:4691 const std::vector<uint32_t>& ssrcs,
92 std::map<uint32_t, RtpState> suspended_ssrcs,
93 const std::map<uint32_t, RtpPayloadState>& states,
94 const RtpConfig& rtp_config,
Jiawei Ou55718122018-11-09 21:17:3995 int rtcp_report_interval_ms,
Stefan Holmerdbdb3a02018-07-17 14:03:4696 Transport* send_transport,
97 const RtpSenderObservers& observers,
Stefan Holmer64be7fa2018-10-04 13:21:5598 RtcEventLog* event_log,
Benjamin Wright192eeec2018-10-18 00:27:2599 std::unique_ptr<FecController> fec_controller,
100 const RtpSenderFrameEncryptionConfig& frame_encryption_config) {
Stefan Holmer9416ef82018-07-19 08:34:38101 video_rtp_senders_.push_back(absl::make_unique<RtpVideoSender>(
Jiawei Ou55718122018-11-09 21:17:39102 ssrcs, suspended_ssrcs, states, rtp_config, rtcp_report_interval_ms,
103 send_transport, observers,
Stefan Holmerdbdb3a02018-07-17 14:03:46104 // TODO(holmer): Remove this circular dependency by injecting
105 // the parts of RtpTransportControllerSendInterface that are really used.
Benjamin Wright192eeec2018-10-18 00:27:25106 this, event_log, &retransmission_rate_limiter_, std::move(fec_controller),
107 frame_encryption_config.frame_encryptor,
108 frame_encryption_config.crypto_options));
Stefan Holmerdbdb3a02018-07-17 14:03:46109 return video_rtp_senders_.back().get();
110}
111
Stefan Holmer9416ef82018-07-19 08:34:38112void RtpTransportControllerSend::DestroyRtpVideoSender(
113 RtpVideoSenderInterface* rtp_video_sender) {
114 std::vector<std::unique_ptr<RtpVideoSenderInterface>>::iterator it =
Stefan Holmer5ed25af2018-07-18 13:17:14115 video_rtp_senders_.end();
116 for (it = video_rtp_senders_.begin(); it != video_rtp_senders_.end(); ++it) {
117 if (it->get() == rtp_video_sender) {
118 break;
119 }
120 }
121 RTC_DCHECK(it != video_rtp_senders_.end());
122 video_rtp_senders_.erase(it);
123}
124
Sebastian Jansson19704ec2018-03-12 14:59:12125void RtpTransportControllerSend::OnNetworkChanged(uint32_t bitrate_bps,
126 uint8_t fraction_loss,
127 int64_t rtt_ms,
128 int64_t probing_interval_ms) {
129 // TODO(srte): Skip this step when old SendSideCongestionController is
130 // deprecated.
131 TargetTransferRate msg;
132 msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
133 msg.target_rate = DataRate::bps(bitrate_bps);
134 msg.network_estimate.at_time = msg.at_time;
135 msg.network_estimate.bwe_period = TimeDelta::ms(probing_interval_ms);
136 uint32_t bandwidth_bps;
Sebastian Janssonbd9fe092018-05-07 14:33:50137 if (send_side_cc_->AvailableBandwidth(&bandwidth_bps))
Sebastian Jansson19704ec2018-03-12 14:59:12138 msg.network_estimate.bandwidth = DataRate::bps(bandwidth_bps);
139 msg.network_estimate.loss_rate_ratio = fraction_loss / 255.0;
140 msg.network_estimate.round_trip_time = TimeDelta::ms(rtt_ms);
Sebastian Janssone6256052018-05-04 12:08:15141
Stefan Holmerdbdb3a02018-07-17 14:03:46142 retransmission_rate_limiter_.SetMaxRate(bandwidth_bps);
143
Sebastian Janssone6256052018-05-04 12:08:15144 if (!task_queue_.IsCurrent()) {
145 task_queue_.PostTask([this, msg] {
146 rtc::CritScope cs(&observer_crit_);
Stefan Holmerdbdb3a02018-07-17 14:03:46147 // We won't register as observer until we have an observers.
Sebastian Janssone6256052018-05-04 12:08:15148 RTC_DCHECK(observer_ != nullptr);
149 observer_->OnTargetTransferRate(msg);
150 });
151 } else {
152 rtc::CritScope cs(&observer_crit_);
Stefan Holmerdbdb3a02018-07-17 14:03:46153 // We won't register as observer until we have an observers.
Sebastian Janssone6256052018-05-04 12:08:15154 RTC_DCHECK(observer_ != nullptr);
155 observer_->OnTargetTransferRate(msg);
156 }
157}
158
159rtc::TaskQueue* RtpTransportControllerSend::GetWorkerQueue() {
160 return &task_queue_;
Sebastian Jansson19704ec2018-03-12 14:59:12161}
162
nisse76e62b02017-05-31 09:24:52163PacketRouter* RtpTransportControllerSend::packet_router() {
164 return &packet_router_;
165}
166
nisse76e62b02017-05-31 09:24:52167TransportFeedbackObserver*
168RtpTransportControllerSend::transport_feedback_observer() {
Sebastian Jansson10211e92018-02-28 15:48:26169 return send_side_cc_.get();
nisse76e62b02017-05-31 09:24:52170}
171
172RtpPacketSender* RtpTransportControllerSend::packet_sender() {
Stefan Holmer5c8942a2017-08-22 14:16:44173 return &pacer_;
nisse76e62b02017-05-31 09:24:52174}
175
sprangdb2a9fc2017-08-09 13:42:32176const RtpKeepAliveConfig& RtpTransportControllerSend::keepalive_config() const {
177 return keepalive_;
178}
179
Stefan Holmer5c8942a2017-08-22 14:16:44180void RtpTransportControllerSend::SetAllocatedSendBitrateLimits(
181 int min_send_bitrate_bps,
philipel832b1c82018-02-28 16:04:18182 int max_padding_bitrate_bps,
philipeldb4fa4b2018-03-06 17:29:22183 int max_total_bitrate_bps) {
Sebastian Jansson68ee4652018-03-13 10:40:34184 send_side_cc_->SetAllocatedSendBitrateLimits(
185 min_send_bitrate_bps, max_padding_bitrate_bps, max_total_bitrate_bps);
Stefan Holmer5c8942a2017-08-22 14:16:44186}
187
sprangdb2a9fc2017-08-09 13:42:32188void RtpTransportControllerSend::SetKeepAliveConfig(
189 const RtpKeepAliveConfig& config) {
190 keepalive_ = config;
191}
Sebastian Jansson4c1ffb82018-02-15 15:51:58192void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) {
Sebastian Jansson68ee4652018-03-13 10:40:34193 send_side_cc_->SetPacingFactor(pacing_factor);
Sebastian Jansson4c1ffb82018-02-15 15:51:58194}
195void RtpTransportControllerSend::SetQueueTimeLimit(int limit_ms) {
196 pacer_.SetQueueTimeLimit(limit_ms);
197}
Sebastian Janssone4be6da2018-02-15 15:51:41198CallStatsObserver* RtpTransportControllerSend::GetCallStatsObserver() {
Sebastian Jansson10211e92018-02-28 15:48:26199 return send_side_cc_.get();
Sebastian Janssone4be6da2018-02-15 15:51:41200}
201void RtpTransportControllerSend::RegisterPacketFeedbackObserver(
202 PacketFeedbackObserver* observer) {
Sebastian Jansson10211e92018-02-28 15:48:26203 send_side_cc_->RegisterPacketFeedbackObserver(observer);
Sebastian Janssone4be6da2018-02-15 15:51:41204}
205void RtpTransportControllerSend::DeRegisterPacketFeedbackObserver(
206 PacketFeedbackObserver* observer) {
Sebastian Jansson10211e92018-02-28 15:48:26207 send_side_cc_->DeRegisterPacketFeedbackObserver(observer);
Sebastian Janssone4be6da2018-02-15 15:51:41208}
Sebastian Jansson19704ec2018-03-12 14:59:12209
210void RtpTransportControllerSend::RegisterTargetTransferRateObserver(
211 TargetTransferRateObserver* observer) {
212 {
213 rtc::CritScope cs(&observer_crit_);
214 RTC_DCHECK(observer_ == nullptr);
215 observer_ = observer;
216 }
217 send_side_cc_->RegisterNetworkObserver(this);
Sebastian Janssone4be6da2018-02-15 15:51:41218}
Sebastian Janssone4be6da2018-02-15 15:51:41219void RtpTransportControllerSend::OnNetworkRouteChanged(
Sebastian Jansson97f61ea2018-02-21 12:01:55220 const std::string& transport_name,
221 const rtc::NetworkRoute& network_route) {
Sebastian Jansson91bb6672018-02-21 12:02:51222 // Check if the network route is connected.
223 if (!network_route.connected) {
224 RTC_LOG(LS_INFO) << "Transport " << transport_name << " is disconnected";
225 // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and
226 // consider merging these two methods.
227 return;
228 }
229
230 // Check whether the network route has changed on each transport.
231 auto result =
232 network_routes_.insert(std::make_pair(transport_name, network_route));
233 auto kv = result.first;
234 bool inserted = result.second;
235 if (inserted) {
236 // No need to reset BWE if this is the first time the network connects.
237 return;
238 }
239 if (kv->second != network_route) {
240 kv->second = network_route;
241 BitrateConstraints bitrate_config = bitrate_configurator_.GetConfig();
242 RTC_LOG(LS_INFO) << "Network route changed on transport " << transport_name
243 << ": new local network id "
244 << network_route.local_network_id
245 << " new remote network id "
246 << network_route.remote_network_id
247 << " Reset bitrates to min: "
248 << bitrate_config.min_bitrate_bps
249 << " bps, start: " << bitrate_config.start_bitrate_bps
250 << " bps, max: " << bitrate_config.max_bitrate_bps
251 << " bps.";
252 RTC_DCHECK_GT(bitrate_config.start_bitrate_bps, 0);
Sebastian Jansson10211e92018-02-28 15:48:26253 send_side_cc_->OnNetworkRouteChanged(
Sebastian Jansson91bb6672018-02-21 12:02:51254 network_route, bitrate_config.start_bitrate_bps,
255 bitrate_config.min_bitrate_bps, bitrate_config.max_bitrate_bps);
256 }
Sebastian Janssone4be6da2018-02-15 15:51:41257}
258void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
Sebastian Jansson10211e92018-02-28 15:48:26259 send_side_cc_->SignalNetworkState(network_available ? kNetworkUp
260 : kNetworkDown);
Stefan Holmerdbdb3a02018-07-17 14:03:46261 for (auto& rtp_sender : video_rtp_senders_) {
262 rtp_sender->OnNetworkAvailability(network_available);
263 }
Sebastian Janssone4be6da2018-02-15 15:51:41264}
Sebastian Janssone4be6da2018-02-15 15:51:41265RtcpBandwidthObserver* RtpTransportControllerSend::GetBandwidthObserver() {
Sebastian Jansson10211e92018-02-28 15:48:26266 return send_side_cc_->GetBandwidthObserver();
Sebastian Janssone4be6da2018-02-15 15:51:41267}
Sebastian Janssone4be6da2018-02-15 15:51:41268int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const {
Sebastian Janssona06e9192018-03-07 17:49:55269 return pacer_.QueueInMs();
Sebastian Janssone4be6da2018-02-15 15:51:41270}
271int64_t RtpTransportControllerSend::GetFirstPacketTimeMs() const {
Sebastian Janssona06e9192018-03-07 17:49:55272 return pacer_.FirstSentPacketTimeMs();
Sebastian Janssone4be6da2018-02-15 15:51:41273}
Sebastian Jansson12130bb2018-03-21 11:48:43274void RtpTransportControllerSend::SetPerPacketFeedbackAvailable(bool available) {
275 send_side_cc_->SetPerPacketFeedbackAvailable(available);
276}
Sebastian Janssone4be6da2018-02-15 15:51:41277void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) {
Sebastian Jansson10211e92018-02-28 15:48:26278 send_side_cc_->EnablePeriodicAlrProbing(enable);
Sebastian Janssone4be6da2018-02-15 15:51:41279}
280void RtpTransportControllerSend::OnSentPacket(
281 const rtc::SentPacket& sent_packet) {
Sebastian Jansson10211e92018-02-28 15:48:26282 send_side_cc_->OnSentPacket(sent_packet);
Sebastian Janssone4be6da2018-02-15 15:51:41283}
sprangdb2a9fc2017-08-09 13:42:32284
Sebastian Jansson97f61ea2018-02-21 12:01:55285void RtpTransportControllerSend::SetSdpBitrateParameters(
286 const BitrateConstraints& constraints) {
Danil Chapovalovb9b146c2018-06-15 10:28:07287 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 12:01:55288 bitrate_configurator_.UpdateWithSdpParameters(constraints);
289 if (updated.has_value()) {
Sebastian Jansson10211e92018-02-28 15:48:26290 send_side_cc_->SetBweBitrates(updated->min_bitrate_bps,
291 updated->start_bitrate_bps,
292 updated->max_bitrate_bps);
Sebastian Jansson97f61ea2018-02-21 12:01:55293 } else {
294 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 12:07:13295 << "WebRTC.RtpTransportControllerSend.SetSdpBitrateParameters: "
Sebastian Jansson97f61ea2018-02-21 12:01:55296 << "nothing to update";
297 }
298}
299
300void RtpTransportControllerSend::SetClientBitratePreferences(
Niels Möller0c4f7be2018-05-07 12:01:37301 const BitrateSettings& preferences) {
Danil Chapovalovb9b146c2018-06-15 10:28:07302 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 12:01:55303 bitrate_configurator_.UpdateWithClientPreferences(preferences);
304 if (updated.has_value()) {
Sebastian Jansson10211e92018-02-28 15:48:26305 send_side_cc_->SetBweBitrates(updated->min_bitrate_bps,
306 updated->start_bitrate_bps,
307 updated->max_bitrate_bps);
Sebastian Jansson97f61ea2018-02-21 12:01:55308 } else {
309 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 12:07:13310 << "WebRTC.RtpTransportControllerSend.SetClientBitratePreferences: "
Sebastian Jansson97f61ea2018-02-21 12:01:55311 << "nothing to update";
312 }
313}
Alex Narestbcf91802018-06-25 14:08:36314
315void RtpTransportControllerSend::SetAllocatedBitrateWithoutFeedback(
316 uint32_t bitrate_bps) {
Sebastian Jansson35fa2802018-10-01 07:16:12317 // Audio transport feedback will not be reported in this mode, instead update
318 // acknowledged bitrate estimator with the bitrate allocated for audio.
319 if (field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC")) {
320 // TODO(srte): Make sure it's safe to always report this and remove the
321 // field trial check.
322 send_side_cc_->SetAllocatedBitrateWithoutFeedback(bitrate_bps);
323 }
Alex Narestbcf91802018-06-25 14:08:36324}
Stefan Holmer64be7fa2018-10-04 13:21:55325
326void RtpTransportControllerSend::OnTransportOverheadChanged(
327 size_t transport_overhead_bytes_per_packet) {
328 if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) {
329 RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes;
330 return;
331 }
332
333 // TODO(holmer): Call AudioRtpSenders when they have been moved to
334 // RtpTransportControllerSend.
335 for (auto& rtp_video_sender : video_rtp_senders_) {
336 rtp_video_sender->OnTransportOverheadChanged(
337 transport_overhead_bytes_per_packet);
338 }
339}
nissecae45d02017-04-24 12:53:20340} // namespace webrtc