blob: 9baf164a60df8aee1629957f282e68c8c04a0ebb [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 */
Jonas Olssona4d87372019-07-05 17:08:3310#include "call/rtp_transport_controller_send.h"
11
Mirko Bonadei317a1f02019-09-17 15:06:1812#include <memory>
Sebastian Jansson91bb6672018-02-21 12:02:5113#include <utility>
Stefan Holmerdbdb3a02018-07-17 14:03:4614#include <vector>
nissecae45d02017-04-24 12:53:2015
Mirko Bonadei06d35592020-04-01 11:43:0816#include "absl/strings/match.h"
Yves Gerey3e707812018-11-28 15:47:4917#include "absl/types/optional.h"
Sebastian Jansson87609be2018-12-05 16:35:3518#include "api/transport/goog_cc_factory.h"
Yves Gerey3e707812018-11-28 15:47:4919#include "api/transport/network_types.h"
20#include "api/units/data_rate.h"
21#include "api/units/time_delta.h"
22#include "api/units/timestamp.h"
Yves Gerey3e707812018-11-28 15:47:4923#include "call/rtp_video_sender.h"
Sebastian Jansson0a5ed892019-09-18 13:37:3124#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
Sebastian Jansson166b45d2019-05-13 09:57:4225#include "logging/rtc_event_log/events/rtc_event_route_change.h"
Sebastian Jansson658f1812020-01-16 09:59:2826#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
Yves Gerey3e707812018-11-28 15:47:4927#include "rtc_base/checks.h"
Sebastian Jansson97f61ea2018-02-21 12:01:5528#include "rtc_base/logging.h"
Stefan Holmerdbdb3a02018-07-17 14:03:4629#include "rtc_base/rate_limiter.h"
nissecae45d02017-04-24 12:53:2030
31namespace webrtc {
Sebastian Jansson19bea512018-03-13 18:07:4632namespace {
Stefan Holmerdbdb3a02018-07-17 14:03:4633static const int64_t kRetransmitWindowSizeMs = 500;
Stefan Holmer64be7fa2018-10-04 13:21:5534static const size_t kMaxOverheadBytes = 500;
Sebastian Jansson19bea512018-03-13 18:07:4635
Danil Chapovalov0c626af2020-02-10 10:16:0036constexpr TimeDelta kPacerQueueUpdateInterval = TimeDelta::Millis(25);
Sebastian Jansson87609be2018-12-05 16:35:3537
38TargetRateConstraints ConvertConstraints(int min_bitrate_bps,
39 int max_bitrate_bps,
40 int start_bitrate_bps,
Sebastian Janssonaa01f272019-01-30 10:28:5941 Clock* clock) {
Sebastian Jansson87609be2018-12-05 16:35:3542 TargetRateConstraints msg;
Danil Chapovalov0c626af2020-02-10 10:16:0043 msg.at_time = Timestamp::Millis(clock->TimeInMilliseconds());
Danil Chapovalovcad3e0e2020-02-17 17:46:0744 msg.min_data_rate = min_bitrate_bps >= 0
45 ? DataRate::BitsPerSec(min_bitrate_bps)
46 : DataRate::Zero();
47 msg.max_data_rate = max_bitrate_bps > 0
48 ? DataRate::BitsPerSec(max_bitrate_bps)
49 : DataRate::Infinity();
Sebastian Jansson87609be2018-12-05 16:35:3550 if (start_bitrate_bps > 0)
Danil Chapovalovcad3e0e2020-02-17 17:46:0751 msg.starting_rate = DataRate::BitsPerSec(start_bitrate_bps);
Sebastian Jansson87609be2018-12-05 16:35:3552 return msg;
53}
54
55TargetRateConstraints ConvertConstraints(const BitrateConstraints& contraints,
Sebastian Janssonaa01f272019-01-30 10:28:5956 Clock* clock) {
Sebastian Jansson87609be2018-12-05 16:35:3557 return ConvertConstraints(contraints.min_bitrate_bps,
58 contraints.max_bitrate_bps,
59 contraints.start_bitrate_bps, clock);
60}
Erik Språng662678d2019-11-15 16:18:5261
62bool IsEnabled(const WebRtcKeyValueConfig* trials, absl::string_view key) {
Erik Språng014dd3c2019-11-28 12:44:2563 RTC_DCHECK(trials != nullptr);
Mirko Bonadei06d35592020-04-01 11:43:0864 return absl::StartsWith(trials->Lookup(key), "Enabled");
Erik Språng662678d2019-11-15 16:18:5265}
66
Christoffer Rodbro6404cdd2020-03-26 19:37:2167bool IsRelayed(const rtc::NetworkRoute& route) {
68 return route.local.uses_turn() || route.remote.uses_turn();
Christoffer Rodbrob0ca5192020-03-26 08:22:2469}
70
Sebastian Jansson19bea512018-03-13 18:07:4671} // namespace
nissecae45d02017-04-24 12:53:2072
73RtpTransportControllerSend::RtpTransportControllerSend(
74 Clock* clock,
Sebastian Jansson97f61ea2018-02-21 12:01:5575 webrtc::RtcEventLog* event_log,
Ying Wang0810a7c2019-04-10 11:48:2476 NetworkStatePredictorFactoryInterface* predictor_factory,
Sebastian Janssondfce03a2018-05-18 16:05:1077 NetworkControllerFactoryInterface* controller_factory,
Sebastian Janssoned50e6c2019-03-01 13:45:2178 const BitrateConstraints& bitrate_config,
79 std::unique_ptr<ProcessThread> process_thread,
Erik Språng662678d2019-11-15 16:18:5280 TaskQueueFactory* task_queue_factory,
81 const WebRtcKeyValueConfig* trials)
Sebastian Jansson19704ec2018-03-12 14:59:1282 : clock_(clock),
Sebastian Jansson166b45d2019-05-13 09:57:4283 event_log_(event_log),
Sebastian Jansson317a5222018-03-16 14:36:3784 bitrate_configurator_(bitrate_config),
Sebastian Janssoned50e6c2019-03-01 13:45:2185 process_thread_(std::move(process_thread)),
Erik Språng014dd3c2019-11-28 12:44:2586 use_task_queue_pacer_(IsEnabled(trials, "WebRTC-TaskQueuePacer")),
Erik Språng4314a492019-11-26 16:48:4987 process_thread_pacer_(use_task_queue_pacer_
88 ? nullptr
89 : new PacedSender(clock,
90 &packet_router_,
91 event_log,
Erik Språng014dd3c2019-11-28 12:44:2592 trials,
Erik Språng4314a492019-11-26 16:48:4993 process_thread_.get())),
Erik Språng4ab61cb2020-05-19 15:40:5894 task_queue_pacer_(
95 use_task_queue_pacer_
96 ? new TaskQueuePacedSender(
97 clock,
98 &packet_router_,
99 event_log,
100 trials,
101 task_queue_factory,
102 /*hold_back_window = */ PacingController::kMinSleepTime)
103 : nullptr),
Sebastian Jansson317a5222018-03-16 14:36:37104 observer_(nullptr),
Sebastian Jansson87609be2018-12-05 16:35:35105 controller_factory_override_(controller_factory),
106 controller_factory_fallback_(
Mirko Bonadei317a1f02019-09-17 15:06:18107 std::make_unique<GoogCcNetworkControllerFactory>(predictor_factory)),
Sebastian Jansson87609be2018-12-05 16:35:35108 process_interval_(controller_factory_fallback_->GetProcessInterval()),
Danil Chapovalov0c626af2020-02-10 10:16:00109 last_report_block_time_(Timestamp::Millis(clock_->TimeInMilliseconds())),
Sebastian Jansson87609be2018-12-05 16:35:35110 reset_feedback_on_route_change_(
Erik Språng014dd3c2019-11-28 12:44:25111 !IsEnabled(trials, "WebRTC-Bwe-NoFeedbackReset")),
Sebastian Jansson87609be2018-12-05 16:35:35112 send_side_bwe_with_overhead_(
Erik Språng014dd3c2019-11-28 12:44:25113 IsEnabled(trials, "WebRTC-SendSideBwe-WithOverhead")),
Christoffer Rodbroc610e262019-01-08 09:49:19114 add_pacing_to_cwin_(
Erik Språng014dd3c2019-11-28 12:44:25115 IsEnabled(trials, "WebRTC-AddPacingToCongestionWindowPushback")),
Christoffer Rodbro6404cdd2020-03-26 19:37:21116 relay_bandwidth_cap_("relay_cap", DataRate::PlusInfinity()),
Sebastian Jansson87609be2018-12-05 16:35:35117 transport_overhead_bytes_per_packet_(0),
118 network_available_(false),
Stefan Holmerdbdb3a02018-07-17 14:03:46119 retransmission_rate_limiter_(clock, kRetransmitWindowSizeMs),
Sebastian Janssoned50e6c2019-03-01 13:45:21120 task_queue_(task_queue_factory->CreateTaskQueue(
121 "rtp_send_controller",
122 TaskQueueFactory::Priority::NORMAL)) {
Christoffer Rodbro6404cdd2020-03-26 19:37:21123 ParseFieldTrial({&relay_bandwidth_cap_},
124 trials->Lookup("WebRTC-Bwe-NetworkRouteConstraints"));
Sebastian Jansson87609be2018-12-05 16:35:35125 initial_config_.constraints = ConvertConstraints(bitrate_config, clock_);
Sebastian Janssondf88cc02019-04-15 13:42:25126 initial_config_.event_log = event_log;
Erik Språng014dd3c2019-11-28 12:44:25127 initial_config_.key_value_config = trials;
Sebastian Jansson87609be2018-12-05 16:35:35128 RTC_DCHECK(bitrate_config.start_bitrate_bps > 0);
129
Danil Chapovalovcad3e0e2020-02-17 17:46:07130 pacer()->SetPacingRates(
131 DataRate::BitsPerSec(bitrate_config.start_bitrate_bps), DataRate::Zero());
Sebastian Janssonbd9fe092018-05-07 14:33:50132
Erik Språng4314a492019-11-26 16:48:49133 if (!use_task_queue_pacer_) {
134 process_thread_->Start();
135 }
Sebastian Jansson97f61ea2018-02-21 12:01:55136}
Sebastian Janssonc33c0fc2018-02-22 10:10:18137
138RtpTransportControllerSend::~RtpTransportControllerSend() {
Erik Språng4314a492019-11-26 16:48:49139 if (!use_task_queue_pacer_) {
140 process_thread_->Stop();
141 }
Sebastian Janssonc33c0fc2018-02-22 10:10:18142}
nissecae45d02017-04-24 12:53:20143
Stefan Holmer9416ef82018-07-19 08:34:38144RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender(
Stefan Holmerdbdb3a02018-07-17 14:03:46145 std::map<uint32_t, RtpState> suspended_ssrcs,
146 const std::map<uint32_t, RtpPayloadState>& states,
147 const RtpConfig& rtp_config,
Jiawei Ou55718122018-11-09 21:17:39148 int rtcp_report_interval_ms,
Stefan Holmerdbdb3a02018-07-17 14:03:46149 Transport* send_transport,
150 const RtpSenderObservers& observers,
Stefan Holmer64be7fa2018-10-04 13:21:55151 RtcEventLog* event_log,
Benjamin Wright192eeec2018-10-18 00:27:25152 std::unique_ptr<FecController> fec_controller,
Marina Cioceae77912b2020-02-27 15:16:55153 const RtpSenderFrameEncryptionConfig& frame_encryption_config,
154 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {
Mirko Bonadei317a1f02019-09-17 15:06:18155 video_rtp_senders_.push_back(std::make_unique<RtpVideoSender>(
Sebastian Jansson572c60f2019-03-04 17:30:41156 clock_, suspended_ssrcs, states, rtp_config, rtcp_report_interval_ms,
Oleh Prypine8964902019-03-29 15:33:01157 send_transport, observers,
Stefan Holmerdbdb3a02018-07-17 14:03:46158 // TODO(holmer): Remove this circular dependency by injecting
159 // the parts of RtpTransportControllerSendInterface that are really used.
Benjamin Wright192eeec2018-10-18 00:27:25160 this, event_log, &retransmission_rate_limiter_, std::move(fec_controller),
161 frame_encryption_config.frame_encryptor,
Marina Cioceae77912b2020-02-27 15:16:55162 frame_encryption_config.crypto_options, std::move(frame_transformer)));
Stefan Holmerdbdb3a02018-07-17 14:03:46163 return video_rtp_senders_.back().get();
164}
165
Stefan Holmer9416ef82018-07-19 08:34:38166void RtpTransportControllerSend::DestroyRtpVideoSender(
167 RtpVideoSenderInterface* rtp_video_sender) {
168 std::vector<std::unique_ptr<RtpVideoSenderInterface>>::iterator it =
Stefan Holmer5ed25af2018-07-18 13:17:14169 video_rtp_senders_.end();
170 for (it = video_rtp_senders_.begin(); it != video_rtp_senders_.end(); ++it) {
171 if (it->get() == rtp_video_sender) {
172 break;
173 }
174 }
175 RTC_DCHECK(it != video_rtp_senders_.end());
176 video_rtp_senders_.erase(it);
177}
178
Sebastian Jansson16180952018-12-12 15:49:10179void RtpTransportControllerSend::UpdateControlState() {
180 absl::optional<TargetTransferRate> update = control_handler_->GetUpdate();
181 if (!update)
182 return;
Sebastian Janssonf34116e2019-09-24 15:55:50183 retransmission_rate_limiter_.SetMaxRate(update->target_rate.bps());
Sebastian Jansson16180952018-12-12 15:49:10184 // We won't create control_handler_ until we have an observers.
Sebastian Jansson87609be2018-12-05 16:35:35185 RTC_DCHECK(observer_ != nullptr);
Sebastian Jansson16180952018-12-12 15:49:10186 observer_->OnTargetTransferRate(*update);
Sebastian Janssone6256052018-05-04 12:08:15187}
188
Erik Språng425d6aa2019-07-29 14:38:27189RtpPacketPacer* RtpTransportControllerSend::pacer() {
Erik Språng4314a492019-11-26 16:48:49190 if (use_task_queue_pacer_) {
191 return task_queue_pacer_.get();
192 }
193 return process_thread_pacer_.get();
Erik Språng425d6aa2019-07-29 14:38:27194}
195
196const RtpPacketPacer* RtpTransportControllerSend::pacer() const {
Erik Språng4314a492019-11-26 16:48:49197 if (use_task_queue_pacer_) {
198 return task_queue_pacer_.get();
199 }
200 return process_thread_pacer_.get();
Erik Språng425d6aa2019-07-29 14:38:27201}
202
Sebastian Janssone6256052018-05-04 12:08:15203rtc::TaskQueue* RtpTransportControllerSend::GetWorkerQueue() {
204 return &task_queue_;
Sebastian Jansson19704ec2018-03-12 14:59:12205}
206
nisse76e62b02017-05-31 09:24:52207PacketRouter* RtpTransportControllerSend::packet_router() {
208 return &packet_router_;
209}
210
Sebastian Janssone1795f42019-07-24 09:38:03211NetworkStateEstimateObserver*
212RtpTransportControllerSend::network_state_estimate_observer() {
213 return this;
214}
215
nisse76e62b02017-05-31 09:24:52216TransportFeedbackObserver*
217RtpTransportControllerSend::transport_feedback_observer() {
Sebastian Jansson87609be2018-12-05 16:35:35218 return this;
nisse76e62b02017-05-31 09:24:52219}
220
Erik Språngaa59eca2019-07-24 12:52:55221RtpPacketSender* RtpTransportControllerSend::packet_sender() {
Erik Språng4314a492019-11-26 16:48:49222 if (use_task_queue_pacer_) {
223 return task_queue_pacer_.get();
224 }
225 return process_thread_pacer_.get();
nisse76e62b02017-05-31 09:24:52226}
227
Stefan Holmer5c8942a2017-08-22 14:16:44228void RtpTransportControllerSend::SetAllocatedSendBitrateLimits(
Sebastian Jansson93b1ea22019-09-18 16:31:52229 BitrateAllocationLimits limits) {
Sebastian Jansson87609be2018-12-05 16:35:35230 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson93b1ea22019-09-18 16:31:52231 streams_config_.min_total_allocated_bitrate = limits.min_allocatable_rate;
232 streams_config_.max_padding_rate = limits.max_padding_rate;
233 streams_config_.max_total_allocated_bitrate = limits.max_allocatable_rate;
Sebastian Jansson87609be2018-12-05 16:35:35234 UpdateStreamsConfig();
Stefan Holmer5c8942a2017-08-22 14:16:44235}
Sebastian Jansson4c1ffb82018-02-15 15:51:58236void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) {
Sebastian Jansson87609be2018-12-05 16:35:35237 RTC_DCHECK_RUN_ON(&task_queue_);
238 streams_config_.pacing_factor = pacing_factor;
239 UpdateStreamsConfig();
Sebastian Jansson4c1ffb82018-02-15 15:51:58240}
241void RtpTransportControllerSend::SetQueueTimeLimit(int limit_ms) {
Danil Chapovalov0c626af2020-02-10 10:16:00242 pacer()->SetQueueTimeLimit(TimeDelta::Millis(limit_ms));
Sebastian Jansson4c1ffb82018-02-15 15:51:58243}
Sebastian Janssonf2988552019-10-29 16:18:51244StreamFeedbackProvider*
245RtpTransportControllerSend::GetStreamFeedbackProvider() {
JT Tehea992f82020-01-15 18:24:20246 return &feedback_demuxer_;
Sebastian Janssone4be6da2018-02-15 15:51:41247}
Sebastian Jansson19704ec2018-03-12 14:59:12248
249void RtpTransportControllerSend::RegisterTargetTransferRateObserver(
250 TargetTransferRateObserver* observer) {
Sebastian Jansson87609be2018-12-05 16:35:35251 task_queue_.PostTask([this, observer] {
252 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson19704ec2018-03-12 14:59:12253 RTC_DCHECK(observer_ == nullptr);
254 observer_ = observer;
Sebastian Jansson2701bc92018-12-11 14:02:47255 observer_->OnStartRateUpdate(*initial_config_.constraints.starting_rate);
Sebastian Jansson87609be2018-12-05 16:35:35256 MaybeCreateControllers();
257 });
Sebastian Janssone4be6da2018-02-15 15:51:41258}
Christoffer Rodbro6404cdd2020-03-26 19:37:21259
260bool RtpTransportControllerSend::IsRelevantRouteChange(
261 const rtc::NetworkRoute& old_route,
262 const rtc::NetworkRoute& new_route) const {
263 // TODO(bugs.webrtc.org/11438): Experiment with using more information/
264 // other conditions.
265 bool connected_changed = old_route.connected != new_route.connected;
266 bool route_ids_changed =
267 old_route.local.network_id() != new_route.local.network_id() ||
268 old_route.remote.network_id() != new_route.remote.network_id();
269 if (relay_bandwidth_cap_->IsFinite()) {
270 bool relaying_changed = IsRelayed(old_route) != IsRelayed(new_route);
271 return connected_changed || route_ids_changed || relaying_changed;
272 } else {
273 return connected_changed || route_ids_changed;
274 }
275}
276
Sebastian Janssone4be6da2018-02-15 15:51:41277void RtpTransportControllerSend::OnNetworkRouteChanged(
Sebastian Jansson97f61ea2018-02-21 12:01:55278 const std::string& transport_name,
279 const rtc::NetworkRoute& network_route) {
Sebastian Jansson91bb6672018-02-21 12:02:51280 // Check if the network route is connected.
Jonas Oreland71fda362020-03-20 15:11:56281
Sebastian Jansson91bb6672018-02-21 12:02:51282 if (!network_route.connected) {
Sebastian Jansson91bb6672018-02-21 12:02:51283 // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and
284 // consider merging these two methods.
285 return;
286 }
287
Christoffer Rodbro6404cdd2020-03-26 19:37:21288 absl::optional<BitrateConstraints> relay_constraint_update =
289 ApplyOrLiftRelayCap(IsRelayed(network_route));
290
Sebastian Jansson91bb6672018-02-21 12:02:51291 // Check whether the network route has changed on each transport.
292 auto result =
293 network_routes_.insert(std::make_pair(transport_name, network_route));
294 auto kv = result.first;
295 bool inserted = result.second;
Jonas Oreland5b6a4d82020-03-24 06:36:52296 if (inserted || !(kv->second == network_route)) {
297 RTC_LOG(LS_INFO) << "Network route changed on transport " << transport_name
298 << ": new_route = " << network_route.DebugString();
299 if (!inserted) {
300 RTC_LOG(LS_INFO) << "old_route = " << kv->second.DebugString();
301 }
302 }
303
Sebastian Jansson91bb6672018-02-21 12:02:51304 if (inserted) {
Christoffer Rodbro6404cdd2020-03-26 19:37:21305 if (relay_constraint_update.has_value()) {
306 UpdateBitrateConstraints(*relay_constraint_update);
307 }
Jakob Ivarssonb4cdd622020-02-13 13:01:26308 task_queue_.PostTask([this, network_route] {
309 RTC_DCHECK_RUN_ON(&task_queue_);
310 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
311 });
Sebastian Jansson91bb6672018-02-21 12:02:51312 // No need to reset BWE if this is the first time the network connects.
313 return;
314 }
Jonas Oreland5b6a4d82020-03-24 06:36:52315
316 const rtc::NetworkRoute old_route = kv->second;
Jonas Oreland71fda362020-03-20 15:11:56317 kv->second = network_route;
Jonas Oreland71fda362020-03-20 15:11:56318
319 // Check if enough conditions of the new/old route has changed
320 // to trigger resetting of bitrates (and a probe).
Christoffer Rodbrob0ca5192020-03-26 08:22:24321 if (IsRelevantRouteChange(old_route, network_route)) {
Sebastian Jansson91bb6672018-02-21 12:02:51322 BitrateConstraints bitrate_config = bitrate_configurator_.GetConfig();
Jonas Oreland71fda362020-03-20 15:11:56323 RTC_LOG(LS_INFO) << "Reset bitrates to min: "
Sebastian Jansson91bb6672018-02-21 12:02:51324 << bitrate_config.min_bitrate_bps
325 << " bps, start: " << bitrate_config.start_bitrate_bps
326 << " bps, max: " << bitrate_config.max_bitrate_bps
327 << " bps.";
328 RTC_DCHECK_GT(bitrate_config.start_bitrate_bps, 0);
Sebastian Jansson87609be2018-12-05 16:35:35329
Sebastian Jansson166b45d2019-05-13 09:57:42330 if (event_log_) {
Mirko Bonadei317a1f02019-09-17 15:06:18331 event_log_->Log(std::make_unique<RtcEventRouteChange>(
Sebastian Jansson166b45d2019-05-13 09:57:42332 network_route.connected, network_route.packet_overhead));
333 }
Sebastian Jansson87609be2018-12-05 16:35:35334 NetworkRouteChange msg;
Danil Chapovalov0c626af2020-02-10 10:16:00335 msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35336 msg.constraints = ConvertConstraints(bitrate_config, clock_);
Sebastian Jansson658f1812020-01-16 09:59:28337 task_queue_.PostTask([this, msg, network_route] {
Sebastian Jansson87609be2018-12-05 16:35:35338 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson658f1812020-01-16 09:59:28339 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
340 if (reset_feedback_on_route_change_) {
Christoffer Rodbrob0ca5192020-03-26 08:22:24341 transport_feedback_adapter_.SetNetworkRoute(network_route);
Sebastian Jansson658f1812020-01-16 09:59:28342 }
Sebastian Jansson87609be2018-12-05 16:35:35343 if (controller_) {
Sebastian Jansson16180952018-12-12 15:49:10344 PostUpdates(controller_->OnNetworkRouteChange(msg));
Sebastian Jansson87609be2018-12-05 16:35:35345 } else {
346 UpdateInitialConstraints(msg.constraints);
347 }
Erik Språng425d6aa2019-07-29 14:38:27348 pacer()->UpdateOutstandingData(DataSize::Zero());
Sebastian Jansson87609be2018-12-05 16:35:35349 });
Sebastian Jansson91bb6672018-02-21 12:02:51350 }
Sebastian Janssone4be6da2018-02-15 15:51:41351}
352void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
Harald Alvestrand977b2652019-12-12 12:40:50353 RTC_LOG(LS_VERBOSE) << "SignalNetworkState "
354 << (network_available ? "Up" : "Down");
Sebastian Jansson87609be2018-12-05 16:35:35355 NetworkAvailability msg;
Danil Chapovalov0c626af2020-02-10 10:16:00356 msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35357 msg.network_available = network_available;
358 task_queue_.PostTask([this, msg]() {
359 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson16180952018-12-12 15:49:10360 if (network_available_ == msg.network_available)
361 return;
Sebastian Jansson87609be2018-12-05 16:35:35362 network_available_ = msg.network_available;
Sebastian Jansson16180952018-12-12 15:49:10363 if (network_available_) {
Erik Språng425d6aa2019-07-29 14:38:27364 pacer()->Resume();
Sebastian Jansson16180952018-12-12 15:49:10365 } else {
Erik Språng425d6aa2019-07-29 14:38:27366 pacer()->Pause();
Sebastian Jansson16180952018-12-12 15:49:10367 }
Erik Språng425d6aa2019-07-29 14:38:27368 pacer()->UpdateOutstandingData(DataSize::Zero());
Sebastian Jansson16180952018-12-12 15:49:10369
Sebastian Jansson87609be2018-12-05 16:35:35370 if (controller_) {
Sebastian Jansson16180952018-12-12 15:49:10371 control_handler_->SetNetworkAvailability(network_available_);
372 PostUpdates(controller_->OnNetworkAvailability(msg));
373 UpdateControlState();
Sebastian Jansson87609be2018-12-05 16:35:35374 } else {
375 MaybeCreateControllers();
376 }
377 });
378
Stefan Holmerdbdb3a02018-07-17 14:03:46379 for (auto& rtp_sender : video_rtp_senders_) {
380 rtp_sender->OnNetworkAvailability(network_available);
381 }
Sebastian Janssone4be6da2018-02-15 15:51:41382}
Sebastian Janssone4be6da2018-02-15 15:51:41383RtcpBandwidthObserver* RtpTransportControllerSend::GetBandwidthObserver() {
Sebastian Jansson87609be2018-12-05 16:35:35384 return this;
Sebastian Janssone4be6da2018-02-15 15:51:41385}
Sebastian Janssone4be6da2018-02-15 15:51:41386int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const {
Erik Språng425d6aa2019-07-29 14:38:27387 return pacer()->OldestPacketWaitTime().ms();
Sebastian Janssone4be6da2018-02-15 15:51:41388}
Erik Språng425d6aa2019-07-29 14:38:27389absl::optional<Timestamp> RtpTransportControllerSend::GetFirstPacketTime()
390 const {
391 return pacer()->FirstSentPacketTime();
Sebastian Janssone4be6da2018-02-15 15:51:41392}
Sebastian Janssone4be6da2018-02-15 15:51:41393void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) {
Sebastian Jansson87609be2018-12-05 16:35:35394 task_queue_.PostTask([this, enable]() {
395 RTC_DCHECK_RUN_ON(&task_queue_);
396 streams_config_.requests_alr_probing = enable;
397 UpdateStreamsConfig();
398 });
Sebastian Janssone4be6da2018-02-15 15:51:41399}
400void RtpTransportControllerSend::OnSentPacket(
401 const rtc::SentPacket& sent_packet) {
Sebastian Jansson658f1812020-01-16 09:59:28402 task_queue_.PostTask([this, sent_packet]() {
403 RTC_DCHECK_RUN_ON(&task_queue_);
404 absl::optional<SentPacket> packet_msg =
405 transport_feedback_adapter_.ProcessSentPacket(sent_packet);
406 pacer()->UpdateOutstandingData(
407 transport_feedback_adapter_.GetOutstandingData());
408 if (packet_msg && controller_)
409 PostUpdates(controller_->OnSentPacket(*packet_msg));
410 });
Sebastian Janssone4be6da2018-02-15 15:51:41411}
sprangdb2a9fc2017-08-09 13:42:32412
Ying Wang8b279102019-05-27 15:19:08413void RtpTransportControllerSend::OnReceivedPacket(
Sebastian Jansson607a6f12019-06-13 15:48:53414 const ReceivedPacket& packet_msg) {
Ying Wang8b279102019-05-27 15:19:08415 task_queue_.PostTask([this, packet_msg]() {
416 RTC_DCHECK_RUN_ON(&task_queue_);
417 if (controller_)
418 PostUpdates(controller_->OnReceivedPacket(packet_msg));
419 });
420}
421
Christoffer Rodbrob0ca5192020-03-26 08:22:24422void RtpTransportControllerSend::UpdateBitrateConstraints(
423 const BitrateConstraints& updated) {
424 TargetRateConstraints msg = ConvertConstraints(updated, clock_);
425 task_queue_.PostTask([this, msg]() {
426 RTC_DCHECK_RUN_ON(&task_queue_);
427 if (controller_) {
428 PostUpdates(controller_->OnTargetRateConstraints(msg));
429 } else {
430 UpdateInitialConstraints(msg);
431 }
432 });
433}
434
Sebastian Jansson97f61ea2018-02-21 12:01:55435void RtpTransportControllerSend::SetSdpBitrateParameters(
436 const BitrateConstraints& constraints) {
Danil Chapovalovb9b146c2018-06-15 10:28:07437 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 12:01:55438 bitrate_configurator_.UpdateWithSdpParameters(constraints);
439 if (updated.has_value()) {
Christoffer Rodbrob0ca5192020-03-26 08:22:24440 UpdateBitrateConstraints(*updated);
Sebastian Jansson97f61ea2018-02-21 12:01:55441 } else {
442 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 12:07:13443 << "WebRTC.RtpTransportControllerSend.SetSdpBitrateParameters: "
Jonas Olssonb2b20312020-01-14 11:11:31444 "nothing to update";
Sebastian Jansson97f61ea2018-02-21 12:01:55445 }
446}
447
448void RtpTransportControllerSend::SetClientBitratePreferences(
Niels Möller0c4f7be2018-05-07 12:01:37449 const BitrateSettings& preferences) {
Danil Chapovalovb9b146c2018-06-15 10:28:07450 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 12:01:55451 bitrate_configurator_.UpdateWithClientPreferences(preferences);
452 if (updated.has_value()) {
Christoffer Rodbrob0ca5192020-03-26 08:22:24453 UpdateBitrateConstraints(*updated);
Sebastian Jansson97f61ea2018-02-21 12:01:55454 } else {
455 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 12:07:13456 << "WebRTC.RtpTransportControllerSend.SetClientBitratePreferences: "
Jonas Olssonb2b20312020-01-14 11:11:31457 "nothing to update";
Sebastian Jansson97f61ea2018-02-21 12:01:55458 }
459}
Alex Narestbcf91802018-06-25 14:08:36460
Christoffer Rodbro6404cdd2020-03-26 19:37:21461absl::optional<BitrateConstraints>
462RtpTransportControllerSend::ApplyOrLiftRelayCap(bool is_relayed) {
463 DataRate cap = is_relayed ? relay_bandwidth_cap_ : DataRate::PlusInfinity();
464 return bitrate_configurator_.UpdateWithRelayCap(cap);
465}
466
Stefan Holmer64be7fa2018-10-04 13:21:55467void RtpTransportControllerSend::OnTransportOverheadChanged(
468 size_t transport_overhead_bytes_per_packet) {
469 if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) {
470 RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes;
471 return;
472 }
473
Mirko Bonadeie7bc3a32020-01-29 18:45:00474 pacer()->SetTransportOverhead(
Danil Chapovalovcad3e0e2020-02-17 17:46:07475 DataSize::Bytes(transport_overhead_bytes_per_packet));
Mirko Bonadeie7bc3a32020-01-29 18:45:00476
Stefan Holmer64be7fa2018-10-04 13:21:55477 // TODO(holmer): Call AudioRtpSenders when they have been moved to
478 // RtpTransportControllerSend.
479 for (auto& rtp_video_sender : video_rtp_senders_) {
480 rtp_video_sender->OnTransportOverheadChanged(
481 transport_overhead_bytes_per_packet);
482 }
483}
Sebastian Jansson87609be2018-12-05 16:35:35484
Erik Språngaa59eca2019-07-24 12:52:55485void RtpTransportControllerSend::AccountForAudioPacketsInPacedSender(
486 bool account_for_audio) {
Erik Språng425d6aa2019-07-29 14:38:27487 pacer()->SetAccountForAudioPackets(account_for_audio);
Erik Språngaa59eca2019-07-24 12:52:55488}
489
Sebastian Janssonc3eb9fd2020-01-29 16:42:52490void RtpTransportControllerSend::IncludeOverheadInPacedSender() {
491 pacer()->SetIncludeOverhead();
492}
493
Sebastian Jansson87609be2018-12-05 16:35:35494void RtpTransportControllerSend::OnReceivedEstimatedBitrate(uint32_t bitrate) {
495 RemoteBitrateReport msg;
Danil Chapovalov0c626af2020-02-10 10:16:00496 msg.receive_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Danil Chapovalovcad3e0e2020-02-17 17:46:07497 msg.bandwidth = DataRate::BitsPerSec(bitrate);
Sebastian Jansson87609be2018-12-05 16:35:35498 task_queue_.PostTask([this, msg]() {
499 RTC_DCHECK_RUN_ON(&task_queue_);
500 if (controller_)
Sebastian Jansson16180952018-12-12 15:49:10501 PostUpdates(controller_->OnRemoteBitrateReport(msg));
Sebastian Jansson87609be2018-12-05 16:35:35502 });
503}
504
505void RtpTransportControllerSend::OnReceivedRtcpReceiverReport(
506 const ReportBlockList& report_blocks,
507 int64_t rtt_ms,
508 int64_t now_ms) {
509 task_queue_.PostTask([this, report_blocks, now_ms]() {
510 RTC_DCHECK_RUN_ON(&task_queue_);
511 OnReceivedRtcpReceiverReportBlocks(report_blocks, now_ms);
512 });
513
514 task_queue_.PostTask([this, now_ms, rtt_ms]() {
515 RTC_DCHECK_RUN_ON(&task_queue_);
516 RoundTripTimeUpdate report;
Danil Chapovalov0c626af2020-02-10 10:16:00517 report.receive_time = Timestamp::Millis(now_ms);
518 report.round_trip_time = TimeDelta::Millis(rtt_ms);
Sebastian Jansson87609be2018-12-05 16:35:35519 report.smoothed = false;
Christoffer Rodbro4bd31772019-03-27 11:34:21520 if (controller_ && !report.round_trip_time.IsZero())
Sebastian Jansson16180952018-12-12 15:49:10521 PostUpdates(controller_->OnRoundTripTimeUpdate(report));
Sebastian Jansson87609be2018-12-05 16:35:35522 });
523}
524
Erik Språng30a276b2019-04-23 10:00:11525void RtpTransportControllerSend::OnAddPacket(
526 const RtpPacketSendInfo& packet_info) {
JT Tehea992f82020-01-15 18:24:20527 feedback_demuxer_.AddPacket(packet_info);
528
Danil Chapovalov0c626af2020-02-10 10:16:00529 Timestamp creation_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson658f1812020-01-16 09:59:28530 task_queue_.PostTask([this, packet_info, creation_time]() {
531 RTC_DCHECK_RUN_ON(&task_queue_);
532 transport_feedback_adapter_.AddPacket(
533 packet_info,
534 send_side_bwe_with_overhead_ ? transport_overhead_bytes_per_packet_ : 0,
535 creation_time);
536 });
Sebastian Jansson87609be2018-12-05 16:35:35537}
538
539void RtpTransportControllerSend::OnTransportFeedback(
540 const rtcp::TransportFeedback& feedback) {
JT Tehea992f82020-01-15 18:24:20541 feedback_demuxer_.OnTransportFeedback(feedback);
Danil Chapovalov0c626af2020-02-10 10:16:00542 auto feedback_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson658f1812020-01-16 09:59:28543 task_queue_.PostTask([this, feedback, feedback_time]() {
544 RTC_DCHECK_RUN_ON(&task_queue_);
545 absl::optional<TransportPacketsFeedback> feedback_msg =
546 transport_feedback_adapter_.ProcessTransportFeedback(feedback,
547 feedback_time);
548 if (feedback_msg && controller_) {
549 PostUpdates(controller_->OnTransportPacketsFeedback(*feedback_msg));
550 }
551 pacer()->UpdateOutstandingData(
552 transport_feedback_adapter_.GetOutstandingData());
553 });
Sebastian Jansson87609be2018-12-05 16:35:35554}
555
Sebastian Janssone1795f42019-07-24 09:38:03556void RtpTransportControllerSend::OnRemoteNetworkEstimate(
557 NetworkStateEstimate estimate) {
Sebastian Jansson0a5ed892019-09-18 13:37:31558 if (event_log_) {
559 event_log_->Log(std::make_unique<RtcEventRemoteEstimate>(
560 estimate.link_capacity_lower, estimate.link_capacity_upper));
561 }
Danil Chapovalov0c626af2020-02-10 10:16:00562 estimate.update_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Janssone1795f42019-07-24 09:38:03563 task_queue_.PostTask([this, estimate] {
564 RTC_DCHECK_RUN_ON(&task_queue_);
565 if (controller_)
Danil Chapovalove34fb872019-10-21 08:51:08566 PostUpdates(controller_->OnNetworkStateEstimate(estimate));
Sebastian Janssone1795f42019-07-24 09:38:03567 });
568}
569
Sebastian Jansson87609be2018-12-05 16:35:35570void RtpTransportControllerSend::MaybeCreateControllers() {
571 RTC_DCHECK(!controller_);
572 RTC_DCHECK(!control_handler_);
573
574 if (!network_available_ || !observer_)
575 return;
Mirko Bonadei317a1f02019-09-17 15:06:18576 control_handler_ = std::make_unique<CongestionControlHandler>();
Sebastian Jansson87609be2018-12-05 16:35:35577
578 initial_config_.constraints.at_time =
Danil Chapovalov0c626af2020-02-10 10:16:00579 Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35580 initial_config_.stream_based_config = streams_config_;
581
582 // TODO(srte): Use fallback controller if no feedback is available.
583 if (controller_factory_override_) {
584 RTC_LOG(LS_INFO) << "Creating overridden congestion controller";
585 controller_ = controller_factory_override_->Create(initial_config_);
586 process_interval_ = controller_factory_override_->GetProcessInterval();
587 } else {
588 RTC_LOG(LS_INFO) << "Creating fallback congestion controller";
589 controller_ = controller_factory_fallback_->Create(initial_config_);
590 process_interval_ = controller_factory_fallback_->GetProcessInterval();
591 }
592 UpdateControllerWithTimeInterval();
593 StartProcessPeriodicTasks();
594}
595
596void RtpTransportControllerSend::UpdateInitialConstraints(
597 TargetRateConstraints new_contraints) {
598 if (!new_contraints.starting_rate)
599 new_contraints.starting_rate = initial_config_.constraints.starting_rate;
600 RTC_DCHECK(new_contraints.starting_rate);
601 initial_config_.constraints = new_contraints;
602}
603
604void RtpTransportControllerSend::StartProcessPeriodicTasks() {
Sebastian Janssonecb68972019-01-18 09:30:54605 if (!pacer_queue_update_task_.Running()) {
606 pacer_queue_update_task_ = RepeatingTaskHandle::DelayedStart(
Danil Chapovalov4423c362019-03-06 17:41:39607 task_queue_.Get(), kPacerQueueUpdateInterval, [this]() {
Sebastian Jansson87609be2018-12-05 16:35:35608 RTC_DCHECK_RUN_ON(&task_queue_);
Erik Språng425d6aa2019-07-29 14:38:27609 TimeDelta expected_queue_time = pacer()->ExpectedQueueTime();
Sebastian Jansson16180952018-12-12 15:49:10610 control_handler_->SetPacerQueue(expected_queue_time);
611 UpdateControlState();
Sebastian Janssonecb68972019-01-18 09:30:54612 return kPacerQueueUpdateInterval;
Sebastian Jansson87609be2018-12-05 16:35:35613 });
614 }
Sebastian Janssonecb68972019-01-18 09:30:54615 controller_task_.Stop();
Sebastian Jansson87609be2018-12-05 16:35:35616 if (process_interval_.IsFinite()) {
Sebastian Janssonecb68972019-01-18 09:30:54617 controller_task_ = RepeatingTaskHandle::DelayedStart(
Danil Chapovalov4423c362019-03-06 17:41:39618 task_queue_.Get(), process_interval_, [this]() {
Sebastian Jansson87609be2018-12-05 16:35:35619 RTC_DCHECK_RUN_ON(&task_queue_);
620 UpdateControllerWithTimeInterval();
Sebastian Janssonecb68972019-01-18 09:30:54621 return process_interval_;
Sebastian Jansson87609be2018-12-05 16:35:35622 });
623 }
624}
625
626void RtpTransportControllerSend::UpdateControllerWithTimeInterval() {
Sebastian Jansson16180952018-12-12 15:49:10627 RTC_DCHECK(controller_);
628 ProcessInterval msg;
Danil Chapovalov0c626af2020-02-10 10:16:00629 msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Christoffer Rodbroc610e262019-01-08 09:49:19630 if (add_pacing_to_cwin_)
Erik Språng425d6aa2019-07-29 14:38:27631 msg.pacer_queue = pacer()->QueueSizeData();
Sebastian Jansson16180952018-12-12 15:49:10632 PostUpdates(controller_->OnProcessInterval(msg));
Sebastian Jansson87609be2018-12-05 16:35:35633}
634
635void RtpTransportControllerSend::UpdateStreamsConfig() {
Danil Chapovalov0c626af2020-02-10 10:16:00636 streams_config_.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35637 if (controller_)
Sebastian Jansson16180952018-12-12 15:49:10638 PostUpdates(controller_->OnStreamsConfig(streams_config_));
639}
640
641void RtpTransportControllerSend::PostUpdates(NetworkControlUpdate update) {
642 if (update.congestion_window) {
Erik Språng425d6aa2019-07-29 14:38:27643 pacer()->SetCongestionWindow(*update.congestion_window);
Sebastian Jansson16180952018-12-12 15:49:10644 }
645 if (update.pacer_config) {
Erik Språng425d6aa2019-07-29 14:38:27646 pacer()->SetPacingRates(update.pacer_config->data_rate(),
647 update.pacer_config->pad_rate());
Sebastian Jansson16180952018-12-12 15:49:10648 }
649 for (const auto& probe : update.probe_cluster_configs) {
Erik Språng425d6aa2019-07-29 14:38:27650 pacer()->CreateProbeCluster(probe.target_data_rate, probe.id);
Sebastian Jansson16180952018-12-12 15:49:10651 }
652 if (update.target_rate) {
653 control_handler_->SetTargetRate(*update.target_rate);
654 UpdateControlState();
655 }
Sebastian Jansson87609be2018-12-05 16:35:35656}
657
658void RtpTransportControllerSend::OnReceivedRtcpReceiverReportBlocks(
659 const ReportBlockList& report_blocks,
660 int64_t now_ms) {
661 if (report_blocks.empty())
662 return;
663
664 int total_packets_lost_delta = 0;
665 int total_packets_delta = 0;
666
667 // Compute the packet loss from all report blocks.
668 for (const RTCPReportBlock& report_block : report_blocks) {
669 auto it = last_report_blocks_.find(report_block.source_ssrc);
670 if (it != last_report_blocks_.end()) {
671 auto number_of_packets = report_block.extended_highest_sequence_number -
672 it->second.extended_highest_sequence_number;
673 total_packets_delta += number_of_packets;
674 auto lost_delta = report_block.packets_lost - it->second.packets_lost;
675 total_packets_lost_delta += lost_delta;
676 }
677 last_report_blocks_[report_block.source_ssrc] = report_block;
678 }
679 // Can only compute delta if there has been previous blocks to compare to. If
680 // not, total_packets_delta will be unchanged and there's nothing more to do.
681 if (!total_packets_delta)
682 return;
683 int packets_received_delta = total_packets_delta - total_packets_lost_delta;
684 // To detect lost packets, at least one packet has to be received. This check
685 // is needed to avoid bandwith detection update in
686 // VideoSendStreamTest.SuspendBelowMinBitrate
687
688 if (packets_received_delta < 1)
689 return;
Danil Chapovalov0c626af2020-02-10 10:16:00690 Timestamp now = Timestamp::Millis(now_ms);
Sebastian Jansson87609be2018-12-05 16:35:35691 TransportLossReport msg;
692 msg.packets_lost_delta = total_packets_lost_delta;
693 msg.packets_received_delta = packets_received_delta;
694 msg.receive_time = now;
695 msg.start_time = last_report_block_time_;
696 msg.end_time = now;
697 if (controller_)
Sebastian Jansson16180952018-12-12 15:49:10698 PostUpdates(controller_->OnTransportLossReport(msg));
Sebastian Jansson87609be2018-12-05 16:35:35699 last_report_block_time_ = now;
700}
701
nissecae45d02017-04-24 12:53:20702} // namespace webrtc