nisse | cae45d0 | 2017-04-24 12:53:20 | [diff] [blame] | 1 | /* |
| 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 Olsson | a4d8737 | 2019-07-05 17:08:33 | [diff] [blame] | 10 | #include "call/rtp_transport_controller_send.h" |
| 11 | |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 12 | #include <cstddef> |
Per K | 02af840 | 2024-03-27 18:35:55 | [diff] [blame] | 13 | #include <cstdint> |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 14 | #include <map> |
Mirko Bonadei | 317a1f0 | 2019-09-17 15:06:18 | [diff] [blame] | 15 | #include <memory> |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 16 | #include <optional> |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 17 | #include <string> |
Sebastian Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 18 | #include <utility> |
Stefan Holmer | dbdb3a0 | 2018-07-17 14:03:46 | [diff] [blame] | 19 | #include <vector> |
nisse | cae45d0 | 2017-04-24 12:53:20 | [diff] [blame] | 20 | |
Ali Tofigh | 641a1b1 | 2022-05-17 09:48:46 | [diff] [blame] | 21 | #include "absl/strings/string_view.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 22 | #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 Chapovalov | af8f626 | 2024-09-04 15:18:30 | [diff] [blame] | 26 | #include "api/rtc_event_log/rtc_event_log.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 27 | #include "api/rtp_packet_sender.h" |
| 28 | #include "api/scoped_refptr.h" |
| 29 | #include "api/sequence_checker.h" |
Per Kjellander | 828ef91 | 2022-10-10 10:53:41 | [diff] [blame] | 30 | #include "api/task_queue/pending_task_safety_flag.h" |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 31 | #include "api/task_queue/task_queue_base.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 32 | #include "api/transport/bandwidth_estimation_settings.h" |
| 33 | #include "api/transport/bitrate_settings.h" |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 34 | #include "api/transport/goog_cc_factory.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 35 | #include "api/transport/network_control.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 36 | #include "api/transport/network_types.h" |
| 37 | #include "api/units/data_rate.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 38 | #include "api/units/data_size.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 39 | #include "api/units/time_delta.h" |
| 40 | #include "api/units/timestamp.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 41 | #include "call/rtp_config.h" |
| 42 | #include "call/rtp_transport_config.h" |
| 43 | #include "call/rtp_transport_controller_send_interface.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 44 | #include "call/rtp_video_sender.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 45 | #include "call/rtp_video_sender_interface.h" |
Sebastian Jansson | 166b45d | 2019-05-13 09:57:42 | [diff] [blame] | 46 | #include "logging/rtc_event_log/events/rtc_event_route_change.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 47 | #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 K | 02af840 | 2024-03-27 18:35:55 | [diff] [blame] | 50 | #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
Per K | 1d2f85d | 2024-10-23 12:11:41 | [diff] [blame] | 51 | #include "modules/rtp_rtcp/source/rtcp_packet/congestion_control_feedback.h" |
Sebastian Jansson | 658f181 | 2020-01-16 09:59:28 | [diff] [blame] | 52 | #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
Per K | 1d2f85d | 2024-10-23 12:11:41 | [diff] [blame] | 53 | #include "modules/rtp_rtcp/source/rtp_header_extensions.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 54 | #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 55 | #include "rtc_base/checks.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 56 | #include "rtc_base/experiments/field_trial_parser.h" |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 57 | #include "rtc_base/logging.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 58 | #include "rtc_base/network/sent_packet.h" |
| 59 | #include "rtc_base/network_route.h" |
Stefan Holmer | dbdb3a0 | 2018-07-17 14:03:46 | [diff] [blame] | 60 | #include "rtc_base/rate_limiter.h" |
Harald Alvestrand | 93c9aa1 | 2024-09-02 20:55:52 | [diff] [blame] | 61 | #include "rtc_base/task_utils/repeating_task.h" |
nisse | cae45d0 | 2017-04-24 12:53:20 | [diff] [blame] | 62 | |
| 63 | namespace webrtc { |
Sebastian Jansson | 19bea51 | 2018-03-13 18:07:46 | [diff] [blame] | 64 | namespace { |
Stefan Holmer | dbdb3a0 | 2018-07-17 14:03:46 | [diff] [blame] | 65 | static const int64_t kRetransmitWindowSizeMs = 500; |
Stefan Holmer | 64be7fa | 2018-10-04 13:21:55 | [diff] [blame] | 66 | static const size_t kMaxOverheadBytes = 500; |
Sebastian Jansson | 19bea51 | 2018-03-13 18:07:46 | [diff] [blame] | 67 | |
Danil Chapovalov | 0c626af | 2020-02-10 10:16:00 | [diff] [blame] | 68 | constexpr TimeDelta kPacerQueueUpdateInterval = TimeDelta::Millis(25); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 69 | |
| 70 | TargetRateConstraints ConvertConstraints(int min_bitrate_bps, |
| 71 | int max_bitrate_bps, |
| 72 | int start_bitrate_bps, |
Sebastian Jansson | aa01f27 | 2019-01-30 10:28:59 | [diff] [blame] | 73 | Clock* clock) { |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 74 | TargetRateConstraints msg; |
Danil Chapovalov | 0c626af | 2020-02-10 10:16:00 | [diff] [blame] | 75 | msg.at_time = Timestamp::Millis(clock->TimeInMilliseconds()); |
Danil Chapovalov | cad3e0e | 2020-02-17 17:46:07 | [diff] [blame] | 76 | 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 Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 82 | if (start_bitrate_bps > 0) |
Danil Chapovalov | cad3e0e | 2020-02-17 17:46:07 | [diff] [blame] | 83 | msg.starting_rate = DataRate::BitsPerSec(start_bitrate_bps); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 84 | return msg; |
| 85 | } |
| 86 | |
| 87 | TargetRateConstraints ConvertConstraints(const BitrateConstraints& contraints, |
Sebastian Jansson | aa01f27 | 2019-01-30 10:28:59 | [diff] [blame] | 88 | Clock* clock) { |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 89 | return ConvertConstraints(contraints.min_bitrate_bps, |
| 90 | contraints.max_bitrate_bps, |
| 91 | contraints.start_bitrate_bps, clock); |
| 92 | } |
Erik Språng | 662678d | 2019-11-15 16:18:52 | [diff] [blame] | 93 | |
Christoffer Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 94 | bool IsRelayed(const rtc::NetworkRoute& route) { |
| 95 | return route.local.uses_turn() || route.remote.uses_turn(); |
Christoffer Rodbro | b0ca519 | 2020-03-26 08:22:24 | [diff] [blame] | 96 | } |
Sebastian Jansson | 19bea51 | 2018-03-13 18:07:46 | [diff] [blame] | 97 | } // namespace |
nisse | cae45d0 | 2017-04-24 12:53:20 | [diff] [blame] | 98 | |
| 99 | RtpTransportControllerSend::RtpTransportControllerSend( |
Henrik Boström | da4c102 | 2022-11-15 14:45:41 | [diff] [blame] | 100 | const RtpTransportConfig& config) |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 101 | : env_(config.env), |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 102 | task_queue_(TaskQueueBase::Current()), |
Henrik Boström | da4c102 | 2022-11-15 14:45:41 | [diff] [blame] | 103 | bitrate_configurator_(config.bitrate_config), |
Etienne Pierre-doray | 03bce3f | 2021-03-29 17:36:15 | [diff] [blame] | 104 | pacer_started_(false), |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 105 | pacer_(&env_.clock(), |
| 106 | &packet_router_, |
| 107 | env_.field_trials(), |
| 108 | TimeDelta::Millis(5), |
| 109 | 3), |
Sebastian Jansson | 317a522 | 2018-03-16 14:36:37 | [diff] [blame] | 110 | observer_(nullptr), |
Henrik Boström | da4c102 | 2022-11-15 14:45:41 | [diff] [blame] | 111 | controller_factory_override_(config.network_controller_factory), |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 112 | controller_factory_fallback_( |
Henrik Boström | da4c102 | 2022-11-15 14:45:41 | [diff] [blame] | 113 | std::make_unique<GoogCcNetworkControllerFactory>( |
Danil Chapovalov | 3a92ae9 | 2024-04-15 17:26:18 | [diff] [blame] | 114 | GoogCcFactoryConfig{.network_state_predictor_factory = |
| 115 | config.network_state_predictor_factory})), |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 116 | process_interval_(controller_factory_fallback_->GetProcessInterval()), |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 117 | last_report_block_time_( |
| 118 | Timestamp::Millis(env_.clock().TimeInMilliseconds())), |
Danil Chapovalov | f20ed3e | 2024-05-08 10:49:40 | [diff] [blame] | 119 | initial_config_(env_), |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 120 | reset_feedback_on_route_change_( |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 121 | !env_.field_trials().IsEnabled("WebRTC-Bwe-NoFeedbackReset")), |
| 122 | add_pacing_to_cwin_(env_.field_trials().IsEnabled( |
| 123 | "WebRTC-AddPacingToCongestionWindowPushback")), |
Per K | d1a8ce5 | 2024-05-16 10:33:52 | [diff] [blame] | 124 | reset_bwe_on_adapter_id_change_( |
| 125 | env_.field_trials().IsEnabled("WebRTC-Bwe-ResetOnAdapterIdChange")), |
Christoffer Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 126 | relay_bandwidth_cap_("relay_cap", DataRate::PlusInfinity()), |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 127 | transport_overhead_bytes_per_packet_(0), |
| 128 | network_available_(false), |
Erik Språng | 6673437 | 2022-03-16 13:20:49 | [diff] [blame] | 129 | congestion_window_size_(DataSize::PlusInfinity()), |
| 130 | is_congested_(false), |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 131 | retransmission_rate_limiter_(&env_.clock(), kRetransmitWindowSizeMs) { |
| 132 | ParseFieldTrial( |
| 133 | {&relay_bandwidth_cap_}, |
| 134 | env_.field_trials().Lookup("WebRTC-Bwe-NetworkRouteConstraints")); |
Henrik Boström | da4c102 | 2022-11-15 14:45:41 | [diff] [blame] | 135 | initial_config_.constraints = |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 136 | ConvertConstraints(config.bitrate_config, &env_.clock()); |
Henrik Boström | da4c102 | 2022-11-15 14:45:41 | [diff] [blame] | 137 | RTC_DCHECK(config.bitrate_config.start_bitrate_bps > 0); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 138 | |
Henrik Boström | da4c102 | 2022-11-15 14:45:41 | [diff] [blame] | 139 | pacer_.SetPacingRates( |
| 140 | DataRate::BitsPerSec(config.bitrate_config.start_bitrate_bps), |
| 141 | DataRate::Zero()); |
Per K | 86b1cf7 | 2023-12-08 13:57:13 | [diff] [blame] | 142 | if (config.pacer_burst_interval) { |
| 143 | // Default burst interval overriden by config. |
| 144 | pacer_.SetSendBurstInterval(*config.pacer_burst_interval); |
| 145 | } |
Per K | 02af840 | 2024-03-27 18:35:55 | [diff] [blame] | 146 | packet_router_.RegisterNotifyBweCallback( |
| 147 | [this](const RtpPacketToSend& packet, |
| 148 | const PacedPacketInfo& pacing_info) { |
| 149 | return NotifyBweOfPacedSentPacket(packet, pacing_info); |
| 150 | }); |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 151 | } |
Sebastian Jansson | c33c0fc | 2018-02-22 10:10:18 | [diff] [blame] | 152 | |
| 153 | RtpTransportControllerSend::~RtpTransportControllerSend() { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 154 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Tommi | 1050fbc | 2021-06-03 15:58:28 | [diff] [blame] | 155 | RTC_DCHECK(video_rtp_senders_.empty()); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 156 | pacer_queue_update_task_.Stop(); |
| 157 | controller_task_.Stop(); |
Sebastian Jansson | c33c0fc | 2018-02-22 10:10:18 | [diff] [blame] | 158 | } |
nisse | cae45d0 | 2017-04-24 12:53:20 | [diff] [blame] | 159 | |
Stefan Holmer | 9416ef8 | 2018-07-19 08:34:38 | [diff] [blame] | 160 | RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender( |
Tommi | 8695282 | 2021-11-29 09:26:40 | [diff] [blame] | 161 | const std::map<uint32_t, RtpState>& suspended_ssrcs, |
Stefan Holmer | dbdb3a0 | 2018-07-17 14:03:46 | [diff] [blame] | 162 | const std::map<uint32_t, RtpPayloadState>& states, |
| 163 | const RtpConfig& rtp_config, |
Jiawei Ou | 5571812 | 2018-11-09 21:17:39 | [diff] [blame] | 164 | int rtcp_report_interval_ms, |
Stefan Holmer | dbdb3a0 | 2018-07-17 14:03:46 | [diff] [blame] | 165 | Transport* send_transport, |
| 166 | const RtpSenderObservers& observers, |
Benjamin Wright | 192eeec | 2018-10-18 00:27:25 | [diff] [blame] | 167 | std::unique_ptr<FecController> fec_controller, |
Marina Ciocea | e77912b | 2020-02-27 15:16:55 | [diff] [blame] | 168 | const RtpSenderFrameEncryptionConfig& frame_encryption_config, |
| 169 | rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 170 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Mirko Bonadei | 317a1f0 | 2019-09-17 15:06:18 | [diff] [blame] | 171 | video_rtp_senders_.push_back(std::make_unique<RtpVideoSender>( |
Danil Chapovalov | 0f02728 | 2024-09-24 09:22:55 | [diff] [blame] | 172 | env_, task_queue_, suspended_ssrcs, states, rtp_config, |
| 173 | rtcp_report_interval_ms, send_transport, observers, |
Stefan Holmer | dbdb3a0 | 2018-07-17 14:03:46 | [diff] [blame] | 174 | // TODO(holmer): Remove this circular dependency by injecting |
| 175 | // the parts of RtpTransportControllerSendInterface that are really used. |
Xinyu Ma | 954fdb0 | 2024-07-26 22:09:09 | [diff] [blame] | 176 | 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 Holmer | dbdb3a0 | 2018-07-17 14:03:46 | [diff] [blame] | 179 | return video_rtp_senders_.back().get(); |
| 180 | } |
| 181 | |
Stefan Holmer | 9416ef8 | 2018-07-19 08:34:38 | [diff] [blame] | 182 | void RtpTransportControllerSend::DestroyRtpVideoSender( |
| 183 | RtpVideoSenderInterface* rtp_video_sender) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 184 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Stefan Holmer | 9416ef8 | 2018-07-19 08:34:38 | [diff] [blame] | 185 | std::vector<std::unique_ptr<RtpVideoSenderInterface>>::iterator it = |
Stefan Holmer | 5ed25af | 2018-07-18 13:17:14 | [diff] [blame] | 186 | 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 K | 979b6d6 | 2024-01-26 10:18:26 | [diff] [blame] | 196 | void 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 K | 98db63c | 2024-01-26 11:57:01 | [diff] [blame] | 202 | pacer_.SetAllowProbeWithoutMediaPacket( |
Per K | 39ac25d | 2024-02-07 13:16:20 | [diff] [blame] | 203 | bwe_settings_.allow_probe_without_media && |
Per K | 98db63c | 2024-01-26 11:57:01 | [diff] [blame] | 204 | packet_router_.SupportsRtxPayloadPadding()); |
Per K | 979b6d6 | 2024-01-26 10:18:26 | [diff] [blame] | 205 | } |
| 206 | |
| 207 | void 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 K | 98db63c | 2024-01-26 11:57:01 | [diff] [blame] | 222 | pacer_.SetAllowProbeWithoutMediaPacket( |
Per K | 39ac25d | 2024-02-07 13:16:20 | [diff] [blame] | 223 | bwe_settings_.allow_probe_without_media && |
Per K | 98db63c | 2024-01-26 11:57:01 | [diff] [blame] | 224 | packet_router_.SupportsRtxPayloadPadding()); |
Per K | 979b6d6 | 2024-01-26 10:18:26 | [diff] [blame] | 225 | } |
| 226 | |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 227 | void RtpTransportControllerSend::UpdateControlState() { |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 228 | std::optional<TargetTransferRate> update = control_handler_->GetUpdate(); |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 229 | if (!update) |
| 230 | return; |
Sebastian Jansson | f34116e | 2019-09-24 15:55:50 | [diff] [blame] | 231 | retransmission_rate_limiter_.SetMaxRate(update->target_rate.bps()); |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 232 | // We won't create control_handler_ until we have an observers. |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 233 | RTC_DCHECK(observer_ != nullptr); |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 234 | observer_->OnTargetTransferRate(*update); |
Sebastian Jansson | e625605 | 2018-05-04 12:08:15 | [diff] [blame] | 235 | } |
| 236 | |
Erik Språng | 6673437 | 2022-03-16 13:20:49 | [diff] [blame] | 237 | void RtpTransportControllerSend::UpdateCongestedState() { |
Markus Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 238 | if (auto update = GetCongestedStateUpdate()) { |
| 239 | is_congested_ = update.value(); |
| 240 | pacer_.SetCongested(update.value()); |
| 241 | } |
| 242 | } |
| 243 | |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 244 | std::optional<bool> RtpTransportControllerSend::GetCongestedStateUpdate() |
Markus Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 245 | const { |
Erik Språng | 6673437 | 2022-03-16 13:20:49 | [diff] [blame] | 246 | bool congested = transport_feedback_adapter_.GetOutstandingData() >= |
| 247 | congestion_window_size_; |
Markus Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 248 | if (congested != is_congested_) |
| 249 | return congested; |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 250 | return std::nullopt; |
Erik Språng | 6673437 | 2022-03-16 13:20:49 | [diff] [blame] | 251 | } |
| 252 | |
nisse | 76e62b0 | 2017-05-31 09:24:52 | [diff] [blame] | 253 | PacketRouter* RtpTransportControllerSend::packet_router() { |
| 254 | return &packet_router_; |
| 255 | } |
| 256 | |
Sebastian Jansson | e1795f4 | 2019-07-24 09:38:03 | [diff] [blame] | 257 | NetworkStateEstimateObserver* |
| 258 | RtpTransportControllerSend::network_state_estimate_observer() { |
| 259 | return this; |
| 260 | } |
| 261 | |
Erik Språng | aa59eca | 2019-07-24 12:52:55 | [diff] [blame] | 262 | RtpPacketSender* RtpTransportControllerSend::packet_sender() { |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 263 | return &pacer_; |
nisse | 76e62b0 | 2017-05-31 09:24:52 | [diff] [blame] | 264 | } |
| 265 | |
Stefan Holmer | 5c8942a | 2017-08-22 14:16:44 | [diff] [blame] | 266 | void RtpTransportControllerSend::SetAllocatedSendBitrateLimits( |
Sebastian Jansson | 93b1ea2 | 2019-09-18 16:31:52 | [diff] [blame] | 267 | BitrateAllocationLimits limits) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 268 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Sebastian Jansson | 93b1ea2 | 2019-09-18 16:31:52 | [diff] [blame] | 269 | 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 Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 272 | UpdateStreamsConfig(); |
Stefan Holmer | 5c8942a | 2017-08-22 14:16:44 | [diff] [blame] | 273 | } |
Sebastian Jansson | 4c1ffb8 | 2018-02-15 15:51:58 | [diff] [blame] | 274 | void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 275 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 276 | streams_config_.pacing_factor = pacing_factor; |
| 277 | UpdateStreamsConfig(); |
Sebastian Jansson | 4c1ffb8 | 2018-02-15 15:51:58 | [diff] [blame] | 278 | } |
| 279 | void RtpTransportControllerSend::SetQueueTimeLimit(int limit_ms) { |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 280 | pacer_.SetQueueTimeLimit(TimeDelta::Millis(limit_ms)); |
Sebastian Jansson | 4c1ffb8 | 2018-02-15 15:51:58 | [diff] [blame] | 281 | } |
Sebastian Jansson | f298855 | 2019-10-29 16:18:51 | [diff] [blame] | 282 | StreamFeedbackProvider* |
| 283 | RtpTransportControllerSend::GetStreamFeedbackProvider() { |
JT Teh | ea992f8 | 2020-01-15 18:24:20 | [diff] [blame] | 284 | return &feedback_demuxer_; |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 285 | } |
Sebastian Jansson | 19704ec | 2018-03-12 14:59:12 | [diff] [blame] | 286 | |
Per K | 39ac25d | 2024-02-07 13:16:20 | [diff] [blame] | 287 | void RtpTransportControllerSend::ReconfigureBandwidthEstimation( |
| 288 | const BandwidthEstimationSettings& settings) { |
| 289 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
| 290 | bwe_settings_ = settings; |
| 291 | |
Per K | cc92b6e | 2024-05-07 15:35:09 | [diff] [blame] | 292 | streams_config_.enable_repeated_initial_probing = |
| 293 | bwe_settings_.allow_probe_without_media; |
Per K | fb61154 | 2024-04-16 11:04:37 | [diff] [blame] | 294 | bool allow_probe_without_media = bwe_settings_.allow_probe_without_media && |
| 295 | packet_router_.SupportsRtxPayloadPadding(); |
Per K | fb61154 | 2024-04-16 11:04:37 | [diff] [blame] | 296 | pacer_.SetAllowProbeWithoutMediaPacket(allow_probe_without_media); |
| 297 | |
Per K | 39ac25d | 2024-02-07 13:16:20 | [diff] [blame] | 298 | 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 K | 39ac25d | 2024-02-07 13:16:20 | [diff] [blame] | 311 | } |
| 312 | |
Sebastian Jansson | 19704ec | 2018-03-12 14:59:12 | [diff] [blame] | 313 | void RtpTransportControllerSend::RegisterTargetTransferRateObserver( |
| 314 | TargetTransferRateObserver* observer) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 315 | 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 Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 320 | } |
Christoffer Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 321 | |
| 322 | bool RtpTransportControllerSend::IsRelevantRouteChange( |
| 323 | const rtc::NetworkRoute& old_route, |
| 324 | const rtc::NetworkRoute& new_route) const { |
Christoffer Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 325 | bool connected_changed = old_route.connected != new_route.connected; |
Per K | d1a8ce5 | 2024-05-16 10:33:52 | [diff] [blame] | 326 | 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 Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 333 | } else { |
Per K | d1a8ce5 | 2024-05-16 10:33:52 | [diff] [blame] | 334 | 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 Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 337 | } |
Per K | d1a8ce5 | 2024-05-16 10:33:52 | [diff] [blame] | 338 | 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 Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 342 | } |
| 343 | |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 344 | void RtpTransportControllerSend::OnNetworkRouteChanged( |
Ali Tofigh | 641a1b1 | 2022-05-17 09:48:46 | [diff] [blame] | 345 | absl::string_view transport_name, |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 346 | const rtc::NetworkRoute& network_route) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 347 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Sebastian Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 348 | // Check if the network route is connected. |
| 349 | if (!network_route.connected) { |
Sebastian Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 350 | // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and |
| 351 | // consider merging these two methods. |
| 352 | return; |
| 353 | } |
| 354 | |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 355 | std::optional<BitrateConstraints> relay_constraint_update = |
Christoffer Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 356 | ApplyOrLiftRelayCap(IsRelayed(network_route)); |
| 357 | |
Sebastian Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 358 | // Check whether the network route has changed on each transport. |
Ali Tofigh | c48f9ef | 2022-08-17 17:20:04 | [diff] [blame] | 359 | 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 Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 364 | auto kv = result.first; |
| 365 | bool inserted = result.second; |
Jonas Oreland | 5b6a4d8 | 2020-03-24 06:36:52 | [diff] [blame] | 366 | 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 Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 374 | if (inserted) { |
Christoffer Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 375 | if (relay_constraint_update.has_value()) { |
| 376 | UpdateBitrateConstraints(*relay_constraint_update); |
| 377 | } |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 378 | transport_overhead_bytes_per_packet_ = network_route.packet_overhead; |
Sebastian Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 379 | // No need to reset BWE if this is the first time the network connects. |
| 380 | return; |
| 381 | } |
Jonas Oreland | 5b6a4d8 | 2020-03-24 06:36:52 | [diff] [blame] | 382 | |
| 383 | const rtc::NetworkRoute old_route = kv->second; |
Jonas Oreland | 71fda36 | 2020-03-20 15:11:56 | [diff] [blame] | 384 | kv->second = network_route; |
Jonas Oreland | 71fda36 | 2020-03-20 15:11:56 | [diff] [blame] | 385 | |
| 386 | // Check if enough conditions of the new/old route has changed |
| 387 | // to trigger resetting of bitrates (and a probe). |
Christoffer Rodbro | b0ca519 | 2020-03-26 08:22:24 | [diff] [blame] | 388 | if (IsRelevantRouteChange(old_route, network_route)) { |
Sebastian Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 389 | BitrateConstraints bitrate_config = bitrate_configurator_.GetConfig(); |
Jonas Oreland | 71fda36 | 2020-03-20 15:11:56 | [diff] [blame] | 390 | RTC_LOG(LS_INFO) << "Reset bitrates to min: " |
Sebastian Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 391 | << 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 Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 396 | |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 397 | env_.event_log().Log(std::make_unique<RtcEventRouteChange>( |
| 398 | network_route.connected, network_route.packet_overhead)); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 399 | NetworkRouteChange msg; |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 400 | msg.at_time = Timestamp::Millis(env_.clock().TimeInMilliseconds()); |
| 401 | msg.constraints = ConvertConstraints(bitrate_config, &env_.clock()); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 402 | 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 Jansson | 91bb667 | 2018-02-21 12:02:51 | [diff] [blame] | 413 | } |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 414 | } |
| 415 | void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 416 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Harald Alvestrand | 977b265 | 2019-12-12 12:40:50 | [diff] [blame] | 417 | RTC_LOG(LS_VERBOSE) << "SignalNetworkState " |
| 418 | << (network_available ? "Up" : "Down"); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 419 | 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 Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 427 | |
Per K | ef4c71c | 2023-10-19 08:06:35 | [diff] [blame] | 428 | if (!controller_) { |
| 429 | MaybeCreateControllers(); |
| 430 | } |
Per K | 39ac25d | 2024-02-07 13:16:20 | [diff] [blame] | 431 | UpdateNetworkAvailability(); |
Stefan Holmer | dbdb3a0 | 2018-07-17 14:03:46 | [diff] [blame] | 432 | for (auto& rtp_sender : video_rtp_senders_) { |
| 433 | rtp_sender->OnNetworkAvailability(network_available); |
| 434 | } |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 435 | } |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 436 | NetworkLinkRtcpObserver* RtpTransportControllerSend::GetRtcpObserver() { |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 437 | return this; |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 438 | } |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 439 | int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const { |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 440 | return pacer_.OldestPacketWaitTime().ms(); |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 441 | } |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 442 | std::optional<Timestamp> RtpTransportControllerSend::GetFirstPacketTime() |
Erik Språng | 425d6aa | 2019-07-29 14:38:27 | [diff] [blame] | 443 | const { |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 444 | return pacer_.FirstSentPacketTime(); |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 445 | } |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 446 | void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 447 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
| 448 | |
| 449 | streams_config_.requests_alr_probing = enable; |
| 450 | UpdateStreamsConfig(); |
Sebastian Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 451 | } |
| 452 | void RtpTransportControllerSend::OnSentPacket( |
| 453 | const rtc::SentPacket& sent_packet) { |
Markus Handell | e32b622 | 2023-05-08 22:59:46 | [diff] [blame] | 454 | // 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 Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 457 | // launches. |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 458 | if (TaskQueueBase::Current() != task_queue_) { |
| 459 | task_queue_->PostTask(SafeTask(safety_.flag(), [this, sent_packet]() { |
| 460 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Markus Handell | e32b622 | 2023-05-08 22:59:46 | [diff] [blame] | 461 | ProcessSentPacket(sent_packet); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 462 | })); |
Markus Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 463 | return; |
| 464 | } |
Per Kjellander | 828ef91 | 2022-10-10 10:53:41 | [diff] [blame] | 465 | |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 466 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Markus Handell | e32b622 | 2023-05-08 22:59:46 | [diff] [blame] | 467 | ProcessSentPacket(sent_packet); |
Markus Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 468 | } |
| 469 | |
Markus Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 470 | void RtpTransportControllerSend::ProcessSentPacket( |
Markus Handell | e32b622 | 2023-05-08 22:59:46 | [diff] [blame] | 471 | const rtc::SentPacket& sent_packet) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 472 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 473 | std::optional<SentPacket> packet_msg = |
Markus Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 474 | 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 Handell | e32b622 | 2023-05-08 22:59:46 | [diff] [blame] | 484 | ProcessSentPacketUpdates(std::move(control_update)); |
Markus Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 485 | } |
| 486 | |
| 487 | // RTC_RUN_ON(task_queue_) |
| 488 | void RtpTransportControllerSend::ProcessSentPacketUpdates( |
| 489 | NetworkControlUpdate updates) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 490 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Markus Handell | eb27752 | 2023-03-03 15:38:10 | [diff] [blame] | 491 | // 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 Jansson | e4be6da | 2018-02-15 15:51:41 | [diff] [blame] | 499 | } |
sprang | db2a9fc | 2017-08-09 13:42:32 | [diff] [blame] | 500 | |
Björn Terelius | b4d4bbc | 2023-09-24 20:36:41 | [diff] [blame] | 501 | void 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 Rodbro | b0ca519 | 2020-03-26 08:22:24 | [diff] [blame] | 508 | void RtpTransportControllerSend::UpdateBitrateConstraints( |
| 509 | const BitrateConstraints& updated) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 510 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 511 | TargetRateConstraints msg = ConvertConstraints(updated, &env_.clock()); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 512 | if (controller_) { |
| 513 | PostUpdates(controller_->OnTargetRateConstraints(msg)); |
| 514 | } else { |
| 515 | UpdateInitialConstraints(msg); |
| 516 | } |
Christoffer Rodbro | b0ca519 | 2020-03-26 08:22:24 | [diff] [blame] | 517 | } |
| 518 | |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 519 | void RtpTransportControllerSend::SetSdpBitrateParameters( |
| 520 | const BitrateConstraints& constraints) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 521 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 522 | std::optional<BitrateConstraints> updated = |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 523 | bitrate_configurator_.UpdateWithSdpParameters(constraints); |
| 524 | if (updated.has_value()) { |
Christoffer Rodbro | b0ca519 | 2020-03-26 08:22:24 | [diff] [blame] | 525 | UpdateBitrateConstraints(*updated); |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 526 | } else { |
| 527 | RTC_LOG(LS_VERBOSE) |
Sebastian Jansson | 8f83b42 | 2018-02-21 12:07:13 | [diff] [blame] | 528 | << "WebRTC.RtpTransportControllerSend.SetSdpBitrateParameters: " |
Jonas Olsson | b2b2031 | 2020-01-14 11:11:31 | [diff] [blame] | 529 | "nothing to update"; |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 530 | } |
| 531 | } |
| 532 | |
| 533 | void RtpTransportControllerSend::SetClientBitratePreferences( |
Niels Möller | 0c4f7be | 2018-05-07 12:01:37 | [diff] [blame] | 534 | const BitrateSettings& preferences) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 535 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 536 | std::optional<BitrateConstraints> updated = |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 537 | bitrate_configurator_.UpdateWithClientPreferences(preferences); |
| 538 | if (updated.has_value()) { |
Christoffer Rodbro | b0ca519 | 2020-03-26 08:22:24 | [diff] [blame] | 539 | UpdateBitrateConstraints(*updated); |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 540 | } else { |
| 541 | RTC_LOG(LS_VERBOSE) |
Sebastian Jansson | 8f83b42 | 2018-02-21 12:07:13 | [diff] [blame] | 542 | << "WebRTC.RtpTransportControllerSend.SetClientBitratePreferences: " |
Jonas Olsson | b2b2031 | 2020-01-14 11:11:31 | [diff] [blame] | 543 | "nothing to update"; |
Sebastian Jansson | 97f61ea | 2018-02-21 12:01:55 | [diff] [blame] | 544 | } |
| 545 | } |
Alex Narest | bcf9180 | 2018-06-25 14:08:36 | [diff] [blame] | 546 | |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 547 | std::optional<BitrateConstraints> |
Christoffer Rodbro | 6404cdd | 2020-03-26 19:37:21 | [diff] [blame] | 548 | RtpTransportControllerSend::ApplyOrLiftRelayCap(bool is_relayed) { |
| 549 | DataRate cap = is_relayed ? relay_bandwidth_cap_ : DataRate::PlusInfinity(); |
| 550 | return bitrate_configurator_.UpdateWithRelayCap(cap); |
| 551 | } |
| 552 | |
Stefan Holmer | 64be7fa | 2018-10-04 13:21:55 | [diff] [blame] | 553 | void RtpTransportControllerSend::OnTransportOverheadChanged( |
| 554 | size_t transport_overhead_bytes_per_packet) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 555 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Stefan Holmer | 64be7fa | 2018-10-04 13:21:55 | [diff] [blame] | 556 | if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) { |
| 557 | RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes; |
| 558 | return; |
| 559 | } |
| 560 | |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 561 | pacer_.SetTransportOverhead( |
Danil Chapovalov | cad3e0e | 2020-02-17 17:46:07 | [diff] [blame] | 562 | DataSize::Bytes(transport_overhead_bytes_per_packet)); |
Mirko Bonadei | e7bc3a3 | 2020-01-29 18:45:00 | [diff] [blame] | 563 | |
Stefan Holmer | 64be7fa | 2018-10-04 13:21:55 | [diff] [blame] | 564 | // 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 Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 571 | |
Erik Språng | aa59eca | 2019-07-24 12:52:55 | [diff] [blame] | 572 | void RtpTransportControllerSend::AccountForAudioPacketsInPacedSender( |
| 573 | bool account_for_audio) { |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 574 | pacer_.SetAccountForAudioPackets(account_for_audio); |
Erik Språng | aa59eca | 2019-07-24 12:52:55 | [diff] [blame] | 575 | } |
| 576 | |
Sebastian Jansson | c3eb9fd | 2020-01-29 16:42:52 | [diff] [blame] | 577 | void RtpTransportControllerSend::IncludeOverheadInPacedSender() { |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 578 | pacer_.SetIncludeOverhead(); |
Sebastian Jansson | c3eb9fd | 2020-01-29 16:42:52 | [diff] [blame] | 579 | } |
| 580 | |
Erik Språng | 7703f23 | 2020-09-14 09:03:13 | [diff] [blame] | 581 | void RtpTransportControllerSend::EnsureStarted() { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 582 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Etienne Pierre-doray | 03bce3f | 2021-03-29 17:36:15 | [diff] [blame] | 583 | if (!pacer_started_) { |
| 584 | pacer_started_ = true; |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 585 | pacer_.EnsureStarted(); |
Erik Språng | 7703f23 | 2020-09-14 09:03:13 | [diff] [blame] | 586 | } |
| 587 | } |
| 588 | |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 589 | void RtpTransportControllerSend::OnReceiverEstimatedMaxBitrate( |
| 590 | Timestamp receive_time, |
| 591 | DataRate bitrate) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 592 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 593 | RemoteBitrateReport msg; |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 594 | msg.receive_time = receive_time; |
| 595 | msg.bandwidth = bitrate; |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 596 | if (controller_) |
| 597 | PostUpdates(controller_->OnRemoteBitrateReport(msg)); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 598 | } |
| 599 | |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 600 | void RtpTransportControllerSend::OnRttUpdate(Timestamp receive_time, |
| 601 | TimeDelta rtt) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 602 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 603 | RoundTripTimeUpdate report; |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 604 | report.receive_time = receive_time; |
Danil Chapovalov | 328c514 | 2023-05-19 09:45:46 | [diff] [blame] | 605 | report.round_trip_time = rtt.RoundTo(TimeDelta::Millis(1)); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 606 | report.smoothed = false; |
| 607 | if (controller_ && !report.round_trip_time.IsZero()) |
| 608 | PostUpdates(controller_->OnRoundTripTimeUpdate(report)); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 609 | } |
| 610 | |
Per K | 02af840 | 2024-03-27 18:35:55 | [diff] [blame] | 611 | void RtpTransportControllerSend::NotifyBweOfPacedSentPacket( |
| 612 | const RtpPacketToSend& packet, |
| 613 | const PacedPacketInfo& pacing_info) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 614 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Per K | 02af840 | 2024-03-27 18:35:55 | [diff] [blame] | 615 | |
| 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 K | 93e1778 | 2024-10-18 09:32:44 | [diff] [blame] | 623 | 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 Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 632 | Timestamp creation_time = |
| 633 | Timestamp::Millis(env_.clock().TimeInMilliseconds()); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 634 | transport_feedback_adapter_.AddPacket( |
Per K | 93e1778 | 2024-10-18 09:32:44 | [diff] [blame] | 635 | packet, pacing_info, transport_overhead_bytes_per_packet_, creation_time); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 636 | } |
| 637 | |
Per Kjellander | 7768667 | 2024-12-19 07:58:06 | [diff] [blame] | 638 | void 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 Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 645 | void RtpTransportControllerSend::OnTransportFeedback( |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 646 | Timestamp receive_time, |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 647 | const rtcp::TransportFeedback& feedback) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 648 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Harald Alvestrand | fb62f90 | 2024-11-19 12:11:47 | [diff] [blame] | 649 | ++transport_cc_feedback_count_; |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 650 | feedback_demuxer_.OnTransportFeedback(feedback); |
Florent Castelli | 8037fc6 | 2024-08-29 13:00:40 | [diff] [blame] | 651 | std::optional<TransportPacketsFeedback> feedback_msg = |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 652 | transport_feedback_adapter_.ProcessTransportFeedback(feedback, |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 653 | receive_time); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 654 | if (feedback_msg) { |
Per Kjellander | 7768667 | 2024-12-19 07:58:06 | [diff] [blame] | 655 | HandleTransportPacketsFeedback(*feedback_msg); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 656 | } |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 657 | } |
| 658 | |
Per K | 1d2f85d | 2024-10-23 12:11:41 | [diff] [blame] | 659 | void RtpTransportControllerSend::OnCongestionControlFeedback( |
| 660 | Timestamp receive_time, |
| 661 | const rtcp::CongestionControlFeedback& feedback) { |
| 662 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Harald Alvestrand | 0c6d319 | 2024-11-13 11:54:41 | [diff] [blame] | 663 | ++feedback_count_; |
Per K | 1d2f85d | 2024-10-23 12:11:41 | [diff] [blame] | 664 | // 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 Kjellander | 7768667 | 2024-12-19 07:58:06 | [diff] [blame] | 671 | HandleTransportPacketsFeedback(*feedback_msg); |
Per K | 1d2f85d | 2024-10-23 12:11:41 | [diff] [blame] | 672 | } |
| 673 | } |
| 674 | |
Per Kjellander | 7768667 | 2024-12-19 07:58:06 | [diff] [blame] | 675 | void 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 Jansson | e1795f4 | 2019-07-24 09:38:03 | [diff] [blame] | 694 | void RtpTransportControllerSend::OnRemoteNetworkEstimate( |
| 695 | NetworkStateEstimate estimate) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 696 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 697 | estimate.update_time = Timestamp::Millis(env_.clock().TimeInMilliseconds()); |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 698 | if (controller_) |
| 699 | PostUpdates(controller_->OnNetworkStateEstimate(estimate)); |
Sebastian Jansson | e1795f4 | 2019-07-24 09:38:03 | [diff] [blame] | 700 | } |
| 701 | |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 702 | void RtpTransportControllerSend::MaybeCreateControllers() { |
| 703 | RTC_DCHECK(!controller_); |
| 704 | RTC_DCHECK(!control_handler_); |
| 705 | |
| 706 | if (!network_available_ || !observer_) |
| 707 | return; |
Mirko Bonadei | 317a1f0 | 2019-09-17 15:06:18 | [diff] [blame] | 708 | control_handler_ = std::make_unique<CongestionControlHandler>(); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 709 | |
| 710 | initial_config_.constraints.at_time = |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 711 | Timestamp::Millis(env_.clock().TimeInMilliseconds()); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 712 | 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 K | 39ac25d | 2024-02-07 13:16:20 | [diff] [blame] | 728 | void 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 Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 740 | void 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 | |
| 748 | void RtpTransportControllerSend::StartProcessPeriodicTasks() { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 749 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Sebastian Jansson | ecb6897 | 2019-01-18 09:30:54 | [diff] [blame] | 750 | if (!pacer_queue_update_task_.Running()) { |
| 751 | pacer_queue_update_task_ = RepeatingTaskHandle::DelayedStart( |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 752 | task_queue_, kPacerQueueUpdateInterval, [this]() { |
| 753 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 754 | TimeDelta expected_queue_time = pacer_.ExpectedQueueTime(); |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 755 | control_handler_->SetPacerQueue(expected_queue_time); |
| 756 | UpdateControlState(); |
Sebastian Jansson | ecb6897 | 2019-01-18 09:30:54 | [diff] [blame] | 757 | return kPacerQueueUpdateInterval; |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 758 | }); |
| 759 | } |
Sebastian Jansson | ecb6897 | 2019-01-18 09:30:54 | [diff] [blame] | 760 | controller_task_.Stop(); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 761 | if (process_interval_.IsFinite()) { |
Sebastian Jansson | ecb6897 | 2019-01-18 09:30:54 | [diff] [blame] | 762 | controller_task_ = RepeatingTaskHandle::DelayedStart( |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 763 | task_queue_, process_interval_, [this]() { |
| 764 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 765 | UpdateControllerWithTimeInterval(); |
Sebastian Jansson | ecb6897 | 2019-01-18 09:30:54 | [diff] [blame] | 766 | return process_interval_; |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 767 | }); |
| 768 | } |
| 769 | } |
| 770 | |
| 771 | void RtpTransportControllerSend::UpdateControllerWithTimeInterval() { |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 772 | RTC_DCHECK(controller_); |
| 773 | ProcessInterval msg; |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 774 | msg.at_time = Timestamp::Millis(env_.clock().TimeInMilliseconds()); |
Christoffer Rodbro | c610e26 | 2019-01-08 09:49:19 | [diff] [blame] | 775 | if (add_pacing_to_cwin_) |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 776 | msg.pacer_queue = pacer_.QueueSizeData(); |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 777 | PostUpdates(controller_->OnProcessInterval(msg)); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 778 | } |
| 779 | |
| 780 | void RtpTransportControllerSend::UpdateStreamsConfig() { |
Danil Chapovalov | ee27f38 | 2023-12-18 12:09:12 | [diff] [blame] | 781 | streams_config_.at_time = |
| 782 | Timestamp::Millis(env_.clock().TimeInMilliseconds()); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 783 | if (controller_) |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 784 | PostUpdates(controller_->OnStreamsConfig(streams_config_)); |
| 785 | } |
| 786 | |
| 787 | void RtpTransportControllerSend::PostUpdates(NetworkControlUpdate update) { |
| 788 | if (update.congestion_window) { |
Erik Språng | 6673437 | 2022-03-16 13:20:49 | [diff] [blame] | 789 | congestion_window_size_ = *update.congestion_window; |
| 790 | UpdateCongestedState(); |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 791 | } |
| 792 | if (update.pacer_config) { |
Erik Språng | f3f3a61 | 2022-05-13 13:55:29 | [diff] [blame] | 793 | pacer_.SetPacingRates(update.pacer_config->data_rate(), |
| 794 | update.pacer_config->pad_rate()); |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 795 | } |
Per Kjellander | 88af203 | 2022-05-16 17:58:40 | [diff] [blame] | 796 | if (!update.probe_cluster_configs.empty()) { |
| 797 | pacer_.CreateProbeClusters(std::move(update.probe_cluster_configs)); |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 798 | } |
| 799 | if (update.target_rate) { |
| 800 | control_handler_->SetTargetRate(*update.target_rate); |
| 801 | UpdateControlState(); |
| 802 | } |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 803 | } |
| 804 | |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 805 | void RtpTransportControllerSend::OnReport( |
| 806 | Timestamp receive_time, |
| 807 | rtc::ArrayView<const ReportBlockData> report_blocks) { |
Per K | 37879e9 | 2023-04-13 06:59:19 | [diff] [blame] | 808 | RTC_DCHECK_RUN_ON(&sequence_checker_); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 809 | 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 Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 816 | for (const ReportBlockData& report_block : report_blocks) { |
Danil Chapovalov | 121f1e7 | 2023-05-15 07:28:02 | [diff] [blame] | 817 | auto [it, inserted] = |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 818 | last_report_blocks_.try_emplace(report_block.source_ssrc()); |
Danil Chapovalov | 121f1e7 | 2023-05-15 07:28:02 | [diff] [blame] | 819 | LossReport& last_loss_report = it->second; |
| 820 | if (!inserted) { |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 821 | total_packets_delta += report_block.extended_highest_sequence_number() - |
Danil Chapovalov | 121f1e7 | 2023-05-15 07:28:02 | [diff] [blame] | 822 | last_loss_report.extended_highest_sequence_number; |
| 823 | total_packets_lost_delta += |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 824 | report_block.cumulative_lost() - last_loss_report.cumulative_lost; |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 825 | } |
Danil Chapovalov | 121f1e7 | 2023-05-15 07:28:02 | [diff] [blame] | 826 | last_loss_report.extended_highest_sequence_number = |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 827 | report_block.extended_highest_sequence_number(); |
| 828 | last_loss_report.cumulative_lost = report_block.cumulative_lost(); |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 829 | } |
| 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 Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 841 | TransportLossReport msg; |
| 842 | msg.packets_lost_delta = total_packets_lost_delta; |
| 843 | msg.packets_received_delta = packets_received_delta; |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 844 | msg.receive_time = receive_time; |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 845 | msg.start_time = last_report_block_time_; |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 846 | msg.end_time = receive_time; |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 847 | if (controller_) |
Sebastian Jansson | 1618095 | 2018-12-12 15:49:10 | [diff] [blame] | 848 | PostUpdates(controller_->OnTransportLossReport(msg)); |
Danil Chapovalov | 3e39254 | 2023-05-17 11:25:39 | [diff] [blame] | 849 | last_report_block_time_ = receive_time; |
Sebastian Jansson | 87609be | 2018-12-05 16:35:35 | [diff] [blame] | 850 | } |
| 851 | |
nisse | cae45d0 | 2017-04-24 12:53:20 | [diff] [blame] | 852 | } // namespace webrtc |