blob: 23f9b91483171acdca48b8b575a19dc266dd4920 [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
Harald Alvestrand93c9aa12024-09-02 20:55:5212#include <cstddef>
Per K02af8402024-03-27 18:35:5513#include <cstdint>
Harald Alvestrand93c9aa12024-09-02 20:55:5214#include <map>
Mirko Bonadei317a1f02019-09-17 15:06:1815#include <memory>
Florent Castelli8037fc62024-08-29 13:00:4016#include <optional>
Harald Alvestrand93c9aa12024-09-02 20:55:5217#include <string>
Sebastian Jansson91bb6672018-02-21 12:02:5118#include <utility>
Stefan Holmerdbdb3a02018-07-17 14:03:4619#include <vector>
nissecae45d02017-04-24 12:53:2020
Ali Tofigh641a1b12022-05-17 09:48:4621#include "absl/strings/string_view.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5222#include "api/array_view.h"
23#include "api/call/transport.h"
24#include "api/fec_controller.h"
25#include "api/frame_transformer_interface.h"
Danil Chapovalovaf8f6262024-09-04 15:18:3026#include "api/rtc_event_log/rtc_event_log.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5227#include "api/rtp_packet_sender.h"
28#include "api/scoped_refptr.h"
29#include "api/sequence_checker.h"
Per Kjellander828ef912022-10-10 10:53:4130#include "api/task_queue/pending_task_safety_flag.h"
Per K37879e92023-04-13 06:59:1931#include "api/task_queue/task_queue_base.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5232#include "api/transport/bandwidth_estimation_settings.h"
33#include "api/transport/bitrate_settings.h"
Sebastian Jansson87609be2018-12-05 16:35:3534#include "api/transport/goog_cc_factory.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5235#include "api/transport/network_control.h"
Yves Gerey3e707812018-11-28 15:47:4936#include "api/transport/network_types.h"
37#include "api/units/data_rate.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5238#include "api/units/data_size.h"
Yves Gerey3e707812018-11-28 15:47:4939#include "api/units/time_delta.h"
40#include "api/units/timestamp.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5241#include "call/rtp_config.h"
42#include "call/rtp_transport_config.h"
43#include "call/rtp_transport_controller_send_interface.h"
Yves Gerey3e707812018-11-28 15:47:4944#include "call/rtp_video_sender.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5245#include "call/rtp_video_sender_interface.h"
Sebastian Jansson166b45d2019-05-13 09:57:4246#include "logging/rtc_event_log/events/rtc_event_route_change.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5247#include "modules/congestion_controller/rtp/control_handler.h"
48#include "modules/pacing/packet_router.h"
49#include "modules/rtp_rtcp/include/report_block_data.h"
Per K02af8402024-03-27 18:35:5550#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Per K1d2f85d2024-10-23 12:11:4151#include "modules/rtp_rtcp/source/rtcp_packet/congestion_control_feedback.h"
Sebastian Jansson658f1812020-01-16 09:59:2852#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
Per K1d2f85d2024-10-23 12:11:4153#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5254#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
Yves Gerey3e707812018-11-28 15:47:4955#include "rtc_base/checks.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5256#include "rtc_base/experiments/field_trial_parser.h"
Sebastian Jansson97f61ea2018-02-21 12:01:5557#include "rtc_base/logging.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5258#include "rtc_base/network/sent_packet.h"
59#include "rtc_base/network_route.h"
Stefan Holmerdbdb3a02018-07-17 14:03:4660#include "rtc_base/rate_limiter.h"
Harald Alvestrand93c9aa12024-09-02 20:55:5261#include "rtc_base/task_utils/repeating_task.h"
nissecae45d02017-04-24 12:53:2062
63namespace webrtc {
Sebastian Jansson19bea512018-03-13 18:07:4664namespace {
Stefan Holmerdbdb3a02018-07-17 14:03:4665static const int64_t kRetransmitWindowSizeMs = 500;
Stefan Holmer64be7fa2018-10-04 13:21:5566static const size_t kMaxOverheadBytes = 500;
Sebastian Jansson19bea512018-03-13 18:07:4667
Danil Chapovalov0c626af2020-02-10 10:16:0068constexpr TimeDelta kPacerQueueUpdateInterval = TimeDelta::Millis(25);
Sebastian Jansson87609be2018-12-05 16:35:3569
70TargetRateConstraints ConvertConstraints(int min_bitrate_bps,
71 int max_bitrate_bps,
72 int start_bitrate_bps,
Sebastian Janssonaa01f272019-01-30 10:28:5973 Clock* clock) {
Sebastian Jansson87609be2018-12-05 16:35:3574 TargetRateConstraints msg;
Danil Chapovalov0c626af2020-02-10 10:16:0075 msg.at_time = Timestamp::Millis(clock->TimeInMilliseconds());
Danil Chapovalovcad3e0e2020-02-17 17:46:0776 msg.min_data_rate = min_bitrate_bps >= 0
77 ? DataRate::BitsPerSec(min_bitrate_bps)
78 : DataRate::Zero();
79 msg.max_data_rate = max_bitrate_bps > 0
80 ? DataRate::BitsPerSec(max_bitrate_bps)
81 : DataRate::Infinity();
Sebastian Jansson87609be2018-12-05 16:35:3582 if (start_bitrate_bps > 0)
Danil Chapovalovcad3e0e2020-02-17 17:46:0783 msg.starting_rate = DataRate::BitsPerSec(start_bitrate_bps);
Sebastian Jansson87609be2018-12-05 16:35:3584 return msg;
85}
86
87TargetRateConstraints ConvertConstraints(const BitrateConstraints& contraints,
Sebastian Janssonaa01f272019-01-30 10:28:5988 Clock* clock) {
Sebastian Jansson87609be2018-12-05 16:35:3589 return ConvertConstraints(contraints.min_bitrate_bps,
90 contraints.max_bitrate_bps,
91 contraints.start_bitrate_bps, clock);
92}
Erik Språng662678d2019-11-15 16:18:5293
Christoffer Rodbro6404cdd2020-03-26 19:37:2194bool IsRelayed(const rtc::NetworkRoute& route) {
95 return route.local.uses_turn() || route.remote.uses_turn();
Christoffer Rodbrob0ca5192020-03-26 08:22:2496}
Sebastian Jansson19bea512018-03-13 18:07:4697} // namespace
nissecae45d02017-04-24 12:53:2098
99RtpTransportControllerSend::RtpTransportControllerSend(
Henrik Boströmda4c1022022-11-15 14:45:41100 const RtpTransportConfig& config)
Danil Chapovalovee27f382023-12-18 12:09:12101 : env_(config.env),
Per K37879e92023-04-13 06:59:19102 task_queue_(TaskQueueBase::Current()),
Henrik Boströmda4c1022022-11-15 14:45:41103 bitrate_configurator_(config.bitrate_config),
Etienne Pierre-doray03bce3f2021-03-29 17:36:15104 pacer_started_(false),
Danil Chapovalovee27f382023-12-18 12:09:12105 pacer_(&env_.clock(),
106 &packet_router_,
107 env_.field_trials(),
108 TimeDelta::Millis(5),
109 3),
Sebastian Jansson317a5222018-03-16 14:36:37110 observer_(nullptr),
Henrik Boströmda4c1022022-11-15 14:45:41111 controller_factory_override_(config.network_controller_factory),
Sebastian Jansson87609be2018-12-05 16:35:35112 controller_factory_fallback_(
Henrik Boströmda4c1022022-11-15 14:45:41113 std::make_unique<GoogCcNetworkControllerFactory>(
Danil Chapovalov3a92ae92024-04-15 17:26:18114 GoogCcFactoryConfig{.network_state_predictor_factory =
115 config.network_state_predictor_factory})),
Sebastian Jansson87609be2018-12-05 16:35:35116 process_interval_(controller_factory_fallback_->GetProcessInterval()),
Danil Chapovalovee27f382023-12-18 12:09:12117 last_report_block_time_(
118 Timestamp::Millis(env_.clock().TimeInMilliseconds())),
Danil Chapovalovf20ed3e2024-05-08 10:49:40119 initial_config_(env_),
Sebastian Jansson87609be2018-12-05 16:35:35120 reset_feedback_on_route_change_(
Danil Chapovalovee27f382023-12-18 12:09:12121 !env_.field_trials().IsEnabled("WebRTC-Bwe-NoFeedbackReset")),
122 add_pacing_to_cwin_(env_.field_trials().IsEnabled(
123 "WebRTC-AddPacingToCongestionWindowPushback")),
Per Kd1a8ce52024-05-16 10:33:52124 reset_bwe_on_adapter_id_change_(
125 env_.field_trials().IsEnabled("WebRTC-Bwe-ResetOnAdapterIdChange")),
Christoffer Rodbro6404cdd2020-03-26 19:37:21126 relay_bandwidth_cap_("relay_cap", DataRate::PlusInfinity()),
Sebastian Jansson87609be2018-12-05 16:35:35127 transport_overhead_bytes_per_packet_(0),
128 network_available_(false),
Erik Språng66734372022-03-16 13:20:49129 congestion_window_size_(DataSize::PlusInfinity()),
130 is_congested_(false),
Danil Chapovalovee27f382023-12-18 12:09:12131 retransmission_rate_limiter_(&env_.clock(), kRetransmitWindowSizeMs) {
132 ParseFieldTrial(
133 {&relay_bandwidth_cap_},
134 env_.field_trials().Lookup("WebRTC-Bwe-NetworkRouteConstraints"));
Henrik Boströmda4c1022022-11-15 14:45:41135 initial_config_.constraints =
Danil Chapovalovee27f382023-12-18 12:09:12136 ConvertConstraints(config.bitrate_config, &env_.clock());
Henrik Boströmda4c1022022-11-15 14:45:41137 RTC_DCHECK(config.bitrate_config.start_bitrate_bps > 0);
Sebastian Jansson87609be2018-12-05 16:35:35138
Henrik Boströmda4c1022022-11-15 14:45:41139 pacer_.SetPacingRates(
140 DataRate::BitsPerSec(config.bitrate_config.start_bitrate_bps),
141 DataRate::Zero());
Per K86b1cf72023-12-08 13:57:13142 if (config.pacer_burst_interval) {
143 // Default burst interval overriden by config.
144 pacer_.SetSendBurstInterval(*config.pacer_burst_interval);
145 }
Per K02af8402024-03-27 18:35:55146 packet_router_.RegisterNotifyBweCallback(
147 [this](const RtpPacketToSend& packet,
148 const PacedPacketInfo& pacing_info) {
149 return NotifyBweOfPacedSentPacket(packet, pacing_info);
150 });
Sebastian Jansson97f61ea2018-02-21 12:01:55151}
Sebastian Janssonc33c0fc2018-02-22 10:10:18152
153RtpTransportControllerSend::~RtpTransportControllerSend() {
Per K37879e92023-04-13 06:59:19154 RTC_DCHECK_RUN_ON(&sequence_checker_);
Tommi1050fbc2021-06-03 15:58:28155 RTC_DCHECK(video_rtp_senders_.empty());
Per K37879e92023-04-13 06:59:19156 pacer_queue_update_task_.Stop();
157 controller_task_.Stop();
Sebastian Janssonc33c0fc2018-02-22 10:10:18158}
nissecae45d02017-04-24 12:53:20159
Stefan Holmer9416ef82018-07-19 08:34:38160RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender(
Tommi86952822021-11-29 09:26:40161 const std::map<uint32_t, RtpState>& suspended_ssrcs,
Stefan Holmerdbdb3a02018-07-17 14:03:46162 const std::map<uint32_t, RtpPayloadState>& states,
163 const RtpConfig& rtp_config,
Jiawei Ou55718122018-11-09 21:17:39164 int rtcp_report_interval_ms,
Stefan Holmerdbdb3a02018-07-17 14:03:46165 Transport* send_transport,
166 const RtpSenderObservers& observers,
Benjamin Wright192eeec2018-10-18 00:27:25167 std::unique_ptr<FecController> fec_controller,
Marina Cioceae77912b2020-02-27 15:16:55168 const RtpSenderFrameEncryptionConfig& frame_encryption_config,
169 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {
Per K37879e92023-04-13 06:59:19170 RTC_DCHECK_RUN_ON(&sequence_checker_);
Mirko Bonadei317a1f02019-09-17 15:06:18171 video_rtp_senders_.push_back(std::make_unique<RtpVideoSender>(
Danil Chapovalov0f027282024-09-24 09:22:55172 env_, task_queue_, suspended_ssrcs, states, rtp_config,
173 rtcp_report_interval_ms, send_transport, observers,
Stefan Holmerdbdb3a02018-07-17 14:03:46174 // TODO(holmer): Remove this circular dependency by injecting
175 // the parts of RtpTransportControllerSendInterface that are really used.
Xinyu Ma954fdb02024-07-26 22:09:09176 this, &retransmission_rate_limiter_, std::move(fec_controller),
177 frame_encryption_config.frame_encryptor,
178 frame_encryption_config.crypto_options, std::move(frame_transformer)));
Stefan Holmerdbdb3a02018-07-17 14:03:46179 return video_rtp_senders_.back().get();
180}
181
Stefan Holmer9416ef82018-07-19 08:34:38182void RtpTransportControllerSend::DestroyRtpVideoSender(
183 RtpVideoSenderInterface* rtp_video_sender) {
Per K37879e92023-04-13 06:59:19184 RTC_DCHECK_RUN_ON(&sequence_checker_);
Stefan Holmer9416ef82018-07-19 08:34:38185 std::vector<std::unique_ptr<RtpVideoSenderInterface>>::iterator it =
Stefan Holmer5ed25af2018-07-18 13:17:14186 video_rtp_senders_.end();
187 for (it = video_rtp_senders_.begin(); it != video_rtp_senders_.end(); ++it) {
188 if (it->get() == rtp_video_sender) {
189 break;
190 }
191 }
192 RTC_DCHECK(it != video_rtp_senders_.end());
193 video_rtp_senders_.erase(it);
194}
195
Per K979b6d62024-01-26 10:18:26196void RtpTransportControllerSend::RegisterSendingRtpStream(
197 RtpRtcpInterface& rtp_module) {
198 RTC_DCHECK_RUN_ON(&sequence_checker_);
199 // Allow pacer to send packets using this module.
200 packet_router_.AddSendRtpModule(&rtp_module,
201 /*remb_candidate=*/true);
Per K98db63c2024-01-26 11:57:01202 pacer_.SetAllowProbeWithoutMediaPacket(
Per K39ac25d2024-02-07 13:16:20203 bwe_settings_.allow_probe_without_media &&
Per K98db63c2024-01-26 11:57:01204 packet_router_.SupportsRtxPayloadPadding());
Per K979b6d62024-01-26 10:18:26205}
206
207void RtpTransportControllerSend::DeRegisterSendingRtpStream(
208 RtpRtcpInterface& rtp_module) {
209 RTC_DCHECK_RUN_ON(&sequence_checker_);
210 // Disabling media, remove from packet router map to reduce size and
211 // prevent any stray packets in the pacer from asynchronously arriving
212 // to a disabled module.
213 packet_router_.RemoveSendRtpModule(&rtp_module);
214 // Clear the pacer queue of any packets pertaining to this module.
215 pacer_.RemovePacketsForSsrc(rtp_module.SSRC());
216 if (rtp_module.RtxSsrc().has_value()) {
217 pacer_.RemovePacketsForSsrc(*rtp_module.RtxSsrc());
218 }
219 if (rtp_module.FlexfecSsrc().has_value()) {
220 pacer_.RemovePacketsForSsrc(*rtp_module.FlexfecSsrc());
221 }
Per K98db63c2024-01-26 11:57:01222 pacer_.SetAllowProbeWithoutMediaPacket(
Per K39ac25d2024-02-07 13:16:20223 bwe_settings_.allow_probe_without_media &&
Per K98db63c2024-01-26 11:57:01224 packet_router_.SupportsRtxPayloadPadding());
Per K979b6d62024-01-26 10:18:26225}
226
Sebastian Jansson16180952018-12-12 15:49:10227void RtpTransportControllerSend::UpdateControlState() {
Florent Castelli8037fc62024-08-29 13:00:40228 std::optional<TargetTransferRate> update = control_handler_->GetUpdate();
Sebastian Jansson16180952018-12-12 15:49:10229 if (!update)
230 return;
Sebastian Janssonf34116e2019-09-24 15:55:50231 retransmission_rate_limiter_.SetMaxRate(update->target_rate.bps());
Sebastian Jansson16180952018-12-12 15:49:10232 // We won't create control_handler_ until we have an observers.
Sebastian Jansson87609be2018-12-05 16:35:35233 RTC_DCHECK(observer_ != nullptr);
Sebastian Jansson16180952018-12-12 15:49:10234 observer_->OnTargetTransferRate(*update);
Sebastian Janssone6256052018-05-04 12:08:15235}
236
Erik Språng66734372022-03-16 13:20:49237void RtpTransportControllerSend::UpdateCongestedState() {
Markus Handelleb277522023-03-03 15:38:10238 if (auto update = GetCongestedStateUpdate()) {
239 is_congested_ = update.value();
240 pacer_.SetCongested(update.value());
241 }
242}
243
Florent Castelli8037fc62024-08-29 13:00:40244std::optional<bool> RtpTransportControllerSend::GetCongestedStateUpdate()
Markus Handelleb277522023-03-03 15:38:10245 const {
Erik Språng66734372022-03-16 13:20:49246 bool congested = transport_feedback_adapter_.GetOutstandingData() >=
247 congestion_window_size_;
Markus Handelleb277522023-03-03 15:38:10248 if (congested != is_congested_)
249 return congested;
Florent Castelli8037fc62024-08-29 13:00:40250 return std::nullopt;
Erik Språng66734372022-03-16 13:20:49251}
252
nisse76e62b02017-05-31 09:24:52253PacketRouter* RtpTransportControllerSend::packet_router() {
254 return &packet_router_;
255}
256
Sebastian Janssone1795f42019-07-24 09:38:03257NetworkStateEstimateObserver*
258RtpTransportControllerSend::network_state_estimate_observer() {
259 return this;
260}
261
Erik Språngaa59eca2019-07-24 12:52:55262RtpPacketSender* RtpTransportControllerSend::packet_sender() {
Erik Språngf3f3a612022-05-13 13:55:29263 return &pacer_;
nisse76e62b02017-05-31 09:24:52264}
265
Stefan Holmer5c8942a2017-08-22 14:16:44266void RtpTransportControllerSend::SetAllocatedSendBitrateLimits(
Sebastian Jansson93b1ea22019-09-18 16:31:52267 BitrateAllocationLimits limits) {
Per K37879e92023-04-13 06:59:19268 RTC_DCHECK_RUN_ON(&sequence_checker_);
Sebastian Jansson93b1ea22019-09-18 16:31:52269 streams_config_.min_total_allocated_bitrate = limits.min_allocatable_rate;
270 streams_config_.max_padding_rate = limits.max_padding_rate;
271 streams_config_.max_total_allocated_bitrate = limits.max_allocatable_rate;
Sebastian Jansson87609be2018-12-05 16:35:35272 UpdateStreamsConfig();
Stefan Holmer5c8942a2017-08-22 14:16:44273}
Sebastian Jansson4c1ffb82018-02-15 15:51:58274void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) {
Per K37879e92023-04-13 06:59:19275 RTC_DCHECK_RUN_ON(&sequence_checker_);
Sebastian Jansson87609be2018-12-05 16:35:35276 streams_config_.pacing_factor = pacing_factor;
277 UpdateStreamsConfig();
Sebastian Jansson4c1ffb82018-02-15 15:51:58278}
279void RtpTransportControllerSend::SetQueueTimeLimit(int limit_ms) {
Erik Språngf3f3a612022-05-13 13:55:29280 pacer_.SetQueueTimeLimit(TimeDelta::Millis(limit_ms));
Sebastian Jansson4c1ffb82018-02-15 15:51:58281}
Sebastian Janssonf2988552019-10-29 16:18:51282StreamFeedbackProvider*
283RtpTransportControllerSend::GetStreamFeedbackProvider() {
JT Tehea992f82020-01-15 18:24:20284 return &feedback_demuxer_;
Sebastian Janssone4be6da2018-02-15 15:51:41285}
Sebastian Jansson19704ec2018-03-12 14:59:12286
Per K39ac25d2024-02-07 13:16:20287void RtpTransportControllerSend::ReconfigureBandwidthEstimation(
288 const BandwidthEstimationSettings& settings) {
289 RTC_DCHECK_RUN_ON(&sequence_checker_);
290 bwe_settings_ = settings;
291
Per Kcc92b6e2024-05-07 15:35:09292 streams_config_.enable_repeated_initial_probing =
293 bwe_settings_.allow_probe_without_media;
Per Kfb611542024-04-16 11:04:37294 bool allow_probe_without_media = bwe_settings_.allow_probe_without_media &&
295 packet_router_.SupportsRtxPayloadPadding();
Per Kfb611542024-04-16 11:04:37296 pacer_.SetAllowProbeWithoutMediaPacket(allow_probe_without_media);
297
Per K39ac25d2024-02-07 13:16:20298 if (controller_) {
299 // Recreate the controller and handler.
300 control_handler_ = nullptr;
301 controller_ = nullptr;
302 // The BWE controller is created when/if the network is available.
303 MaybeCreateControllers();
304 if (controller_) {
305 BitrateConstraints constraints = bitrate_configurator_.GetConfig();
306 UpdateBitrateConstraints(constraints);
307 UpdateStreamsConfig();
308 UpdateNetworkAvailability();
309 }
310 }
Per K39ac25d2024-02-07 13:16:20311}
312
Sebastian Jansson19704ec2018-03-12 14:59:12313void RtpTransportControllerSend::RegisterTargetTransferRateObserver(
314 TargetTransferRateObserver* observer) {
Per K37879e92023-04-13 06:59:19315 RTC_DCHECK_RUN_ON(&sequence_checker_);
316 RTC_DCHECK(observer_ == nullptr);
317 observer_ = observer;
318 observer_->OnStartRateUpdate(*initial_config_.constraints.starting_rate);
319 MaybeCreateControllers();
Sebastian Janssone4be6da2018-02-15 15:51:41320}
Christoffer Rodbro6404cdd2020-03-26 19:37:21321
322bool RtpTransportControllerSend::IsRelevantRouteChange(
323 const rtc::NetworkRoute& old_route,
324 const rtc::NetworkRoute& new_route) const {
Christoffer Rodbro6404cdd2020-03-26 19:37:21325 bool connected_changed = old_route.connected != new_route.connected;
Per Kd1a8ce52024-05-16 10:33:52326 bool route_ids_changed = false;
327 bool relaying_changed = false;
328
329 if (reset_bwe_on_adapter_id_change_) {
330 route_ids_changed =
331 old_route.local.adapter_id() != new_route.local.adapter_id() ||
332 old_route.remote.adapter_id() != new_route.remote.adapter_id();
Christoffer Rodbro6404cdd2020-03-26 19:37:21333 } else {
Per Kd1a8ce52024-05-16 10:33:52334 route_ids_changed =
335 old_route.local.network_id() != new_route.local.network_id() ||
336 old_route.remote.network_id() != new_route.remote.network_id();
Christoffer Rodbro6404cdd2020-03-26 19:37:21337 }
Per Kd1a8ce52024-05-16 10:33:52338 if (relay_bandwidth_cap_->IsFinite()) {
339 relaying_changed = IsRelayed(old_route) != IsRelayed(new_route);
340 }
341 return connected_changed || route_ids_changed || relaying_changed;
Christoffer Rodbro6404cdd2020-03-26 19:37:21342}
343
Sebastian Janssone4be6da2018-02-15 15:51:41344void RtpTransportControllerSend::OnNetworkRouteChanged(
Ali Tofigh641a1b12022-05-17 09:48:46345 absl::string_view transport_name,
Sebastian Jansson97f61ea2018-02-21 12:01:55346 const rtc::NetworkRoute& network_route) {
Per K37879e92023-04-13 06:59:19347 RTC_DCHECK_RUN_ON(&sequence_checker_);
Sebastian Jansson91bb6672018-02-21 12:02:51348 // Check if the network route is connected.
349 if (!network_route.connected) {
Sebastian Jansson91bb6672018-02-21 12:02:51350 // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and
351 // consider merging these two methods.
352 return;
353 }
354
Florent Castelli8037fc62024-08-29 13:00:40355 std::optional<BitrateConstraints> relay_constraint_update =
Christoffer Rodbro6404cdd2020-03-26 19:37:21356 ApplyOrLiftRelayCap(IsRelayed(network_route));
357
Sebastian Jansson91bb6672018-02-21 12:02:51358 // Check whether the network route has changed on each transport.
Ali Tofighc48f9ef2022-08-17 17:20:04359 auto result = network_routes_.insert(
360 // Explicit conversion of transport_name to std::string here is necessary
361 // to support some platforms that cannot yet deal with implicit
362 // conversion in these types of situations.
363 std::make_pair(std::string(transport_name), network_route));
Sebastian Jansson91bb6672018-02-21 12:02:51364 auto kv = result.first;
365 bool inserted = result.second;
Jonas Oreland5b6a4d82020-03-24 06:36:52366 if (inserted || !(kv->second == network_route)) {
367 RTC_LOG(LS_INFO) << "Network route changed on transport " << transport_name
368 << ": new_route = " << network_route.DebugString();
369 if (!inserted) {
370 RTC_LOG(LS_INFO) << "old_route = " << kv->second.DebugString();
371 }
372 }
373
Sebastian Jansson91bb6672018-02-21 12:02:51374 if (inserted) {
Christoffer Rodbro6404cdd2020-03-26 19:37:21375 if (relay_constraint_update.has_value()) {
376 UpdateBitrateConstraints(*relay_constraint_update);
377 }
Per K37879e92023-04-13 06:59:19378 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
Sebastian Jansson91bb6672018-02-21 12:02:51379 // No need to reset BWE if this is the first time the network connects.
380 return;
381 }
Jonas Oreland5b6a4d82020-03-24 06:36:52382
383 const rtc::NetworkRoute old_route = kv->second;
Jonas Oreland71fda362020-03-20 15:11:56384 kv->second = network_route;
Jonas Oreland71fda362020-03-20 15:11:56385
386 // Check if enough conditions of the new/old route has changed
387 // to trigger resetting of bitrates (and a probe).
Christoffer Rodbrob0ca5192020-03-26 08:22:24388 if (IsRelevantRouteChange(old_route, network_route)) {
Sebastian Jansson91bb6672018-02-21 12:02:51389 BitrateConstraints bitrate_config = bitrate_configurator_.GetConfig();
Jonas Oreland71fda362020-03-20 15:11:56390 RTC_LOG(LS_INFO) << "Reset bitrates to min: "
Sebastian Jansson91bb6672018-02-21 12:02:51391 << bitrate_config.min_bitrate_bps
392 << " bps, start: " << bitrate_config.start_bitrate_bps
393 << " bps, max: " << bitrate_config.max_bitrate_bps
394 << " bps.";
395 RTC_DCHECK_GT(bitrate_config.start_bitrate_bps, 0);
Sebastian Jansson87609be2018-12-05 16:35:35396
Danil Chapovalovee27f382023-12-18 12:09:12397 env_.event_log().Log(std::make_unique<RtcEventRouteChange>(
398 network_route.connected, network_route.packet_overhead));
Sebastian Jansson87609be2018-12-05 16:35:35399 NetworkRouteChange msg;
Danil Chapovalovee27f382023-12-18 12:09:12400 msg.at_time = Timestamp::Millis(env_.clock().TimeInMilliseconds());
401 msg.constraints = ConvertConstraints(bitrate_config, &env_.clock());
Per K37879e92023-04-13 06:59:19402 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
403 if (reset_feedback_on_route_change_) {
404 transport_feedback_adapter_.SetNetworkRoute(network_route);
405 }
406 if (controller_) {
407 PostUpdates(controller_->OnNetworkRouteChange(msg));
408 } else {
409 UpdateInitialConstraints(msg.constraints);
410 }
411 is_congested_ = false;
412 pacer_.SetCongested(false);
Sebastian Jansson91bb6672018-02-21 12:02:51413 }
Sebastian Janssone4be6da2018-02-15 15:51:41414}
415void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
Per K37879e92023-04-13 06:59:19416 RTC_DCHECK_RUN_ON(&sequence_checker_);
Harald Alvestrand977b2652019-12-12 12:40:50417 RTC_LOG(LS_VERBOSE) << "SignalNetworkState "
418 << (network_available ? "Up" : "Down");
Per K37879e92023-04-13 06:59:19419 network_available_ = network_available;
420 if (network_available) {
421 pacer_.Resume();
422 } else {
423 pacer_.Pause();
424 }
425 is_congested_ = false;
426 pacer_.SetCongested(false);
Sebastian Jansson16180952018-12-12 15:49:10427
Per Kef4c71c2023-10-19 08:06:35428 if (!controller_) {
429 MaybeCreateControllers();
430 }
Per K39ac25d2024-02-07 13:16:20431 UpdateNetworkAvailability();
Stefan Holmerdbdb3a02018-07-17 14:03:46432 for (auto& rtp_sender : video_rtp_senders_) {
433 rtp_sender->OnNetworkAvailability(network_available);
434 }
Sebastian Janssone4be6da2018-02-15 15:51:41435}
Danil Chapovalov3e392542023-05-17 11:25:39436NetworkLinkRtcpObserver* RtpTransportControllerSend::GetRtcpObserver() {
Sebastian Jansson87609be2018-12-05 16:35:35437 return this;
Sebastian Janssone4be6da2018-02-15 15:51:41438}
Sebastian Janssone4be6da2018-02-15 15:51:41439int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const {
Erik Språngf3f3a612022-05-13 13:55:29440 return pacer_.OldestPacketWaitTime().ms();
Sebastian Janssone4be6da2018-02-15 15:51:41441}
Florent Castelli8037fc62024-08-29 13:00:40442std::optional<Timestamp> RtpTransportControllerSend::GetFirstPacketTime()
Erik Språng425d6aa2019-07-29 14:38:27443 const {
Erik Språngf3f3a612022-05-13 13:55:29444 return pacer_.FirstSentPacketTime();
Sebastian Janssone4be6da2018-02-15 15:51:41445}
Sebastian Janssone4be6da2018-02-15 15:51:41446void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) {
Per K37879e92023-04-13 06:59:19447 RTC_DCHECK_RUN_ON(&sequence_checker_);
448
449 streams_config_.requests_alr_probing = enable;
450 UpdateStreamsConfig();
Sebastian Janssone4be6da2018-02-15 15:51:41451}
452void RtpTransportControllerSend::OnSentPacket(
453 const rtc::SentPacket& sent_packet) {
Markus Handelle32b6222023-05-08 22:59:46454 // Normally called on the network thread!
455 // TODO(crbug.com/1373439): Clarify other thread contexts calling in,
456 // and simplify task posting logic when the combined network/worker project
Markus Handelleb277522023-03-03 15:38:10457 // launches.
Per K37879e92023-04-13 06:59:19458 if (TaskQueueBase::Current() != task_queue_) {
459 task_queue_->PostTask(SafeTask(safety_.flag(), [this, sent_packet]() {
460 RTC_DCHECK_RUN_ON(&sequence_checker_);
Markus Handelle32b6222023-05-08 22:59:46461 ProcessSentPacket(sent_packet);
Per K37879e92023-04-13 06:59:19462 }));
Markus Handelleb277522023-03-03 15:38:10463 return;
464 }
Per Kjellander828ef912022-10-10 10:53:41465
Per K37879e92023-04-13 06:59:19466 RTC_DCHECK_RUN_ON(&sequence_checker_);
Markus Handelle32b6222023-05-08 22:59:46467 ProcessSentPacket(sent_packet);
Markus Handelleb277522023-03-03 15:38:10468}
469
Markus Handelleb277522023-03-03 15:38:10470void RtpTransportControllerSend::ProcessSentPacket(
Markus Handelle32b6222023-05-08 22:59:46471 const rtc::SentPacket& sent_packet) {
Per K37879e92023-04-13 06:59:19472 RTC_DCHECK_RUN_ON(&sequence_checker_);
Florent Castelli8037fc62024-08-29 13:00:40473 std::optional<SentPacket> packet_msg =
Markus Handelleb277522023-03-03 15:38:10474 transport_feedback_adapter_.ProcessSentPacket(sent_packet);
475 if (!packet_msg)
476 return;
477
478 auto congestion_update = GetCongestedStateUpdate();
479 NetworkControlUpdate control_update;
480 if (controller_)
481 control_update = controller_->OnSentPacket(*packet_msg);
482 if (!congestion_update && !control_update.has_updates())
483 return;
Markus Handelle32b6222023-05-08 22:59:46484 ProcessSentPacketUpdates(std::move(control_update));
Markus Handelleb277522023-03-03 15:38:10485}
486
487// RTC_RUN_ON(task_queue_)
488void RtpTransportControllerSend::ProcessSentPacketUpdates(
489 NetworkControlUpdate updates) {
Per K37879e92023-04-13 06:59:19490 RTC_DCHECK_RUN_ON(&sequence_checker_);
Markus Handelleb277522023-03-03 15:38:10491 // Only update outstanding data if:
492 // 1. Packet feedback is used.
493 // 2. The packet has not yet received an acknowledgement.
494 // 3. It is not a retransmission of an earlier packet.
495 UpdateCongestedState();
496 if (controller_) {
497 PostUpdates(std::move(updates));
498 }
Sebastian Janssone4be6da2018-02-15 15:51:41499}
sprangdb2a9fc2017-08-09 13:42:32500
Björn Tereliusb4d4bbc2023-09-24 20:36:41501void RtpTransportControllerSend::OnReceivedPacket(
502 const ReceivedPacket& packet_msg) {
503 RTC_DCHECK_RUN_ON(&sequence_checker_);
504 if (controller_)
505 PostUpdates(controller_->OnReceivedPacket(packet_msg));
506}
507
Christoffer Rodbrob0ca5192020-03-26 08:22:24508void RtpTransportControllerSend::UpdateBitrateConstraints(
509 const BitrateConstraints& updated) {
Per K37879e92023-04-13 06:59:19510 RTC_DCHECK_RUN_ON(&sequence_checker_);
Danil Chapovalovee27f382023-12-18 12:09:12511 TargetRateConstraints msg = ConvertConstraints(updated, &env_.clock());
Per K37879e92023-04-13 06:59:19512 if (controller_) {
513 PostUpdates(controller_->OnTargetRateConstraints(msg));
514 } else {
515 UpdateInitialConstraints(msg);
516 }
Christoffer Rodbrob0ca5192020-03-26 08:22:24517}
518
Sebastian Jansson97f61ea2018-02-21 12:01:55519void RtpTransportControllerSend::SetSdpBitrateParameters(
520 const BitrateConstraints& constraints) {
Per K37879e92023-04-13 06:59:19521 RTC_DCHECK_RUN_ON(&sequence_checker_);
Florent Castelli8037fc62024-08-29 13:00:40522 std::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 12:01:55523 bitrate_configurator_.UpdateWithSdpParameters(constraints);
524 if (updated.has_value()) {
Christoffer Rodbrob0ca5192020-03-26 08:22:24525 UpdateBitrateConstraints(*updated);
Sebastian Jansson97f61ea2018-02-21 12:01:55526 } else {
527 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 12:07:13528 << "WebRTC.RtpTransportControllerSend.SetSdpBitrateParameters: "
Jonas Olssonb2b20312020-01-14 11:11:31529 "nothing to update";
Sebastian Jansson97f61ea2018-02-21 12:01:55530 }
531}
532
533void RtpTransportControllerSend::SetClientBitratePreferences(
Niels Möller0c4f7be2018-05-07 12:01:37534 const BitrateSettings& preferences) {
Per K37879e92023-04-13 06:59:19535 RTC_DCHECK_RUN_ON(&sequence_checker_);
Florent Castelli8037fc62024-08-29 13:00:40536 std::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 12:01:55537 bitrate_configurator_.UpdateWithClientPreferences(preferences);
538 if (updated.has_value()) {
Christoffer Rodbrob0ca5192020-03-26 08:22:24539 UpdateBitrateConstraints(*updated);
Sebastian Jansson97f61ea2018-02-21 12:01:55540 } else {
541 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 12:07:13542 << "WebRTC.RtpTransportControllerSend.SetClientBitratePreferences: "
Jonas Olssonb2b20312020-01-14 11:11:31543 "nothing to update";
Sebastian Jansson97f61ea2018-02-21 12:01:55544 }
545}
Alex Narestbcf91802018-06-25 14:08:36546
Florent Castelli8037fc62024-08-29 13:00:40547std::optional<BitrateConstraints>
Christoffer Rodbro6404cdd2020-03-26 19:37:21548RtpTransportControllerSend::ApplyOrLiftRelayCap(bool is_relayed) {
549 DataRate cap = is_relayed ? relay_bandwidth_cap_ : DataRate::PlusInfinity();
550 return bitrate_configurator_.UpdateWithRelayCap(cap);
551}
552
Stefan Holmer64be7fa2018-10-04 13:21:55553void RtpTransportControllerSend::OnTransportOverheadChanged(
554 size_t transport_overhead_bytes_per_packet) {
Per K37879e92023-04-13 06:59:19555 RTC_DCHECK_RUN_ON(&sequence_checker_);
Stefan Holmer64be7fa2018-10-04 13:21:55556 if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) {
557 RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes;
558 return;
559 }
560
Erik Språngf3f3a612022-05-13 13:55:29561 pacer_.SetTransportOverhead(
Danil Chapovalovcad3e0e2020-02-17 17:46:07562 DataSize::Bytes(transport_overhead_bytes_per_packet));
Mirko Bonadeie7bc3a32020-01-29 18:45:00563
Stefan Holmer64be7fa2018-10-04 13:21:55564 // TODO(holmer): Call AudioRtpSenders when they have been moved to
565 // RtpTransportControllerSend.
566 for (auto& rtp_video_sender : video_rtp_senders_) {
567 rtp_video_sender->OnTransportOverheadChanged(
568 transport_overhead_bytes_per_packet);
569 }
570}
Sebastian Jansson87609be2018-12-05 16:35:35571
Erik Språngaa59eca2019-07-24 12:52:55572void RtpTransportControllerSend::AccountForAudioPacketsInPacedSender(
573 bool account_for_audio) {
Erik Språngf3f3a612022-05-13 13:55:29574 pacer_.SetAccountForAudioPackets(account_for_audio);
Erik Språngaa59eca2019-07-24 12:52:55575}
576
Sebastian Janssonc3eb9fd2020-01-29 16:42:52577void RtpTransportControllerSend::IncludeOverheadInPacedSender() {
Erik Språngf3f3a612022-05-13 13:55:29578 pacer_.SetIncludeOverhead();
Sebastian Janssonc3eb9fd2020-01-29 16:42:52579}
580
Erik Språng7703f232020-09-14 09:03:13581void RtpTransportControllerSend::EnsureStarted() {
Per K37879e92023-04-13 06:59:19582 RTC_DCHECK_RUN_ON(&sequence_checker_);
Etienne Pierre-doray03bce3f2021-03-29 17:36:15583 if (!pacer_started_) {
584 pacer_started_ = true;
Erik Språngf3f3a612022-05-13 13:55:29585 pacer_.EnsureStarted();
Erik Språng7703f232020-09-14 09:03:13586 }
587}
588
Danil Chapovalov3e392542023-05-17 11:25:39589void RtpTransportControllerSend::OnReceiverEstimatedMaxBitrate(
590 Timestamp receive_time,
591 DataRate bitrate) {
Per K37879e92023-04-13 06:59:19592 RTC_DCHECK_RUN_ON(&sequence_checker_);
Sebastian Jansson87609be2018-12-05 16:35:35593 RemoteBitrateReport msg;
Danil Chapovalov3e392542023-05-17 11:25:39594 msg.receive_time = receive_time;
595 msg.bandwidth = bitrate;
Per K37879e92023-04-13 06:59:19596 if (controller_)
597 PostUpdates(controller_->OnRemoteBitrateReport(msg));
Sebastian Jansson87609be2018-12-05 16:35:35598}
599
Danil Chapovalov3e392542023-05-17 11:25:39600void RtpTransportControllerSend::OnRttUpdate(Timestamp receive_time,
601 TimeDelta rtt) {
Per K37879e92023-04-13 06:59:19602 RTC_DCHECK_RUN_ON(&sequence_checker_);
Per K37879e92023-04-13 06:59:19603 RoundTripTimeUpdate report;
Danil Chapovalov3e392542023-05-17 11:25:39604 report.receive_time = receive_time;
Danil Chapovalov328c5142023-05-19 09:45:46605 report.round_trip_time = rtt.RoundTo(TimeDelta::Millis(1));
Per K37879e92023-04-13 06:59:19606 report.smoothed = false;
607 if (controller_ && !report.round_trip_time.IsZero())
608 PostUpdates(controller_->OnRoundTripTimeUpdate(report));
Sebastian Jansson87609be2018-12-05 16:35:35609}
610
Per K02af8402024-03-27 18:35:55611void RtpTransportControllerSend::NotifyBweOfPacedSentPacket(
612 const RtpPacketToSend& packet,
613 const PacedPacketInfo& pacing_info) {
Per K37879e92023-04-13 06:59:19614 RTC_DCHECK_RUN_ON(&sequence_checker_);
Per K02af8402024-03-27 18:35:55615
616 if (!packet.transport_sequence_number()) {
617 return;
618 }
619 if (!packet.packet_type()) {
620 RTC_DCHECK_NOTREACHED() << "Unknown packet type";
621 return;
622 }
Per K93e17782024-10-18 09:32:44623 if (packet.HasExtension<TransportSequenceNumber>()) {
624 // TODO: bugs.webrtc.org/42225697 - Refactor TransportFeedbackDemuxer to use
625 // TransportPacketsFeedback instead of directly using
626 // rtcp::TransportFeedback. For now, only use it if TransportSeqeunce number
627 // header extension is used.
628 RtpPacketSendInfo packet_info =
629 RtpPacketSendInfo::From(packet, pacing_info);
630 feedback_demuxer_.AddPacket(packet_info);
631 }
Danil Chapovalovee27f382023-12-18 12:09:12632 Timestamp creation_time =
633 Timestamp::Millis(env_.clock().TimeInMilliseconds());
Per K37879e92023-04-13 06:59:19634 transport_feedback_adapter_.AddPacket(
Per K93e17782024-10-18 09:32:44635 packet, pacing_info, transport_overhead_bytes_per_packet_, creation_time);
Sebastian Jansson87609be2018-12-05 16:35:35636}
637
Per Kjellander77686672024-12-19 07:58:06638void RtpTransportControllerSend::
639 EnableCongestionControlFeedbackAccordingToRfc8888() {
640 RTC_DCHECK_RUN_ON(&sequence_checker_);
641 transport_is_ecn_capable_ = true;
642 packet_router_.ConfigureForRfc8888Feedback(transport_is_ecn_capable_);
643}
644
Sebastian Jansson87609be2018-12-05 16:35:35645void RtpTransportControllerSend::OnTransportFeedback(
Danil Chapovalov3e392542023-05-17 11:25:39646 Timestamp receive_time,
Sebastian Jansson87609be2018-12-05 16:35:35647 const rtcp::TransportFeedback& feedback) {
Per K37879e92023-04-13 06:59:19648 RTC_DCHECK_RUN_ON(&sequence_checker_);
Harald Alvestrandfb62f902024-11-19 12:11:47649 ++transport_cc_feedback_count_;
Per K37879e92023-04-13 06:59:19650 feedback_demuxer_.OnTransportFeedback(feedback);
Florent Castelli8037fc62024-08-29 13:00:40651 std::optional<TransportPacketsFeedback> feedback_msg =
Per K37879e92023-04-13 06:59:19652 transport_feedback_adapter_.ProcessTransportFeedback(feedback,
Danil Chapovalov3e392542023-05-17 11:25:39653 receive_time);
Per K37879e92023-04-13 06:59:19654 if (feedback_msg) {
Per Kjellander77686672024-12-19 07:58:06655 HandleTransportPacketsFeedback(*feedback_msg);
Per K37879e92023-04-13 06:59:19656 }
Sebastian Jansson87609be2018-12-05 16:35:35657}
658
Per K1d2f85d2024-10-23 12:11:41659void RtpTransportControllerSend::OnCongestionControlFeedback(
660 Timestamp receive_time,
661 const rtcp::CongestionControlFeedback& feedback) {
662 RTC_DCHECK_RUN_ON(&sequence_checker_);
Harald Alvestrand0c6d3192024-11-13 11:54:41663 ++feedback_count_;
Per K1d2f85d2024-10-23 12:11:41664 // TODO: bugs.webrtc.org/42225697 - update feedback demuxer for RFC 8888.
665 // Suggest feedback_demuxer_.OnTransportFeedback use TransportPacketFeedback
666 // instead. See usage in OnTransportFeedback.
667 std::optional<TransportPacketsFeedback> feedback_msg =
668 transport_feedback_adapter_.ProcessCongestionControlFeedback(
669 feedback, receive_time);
670 if (feedback_msg) {
Per Kjellander77686672024-12-19 07:58:06671 HandleTransportPacketsFeedback(*feedback_msg);
Per K1d2f85d2024-10-23 12:11:41672 }
673}
674
Per Kjellander77686672024-12-19 07:58:06675void RtpTransportControllerSend::HandleTransportPacketsFeedback(
676 const TransportPacketsFeedback& feedback) {
677 if (transport_is_ecn_capable_) {
678 // If transport does not support ECN, packets should not be sent as ECT(1).
679 // TODO: bugs.webrtc.org/42225697 - adapt to ECN feedback and continue to
680 // send packets as ECT(1) if transport is ECN capable.
681 transport_is_ecn_capable_ = false;
682 RTC_LOG(LS_INFO) << " Transport is "
683 << (feedback.transport_supports_ecn ? "" : " not ")
684 << " ECN capable. Stop sending ECT(1).";
685 packet_router_.ConfigureForRfc8888Feedback(transport_is_ecn_capable_);
686 }
687 if (controller_)
688 PostUpdates(controller_->OnTransportPacketsFeedback(feedback));
689
690 // Only update outstanding data if any packet is first time acked.
691 UpdateCongestedState();
692}
693
Sebastian Janssone1795f42019-07-24 09:38:03694void RtpTransportControllerSend::OnRemoteNetworkEstimate(
695 NetworkStateEstimate estimate) {
Per K37879e92023-04-13 06:59:19696 RTC_DCHECK_RUN_ON(&sequence_checker_);
Danil Chapovalovee27f382023-12-18 12:09:12697 estimate.update_time = Timestamp::Millis(env_.clock().TimeInMilliseconds());
Per K37879e92023-04-13 06:59:19698 if (controller_)
699 PostUpdates(controller_->OnNetworkStateEstimate(estimate));
Sebastian Janssone1795f42019-07-24 09:38:03700}
701
Sebastian Jansson87609be2018-12-05 16:35:35702void RtpTransportControllerSend::MaybeCreateControllers() {
703 RTC_DCHECK(!controller_);
704 RTC_DCHECK(!control_handler_);
705
706 if (!network_available_ || !observer_)
707 return;
Mirko Bonadei317a1f02019-09-17 15:06:18708 control_handler_ = std::make_unique<CongestionControlHandler>();
Sebastian Jansson87609be2018-12-05 16:35:35709
710 initial_config_.constraints.at_time =
Danil Chapovalovee27f382023-12-18 12:09:12711 Timestamp::Millis(env_.clock().TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35712 initial_config_.stream_based_config = streams_config_;
713
714 // TODO(srte): Use fallback controller if no feedback is available.
715 if (controller_factory_override_) {
716 RTC_LOG(LS_INFO) << "Creating overridden congestion controller";
717 controller_ = controller_factory_override_->Create(initial_config_);
718 process_interval_ = controller_factory_override_->GetProcessInterval();
719 } else {
720 RTC_LOG(LS_INFO) << "Creating fallback congestion controller";
721 controller_ = controller_factory_fallback_->Create(initial_config_);
722 process_interval_ = controller_factory_fallback_->GetProcessInterval();
723 }
724 UpdateControllerWithTimeInterval();
725 StartProcessPeriodicTasks();
726}
727
Per K39ac25d2024-02-07 13:16:20728void RtpTransportControllerSend::UpdateNetworkAvailability() {
729 if (!controller_) {
730 return;
731 }
732 NetworkAvailability msg;
733 msg.at_time = Timestamp::Millis(env_.clock().TimeInMilliseconds());
734 msg.network_available = network_available_;
735 control_handler_->SetNetworkAvailability(network_available_);
736 PostUpdates(controller_->OnNetworkAvailability(msg));
737 UpdateControlState();
738}
739
Sebastian Jansson87609be2018-12-05 16:35:35740void RtpTransportControllerSend::UpdateInitialConstraints(
741 TargetRateConstraints new_contraints) {
742 if (!new_contraints.starting_rate)
743 new_contraints.starting_rate = initial_config_.constraints.starting_rate;
744 RTC_DCHECK(new_contraints.starting_rate);
745 initial_config_.constraints = new_contraints;
746}
747
748void RtpTransportControllerSend::StartProcessPeriodicTasks() {
Per K37879e92023-04-13 06:59:19749 RTC_DCHECK_RUN_ON(&sequence_checker_);
Sebastian Janssonecb68972019-01-18 09:30:54750 if (!pacer_queue_update_task_.Running()) {
751 pacer_queue_update_task_ = RepeatingTaskHandle::DelayedStart(
Per K37879e92023-04-13 06:59:19752 task_queue_, kPacerQueueUpdateInterval, [this]() {
753 RTC_DCHECK_RUN_ON(&sequence_checker_);
Erik Språngf3f3a612022-05-13 13:55:29754 TimeDelta expected_queue_time = pacer_.ExpectedQueueTime();
Sebastian Jansson16180952018-12-12 15:49:10755 control_handler_->SetPacerQueue(expected_queue_time);
756 UpdateControlState();
Sebastian Janssonecb68972019-01-18 09:30:54757 return kPacerQueueUpdateInterval;
Sebastian Jansson87609be2018-12-05 16:35:35758 });
759 }
Sebastian Janssonecb68972019-01-18 09:30:54760 controller_task_.Stop();
Sebastian Jansson87609be2018-12-05 16:35:35761 if (process_interval_.IsFinite()) {
Sebastian Janssonecb68972019-01-18 09:30:54762 controller_task_ = RepeatingTaskHandle::DelayedStart(
Per K37879e92023-04-13 06:59:19763 task_queue_, process_interval_, [this]() {
764 RTC_DCHECK_RUN_ON(&sequence_checker_);
Sebastian Jansson87609be2018-12-05 16:35:35765 UpdateControllerWithTimeInterval();
Sebastian Janssonecb68972019-01-18 09:30:54766 return process_interval_;
Sebastian Jansson87609be2018-12-05 16:35:35767 });
768 }
769}
770
771void RtpTransportControllerSend::UpdateControllerWithTimeInterval() {
Sebastian Jansson16180952018-12-12 15:49:10772 RTC_DCHECK(controller_);
773 ProcessInterval msg;
Danil Chapovalovee27f382023-12-18 12:09:12774 msg.at_time = Timestamp::Millis(env_.clock().TimeInMilliseconds());
Christoffer Rodbroc610e262019-01-08 09:49:19775 if (add_pacing_to_cwin_)
Erik Språngf3f3a612022-05-13 13:55:29776 msg.pacer_queue = pacer_.QueueSizeData();
Sebastian Jansson16180952018-12-12 15:49:10777 PostUpdates(controller_->OnProcessInterval(msg));
Sebastian Jansson87609be2018-12-05 16:35:35778}
779
780void RtpTransportControllerSend::UpdateStreamsConfig() {
Danil Chapovalovee27f382023-12-18 12:09:12781 streams_config_.at_time =
782 Timestamp::Millis(env_.clock().TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35783 if (controller_)
Sebastian Jansson16180952018-12-12 15:49:10784 PostUpdates(controller_->OnStreamsConfig(streams_config_));
785}
786
787void RtpTransportControllerSend::PostUpdates(NetworkControlUpdate update) {
788 if (update.congestion_window) {
Erik Språng66734372022-03-16 13:20:49789 congestion_window_size_ = *update.congestion_window;
790 UpdateCongestedState();
Sebastian Jansson16180952018-12-12 15:49:10791 }
792 if (update.pacer_config) {
Erik Språngf3f3a612022-05-13 13:55:29793 pacer_.SetPacingRates(update.pacer_config->data_rate(),
794 update.pacer_config->pad_rate());
Sebastian Jansson16180952018-12-12 15:49:10795 }
Per Kjellander88af2032022-05-16 17:58:40796 if (!update.probe_cluster_configs.empty()) {
797 pacer_.CreateProbeClusters(std::move(update.probe_cluster_configs));
Sebastian Jansson16180952018-12-12 15:49:10798 }
799 if (update.target_rate) {
800 control_handler_->SetTargetRate(*update.target_rate);
801 UpdateControlState();
802 }
Sebastian Jansson87609be2018-12-05 16:35:35803}
804
Danil Chapovalov3e392542023-05-17 11:25:39805void RtpTransportControllerSend::OnReport(
806 Timestamp receive_time,
807 rtc::ArrayView<const ReportBlockData> report_blocks) {
Per K37879e92023-04-13 06:59:19808 RTC_DCHECK_RUN_ON(&sequence_checker_);
Sebastian Jansson87609be2018-12-05 16:35:35809 if (report_blocks.empty())
810 return;
811
812 int total_packets_lost_delta = 0;
813 int total_packets_delta = 0;
814
815 // Compute the packet loss from all report blocks.
Danil Chapovalov3e392542023-05-17 11:25:39816 for (const ReportBlockData& report_block : report_blocks) {
Danil Chapovalov121f1e72023-05-15 07:28:02817 auto [it, inserted] =
Danil Chapovalov3e392542023-05-17 11:25:39818 last_report_blocks_.try_emplace(report_block.source_ssrc());
Danil Chapovalov121f1e72023-05-15 07:28:02819 LossReport& last_loss_report = it->second;
820 if (!inserted) {
Danil Chapovalov3e392542023-05-17 11:25:39821 total_packets_delta += report_block.extended_highest_sequence_number() -
Danil Chapovalov121f1e72023-05-15 07:28:02822 last_loss_report.extended_highest_sequence_number;
823 total_packets_lost_delta +=
Danil Chapovalov3e392542023-05-17 11:25:39824 report_block.cumulative_lost() - last_loss_report.cumulative_lost;
Sebastian Jansson87609be2018-12-05 16:35:35825 }
Danil Chapovalov121f1e72023-05-15 07:28:02826 last_loss_report.extended_highest_sequence_number =
Danil Chapovalov3e392542023-05-17 11:25:39827 report_block.extended_highest_sequence_number();
828 last_loss_report.cumulative_lost = report_block.cumulative_lost();
Sebastian Jansson87609be2018-12-05 16:35:35829 }
830 // Can only compute delta if there has been previous blocks to compare to. If
831 // not, total_packets_delta will be unchanged and there's nothing more to do.
832 if (!total_packets_delta)
833 return;
834 int packets_received_delta = total_packets_delta - total_packets_lost_delta;
835 // To detect lost packets, at least one packet has to be received. This check
836 // is needed to avoid bandwith detection update in
837 // VideoSendStreamTest.SuspendBelowMinBitrate
838
839 if (packets_received_delta < 1)
840 return;
Sebastian Jansson87609be2018-12-05 16:35:35841 TransportLossReport msg;
842 msg.packets_lost_delta = total_packets_lost_delta;
843 msg.packets_received_delta = packets_received_delta;
Danil Chapovalov3e392542023-05-17 11:25:39844 msg.receive_time = receive_time;
Sebastian Jansson87609be2018-12-05 16:35:35845 msg.start_time = last_report_block_time_;
Danil Chapovalov3e392542023-05-17 11:25:39846 msg.end_time = receive_time;
Sebastian Jansson87609be2018-12-05 16:35:35847 if (controller_)
Sebastian Jansson16180952018-12-12 15:49:10848 PostUpdates(controller_->OnTransportLossReport(msg));
Danil Chapovalov3e392542023-05-17 11:25:39849 last_report_block_time_ = receive_time;
Sebastian Jansson87609be2018-12-05 16:35:35850}
851
nissecae45d02017-04-24 12:53:20852} // namespace webrtc