blob: 1225e5846296ccaf11b8c5c042da682cfb87cbd9 [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"
Ali Tofigh641a1b12022-05-17 09:48:4617#include "absl/strings/string_view.h"
Yves Gerey3e707812018-11-28 15:47:4918#include "absl/types/optional.h"
Per Kjellander828ef912022-10-10 10:53:4119#include "api/task_queue/pending_task_safety_flag.h"
Sebastian Jansson87609be2018-12-05 16:35:3520#include "api/transport/goog_cc_factory.h"
Yves Gerey3e707812018-11-28 15:47:4921#include "api/transport/network_types.h"
22#include "api/units/data_rate.h"
23#include "api/units/time_delta.h"
24#include "api/units/timestamp.h"
Yves Gerey3e707812018-11-28 15:47:4925#include "call/rtp_video_sender.h"
Sebastian Jansson0a5ed892019-09-18 13:37:3126#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
Sebastian Jansson166b45d2019-05-13 09:57:4227#include "logging/rtc_event_log/events/rtc_event_route_change.h"
Sebastian Jansson658f1812020-01-16 09:59:2828#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
Yves Gerey3e707812018-11-28 15:47:4929#include "rtc_base/checks.h"
Sebastian Jansson97f61ea2018-02-21 12:01:5530#include "rtc_base/logging.h"
Stefan Holmerdbdb3a02018-07-17 14:03:4631#include "rtc_base/rate_limiter.h"
nissecae45d02017-04-24 12:53:2032
33namespace webrtc {
Sebastian Jansson19bea512018-03-13 18:07:4634namespace {
Stefan Holmerdbdb3a02018-07-17 14:03:4635static const int64_t kRetransmitWindowSizeMs = 500;
Stefan Holmer64be7fa2018-10-04 13:21:5536static const size_t kMaxOverheadBytes = 500;
Sebastian Jansson19bea512018-03-13 18:07:4637
Danil Chapovalov0c626af2020-02-10 10:16:0038constexpr TimeDelta kPacerQueueUpdateInterval = TimeDelta::Millis(25);
Sebastian Jansson87609be2018-12-05 16:35:3539
40TargetRateConstraints ConvertConstraints(int min_bitrate_bps,
41 int max_bitrate_bps,
42 int start_bitrate_bps,
Sebastian Janssonaa01f272019-01-30 10:28:5943 Clock* clock) {
Sebastian Jansson87609be2018-12-05 16:35:3544 TargetRateConstraints msg;
Danil Chapovalov0c626af2020-02-10 10:16:0045 msg.at_time = Timestamp::Millis(clock->TimeInMilliseconds());
Danil Chapovalovcad3e0e2020-02-17 17:46:0746 msg.min_data_rate = min_bitrate_bps >= 0
47 ? DataRate::BitsPerSec(min_bitrate_bps)
48 : DataRate::Zero();
49 msg.max_data_rate = max_bitrate_bps > 0
50 ? DataRate::BitsPerSec(max_bitrate_bps)
51 : DataRate::Infinity();
Sebastian Jansson87609be2018-12-05 16:35:3552 if (start_bitrate_bps > 0)
Danil Chapovalovcad3e0e2020-02-17 17:46:0753 msg.starting_rate = DataRate::BitsPerSec(start_bitrate_bps);
Sebastian Jansson87609be2018-12-05 16:35:3554 return msg;
55}
56
57TargetRateConstraints ConvertConstraints(const BitrateConstraints& contraints,
Sebastian Janssonaa01f272019-01-30 10:28:5958 Clock* clock) {
Sebastian Jansson87609be2018-12-05 16:35:3559 return ConvertConstraints(contraints.min_bitrate_bps,
60 contraints.max_bitrate_bps,
61 contraints.start_bitrate_bps, clock);
62}
Erik Språng662678d2019-11-15 16:18:5263
Jonas Orelande62c2f22022-03-29 09:04:4864bool IsEnabled(const FieldTrialsView& trials, absl::string_view key) {
Erik Språnge486a7b2022-03-15 14:13:2565 return absl::StartsWith(trials.Lookup(key), "Enabled");
Erik Språng662678d2019-11-15 16:18:5266}
67
Christoffer Rodbro6404cdd2020-03-26 19:37:2168bool IsRelayed(const rtc::NetworkRoute& route) {
69 return route.local.uses_turn() || route.remote.uses_turn();
Christoffer Rodbrob0ca5192020-03-26 08:22:2470}
Sebastian Jansson19bea512018-03-13 18:07:4671} // namespace
nissecae45d02017-04-24 12:53:2072
73RtpTransportControllerSend::RtpTransportControllerSend(
74 Clock* clock,
Henrik Boströmda4c1022022-11-15 14:45:4175 const RtpTransportConfig& config)
Sebastian Jansson19704ec2018-03-12 14:59:1276 : clock_(clock),
Henrik Boströmda4c1022022-11-15 14:45:4177 event_log_(config.event_log),
78 task_queue_factory_(config.task_queue_factory),
79 bitrate_configurator_(config.bitrate_config),
Etienne Pierre-doray03bce3f2021-03-29 17:36:1580 pacer_started_(false),
Erik Språngf3f3a612022-05-13 13:55:2981 pacer_(clock,
82 &packet_router_,
Henrik Boströmda4c1022022-11-15 14:45:4183 *config.trials,
Erik Språng4f642c12023-02-14 15:50:0084 TimeDelta::Millis(5),
85 3,
Henrik Boströmda4c1022022-11-15 14:45:4186 config.pacer_burst_interval),
Sebastian Jansson317a5222018-03-16 14:36:3787 observer_(nullptr),
Henrik Boströmda4c1022022-11-15 14:45:4188 controller_factory_override_(config.network_controller_factory),
Sebastian Jansson87609be2018-12-05 16:35:3589 controller_factory_fallback_(
Henrik Boströmda4c1022022-11-15 14:45:4190 std::make_unique<GoogCcNetworkControllerFactory>(
91 config.network_state_predictor_factory)),
Sebastian Jansson87609be2018-12-05 16:35:3592 process_interval_(controller_factory_fallback_->GetProcessInterval()),
Danil Chapovalov0c626af2020-02-10 10:16:0093 last_report_block_time_(Timestamp::Millis(clock_->TimeInMilliseconds())),
Sebastian Jansson87609be2018-12-05 16:35:3594 reset_feedback_on_route_change_(
Henrik Boströmda4c1022022-11-15 14:45:4195 !IsEnabled(*config.trials, "WebRTC-Bwe-NoFeedbackReset")),
Christoffer Rodbroc610e262019-01-08 09:49:1996 add_pacing_to_cwin_(
Henrik Boströmda4c1022022-11-15 14:45:4197 IsEnabled(*config.trials,
98 "WebRTC-AddPacingToCongestionWindowPushback")),
Christoffer Rodbro6404cdd2020-03-26 19:37:2199 relay_bandwidth_cap_("relay_cap", DataRate::PlusInfinity()),
Sebastian Jansson87609be2018-12-05 16:35:35100 transport_overhead_bytes_per_packet_(0),
101 network_available_(false),
Erik Språng66734372022-03-16 13:20:49102 congestion_window_size_(DataSize::PlusInfinity()),
103 is_congested_(false),
Stefan Holmerdbdb3a02018-07-17 14:03:46104 retransmission_rate_limiter_(clock, kRetransmitWindowSizeMs),
Henrik Boströmda4c1022022-11-15 14:45:41105 task_queue_(*config.trials,
106 "rtp_send_controller",
107 config.task_queue_factory),
108 field_trials_(*config.trials) {
Christoffer Rodbro6404cdd2020-03-26 19:37:21109 ParseFieldTrial({&relay_bandwidth_cap_},
Henrik Boströmda4c1022022-11-15 14:45:41110 config.trials->Lookup("WebRTC-Bwe-NetworkRouteConstraints"));
111 initial_config_.constraints =
112 ConvertConstraints(config.bitrate_config, clock_);
113 initial_config_.event_log = config.event_log;
114 initial_config_.key_value_config = config.trials;
115 RTC_DCHECK(config.bitrate_config.start_bitrate_bps > 0);
Sebastian Jansson87609be2018-12-05 16:35:35116
Henrik Boströmda4c1022022-11-15 14:45:41117 pacer_.SetPacingRates(
118 DataRate::BitsPerSec(config.bitrate_config.start_bitrate_bps),
119 DataRate::Zero());
Sebastian Jansson97f61ea2018-02-21 12:01:55120}
Sebastian Janssonc33c0fc2018-02-22 10:10:18121
122RtpTransportControllerSend::~RtpTransportControllerSend() {
Per Kjellander828ef912022-10-10 10:53:41123 RTC_DCHECK_RUN_ON(&main_thread_);
Tommi1050fbc2021-06-03 15:58:28124 RTC_DCHECK(video_rtp_senders_.empty());
Per Kjellander828ef912022-10-10 10:53:41125 if (task_queue_.IsCurrent()) {
126 // If these repeated tasks run on a task queue owned by
127 // `task_queue_`, they are stopped when the task queue is deleted.
128 // Otherwise, stop them here.
129 pacer_queue_update_task_.Stop();
130 controller_task_.Stop();
131 }
Sebastian Janssonc33c0fc2018-02-22 10:10:18132}
nissecae45d02017-04-24 12:53:20133
Stefan Holmer9416ef82018-07-19 08:34:38134RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender(
Tommi86952822021-11-29 09:26:40135 const std::map<uint32_t, RtpState>& suspended_ssrcs,
Stefan Holmerdbdb3a02018-07-17 14:03:46136 const std::map<uint32_t, RtpPayloadState>& states,
137 const RtpConfig& rtp_config,
Jiawei Ou55718122018-11-09 21:17:39138 int rtcp_report_interval_ms,
Stefan Holmerdbdb3a02018-07-17 14:03:46139 Transport* send_transport,
140 const RtpSenderObservers& observers,
Stefan Holmer64be7fa2018-10-04 13:21:55141 RtcEventLog* event_log,
Benjamin Wright192eeec2018-10-18 00:27:25142 std::unique_ptr<FecController> fec_controller,
Marina Cioceae77912b2020-02-27 15:16:55143 const RtpSenderFrameEncryptionConfig& frame_encryption_config,
144 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {
Tommi1050fbc2021-06-03 15:58:28145 RTC_DCHECK_RUN_ON(&main_thread_);
Mirko Bonadei317a1f02019-09-17 15:06:18146 video_rtp_senders_.push_back(std::make_unique<RtpVideoSender>(
Sebastian Jansson572c60f2019-03-04 17:30:41147 clock_, suspended_ssrcs, states, rtp_config, rtcp_report_interval_ms,
Oleh Prypine8964902019-03-29 15:33:01148 send_transport, observers,
Stefan Holmerdbdb3a02018-07-17 14:03:46149 // TODO(holmer): Remove this circular dependency by injecting
150 // the parts of RtpTransportControllerSendInterface that are really used.
Benjamin Wright192eeec2018-10-18 00:27:25151 this, event_log, &retransmission_rate_limiter_, std::move(fec_controller),
152 frame_encryption_config.frame_encryptor,
Jonas Orelandc7f691a2022-03-09 14:12:07153 frame_encryption_config.crypto_options, std::move(frame_transformer),
Evan Shrubsole9b643d42022-10-07 14:22:44154 field_trials_, task_queue_factory_));
Stefan Holmerdbdb3a02018-07-17 14:03:46155 return video_rtp_senders_.back().get();
156}
157
Stefan Holmer9416ef82018-07-19 08:34:38158void RtpTransportControllerSend::DestroyRtpVideoSender(
159 RtpVideoSenderInterface* rtp_video_sender) {
Tommi1050fbc2021-06-03 15:58:28160 RTC_DCHECK_RUN_ON(&main_thread_);
Stefan Holmer9416ef82018-07-19 08:34:38161 std::vector<std::unique_ptr<RtpVideoSenderInterface>>::iterator it =
Stefan Holmer5ed25af2018-07-18 13:17:14162 video_rtp_senders_.end();
163 for (it = video_rtp_senders_.begin(); it != video_rtp_senders_.end(); ++it) {
164 if (it->get() == rtp_video_sender) {
165 break;
166 }
167 }
168 RTC_DCHECK(it != video_rtp_senders_.end());
169 video_rtp_senders_.erase(it);
170}
171
Sebastian Jansson16180952018-12-12 15:49:10172void RtpTransportControllerSend::UpdateControlState() {
173 absl::optional<TargetTransferRate> update = control_handler_->GetUpdate();
174 if (!update)
175 return;
Sebastian Janssonf34116e2019-09-24 15:55:50176 retransmission_rate_limiter_.SetMaxRate(update->target_rate.bps());
Sebastian Jansson16180952018-12-12 15:49:10177 // We won't create control_handler_ until we have an observers.
Sebastian Jansson87609be2018-12-05 16:35:35178 RTC_DCHECK(observer_ != nullptr);
Sebastian Jansson16180952018-12-12 15:49:10179 observer_->OnTargetTransferRate(*update);
Sebastian Janssone6256052018-05-04 12:08:15180}
181
Erik Språng66734372022-03-16 13:20:49182void RtpTransportControllerSend::UpdateCongestedState() {
Markus Handelleb277522023-03-03 15:38:10183 if (auto update = GetCongestedStateUpdate()) {
184 is_congested_ = update.value();
185 pacer_.SetCongested(update.value());
186 }
187}
188
189absl::optional<bool> RtpTransportControllerSend::GetCongestedStateUpdate()
190 const {
Erik Språng66734372022-03-16 13:20:49191 bool congested = transport_feedback_adapter_.GetOutstandingData() >=
192 congestion_window_size_;
Markus Handelleb277522023-03-03 15:38:10193 if (congested != is_congested_)
194 return congested;
195 return absl::nullopt;
Erik Språng66734372022-03-16 13:20:49196}
197
Per Kjellander828ef912022-10-10 10:53:41198MaybeWorkerThread* RtpTransportControllerSend::GetWorkerQueue() {
Sebastian Janssone6256052018-05-04 12:08:15199 return &task_queue_;
Sebastian Jansson19704ec2018-03-12 14:59:12200}
201
nisse76e62b02017-05-31 09:24:52202PacketRouter* RtpTransportControllerSend::packet_router() {
203 return &packet_router_;
204}
205
Sebastian Janssone1795f42019-07-24 09:38:03206NetworkStateEstimateObserver*
207RtpTransportControllerSend::network_state_estimate_observer() {
208 return this;
209}
210
nisse76e62b02017-05-31 09:24:52211TransportFeedbackObserver*
212RtpTransportControllerSend::transport_feedback_observer() {
Sebastian Jansson87609be2018-12-05 16:35:35213 return this;
nisse76e62b02017-05-31 09:24:52214}
215
Erik Språngaa59eca2019-07-24 12:52:55216RtpPacketSender* RtpTransportControllerSend::packet_sender() {
Erik Språngf3f3a612022-05-13 13:55:29217 return &pacer_;
nisse76e62b02017-05-31 09:24:52218}
219
Stefan Holmer5c8942a2017-08-22 14:16:44220void RtpTransportControllerSend::SetAllocatedSendBitrateLimits(
Sebastian Jansson93b1ea22019-09-18 16:31:52221 BitrateAllocationLimits limits) {
Sebastian Jansson87609be2018-12-05 16:35:35222 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson93b1ea22019-09-18 16:31:52223 streams_config_.min_total_allocated_bitrate = limits.min_allocatable_rate;
224 streams_config_.max_padding_rate = limits.max_padding_rate;
225 streams_config_.max_total_allocated_bitrate = limits.max_allocatable_rate;
Sebastian Jansson87609be2018-12-05 16:35:35226 UpdateStreamsConfig();
Stefan Holmer5c8942a2017-08-22 14:16:44227}
Sebastian Jansson4c1ffb82018-02-15 15:51:58228void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) {
Sebastian Jansson87609be2018-12-05 16:35:35229 RTC_DCHECK_RUN_ON(&task_queue_);
230 streams_config_.pacing_factor = pacing_factor;
231 UpdateStreamsConfig();
Sebastian Jansson4c1ffb82018-02-15 15:51:58232}
233void RtpTransportControllerSend::SetQueueTimeLimit(int limit_ms) {
Erik Språngf3f3a612022-05-13 13:55:29234 pacer_.SetQueueTimeLimit(TimeDelta::Millis(limit_ms));
Sebastian Jansson4c1ffb82018-02-15 15:51:58235}
Sebastian Janssonf2988552019-10-29 16:18:51236StreamFeedbackProvider*
237RtpTransportControllerSend::GetStreamFeedbackProvider() {
JT Tehea992f82020-01-15 18:24:20238 return &feedback_demuxer_;
Sebastian Janssone4be6da2018-02-15 15:51:41239}
Sebastian Jansson19704ec2018-03-12 14:59:12240
241void RtpTransportControllerSend::RegisterTargetTransferRateObserver(
242 TargetTransferRateObserver* observer) {
Per Kjellander828ef912022-10-10 10:53:41243 task_queue_.RunOrPost([this, observer] {
Sebastian Jansson87609be2018-12-05 16:35:35244 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson19704ec2018-03-12 14:59:12245 RTC_DCHECK(observer_ == nullptr);
246 observer_ = observer;
Sebastian Jansson2701bc92018-12-11 14:02:47247 observer_->OnStartRateUpdate(*initial_config_.constraints.starting_rate);
Sebastian Jansson87609be2018-12-05 16:35:35248 MaybeCreateControllers();
249 });
Sebastian Janssone4be6da2018-02-15 15:51:41250}
Christoffer Rodbro6404cdd2020-03-26 19:37:21251
252bool RtpTransportControllerSend::IsRelevantRouteChange(
253 const rtc::NetworkRoute& old_route,
254 const rtc::NetworkRoute& new_route) const {
255 // TODO(bugs.webrtc.org/11438): Experiment with using more information/
256 // other conditions.
257 bool connected_changed = old_route.connected != new_route.connected;
258 bool route_ids_changed =
259 old_route.local.network_id() != new_route.local.network_id() ||
260 old_route.remote.network_id() != new_route.remote.network_id();
261 if (relay_bandwidth_cap_->IsFinite()) {
262 bool relaying_changed = IsRelayed(old_route) != IsRelayed(new_route);
263 return connected_changed || route_ids_changed || relaying_changed;
264 } else {
265 return connected_changed || route_ids_changed;
266 }
267}
268
Sebastian Janssone4be6da2018-02-15 15:51:41269void RtpTransportControllerSend::OnNetworkRouteChanged(
Ali Tofigh641a1b12022-05-17 09:48:46270 absl::string_view transport_name,
Sebastian Jansson97f61ea2018-02-21 12:01:55271 const rtc::NetworkRoute& network_route) {
Sebastian Jansson91bb6672018-02-21 12:02:51272 // Check if the network route is connected.
Jonas Oreland71fda362020-03-20 15:11:56273
Sebastian Jansson91bb6672018-02-21 12:02:51274 if (!network_route.connected) {
Sebastian Jansson91bb6672018-02-21 12:02:51275 // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and
276 // consider merging these two methods.
277 return;
278 }
279
Christoffer Rodbro6404cdd2020-03-26 19:37:21280 absl::optional<BitrateConstraints> relay_constraint_update =
281 ApplyOrLiftRelayCap(IsRelayed(network_route));
282
Sebastian Jansson91bb6672018-02-21 12:02:51283 // Check whether the network route has changed on each transport.
Ali Tofighc48f9ef2022-08-17 17:20:04284 auto result = network_routes_.insert(
285 // Explicit conversion of transport_name to std::string here is necessary
286 // to support some platforms that cannot yet deal with implicit
287 // conversion in these types of situations.
288 std::make_pair(std::string(transport_name), network_route));
Sebastian Jansson91bb6672018-02-21 12:02:51289 auto kv = result.first;
290 bool inserted = result.second;
Jonas Oreland5b6a4d82020-03-24 06:36:52291 if (inserted || !(kv->second == network_route)) {
292 RTC_LOG(LS_INFO) << "Network route changed on transport " << transport_name
293 << ": new_route = " << network_route.DebugString();
294 if (!inserted) {
295 RTC_LOG(LS_INFO) << "old_route = " << kv->second.DebugString();
296 }
297 }
298
Sebastian Jansson91bb6672018-02-21 12:02:51299 if (inserted) {
Christoffer Rodbro6404cdd2020-03-26 19:37:21300 if (relay_constraint_update.has_value()) {
301 UpdateBitrateConstraints(*relay_constraint_update);
302 }
Per Kjellander828ef912022-10-10 10:53:41303 task_queue_.RunOrPost([this, network_route] {
Jakob Ivarssonb4cdd622020-02-13 13:01:26304 RTC_DCHECK_RUN_ON(&task_queue_);
305 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
306 });
Sebastian Jansson91bb6672018-02-21 12:02:51307 // No need to reset BWE if this is the first time the network connects.
308 return;
309 }
Jonas Oreland5b6a4d82020-03-24 06:36:52310
311 const rtc::NetworkRoute old_route = kv->second;
Jonas Oreland71fda362020-03-20 15:11:56312 kv->second = network_route;
Jonas Oreland71fda362020-03-20 15:11:56313
314 // Check if enough conditions of the new/old route has changed
315 // to trigger resetting of bitrates (and a probe).
Christoffer Rodbrob0ca5192020-03-26 08:22:24316 if (IsRelevantRouteChange(old_route, network_route)) {
Sebastian Jansson91bb6672018-02-21 12:02:51317 BitrateConstraints bitrate_config = bitrate_configurator_.GetConfig();
Jonas Oreland71fda362020-03-20 15:11:56318 RTC_LOG(LS_INFO) << "Reset bitrates to min: "
Sebastian Jansson91bb6672018-02-21 12:02:51319 << bitrate_config.min_bitrate_bps
320 << " bps, start: " << bitrate_config.start_bitrate_bps
321 << " bps, max: " << bitrate_config.max_bitrate_bps
322 << " bps.";
323 RTC_DCHECK_GT(bitrate_config.start_bitrate_bps, 0);
Sebastian Jansson87609be2018-12-05 16:35:35324
Sebastian Jansson166b45d2019-05-13 09:57:42325 if (event_log_) {
Mirko Bonadei317a1f02019-09-17 15:06:18326 event_log_->Log(std::make_unique<RtcEventRouteChange>(
Sebastian Jansson166b45d2019-05-13 09:57:42327 network_route.connected, network_route.packet_overhead));
328 }
Sebastian Jansson87609be2018-12-05 16:35:35329 NetworkRouteChange msg;
Danil Chapovalov0c626af2020-02-10 10:16:00330 msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35331 msg.constraints = ConvertConstraints(bitrate_config, clock_);
Per Kjellander828ef912022-10-10 10:53:41332 task_queue_.RunOrPost([this, msg, network_route] {
Sebastian Jansson87609be2018-12-05 16:35:35333 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson658f1812020-01-16 09:59:28334 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
335 if (reset_feedback_on_route_change_) {
Christoffer Rodbrob0ca5192020-03-26 08:22:24336 transport_feedback_adapter_.SetNetworkRoute(network_route);
Sebastian Jansson658f1812020-01-16 09:59:28337 }
Sebastian Jansson87609be2018-12-05 16:35:35338 if (controller_) {
Sebastian Jansson16180952018-12-12 15:49:10339 PostUpdates(controller_->OnNetworkRouteChange(msg));
Sebastian Jansson87609be2018-12-05 16:35:35340 } else {
341 UpdateInitialConstraints(msg.constraints);
342 }
Erik Språng66734372022-03-16 13:20:49343 is_congested_ = false;
Erik Språngf3f3a612022-05-13 13:55:29344 pacer_.SetCongested(false);
Sebastian Jansson87609be2018-12-05 16:35:35345 });
Sebastian Jansson91bb6672018-02-21 12:02:51346 }
Sebastian Janssone4be6da2018-02-15 15:51:41347}
348void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
Tommi1050fbc2021-06-03 15:58:28349 RTC_DCHECK_RUN_ON(&main_thread_);
Harald Alvestrand977b2652019-12-12 12:40:50350 RTC_LOG(LS_VERBOSE) << "SignalNetworkState "
351 << (network_available ? "Up" : "Down");
Sebastian Jansson87609be2018-12-05 16:35:35352 NetworkAvailability msg;
Danil Chapovalov0c626af2020-02-10 10:16:00353 msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35354 msg.network_available = network_available;
Per Kjellander828ef912022-10-10 10:53:41355 task_queue_.RunOrPost([this, msg]() {
Sebastian Jansson87609be2018-12-05 16:35:35356 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson16180952018-12-12 15:49:10357 if (network_available_ == msg.network_available)
358 return;
Sebastian Jansson87609be2018-12-05 16:35:35359 network_available_ = msg.network_available;
Sebastian Jansson16180952018-12-12 15:49:10360 if (network_available_) {
Erik Språngf3f3a612022-05-13 13:55:29361 pacer_.Resume();
Sebastian Jansson16180952018-12-12 15:49:10362 } else {
Erik Språngf3f3a612022-05-13 13:55:29363 pacer_.Pause();
Sebastian Jansson16180952018-12-12 15:49:10364 }
Erik Språng66734372022-03-16 13:20:49365 is_congested_ = false;
Erik Språngf3f3a612022-05-13 13:55:29366 pacer_.SetCongested(false);
Sebastian Jansson16180952018-12-12 15:49:10367
Sebastian Jansson87609be2018-12-05 16:35:35368 if (controller_) {
Sebastian Jansson16180952018-12-12 15:49:10369 control_handler_->SetNetworkAvailability(network_available_);
370 PostUpdates(controller_->OnNetworkAvailability(msg));
371 UpdateControlState();
Sebastian Jansson87609be2018-12-05 16:35:35372 } else {
373 MaybeCreateControllers();
374 }
375 });
376
Stefan Holmerdbdb3a02018-07-17 14:03:46377 for (auto& rtp_sender : video_rtp_senders_) {
378 rtp_sender->OnNetworkAvailability(network_available);
379 }
Sebastian Janssone4be6da2018-02-15 15:51:41380}
Sebastian Janssone4be6da2018-02-15 15:51:41381RtcpBandwidthObserver* RtpTransportControllerSend::GetBandwidthObserver() {
Sebastian Jansson87609be2018-12-05 16:35:35382 return this;
Sebastian Janssone4be6da2018-02-15 15:51:41383}
Sebastian Janssone4be6da2018-02-15 15:51:41384int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const {
Erik Språngf3f3a612022-05-13 13:55:29385 return pacer_.OldestPacketWaitTime().ms();
Sebastian Janssone4be6da2018-02-15 15:51:41386}
Erik Språng425d6aa2019-07-29 14:38:27387absl::optional<Timestamp> RtpTransportControllerSend::GetFirstPacketTime()
388 const {
Erik Språngf3f3a612022-05-13 13:55:29389 return pacer_.FirstSentPacketTime();
Sebastian Janssone4be6da2018-02-15 15:51:41390}
Sebastian Janssone4be6da2018-02-15 15:51:41391void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) {
Per Kjellander828ef912022-10-10 10:53:41392 task_queue_.RunOrPost([this, enable]() {
Sebastian Jansson87609be2018-12-05 16:35:35393 RTC_DCHECK_RUN_ON(&task_queue_);
394 streams_config_.requests_alr_probing = enable;
395 UpdateStreamsConfig();
396 });
Sebastian Janssone4be6da2018-02-15 15:51:41397}
398void RtpTransportControllerSend::OnSentPacket(
399 const rtc::SentPacket& sent_packet) {
Per Kjellander828ef912022-10-10 10:53:41400 // Normally called on the network thread !
Markus Handelleb277522023-03-03 15:38:10401 // TODO(bugs.webrtc.org/137439): Clarify other thread contexts calling in, and
402 // simplify task posting logic when the combined network/worker project
403 // launches.
404 if (TaskQueueBase::Current() != task_queue_.TaskQueueForPost()) {
405 // We can't use SafeTask here if we are using an owned task queue, because
406 // the safety flag will be destroyed when RtpTransportControllerSend is
407 // destroyed on the worker thread. But we must use SafeTask if we are using
408 // the worker thread, since the worker thread outlives
409 // RtpTransportControllerSend.
410 task_queue_.TaskQueueForPost()->PostTask(
411 task_queue_.MaybeSafeTask(safety_.flag(), [this, sent_packet]() {
412 RTC_DCHECK_RUN_ON(&task_queue_);
413 ProcessSentPacket(sent_packet, /*posted_to_worker=*/true);
414 }));
415 return;
416 }
Per Kjellander828ef912022-10-10 10:53:41417
Markus Handelleb277522023-03-03 15:38:10418 RTC_DCHECK_RUN_ON(&task_queue_);
419 ProcessSentPacket(sent_packet, /*posted_to_worker=*/false);
420}
421
422// RTC_RUN_ON(task_queue_)
423void RtpTransportControllerSend::ProcessSentPacket(
424 const rtc::SentPacket& sent_packet,
425 bool posted_to_worker) {
426 absl::optional<SentPacket> packet_msg =
427 transport_feedback_adapter_.ProcessSentPacket(sent_packet);
428 if (!packet_msg)
429 return;
430
431 auto congestion_update = GetCongestedStateUpdate();
432 NetworkControlUpdate control_update;
433 if (controller_)
434 control_update = controller_->OnSentPacket(*packet_msg);
435 if (!congestion_update && !control_update.has_updates())
436 return;
437 if (posted_to_worker) {
438 ProcessSentPacketUpdates(std::move(control_update));
439 } else {
440 // TODO(bugs.webrtc.org/137439): Aim to remove downstream locks to permit
441 // removing this PostTask.
442 // At least in test situations (and possibly in production environments), we
443 // may get here synchronously with locks taken in PacketRouter::SendPacket.
444 // Because the pacer may at times synchronously re-enter
445 // PacketRouter::SendPacket, we need to break the chain here and PostTask to
446 // get out of the lock. In testing, having updates to process happens pretty
447 // rarely so we do not usually get here.
448 task_queue_.TaskQueueForPost()->PostTask(task_queue_.MaybeSafeTask(
449 safety_.flag(),
450 [this, control_update = std::move(control_update)]() mutable {
451 RTC_DCHECK_RUN_ON(&task_queue_);
452 ProcessSentPacketUpdates(std::move(control_update));
453 }));
454 }
455}
456
457// RTC_RUN_ON(task_queue_)
458void RtpTransportControllerSend::ProcessSentPacketUpdates(
459 NetworkControlUpdate updates) {
460 // Only update outstanding data if:
461 // 1. Packet feedback is used.
462 // 2. The packet has not yet received an acknowledgement.
463 // 3. It is not a retransmission of an earlier packet.
464 UpdateCongestedState();
465 if (controller_) {
466 PostUpdates(std::move(updates));
467 }
Sebastian Janssone4be6da2018-02-15 15:51:41468}
sprangdb2a9fc2017-08-09 13:42:32469
Ying Wang8b279102019-05-27 15:19:08470void RtpTransportControllerSend::OnReceivedPacket(
Sebastian Jansson607a6f12019-06-13 15:48:53471 const ReceivedPacket& packet_msg) {
Per Kjellander828ef912022-10-10 10:53:41472 task_queue_.RunOrPost([this, packet_msg]() {
Ying Wang8b279102019-05-27 15:19:08473 RTC_DCHECK_RUN_ON(&task_queue_);
474 if (controller_)
475 PostUpdates(controller_->OnReceivedPacket(packet_msg));
476 });
477}
478
Christoffer Rodbrob0ca5192020-03-26 08:22:24479void RtpTransportControllerSend::UpdateBitrateConstraints(
480 const BitrateConstraints& updated) {
481 TargetRateConstraints msg = ConvertConstraints(updated, clock_);
Per Kjellander828ef912022-10-10 10:53:41482 task_queue_.RunOrPost([this, msg]() {
Christoffer Rodbrob0ca5192020-03-26 08:22:24483 RTC_DCHECK_RUN_ON(&task_queue_);
484 if (controller_) {
485 PostUpdates(controller_->OnTargetRateConstraints(msg));
486 } else {
487 UpdateInitialConstraints(msg);
488 }
489 });
490}
491
Sebastian Jansson97f61ea2018-02-21 12:01:55492void RtpTransportControllerSend::SetSdpBitrateParameters(
493 const BitrateConstraints& constraints) {
Danil Chapovalovb9b146c2018-06-15 10:28:07494 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 12:01:55495 bitrate_configurator_.UpdateWithSdpParameters(constraints);
496 if (updated.has_value()) {
Christoffer Rodbrob0ca5192020-03-26 08:22:24497 UpdateBitrateConstraints(*updated);
Sebastian Jansson97f61ea2018-02-21 12:01:55498 } else {
499 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 12:07:13500 << "WebRTC.RtpTransportControllerSend.SetSdpBitrateParameters: "
Jonas Olssonb2b20312020-01-14 11:11:31501 "nothing to update";
Sebastian Jansson97f61ea2018-02-21 12:01:55502 }
503}
504
505void RtpTransportControllerSend::SetClientBitratePreferences(
Niels Möller0c4f7be2018-05-07 12:01:37506 const BitrateSettings& preferences) {
Danil Chapovalovb9b146c2018-06-15 10:28:07507 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 12:01:55508 bitrate_configurator_.UpdateWithClientPreferences(preferences);
509 if (updated.has_value()) {
Christoffer Rodbrob0ca5192020-03-26 08:22:24510 UpdateBitrateConstraints(*updated);
Sebastian Jansson97f61ea2018-02-21 12:01:55511 } else {
512 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 12:07:13513 << "WebRTC.RtpTransportControllerSend.SetClientBitratePreferences: "
Jonas Olssonb2b20312020-01-14 11:11:31514 "nothing to update";
Sebastian Jansson97f61ea2018-02-21 12:01:55515 }
516}
Alex Narestbcf91802018-06-25 14:08:36517
Christoffer Rodbro6404cdd2020-03-26 19:37:21518absl::optional<BitrateConstraints>
519RtpTransportControllerSend::ApplyOrLiftRelayCap(bool is_relayed) {
520 DataRate cap = is_relayed ? relay_bandwidth_cap_ : DataRate::PlusInfinity();
521 return bitrate_configurator_.UpdateWithRelayCap(cap);
522}
523
Stefan Holmer64be7fa2018-10-04 13:21:55524void RtpTransportControllerSend::OnTransportOverheadChanged(
525 size_t transport_overhead_bytes_per_packet) {
Tommi1050fbc2021-06-03 15:58:28526 RTC_DCHECK_RUN_ON(&main_thread_);
Stefan Holmer64be7fa2018-10-04 13:21:55527 if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) {
528 RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes;
529 return;
530 }
531
Erik Språngf3f3a612022-05-13 13:55:29532 pacer_.SetTransportOverhead(
Danil Chapovalovcad3e0e2020-02-17 17:46:07533 DataSize::Bytes(transport_overhead_bytes_per_packet));
Mirko Bonadeie7bc3a32020-01-29 18:45:00534
Stefan Holmer64be7fa2018-10-04 13:21:55535 // TODO(holmer): Call AudioRtpSenders when they have been moved to
536 // RtpTransportControllerSend.
537 for (auto& rtp_video_sender : video_rtp_senders_) {
538 rtp_video_sender->OnTransportOverheadChanged(
539 transport_overhead_bytes_per_packet);
540 }
541}
Sebastian Jansson87609be2018-12-05 16:35:35542
Erik Språngaa59eca2019-07-24 12:52:55543void RtpTransportControllerSend::AccountForAudioPacketsInPacedSender(
544 bool account_for_audio) {
Erik Språngf3f3a612022-05-13 13:55:29545 pacer_.SetAccountForAudioPackets(account_for_audio);
Erik Språngaa59eca2019-07-24 12:52:55546}
547
Sebastian Janssonc3eb9fd2020-01-29 16:42:52548void RtpTransportControllerSend::IncludeOverheadInPacedSender() {
Erik Språngf3f3a612022-05-13 13:55:29549 pacer_.SetIncludeOverhead();
Sebastian Janssonc3eb9fd2020-01-29 16:42:52550}
551
Erik Språng7703f232020-09-14 09:03:13552void RtpTransportControllerSend::EnsureStarted() {
Etienne Pierre-doray03bce3f2021-03-29 17:36:15553 if (!pacer_started_) {
554 pacer_started_ = true;
Erik Språngf3f3a612022-05-13 13:55:29555 pacer_.EnsureStarted();
Erik Språng7703f232020-09-14 09:03:13556 }
557}
558
Sebastian Jansson87609be2018-12-05 16:35:35559void RtpTransportControllerSend::OnReceivedEstimatedBitrate(uint32_t bitrate) {
560 RemoteBitrateReport msg;
Danil Chapovalov0c626af2020-02-10 10:16:00561 msg.receive_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Danil Chapovalovcad3e0e2020-02-17 17:46:07562 msg.bandwidth = DataRate::BitsPerSec(bitrate);
Per Kjellander828ef912022-10-10 10:53:41563 task_queue_.RunOrPost([this, msg]() {
Sebastian Jansson87609be2018-12-05 16:35:35564 RTC_DCHECK_RUN_ON(&task_queue_);
565 if (controller_)
Sebastian Jansson16180952018-12-12 15:49:10566 PostUpdates(controller_->OnRemoteBitrateReport(msg));
Sebastian Jansson87609be2018-12-05 16:35:35567 });
568}
569
570void RtpTransportControllerSend::OnReceivedRtcpReceiverReport(
571 const ReportBlockList& report_blocks,
572 int64_t rtt_ms,
573 int64_t now_ms) {
Per Kjellander828ef912022-10-10 10:53:41574 task_queue_.RunOrPost([this, report_blocks, now_ms, rtt_ms]() {
Sebastian Jansson87609be2018-12-05 16:35:35575 RTC_DCHECK_RUN_ON(&task_queue_);
576 OnReceivedRtcpReceiverReportBlocks(report_blocks, now_ms);
Sebastian Jansson87609be2018-12-05 16:35:35577 RoundTripTimeUpdate report;
Danil Chapovalov0c626af2020-02-10 10:16:00578 report.receive_time = Timestamp::Millis(now_ms);
579 report.round_trip_time = TimeDelta::Millis(rtt_ms);
Sebastian Jansson87609be2018-12-05 16:35:35580 report.smoothed = false;
Christoffer Rodbro4bd31772019-03-27 11:34:21581 if (controller_ && !report.round_trip_time.IsZero())
Sebastian Jansson16180952018-12-12 15:49:10582 PostUpdates(controller_->OnRoundTripTimeUpdate(report));
Sebastian Jansson87609be2018-12-05 16:35:35583 });
584}
585
Erik Språng30a276b2019-04-23 10:00:11586void RtpTransportControllerSend::OnAddPacket(
587 const RtpPacketSendInfo& packet_info) {
Danil Chapovalov0c626af2020-02-10 10:16:00588 Timestamp creation_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Per Kjellander828ef912022-10-10 10:53:41589
590 task_queue_.RunOrPost([this, packet_info, creation_time]() {
Sebastian Jansson658f1812020-01-16 09:59:28591 RTC_DCHECK_RUN_ON(&task_queue_);
Tommi6f542d52022-01-24 12:36:40592 feedback_demuxer_.AddPacket(packet_info);
Sebastian Jansson658f1812020-01-16 09:59:28593 transport_feedback_adapter_.AddPacket(
Per Kjellandere0b4cab2022-11-30 18:41:22594 packet_info, transport_overhead_bytes_per_packet_, creation_time);
Sebastian Jansson658f1812020-01-16 09:59:28595 });
Sebastian Jansson87609be2018-12-05 16:35:35596}
597
598void RtpTransportControllerSend::OnTransportFeedback(
599 const rtcp::TransportFeedback& feedback) {
Danil Chapovalov0c626af2020-02-10 10:16:00600 auto feedback_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Per Kjellander828ef912022-10-10 10:53:41601 task_queue_.RunOrPost([this, feedback, feedback_time]() {
Sebastian Jansson658f1812020-01-16 09:59:28602 RTC_DCHECK_RUN_ON(&task_queue_);
Tommi6fba6b72022-01-28 08:00:01603 feedback_demuxer_.OnTransportFeedback(feedback);
Sebastian Jansson658f1812020-01-16 09:59:28604 absl::optional<TransportPacketsFeedback> feedback_msg =
605 transport_feedback_adapter_.ProcessTransportFeedback(feedback,
606 feedback_time);
Jianhui Daibf287972021-11-24 14:23:21607 if (feedback_msg) {
608 if (controller_)
609 PostUpdates(controller_->OnTransportPacketsFeedback(*feedback_msg));
610
Erik Språng66734372022-03-16 13:20:49611 // Only update outstanding data if any packet is first time acked.
612 UpdateCongestedState();
Sebastian Jansson658f1812020-01-16 09:59:28613 }
Sebastian Jansson658f1812020-01-16 09:59:28614 });
Sebastian Jansson87609be2018-12-05 16:35:35615}
616
Sebastian Janssone1795f42019-07-24 09:38:03617void RtpTransportControllerSend::OnRemoteNetworkEstimate(
618 NetworkStateEstimate estimate) {
Sebastian Jansson0a5ed892019-09-18 13:37:31619 if (event_log_) {
620 event_log_->Log(std::make_unique<RtcEventRemoteEstimate>(
621 estimate.link_capacity_lower, estimate.link_capacity_upper));
622 }
Danil Chapovalov0c626af2020-02-10 10:16:00623 estimate.update_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Per Kjellander828ef912022-10-10 10:53:41624 task_queue_.RunOrPost([this, estimate] {
Sebastian Janssone1795f42019-07-24 09:38:03625 RTC_DCHECK_RUN_ON(&task_queue_);
626 if (controller_)
Danil Chapovalove34fb872019-10-21 08:51:08627 PostUpdates(controller_->OnNetworkStateEstimate(estimate));
Sebastian Janssone1795f42019-07-24 09:38:03628 });
629}
630
Sebastian Jansson87609be2018-12-05 16:35:35631void RtpTransportControllerSend::MaybeCreateControllers() {
632 RTC_DCHECK(!controller_);
633 RTC_DCHECK(!control_handler_);
634
635 if (!network_available_ || !observer_)
636 return;
Mirko Bonadei317a1f02019-09-17 15:06:18637 control_handler_ = std::make_unique<CongestionControlHandler>();
Sebastian Jansson87609be2018-12-05 16:35:35638
639 initial_config_.constraints.at_time =
Danil Chapovalov0c626af2020-02-10 10:16:00640 Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35641 initial_config_.stream_based_config = streams_config_;
642
643 // TODO(srte): Use fallback controller if no feedback is available.
644 if (controller_factory_override_) {
645 RTC_LOG(LS_INFO) << "Creating overridden congestion controller";
646 controller_ = controller_factory_override_->Create(initial_config_);
647 process_interval_ = controller_factory_override_->GetProcessInterval();
648 } else {
649 RTC_LOG(LS_INFO) << "Creating fallback congestion controller";
650 controller_ = controller_factory_fallback_->Create(initial_config_);
651 process_interval_ = controller_factory_fallback_->GetProcessInterval();
652 }
653 UpdateControllerWithTimeInterval();
654 StartProcessPeriodicTasks();
655}
656
657void RtpTransportControllerSend::UpdateInitialConstraints(
658 TargetRateConstraints new_contraints) {
659 if (!new_contraints.starting_rate)
660 new_contraints.starting_rate = initial_config_.constraints.starting_rate;
661 RTC_DCHECK(new_contraints.starting_rate);
662 initial_config_.constraints = new_contraints;
663}
664
665void RtpTransportControllerSend::StartProcessPeriodicTasks() {
Per Kjellander828ef912022-10-10 10:53:41666 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Janssonecb68972019-01-18 09:30:54667 if (!pacer_queue_update_task_.Running()) {
668 pacer_queue_update_task_ = RepeatingTaskHandle::DelayedStart(
Per Kjellander828ef912022-10-10 10:53:41669 task_queue_.TaskQueueForDelayedTasks(), kPacerQueueUpdateInterval,
670 [this]() {
Sebastian Jansson87609be2018-12-05 16:35:35671 RTC_DCHECK_RUN_ON(&task_queue_);
Erik Språngf3f3a612022-05-13 13:55:29672 TimeDelta expected_queue_time = pacer_.ExpectedQueueTime();
Sebastian Jansson16180952018-12-12 15:49:10673 control_handler_->SetPacerQueue(expected_queue_time);
674 UpdateControlState();
Sebastian Janssonecb68972019-01-18 09:30:54675 return kPacerQueueUpdateInterval;
Sebastian Jansson87609be2018-12-05 16:35:35676 });
677 }
Sebastian Janssonecb68972019-01-18 09:30:54678 controller_task_.Stop();
Sebastian Jansson87609be2018-12-05 16:35:35679 if (process_interval_.IsFinite()) {
Sebastian Janssonecb68972019-01-18 09:30:54680 controller_task_ = RepeatingTaskHandle::DelayedStart(
Per Kjellander828ef912022-10-10 10:53:41681 task_queue_.TaskQueueForDelayedTasks(), process_interval_, [this]() {
Sebastian Jansson87609be2018-12-05 16:35:35682 RTC_DCHECK_RUN_ON(&task_queue_);
683 UpdateControllerWithTimeInterval();
Sebastian Janssonecb68972019-01-18 09:30:54684 return process_interval_;
Sebastian Jansson87609be2018-12-05 16:35:35685 });
686 }
687}
688
689void RtpTransportControllerSend::UpdateControllerWithTimeInterval() {
Sebastian Jansson16180952018-12-12 15:49:10690 RTC_DCHECK(controller_);
691 ProcessInterval msg;
Danil Chapovalov0c626af2020-02-10 10:16:00692 msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Christoffer Rodbroc610e262019-01-08 09:49:19693 if (add_pacing_to_cwin_)
Erik Språngf3f3a612022-05-13 13:55:29694 msg.pacer_queue = pacer_.QueueSizeData();
Sebastian Jansson16180952018-12-12 15:49:10695 PostUpdates(controller_->OnProcessInterval(msg));
Sebastian Jansson87609be2018-12-05 16:35:35696}
697
698void RtpTransportControllerSend::UpdateStreamsConfig() {
Danil Chapovalov0c626af2020-02-10 10:16:00699 streams_config_.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 16:35:35700 if (controller_)
Sebastian Jansson16180952018-12-12 15:49:10701 PostUpdates(controller_->OnStreamsConfig(streams_config_));
702}
703
704void RtpTransportControllerSend::PostUpdates(NetworkControlUpdate update) {
705 if (update.congestion_window) {
Erik Språng66734372022-03-16 13:20:49706 congestion_window_size_ = *update.congestion_window;
707 UpdateCongestedState();
Sebastian Jansson16180952018-12-12 15:49:10708 }
709 if (update.pacer_config) {
Erik Språngf3f3a612022-05-13 13:55:29710 pacer_.SetPacingRates(update.pacer_config->data_rate(),
711 update.pacer_config->pad_rate());
Sebastian Jansson16180952018-12-12 15:49:10712 }
Per Kjellander88af2032022-05-16 17:58:40713 if (!update.probe_cluster_configs.empty()) {
714 pacer_.CreateProbeClusters(std::move(update.probe_cluster_configs));
Sebastian Jansson16180952018-12-12 15:49:10715 }
716 if (update.target_rate) {
717 control_handler_->SetTargetRate(*update.target_rate);
718 UpdateControlState();
719 }
Sebastian Jansson87609be2018-12-05 16:35:35720}
721
722void RtpTransportControllerSend::OnReceivedRtcpReceiverReportBlocks(
723 const ReportBlockList& report_blocks,
724 int64_t now_ms) {
725 if (report_blocks.empty())
726 return;
727
728 int total_packets_lost_delta = 0;
729 int total_packets_delta = 0;
730
731 // Compute the packet loss from all report blocks.
732 for (const RTCPReportBlock& report_block : report_blocks) {
733 auto it = last_report_blocks_.find(report_block.source_ssrc);
734 if (it != last_report_blocks_.end()) {
735 auto number_of_packets = report_block.extended_highest_sequence_number -
736 it->second.extended_highest_sequence_number;
737 total_packets_delta += number_of_packets;
738 auto lost_delta = report_block.packets_lost - it->second.packets_lost;
739 total_packets_lost_delta += lost_delta;
740 }
741 last_report_blocks_[report_block.source_ssrc] = report_block;
742 }
743 // Can only compute delta if there has been previous blocks to compare to. If
744 // not, total_packets_delta will be unchanged and there's nothing more to do.
745 if (!total_packets_delta)
746 return;
747 int packets_received_delta = total_packets_delta - total_packets_lost_delta;
748 // To detect lost packets, at least one packet has to be received. This check
749 // is needed to avoid bandwith detection update in
750 // VideoSendStreamTest.SuspendBelowMinBitrate
751
752 if (packets_received_delta < 1)
753 return;
Danil Chapovalov0c626af2020-02-10 10:16:00754 Timestamp now = Timestamp::Millis(now_ms);
Sebastian Jansson87609be2018-12-05 16:35:35755 TransportLossReport msg;
756 msg.packets_lost_delta = total_packets_lost_delta;
757 msg.packets_received_delta = packets_received_delta;
758 msg.receive_time = now;
759 msg.start_time = last_report_block_time_;
760 msg.end_time = now;
761 if (controller_)
Sebastian Jansson16180952018-12-12 15:49:10762 PostUpdates(controller_->OnTransportLossReport(msg));
Sebastian Jansson87609be2018-12-05 16:35:35763 last_report_block_time_ = now;
764}
765
nissecae45d02017-04-24 12:53:20766} // namespace webrtc