blob: fb684ca014a890a41e6090529f007d5028be88bd [file] [log] [blame]
nissecae45d02017-04-24 05:53:20 -07001/*
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 19:08:33 +020010#include "call/rtp_transport_controller_send.h"
11
Mirko Bonadei317a1f02019-09-17 17:06:18 +020012#include <memory>
Sebastian Jansson91bb6672018-02-21 13:02:51 +010013#include <utility>
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020014#include <vector>
nissecae45d02017-04-24 05:53:20 -070015
Yves Gerey3e707812018-11-28 16:47:49 +010016#include "absl/types/optional.h"
Sebastian Jansson87609be2018-12-05 17:35:35 +010017#include "api/transport/goog_cc_factory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "api/transport/network_types.h"
19#include "api/units/data_rate.h"
20#include "api/units/time_delta.h"
21#include "api/units/timestamp.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "call/rtp_video_sender.h"
Sebastian Jansson0a5ed892019-09-18 15:37:31 +020023#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
Sebastian Jansson166b45d2019-05-13 11:57:42 +020024#include "logging/rtc_event_log/events/rtc_event_route_change.h"
Sebastian Jansson658f1812020-01-16 10:59:28 +010025#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
Yves Gerey3e707812018-11-28 16:47:49 +010026#include "rtc_base/checks.h"
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010027#include "rtc_base/logging.h"
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020028#include "rtc_base/rate_limiter.h"
nissecae45d02017-04-24 05:53:20 -070029
30namespace webrtc {
Sebastian Jansson19bea512018-03-13 19:07:46 +010031namespace {
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020032static const int64_t kRetransmitWindowSizeMs = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +020033static const size_t kMaxOverheadBytes = 500;
Sebastian Jansson19bea512018-03-13 19:07:46 +010034
Danil Chapovalov0c626af2020-02-10 11:16:00 +010035constexpr TimeDelta kPacerQueueUpdateInterval = TimeDelta::Millis(25);
Sebastian Jansson87609be2018-12-05 17:35:35 +010036
37TargetRateConstraints ConvertConstraints(int min_bitrate_bps,
38 int max_bitrate_bps,
39 int start_bitrate_bps,
Sebastian Janssonaa01f272019-01-30 11:28:59 +010040 Clock* clock) {
Sebastian Jansson87609be2018-12-05 17:35:35 +010041 TargetRateConstraints msg;
Danil Chapovalov0c626af2020-02-10 11:16:00 +010042 msg.at_time = Timestamp::Millis(clock->TimeInMilliseconds());
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +010043 msg.min_data_rate = min_bitrate_bps >= 0
44 ? DataRate::BitsPerSec(min_bitrate_bps)
45 : DataRate::Zero();
46 msg.max_data_rate = max_bitrate_bps > 0
47 ? DataRate::BitsPerSec(max_bitrate_bps)
48 : DataRate::Infinity();
Sebastian Jansson87609be2018-12-05 17:35:35 +010049 if (start_bitrate_bps > 0)
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +010050 msg.starting_rate = DataRate::BitsPerSec(start_bitrate_bps);
Sebastian Jansson87609be2018-12-05 17:35:35 +010051 return msg;
52}
53
54TargetRateConstraints ConvertConstraints(const BitrateConstraints& contraints,
Sebastian Janssonaa01f272019-01-30 11:28:59 +010055 Clock* clock) {
Sebastian Jansson87609be2018-12-05 17:35:35 +010056 return ConvertConstraints(contraints.min_bitrate_bps,
57 contraints.max_bitrate_bps,
58 contraints.start_bitrate_bps, clock);
59}
Erik Språng662678d2019-11-15 17:18:52 +010060
61bool IsEnabled(const WebRtcKeyValueConfig* trials, absl::string_view key) {
Erik Språng014dd3c2019-11-28 13:44:25 +010062 RTC_DCHECK(trials != nullptr);
63 return trials->Lookup(key).find("Enabled") == 0;
Erik Språng662678d2019-11-15 17:18:52 +010064}
65
Sebastian Jansson19bea512018-03-13 19:07:46 +010066} // namespace
nissecae45d02017-04-24 05:53:20 -070067
68RtpTransportControllerSend::RtpTransportControllerSend(
69 Clock* clock,
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010070 webrtc::RtcEventLog* event_log,
Ying Wang0810a7c2019-04-10 13:48:24 +020071 NetworkStatePredictorFactoryInterface* predictor_factory,
Sebastian Janssondfce03a2018-05-18 18:05:10 +020072 NetworkControllerFactoryInterface* controller_factory,
Sebastian Janssoned50e6c2019-03-01 14:45:21 +010073 const BitrateConstraints& bitrate_config,
74 std::unique_ptr<ProcessThread> process_thread,
Erik Språng662678d2019-11-15 17:18:52 +010075 TaskQueueFactory* task_queue_factory,
76 const WebRtcKeyValueConfig* trials)
Sebastian Jansson19704ec2018-03-12 15:59:12 +010077 : clock_(clock),
Sebastian Jansson166b45d2019-05-13 11:57:42 +020078 event_log_(event_log),
Sebastian Jansson317a5222018-03-16 15:36:37 +010079 bitrate_configurator_(bitrate_config),
Sebastian Janssoned50e6c2019-03-01 14:45:21 +010080 process_thread_(std::move(process_thread)),
Erik Språng014dd3c2019-11-28 13:44:25 +010081 use_task_queue_pacer_(IsEnabled(trials, "WebRTC-TaskQueuePacer")),
Erik Språng4314a492019-11-26 17:48:49 +010082 process_thread_pacer_(use_task_queue_pacer_
83 ? nullptr
84 : new PacedSender(clock,
85 &packet_router_,
86 event_log,
Erik Språng014dd3c2019-11-28 13:44:25 +010087 trials,
Erik Språng4314a492019-11-26 17:48:49 +010088 process_thread_.get())),
89 task_queue_pacer_(use_task_queue_pacer_
90 ? new TaskQueuePacedSender(clock,
91 &packet_router_,
92 event_log,
Erik Språng014dd3c2019-11-28 13:44:25 +010093 trials,
Erik Språng4314a492019-11-26 17:48:49 +010094 task_queue_factory)
95 : nullptr),
Sebastian Jansson317a5222018-03-16 15:36:37 +010096 observer_(nullptr),
Sebastian Jansson87609be2018-12-05 17:35:35 +010097 controller_factory_override_(controller_factory),
98 controller_factory_fallback_(
Mirko Bonadei317a1f02019-09-17 17:06:18 +020099 std::make_unique<GoogCcNetworkControllerFactory>(predictor_factory)),
Sebastian Jansson87609be2018-12-05 17:35:35 +0100100 process_interval_(controller_factory_fallback_->GetProcessInterval()),
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100101 last_report_block_time_(Timestamp::Millis(clock_->TimeInMilliseconds())),
Sebastian Jansson87609be2018-12-05 17:35:35 +0100102 reset_feedback_on_route_change_(
Erik Språng014dd3c2019-11-28 13:44:25 +0100103 !IsEnabled(trials, "WebRTC-Bwe-NoFeedbackReset")),
Sebastian Jansson87609be2018-12-05 17:35:35 +0100104 send_side_bwe_with_overhead_(
Erik Språng014dd3c2019-11-28 13:44:25 +0100105 IsEnabled(trials, "WebRTC-SendSideBwe-WithOverhead")),
Christoffer Rodbroc610e262019-01-08 10:49:19 +0100106 add_pacing_to_cwin_(
Erik Språng014dd3c2019-11-28 13:44:25 +0100107 IsEnabled(trials, "WebRTC-AddPacingToCongestionWindowPushback")),
Sebastian Jansson87609be2018-12-05 17:35:35 +0100108 transport_overhead_bytes_per_packet_(0),
109 network_available_(false),
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200110 retransmission_rate_limiter_(clock, kRetransmitWindowSizeMs),
Sebastian Janssoned50e6c2019-03-01 14:45:21 +0100111 task_queue_(task_queue_factory->CreateTaskQueue(
112 "rtp_send_controller",
113 TaskQueueFactory::Priority::NORMAL)) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100114 initial_config_.constraints = ConvertConstraints(bitrate_config, clock_);
Sebastian Janssondf88cc02019-04-15 15:42:25 +0200115 initial_config_.event_log = event_log;
Erik Språng014dd3c2019-11-28 13:44:25 +0100116 initial_config_.key_value_config = trials;
Sebastian Jansson87609be2018-12-05 17:35:35 +0100117 RTC_DCHECK(bitrate_config.start_bitrate_bps > 0);
118
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +0100119 pacer()->SetPacingRates(
120 DataRate::BitsPerSec(bitrate_config.start_bitrate_bps), DataRate::Zero());
Sebastian Janssonbd9fe092018-05-07 16:33:50 +0200121
Erik Språng4314a492019-11-26 17:48:49 +0100122 if (!use_task_queue_pacer_) {
123 process_thread_->Start();
124 }
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100125}
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +0100126
127RtpTransportControllerSend::~RtpTransportControllerSend() {
Erik Språng4314a492019-11-26 17:48:49 +0100128 if (!use_task_queue_pacer_) {
129 process_thread_->Stop();
130 }
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +0100131}
nissecae45d02017-04-24 05:53:20 -0700132
Stefan Holmer9416ef82018-07-19 10:34:38 +0200133RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender(
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200134 std::map<uint32_t, RtpState> suspended_ssrcs,
135 const std::map<uint32_t, RtpPayloadState>& states,
136 const RtpConfig& rtp_config,
Jiawei Ou55718122018-11-09 13:17:39 -0800137 int rtcp_report_interval_ms,
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200138 Transport* send_transport,
139 const RtpSenderObservers& observers,
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200140 RtcEventLog* event_log,
Benjamin Wright192eeec2018-10-17 17:27:25 -0700141 std::unique_ptr<FecController> fec_controller,
Marina Cioceae77912b2020-02-27 16:16:55 +0100142 const RtpSenderFrameEncryptionConfig& frame_encryption_config,
143 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200144 video_rtp_senders_.push_back(std::make_unique<RtpVideoSender>(
Sebastian Jansson572c60f2019-03-04 18:30:41 +0100145 clock_, suspended_ssrcs, states, rtp_config, rtcp_report_interval_ms,
Oleh Prypine8964902019-03-29 15:33:01 +0000146 send_transport, observers,
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200147 // TODO(holmer): Remove this circular dependency by injecting
148 // the parts of RtpTransportControllerSendInterface that are really used.
Benjamin Wright192eeec2018-10-17 17:27:25 -0700149 this, event_log, &retransmission_rate_limiter_, std::move(fec_controller),
150 frame_encryption_config.frame_encryptor,
Marina Cioceae77912b2020-02-27 16:16:55 +0100151 frame_encryption_config.crypto_options, std::move(frame_transformer)));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200152 return video_rtp_senders_.back().get();
153}
154
Stefan Holmer9416ef82018-07-19 10:34:38 +0200155void RtpTransportControllerSend::DestroyRtpVideoSender(
156 RtpVideoSenderInterface* rtp_video_sender) {
157 std::vector<std::unique_ptr<RtpVideoSenderInterface>>::iterator it =
Stefan Holmer5ed25af2018-07-18 15:17:14 +0200158 video_rtp_senders_.end();
159 for (it = video_rtp_senders_.begin(); it != video_rtp_senders_.end(); ++it) {
160 if (it->get() == rtp_video_sender) {
161 break;
162 }
163 }
164 RTC_DCHECK(it != video_rtp_senders_.end());
165 video_rtp_senders_.erase(it);
166}
167
Sebastian Jansson16180952018-12-12 16:49:10 +0100168void RtpTransportControllerSend::UpdateControlState() {
169 absl::optional<TargetTransferRate> update = control_handler_->GetUpdate();
170 if (!update)
171 return;
Sebastian Janssonf34116e2019-09-24 17:55:50 +0200172 retransmission_rate_limiter_.SetMaxRate(update->target_rate.bps());
Sebastian Jansson16180952018-12-12 16:49:10 +0100173 // We won't create control_handler_ until we have an observers.
Sebastian Jansson87609be2018-12-05 17:35:35 +0100174 RTC_DCHECK(observer_ != nullptr);
Sebastian Jansson16180952018-12-12 16:49:10 +0100175 observer_->OnTargetTransferRate(*update);
Sebastian Janssone6256052018-05-04 14:08:15 +0200176}
177
Erik Språng425d6aa2019-07-29 16:38:27 +0200178RtpPacketPacer* RtpTransportControllerSend::pacer() {
Erik Språng4314a492019-11-26 17:48:49 +0100179 if (use_task_queue_pacer_) {
180 return task_queue_pacer_.get();
181 }
182 return process_thread_pacer_.get();
Erik Språng425d6aa2019-07-29 16:38:27 +0200183}
184
185const RtpPacketPacer* RtpTransportControllerSend::pacer() const {
Erik Språng4314a492019-11-26 17:48:49 +0100186 if (use_task_queue_pacer_) {
187 return task_queue_pacer_.get();
188 }
189 return process_thread_pacer_.get();
Erik Språng425d6aa2019-07-29 16:38:27 +0200190}
191
Sebastian Janssone6256052018-05-04 14:08:15 +0200192rtc::TaskQueue* RtpTransportControllerSend::GetWorkerQueue() {
193 return &task_queue_;
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100194}
195
nisse76e62b02017-05-31 02:24:52 -0700196PacketRouter* RtpTransportControllerSend::packet_router() {
197 return &packet_router_;
198}
199
Sebastian Janssone1795f42019-07-24 11:38:03 +0200200NetworkStateEstimateObserver*
201RtpTransportControllerSend::network_state_estimate_observer() {
202 return this;
203}
204
nisse76e62b02017-05-31 02:24:52 -0700205TransportFeedbackObserver*
206RtpTransportControllerSend::transport_feedback_observer() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100207 return this;
nisse76e62b02017-05-31 02:24:52 -0700208}
209
Erik Språngaa59eca2019-07-24 14:52:55 +0200210RtpPacketSender* RtpTransportControllerSend::packet_sender() {
Erik Språng4314a492019-11-26 17:48:49 +0100211 if (use_task_queue_pacer_) {
212 return task_queue_pacer_.get();
213 }
214 return process_thread_pacer_.get();
nisse76e62b02017-05-31 02:24:52 -0700215}
216
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200217void RtpTransportControllerSend::SetAllocatedSendBitrateLimits(
Sebastian Jansson93b1ea22019-09-18 18:31:52 +0200218 BitrateAllocationLimits limits) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100219 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson93b1ea22019-09-18 18:31:52 +0200220 streams_config_.min_total_allocated_bitrate = limits.min_allocatable_rate;
221 streams_config_.max_padding_rate = limits.max_padding_rate;
222 streams_config_.max_total_allocated_bitrate = limits.max_allocatable_rate;
Sebastian Jansson87609be2018-12-05 17:35:35 +0100223 UpdateStreamsConfig();
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200224}
Sebastian Jansson4c1ffb82018-02-15 16:51:58 +0100225void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100226 RTC_DCHECK_RUN_ON(&task_queue_);
227 streams_config_.pacing_factor = pacing_factor;
228 UpdateStreamsConfig();
Sebastian Jansson4c1ffb82018-02-15 16:51:58 +0100229}
230void RtpTransportControllerSend::SetQueueTimeLimit(int limit_ms) {
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100231 pacer()->SetQueueTimeLimit(TimeDelta::Millis(limit_ms));
Sebastian Jansson4c1ffb82018-02-15 16:51:58 +0100232}
Sebastian Janssonf2988552019-10-29 17:18:51 +0100233StreamFeedbackProvider*
234RtpTransportControllerSend::GetStreamFeedbackProvider() {
JT Tehea992f82020-01-15 18:24:20 +0000235 return &feedback_demuxer_;
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100236}
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100237
238void RtpTransportControllerSend::RegisterTargetTransferRateObserver(
239 TargetTransferRateObserver* observer) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100240 task_queue_.PostTask([this, observer] {
241 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100242 RTC_DCHECK(observer_ == nullptr);
243 observer_ = observer;
Sebastian Jansson2701bc92018-12-11 15:02:47 +0100244 observer_->OnStartRateUpdate(*initial_config_.constraints.starting_rate);
Sebastian Jansson87609be2018-12-05 17:35:35 +0100245 MaybeCreateControllers();
246 });
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100247}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100248void RtpTransportControllerSend::OnNetworkRouteChanged(
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100249 const std::string& transport_name,
250 const rtc::NetworkRoute& network_route) {
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100251 // Check if the network route is connected.
252 if (!network_route.connected) {
253 RTC_LOG(LS_INFO) << "Transport " << transport_name << " is disconnected";
254 // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and
255 // consider merging these two methods.
256 return;
257 }
258
259 // Check whether the network route has changed on each transport.
260 auto result =
261 network_routes_.insert(std::make_pair(transport_name, network_route));
262 auto kv = result.first;
263 bool inserted = result.second;
264 if (inserted) {
Jakob Ivarssonb4cdd622020-02-13 14:01:26 +0100265 task_queue_.PostTask([this, network_route] {
266 RTC_DCHECK_RUN_ON(&task_queue_);
267 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
268 });
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100269 // No need to reset BWE if this is the first time the network connects.
270 return;
271 }
Sebastian Janssonaf2adda2018-12-04 11:16:19 +0100272 if (kv->second.connected != network_route.connected ||
273 kv->second.local_network_id != network_route.local_network_id ||
274 kv->second.remote_network_id != network_route.remote_network_id) {
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100275 kv->second = network_route;
276 BitrateConstraints bitrate_config = bitrate_configurator_.GetConfig();
277 RTC_LOG(LS_INFO) << "Network route changed on transport " << transport_name
278 << ": new local network id "
279 << network_route.local_network_id
280 << " new remote network id "
281 << network_route.remote_network_id
282 << " Reset bitrates to min: "
283 << bitrate_config.min_bitrate_bps
284 << " bps, start: " << bitrate_config.start_bitrate_bps
285 << " bps, max: " << bitrate_config.max_bitrate_bps
286 << " bps.";
287 RTC_DCHECK_GT(bitrate_config.start_bitrate_bps, 0);
Sebastian Jansson87609be2018-12-05 17:35:35 +0100288
Sebastian Jansson166b45d2019-05-13 11:57:42 +0200289 if (event_log_) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200290 event_log_->Log(std::make_unique<RtcEventRouteChange>(
Sebastian Jansson166b45d2019-05-13 11:57:42 +0200291 network_route.connected, network_route.packet_overhead));
292 }
Sebastian Jansson87609be2018-12-05 17:35:35 +0100293 NetworkRouteChange msg;
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100294 msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 17:35:35 +0100295 msg.constraints = ConvertConstraints(bitrate_config, clock_);
Sebastian Jansson658f1812020-01-16 10:59:28 +0100296 task_queue_.PostTask([this, msg, network_route] {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100297 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson658f1812020-01-16 10:59:28 +0100298 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
299 if (reset_feedback_on_route_change_) {
300 transport_feedback_adapter_.SetNetworkIds(
301 network_route.local_network_id, network_route.remote_network_id);
302 }
Sebastian Jansson87609be2018-12-05 17:35:35 +0100303 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100304 PostUpdates(controller_->OnNetworkRouteChange(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100305 } else {
306 UpdateInitialConstraints(msg.constraints);
307 }
Erik Språng425d6aa2019-07-29 16:38:27 +0200308 pacer()->UpdateOutstandingData(DataSize::Zero());
Sebastian Jansson87609be2018-12-05 17:35:35 +0100309 });
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100310 }
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100311}
312void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
Harald Alvestrand977b2652019-12-12 13:40:50 +0100313 RTC_LOG(LS_VERBOSE) << "SignalNetworkState "
314 << (network_available ? "Up" : "Down");
Sebastian Jansson87609be2018-12-05 17:35:35 +0100315 NetworkAvailability msg;
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100316 msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 17:35:35 +0100317 msg.network_available = network_available;
318 task_queue_.PostTask([this, msg]() {
319 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson16180952018-12-12 16:49:10 +0100320 if (network_available_ == msg.network_available)
321 return;
Sebastian Jansson87609be2018-12-05 17:35:35 +0100322 network_available_ = msg.network_available;
Sebastian Jansson16180952018-12-12 16:49:10 +0100323 if (network_available_) {
Erik Språng425d6aa2019-07-29 16:38:27 +0200324 pacer()->Resume();
Sebastian Jansson16180952018-12-12 16:49:10 +0100325 } else {
Erik Språng425d6aa2019-07-29 16:38:27 +0200326 pacer()->Pause();
Sebastian Jansson16180952018-12-12 16:49:10 +0100327 }
Erik Språng425d6aa2019-07-29 16:38:27 +0200328 pacer()->UpdateOutstandingData(DataSize::Zero());
Sebastian Jansson16180952018-12-12 16:49:10 +0100329
Sebastian Jansson87609be2018-12-05 17:35:35 +0100330 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100331 control_handler_->SetNetworkAvailability(network_available_);
332 PostUpdates(controller_->OnNetworkAvailability(msg));
333 UpdateControlState();
Sebastian Jansson87609be2018-12-05 17:35:35 +0100334 } else {
335 MaybeCreateControllers();
336 }
337 });
338
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200339 for (auto& rtp_sender : video_rtp_senders_) {
340 rtp_sender->OnNetworkAvailability(network_available);
341 }
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100342}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100343RtcpBandwidthObserver* RtpTransportControllerSend::GetBandwidthObserver() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100344 return this;
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100345}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100346int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const {
Erik Språng425d6aa2019-07-29 16:38:27 +0200347 return pacer()->OldestPacketWaitTime().ms();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100348}
Erik Språng425d6aa2019-07-29 16:38:27 +0200349absl::optional<Timestamp> RtpTransportControllerSend::GetFirstPacketTime()
350 const {
351 return pacer()->FirstSentPacketTime();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100352}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100353void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100354 task_queue_.PostTask([this, enable]() {
355 RTC_DCHECK_RUN_ON(&task_queue_);
356 streams_config_.requests_alr_probing = enable;
357 UpdateStreamsConfig();
358 });
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100359}
360void RtpTransportControllerSend::OnSentPacket(
361 const rtc::SentPacket& sent_packet) {
Sebastian Jansson658f1812020-01-16 10:59:28 +0100362 task_queue_.PostTask([this, sent_packet]() {
363 RTC_DCHECK_RUN_ON(&task_queue_);
364 absl::optional<SentPacket> packet_msg =
365 transport_feedback_adapter_.ProcessSentPacket(sent_packet);
366 pacer()->UpdateOutstandingData(
367 transport_feedback_adapter_.GetOutstandingData());
368 if (packet_msg && controller_)
369 PostUpdates(controller_->OnSentPacket(*packet_msg));
370 });
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100371}
sprangdb2a9fc2017-08-09 06:42:32 -0700372
Ying Wang8b279102019-05-27 17:19:08 +0200373void RtpTransportControllerSend::OnReceivedPacket(
Sebastian Jansson607a6f12019-06-13 17:48:53 +0200374 const ReceivedPacket& packet_msg) {
Ying Wang8b279102019-05-27 17:19:08 +0200375 task_queue_.PostTask([this, packet_msg]() {
376 RTC_DCHECK_RUN_ON(&task_queue_);
377 if (controller_)
378 PostUpdates(controller_->OnReceivedPacket(packet_msg));
379 });
380}
381
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100382void RtpTransportControllerSend::SetSdpBitrateParameters(
383 const BitrateConstraints& constraints) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200384 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100385 bitrate_configurator_.UpdateWithSdpParameters(constraints);
386 if (updated.has_value()) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100387 TargetRateConstraints msg = ConvertConstraints(*updated, clock_);
388 task_queue_.PostTask([this, msg]() {
389 RTC_DCHECK_RUN_ON(&task_queue_);
390 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100391 PostUpdates(controller_->OnTargetRateConstraints(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100392 } else {
393 UpdateInitialConstraints(msg);
394 }
395 });
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100396 } else {
397 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100398 << "WebRTC.RtpTransportControllerSend.SetSdpBitrateParameters: "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100399 "nothing to update";
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100400 }
401}
402
403void RtpTransportControllerSend::SetClientBitratePreferences(
Niels Möller0c4f7be2018-05-07 14:01:37 +0200404 const BitrateSettings& preferences) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200405 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100406 bitrate_configurator_.UpdateWithClientPreferences(preferences);
407 if (updated.has_value()) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100408 TargetRateConstraints msg = ConvertConstraints(*updated, clock_);
409 task_queue_.PostTask([this, msg]() {
410 RTC_DCHECK_RUN_ON(&task_queue_);
411 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100412 PostUpdates(controller_->OnTargetRateConstraints(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100413 } else {
414 UpdateInitialConstraints(msg);
415 }
416 });
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100417 } else {
418 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100419 << "WebRTC.RtpTransportControllerSend.SetClientBitratePreferences: "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100420 "nothing to update";
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100421 }
422}
Alex Narestbcf91802018-06-25 16:08:36 +0200423
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200424void RtpTransportControllerSend::OnTransportOverheadChanged(
425 size_t transport_overhead_bytes_per_packet) {
426 if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) {
427 RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes;
428 return;
429 }
430
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000431 pacer()->SetTransportOverhead(
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +0100432 DataSize::Bytes(transport_overhead_bytes_per_packet));
Mirko Bonadeie7bc3a32020-01-29 18:45:00 +0000433
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200434 // TODO(holmer): Call AudioRtpSenders when they have been moved to
435 // RtpTransportControllerSend.
436 for (auto& rtp_video_sender : video_rtp_senders_) {
437 rtp_video_sender->OnTransportOverheadChanged(
438 transport_overhead_bytes_per_packet);
439 }
440}
Sebastian Jansson87609be2018-12-05 17:35:35 +0100441
Erik Språngaa59eca2019-07-24 14:52:55 +0200442void RtpTransportControllerSend::AccountForAudioPacketsInPacedSender(
443 bool account_for_audio) {
Erik Språng425d6aa2019-07-29 16:38:27 +0200444 pacer()->SetAccountForAudioPackets(account_for_audio);
Erik Språngaa59eca2019-07-24 14:52:55 +0200445}
446
Sebastian Janssonc3eb9fd2020-01-29 17:42:52 +0100447void RtpTransportControllerSend::IncludeOverheadInPacedSender() {
448 pacer()->SetIncludeOverhead();
449}
450
Sebastian Jansson87609be2018-12-05 17:35:35 +0100451void RtpTransportControllerSend::OnReceivedEstimatedBitrate(uint32_t bitrate) {
452 RemoteBitrateReport msg;
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100453 msg.receive_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Danil Chapovalovcad3e0e2020-02-17 18:46:07 +0100454 msg.bandwidth = DataRate::BitsPerSec(bitrate);
Sebastian Jansson87609be2018-12-05 17:35:35 +0100455 task_queue_.PostTask([this, msg]() {
456 RTC_DCHECK_RUN_ON(&task_queue_);
457 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100458 PostUpdates(controller_->OnRemoteBitrateReport(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100459 });
460}
461
462void RtpTransportControllerSend::OnReceivedRtcpReceiverReport(
463 const ReportBlockList& report_blocks,
464 int64_t rtt_ms,
465 int64_t now_ms) {
466 task_queue_.PostTask([this, report_blocks, now_ms]() {
467 RTC_DCHECK_RUN_ON(&task_queue_);
468 OnReceivedRtcpReceiverReportBlocks(report_blocks, now_ms);
469 });
470
471 task_queue_.PostTask([this, now_ms, rtt_ms]() {
472 RTC_DCHECK_RUN_ON(&task_queue_);
473 RoundTripTimeUpdate report;
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100474 report.receive_time = Timestamp::Millis(now_ms);
475 report.round_trip_time = TimeDelta::Millis(rtt_ms);
Sebastian Jansson87609be2018-12-05 17:35:35 +0100476 report.smoothed = false;
Christoffer Rodbro4bd31772019-03-27 12:34:21 +0100477 if (controller_ && !report.round_trip_time.IsZero())
Sebastian Jansson16180952018-12-12 16:49:10 +0100478 PostUpdates(controller_->OnRoundTripTimeUpdate(report));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100479 });
480}
481
Erik Språng30a276b2019-04-23 12:00:11 +0200482void RtpTransportControllerSend::OnAddPacket(
483 const RtpPacketSendInfo& packet_info) {
JT Tehea992f82020-01-15 18:24:20 +0000484 feedback_demuxer_.AddPacket(packet_info);
485
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100486 Timestamp creation_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson658f1812020-01-16 10:59:28 +0100487 task_queue_.PostTask([this, packet_info, creation_time]() {
488 RTC_DCHECK_RUN_ON(&task_queue_);
489 transport_feedback_adapter_.AddPacket(
490 packet_info,
491 send_side_bwe_with_overhead_ ? transport_overhead_bytes_per_packet_ : 0,
492 creation_time);
493 });
Sebastian Jansson87609be2018-12-05 17:35:35 +0100494}
495
496void RtpTransportControllerSend::OnTransportFeedback(
497 const rtcp::TransportFeedback& feedback) {
JT Tehea992f82020-01-15 18:24:20 +0000498 feedback_demuxer_.OnTransportFeedback(feedback);
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100499 auto feedback_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson658f1812020-01-16 10:59:28 +0100500 task_queue_.PostTask([this, feedback, feedback_time]() {
501 RTC_DCHECK_RUN_ON(&task_queue_);
502 absl::optional<TransportPacketsFeedback> feedback_msg =
503 transport_feedback_adapter_.ProcessTransportFeedback(feedback,
504 feedback_time);
505 if (feedback_msg && controller_) {
506 PostUpdates(controller_->OnTransportPacketsFeedback(*feedback_msg));
507 }
508 pacer()->UpdateOutstandingData(
509 transport_feedback_adapter_.GetOutstandingData());
510 });
Sebastian Jansson87609be2018-12-05 17:35:35 +0100511}
512
Sebastian Janssone1795f42019-07-24 11:38:03 +0200513void RtpTransportControllerSend::OnRemoteNetworkEstimate(
514 NetworkStateEstimate estimate) {
Sebastian Jansson0a5ed892019-09-18 15:37:31 +0200515 if (event_log_) {
516 event_log_->Log(std::make_unique<RtcEventRemoteEstimate>(
517 estimate.link_capacity_lower, estimate.link_capacity_upper));
518 }
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100519 estimate.update_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Janssone1795f42019-07-24 11:38:03 +0200520 task_queue_.PostTask([this, estimate] {
521 RTC_DCHECK_RUN_ON(&task_queue_);
522 if (controller_)
Danil Chapovalove34fb872019-10-21 10:51:08 +0200523 PostUpdates(controller_->OnNetworkStateEstimate(estimate));
Sebastian Janssone1795f42019-07-24 11:38:03 +0200524 });
525}
526
Sebastian Jansson87609be2018-12-05 17:35:35 +0100527void RtpTransportControllerSend::MaybeCreateControllers() {
528 RTC_DCHECK(!controller_);
529 RTC_DCHECK(!control_handler_);
530
531 if (!network_available_ || !observer_)
532 return;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200533 control_handler_ = std::make_unique<CongestionControlHandler>();
Sebastian Jansson87609be2018-12-05 17:35:35 +0100534
535 initial_config_.constraints.at_time =
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100536 Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 17:35:35 +0100537 initial_config_.stream_based_config = streams_config_;
538
539 // TODO(srte): Use fallback controller if no feedback is available.
540 if (controller_factory_override_) {
541 RTC_LOG(LS_INFO) << "Creating overridden congestion controller";
542 controller_ = controller_factory_override_->Create(initial_config_);
543 process_interval_ = controller_factory_override_->GetProcessInterval();
544 } else {
545 RTC_LOG(LS_INFO) << "Creating fallback congestion controller";
546 controller_ = controller_factory_fallback_->Create(initial_config_);
547 process_interval_ = controller_factory_fallback_->GetProcessInterval();
548 }
549 UpdateControllerWithTimeInterval();
550 StartProcessPeriodicTasks();
551}
552
553void RtpTransportControllerSend::UpdateInitialConstraints(
554 TargetRateConstraints new_contraints) {
555 if (!new_contraints.starting_rate)
556 new_contraints.starting_rate = initial_config_.constraints.starting_rate;
557 RTC_DCHECK(new_contraints.starting_rate);
558 initial_config_.constraints = new_contraints;
559}
560
561void RtpTransportControllerSend::StartProcessPeriodicTasks() {
Sebastian Janssonecb68972019-01-18 10:30:54 +0100562 if (!pacer_queue_update_task_.Running()) {
563 pacer_queue_update_task_ = RepeatingTaskHandle::DelayedStart(
Danil Chapovalov4423c362019-03-06 18:41:39 +0100564 task_queue_.Get(), kPacerQueueUpdateInterval, [this]() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100565 RTC_DCHECK_RUN_ON(&task_queue_);
Erik Språng425d6aa2019-07-29 16:38:27 +0200566 TimeDelta expected_queue_time = pacer()->ExpectedQueueTime();
Sebastian Jansson16180952018-12-12 16:49:10 +0100567 control_handler_->SetPacerQueue(expected_queue_time);
568 UpdateControlState();
Sebastian Janssonecb68972019-01-18 10:30:54 +0100569 return kPacerQueueUpdateInterval;
Sebastian Jansson87609be2018-12-05 17:35:35 +0100570 });
571 }
Sebastian Janssonecb68972019-01-18 10:30:54 +0100572 controller_task_.Stop();
Sebastian Jansson87609be2018-12-05 17:35:35 +0100573 if (process_interval_.IsFinite()) {
Sebastian Janssonecb68972019-01-18 10:30:54 +0100574 controller_task_ = RepeatingTaskHandle::DelayedStart(
Danil Chapovalov4423c362019-03-06 18:41:39 +0100575 task_queue_.Get(), process_interval_, [this]() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100576 RTC_DCHECK_RUN_ON(&task_queue_);
577 UpdateControllerWithTimeInterval();
Sebastian Janssonecb68972019-01-18 10:30:54 +0100578 return process_interval_;
Sebastian Jansson87609be2018-12-05 17:35:35 +0100579 });
580 }
581}
582
583void RtpTransportControllerSend::UpdateControllerWithTimeInterval() {
Sebastian Jansson16180952018-12-12 16:49:10 +0100584 RTC_DCHECK(controller_);
585 ProcessInterval msg;
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100586 msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Christoffer Rodbroc610e262019-01-08 10:49:19 +0100587 if (add_pacing_to_cwin_)
Erik Språng425d6aa2019-07-29 16:38:27 +0200588 msg.pacer_queue = pacer()->QueueSizeData();
Sebastian Jansson16180952018-12-12 16:49:10 +0100589 PostUpdates(controller_->OnProcessInterval(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100590}
591
592void RtpTransportControllerSend::UpdateStreamsConfig() {
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100593 streams_config_.at_time = Timestamp::Millis(clock_->TimeInMilliseconds());
Sebastian Jansson87609be2018-12-05 17:35:35 +0100594 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100595 PostUpdates(controller_->OnStreamsConfig(streams_config_));
596}
597
598void RtpTransportControllerSend::PostUpdates(NetworkControlUpdate update) {
599 if (update.congestion_window) {
Erik Språng425d6aa2019-07-29 16:38:27 +0200600 pacer()->SetCongestionWindow(*update.congestion_window);
Sebastian Jansson16180952018-12-12 16:49:10 +0100601 }
602 if (update.pacer_config) {
Erik Språng425d6aa2019-07-29 16:38:27 +0200603 pacer()->SetPacingRates(update.pacer_config->data_rate(),
604 update.pacer_config->pad_rate());
Sebastian Jansson16180952018-12-12 16:49:10 +0100605 }
606 for (const auto& probe : update.probe_cluster_configs) {
Erik Språng425d6aa2019-07-29 16:38:27 +0200607 pacer()->CreateProbeCluster(probe.target_data_rate, probe.id);
Sebastian Jansson16180952018-12-12 16:49:10 +0100608 }
609 if (update.target_rate) {
610 control_handler_->SetTargetRate(*update.target_rate);
611 UpdateControlState();
612 }
Sebastian Jansson87609be2018-12-05 17:35:35 +0100613}
614
615void RtpTransportControllerSend::OnReceivedRtcpReceiverReportBlocks(
616 const ReportBlockList& report_blocks,
617 int64_t now_ms) {
618 if (report_blocks.empty())
619 return;
620
621 int total_packets_lost_delta = 0;
622 int total_packets_delta = 0;
623
624 // Compute the packet loss from all report blocks.
625 for (const RTCPReportBlock& report_block : report_blocks) {
626 auto it = last_report_blocks_.find(report_block.source_ssrc);
627 if (it != last_report_blocks_.end()) {
628 auto number_of_packets = report_block.extended_highest_sequence_number -
629 it->second.extended_highest_sequence_number;
630 total_packets_delta += number_of_packets;
631 auto lost_delta = report_block.packets_lost - it->second.packets_lost;
632 total_packets_lost_delta += lost_delta;
633 }
634 last_report_blocks_[report_block.source_ssrc] = report_block;
635 }
636 // Can only compute delta if there has been previous blocks to compare to. If
637 // not, total_packets_delta will be unchanged and there's nothing more to do.
638 if (!total_packets_delta)
639 return;
640 int packets_received_delta = total_packets_delta - total_packets_lost_delta;
641 // To detect lost packets, at least one packet has to be received. This check
642 // is needed to avoid bandwith detection update in
643 // VideoSendStreamTest.SuspendBelowMinBitrate
644
645 if (packets_received_delta < 1)
646 return;
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100647 Timestamp now = Timestamp::Millis(now_ms);
Sebastian Jansson87609be2018-12-05 17:35:35 +0100648 TransportLossReport msg;
649 msg.packets_lost_delta = total_packets_lost_delta;
650 msg.packets_received_delta = packets_received_delta;
651 msg.receive_time = now;
652 msg.start_time = last_report_block_time_;
653 msg.end_time = now;
654 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100655 PostUpdates(controller_->OnTransportLossReport(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100656 last_report_block_time_ = now;
657}
658
nissecae45d02017-04-24 05:53:20 -0700659} // namespace webrtc