blob: 9f173b1ad1a09ee38d3b9ab42b04964d3a0ca438 [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 */
Sebastian Jansson91bb6672018-02-21 13:02:51 +010010#include <utility>
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020011#include <vector>
nissecae45d02017-04-24 05:53:20 -070012
Karl Wiberg918f50c2018-07-05 11:40:33 +020013#include "absl/memory/memory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010014#include "absl/types/optional.h"
Sebastian Jansson87609be2018-12-05 17:35:35 +010015#include "api/transport/goog_cc_factory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010016#include "api/transport/network_types.h"
17#include "api/units/data_rate.h"
18#include "api/units/time_delta.h"
19#include "api/units/timestamp.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "call/rtp_transport_controller_send.h"
Yves Gerey3e707812018-11-28 16:47:49 +010021#include "call/rtp_video_sender.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "rtc_base/checks.h"
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010023#include "rtc_base/location.h"
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010024#include "rtc_base/logging.h"
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020025#include "rtc_base/rate_limiter.h"
Sebastian Jansson19bea512018-03-13 19:07:46 +010026#include "system_wrappers/include/field_trial.h"
nissecae45d02017-04-24 05:53:20 -070027
28namespace webrtc {
Sebastian Jansson87609be2018-12-05 17:35:35 +010029class RtpTransportControllerSend::PeriodicTask : public rtc::QueuedTask {
30 public:
31 virtual void Stop() = 0;
32};
33
Sebastian Jansson19bea512018-03-13 19:07:46 +010034namespace {
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020035static const int64_t kRetransmitWindowSizeMs = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +020036static const size_t kMaxOverheadBytes = 500;
Sebastian Jansson19bea512018-03-13 19:07:46 +010037
Sebastian Jansson87609be2018-12-05 17:35:35 +010038const int64_t PacerQueueUpdateIntervalMs = 25;
39
40TargetRateConstraints ConvertConstraints(int min_bitrate_bps,
41 int max_bitrate_bps,
42 int start_bitrate_bps,
43 const Clock* clock) {
44 TargetRateConstraints msg;
45 msg.at_time = Timestamp::ms(clock->TimeInMilliseconds());
46 msg.min_data_rate =
47 min_bitrate_bps >= 0 ? DataRate::bps(min_bitrate_bps) : DataRate::Zero();
48 msg.max_data_rate = max_bitrate_bps > 0 ? DataRate::bps(max_bitrate_bps)
49 : DataRate::Infinity();
50 if (start_bitrate_bps > 0)
51 msg.starting_rate = DataRate::bps(start_bitrate_bps);
52 return msg;
53}
54
55TargetRateConstraints ConvertConstraints(const BitrateConstraints& contraints,
56 const Clock* clock) {
57 return ConvertConstraints(contraints.min_bitrate_bps,
58 contraints.max_bitrate_bps,
59 contraints.start_bitrate_bps, clock);
60}
61
62// The template closure pattern is based on rtc::ClosureTask.
63template <class Closure>
64class PeriodicTaskImpl final : public RtpTransportControllerSend::PeriodicTask {
65 public:
66 PeriodicTaskImpl(rtc::TaskQueue* task_queue,
67 int64_t period_ms,
68 Closure&& closure)
69 : task_queue_(task_queue),
70 period_ms_(period_ms),
71 closure_(std::forward<Closure>(closure)) {}
72 bool Run() override {
73 if (!running_)
74 return true;
75 closure_();
76 // absl::WrapUnique lets us repost this task on the TaskQueue.
77 task_queue_->PostDelayedTask(absl::WrapUnique(this), period_ms_);
78 // Return false to tell TaskQueue to not destruct this object, since we have
79 // taken ownership with absl::WrapUnique.
80 return false;
Sebastian Jansson19bea512018-03-13 19:07:46 +010081 }
Sebastian Jansson87609be2018-12-05 17:35:35 +010082 void Stop() override {
83 if (task_queue_->IsCurrent()) {
84 RTC_DCHECK(running_);
85 running_ = false;
86 } else {
87 task_queue_->PostTask([this] { Stop(); });
88 }
89 }
90
91 private:
92 rtc::TaskQueue* const task_queue_;
93 const int64_t period_ms_;
94 typename std::remove_const<
95 typename std::remove_reference<Closure>::type>::type closure_;
96 bool running_ = true;
97};
98
99template <class Closure>
100static RtpTransportControllerSend::PeriodicTask* StartPeriodicTask(
101 rtc::TaskQueue* task_queue,
102 int64_t period_ms,
103 Closure&& closure) {
104 auto periodic_task = absl::make_unique<PeriodicTaskImpl<Closure>>(
105 task_queue, period_ms, std::forward<Closure>(closure));
106 RtpTransportControllerSend::PeriodicTask* periodic_task_ptr =
107 periodic_task.get();
108 task_queue->PostDelayedTask(std::move(periodic_task), period_ms);
109 return periodic_task_ptr;
Sebastian Jansson19bea512018-03-13 19:07:46 +0100110}
111} // namespace
nissecae45d02017-04-24 05:53:20 -0700112
113RtpTransportControllerSend::RtpTransportControllerSend(
114 Clock* clock,
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100115 webrtc::RtcEventLog* event_log,
Sebastian Janssondfce03a2018-05-18 18:05:10 +0200116 NetworkControllerFactoryInterface* controller_factory,
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100117 const BitrateConstraints& bitrate_config)
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100118 : clock_(clock),
119 pacer_(clock, &packet_router_, event_log),
Sebastian Jansson317a5222018-03-16 15:36:37 +0100120 bitrate_configurator_(bitrate_config),
121 process_thread_(ProcessThread::Create("SendControllerThread")),
122 observer_(nullptr),
Sebastian Jansson87609be2018-12-05 17:35:35 +0100123 transport_feedback_adapter_(clock_),
124 controller_factory_override_(controller_factory),
125 controller_factory_fallback_(
126 absl::make_unique<GoogCcNetworkControllerFactory>(event_log)),
127 process_interval_(controller_factory_fallback_->GetProcessInterval()),
128 last_report_block_time_(Timestamp::ms(clock_->TimeInMilliseconds())),
129 reset_feedback_on_route_change_(
130 !field_trial::IsEnabled("WebRTC-Bwe-NoFeedbackReset")),
131 send_side_bwe_with_overhead_(
132 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
Christoffer Rodbroc610e262019-01-08 10:49:19 +0100133 add_pacing_to_cwin_(
134 field_trial::IsEnabled("WebRTC-AddPacingToCongestionWindowPushback")),
Sebastian Jansson87609be2018-12-05 17:35:35 +0100135 transport_overhead_bytes_per_packet_(0),
136 network_available_(false),
Sebastian Jansson87609be2018-12-05 17:35:35 +0100137 packet_feedback_available_(false),
138 pacer_queue_update_task_(nullptr),
139 controller_task_(nullptr),
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200140 retransmission_rate_limiter_(clock, kRetransmitWindowSizeMs),
Sebastian Janssone6256052018-05-04 14:08:15 +0200141 task_queue_("rtp_send_controller") {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100142 initial_config_.constraints = ConvertConstraints(bitrate_config, clock_);
143 RTC_DCHECK(bitrate_config.start_bitrate_bps > 0);
144
Sebastian Jansson02c4f152018-12-20 09:41:03 +0100145 pacer_.SetPacingRates(bitrate_config.start_bitrate_bps, 0);
Sebastian Janssonbd9fe092018-05-07 16:33:50 +0200146
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +0100147 process_thread_->RegisterModule(&pacer_, RTC_FROM_HERE);
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +0100148 process_thread_->Start();
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100149}
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +0100150
151RtpTransportControllerSend::~RtpTransportControllerSend() {
152 process_thread_->Stop();
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +0100153 process_thread_->DeRegisterModule(&pacer_);
154}
nissecae45d02017-04-24 05:53:20 -0700155
Stefan Holmer9416ef82018-07-19 10:34:38 +0200156RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender(
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200157 std::map<uint32_t, RtpState> suspended_ssrcs,
158 const std::map<uint32_t, RtpPayloadState>& states,
159 const RtpConfig& rtp_config,
Jiawei Ou55718122018-11-09 13:17:39 -0800160 int rtcp_report_interval_ms,
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200161 Transport* send_transport,
162 const RtpSenderObservers& observers,
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200163 RtcEventLog* event_log,
Benjamin Wright192eeec2018-10-17 17:27:25 -0700164 std::unique_ptr<FecController> fec_controller,
165 const RtpSenderFrameEncryptionConfig& frame_encryption_config) {
Stefan Holmer9416ef82018-07-19 10:34:38 +0200166 video_rtp_senders_.push_back(absl::make_unique<RtpVideoSender>(
Amit Hilbuch0fc28432018-12-18 13:01:47 -0800167 suspended_ssrcs, states, rtp_config, rtcp_report_interval_ms,
Jiawei Ou55718122018-11-09 13:17:39 -0800168 send_transport, observers,
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200169 // TODO(holmer): Remove this circular dependency by injecting
170 // the parts of RtpTransportControllerSendInterface that are really used.
Benjamin Wright192eeec2018-10-17 17:27:25 -0700171 this, event_log, &retransmission_rate_limiter_, std::move(fec_controller),
172 frame_encryption_config.frame_encryptor,
173 frame_encryption_config.crypto_options));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200174 return video_rtp_senders_.back().get();
175}
176
Stefan Holmer9416ef82018-07-19 10:34:38 +0200177void RtpTransportControllerSend::DestroyRtpVideoSender(
178 RtpVideoSenderInterface* rtp_video_sender) {
179 std::vector<std::unique_ptr<RtpVideoSenderInterface>>::iterator it =
Stefan Holmer5ed25af2018-07-18 15:17:14 +0200180 video_rtp_senders_.end();
181 for (it = video_rtp_senders_.begin(); it != video_rtp_senders_.end(); ++it) {
182 if (it->get() == rtp_video_sender) {
183 break;
184 }
185 }
186 RTC_DCHECK(it != video_rtp_senders_.end());
187 video_rtp_senders_.erase(it);
188}
189
Sebastian Jansson16180952018-12-12 16:49:10 +0100190void RtpTransportControllerSend::UpdateControlState() {
191 absl::optional<TargetTransferRate> update = control_handler_->GetUpdate();
192 if (!update)
193 return;
194 retransmission_rate_limiter_.SetMaxRate(
195 update->network_estimate.bandwidth.bps());
196 // We won't create control_handler_ until we have an observers.
Sebastian Jansson87609be2018-12-05 17:35:35 +0100197 RTC_DCHECK(observer_ != nullptr);
Sebastian Jansson16180952018-12-12 16:49:10 +0100198 observer_->OnTargetTransferRate(*update);
Sebastian Janssone6256052018-05-04 14:08:15 +0200199}
200
201rtc::TaskQueue* RtpTransportControllerSend::GetWorkerQueue() {
202 return &task_queue_;
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100203}
204
nisse76e62b02017-05-31 02:24:52 -0700205PacketRouter* RtpTransportControllerSend::packet_router() {
206 return &packet_router_;
207}
208
nisse76e62b02017-05-31 02:24:52 -0700209TransportFeedbackObserver*
210RtpTransportControllerSend::transport_feedback_observer() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100211 return this;
nisse76e62b02017-05-31 02:24:52 -0700212}
213
214RtpPacketSender* RtpTransportControllerSend::packet_sender() {
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200215 return &pacer_;
nisse76e62b02017-05-31 02:24:52 -0700216}
217
sprangdb2a9fc2017-08-09 06:42:32 -0700218const RtpKeepAliveConfig& RtpTransportControllerSend::keepalive_config() const {
219 return keepalive_;
220}
221
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200222void RtpTransportControllerSend::SetAllocatedSendBitrateLimits(
223 int min_send_bitrate_bps,
philipel832b1c82018-02-28 17:04:18 +0100224 int max_padding_bitrate_bps,
philipeldb4fa4b2018-03-06 18:29:22 +0100225 int max_total_bitrate_bps) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100226 RTC_DCHECK_RUN_ON(&task_queue_);
227 streams_config_.min_pacing_rate = DataRate::bps(min_send_bitrate_bps);
228 streams_config_.max_padding_rate = DataRate::bps(max_padding_bitrate_bps);
229 streams_config_.max_total_allocated_bitrate =
230 DataRate::bps(max_total_bitrate_bps);
231 UpdateStreamsConfig();
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200232}
233
sprangdb2a9fc2017-08-09 06:42:32 -0700234void RtpTransportControllerSend::SetKeepAliveConfig(
235 const RtpKeepAliveConfig& config) {
236 keepalive_ = config;
237}
Sebastian Jansson4c1ffb82018-02-15 16:51:58 +0100238void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100239 RTC_DCHECK_RUN_ON(&task_queue_);
240 streams_config_.pacing_factor = pacing_factor;
241 UpdateStreamsConfig();
Sebastian Jansson4c1ffb82018-02-15 16:51:58 +0100242}
243void RtpTransportControllerSend::SetQueueTimeLimit(int limit_ms) {
244 pacer_.SetQueueTimeLimit(limit_ms);
245}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100246CallStatsObserver* RtpTransportControllerSend::GetCallStatsObserver() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100247 return this;
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100248}
249void RtpTransportControllerSend::RegisterPacketFeedbackObserver(
250 PacketFeedbackObserver* observer) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100251 transport_feedback_adapter_.RegisterPacketFeedbackObserver(observer);
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100252}
253void RtpTransportControllerSend::DeRegisterPacketFeedbackObserver(
254 PacketFeedbackObserver* observer) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100255 transport_feedback_adapter_.DeRegisterPacketFeedbackObserver(observer);
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100256}
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100257
258void RtpTransportControllerSend::RegisterTargetTransferRateObserver(
259 TargetTransferRateObserver* observer) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100260 task_queue_.PostTask([this, observer] {
261 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100262 RTC_DCHECK(observer_ == nullptr);
263 observer_ = observer;
Sebastian Jansson2701bc92018-12-11 15:02:47 +0100264 observer_->OnStartRateUpdate(*initial_config_.constraints.starting_rate);
Sebastian Jansson87609be2018-12-05 17:35:35 +0100265 MaybeCreateControllers();
266 });
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100267}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100268void RtpTransportControllerSend::OnNetworkRouteChanged(
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100269 const std::string& transport_name,
270 const rtc::NetworkRoute& network_route) {
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100271 // Check if the network route is connected.
272 if (!network_route.connected) {
273 RTC_LOG(LS_INFO) << "Transport " << transport_name << " is disconnected";
274 // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and
275 // consider merging these two methods.
276 return;
277 }
278
279 // Check whether the network route has changed on each transport.
280 auto result =
281 network_routes_.insert(std::make_pair(transport_name, network_route));
282 auto kv = result.first;
283 bool inserted = result.second;
284 if (inserted) {
285 // No need to reset BWE if this is the first time the network connects.
286 return;
287 }
Sebastian Janssonaf2adda2018-12-04 11:16:19 +0100288 if (kv->second.connected != network_route.connected ||
289 kv->second.local_network_id != network_route.local_network_id ||
290 kv->second.remote_network_id != network_route.remote_network_id) {
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100291 kv->second = network_route;
292 BitrateConstraints bitrate_config = bitrate_configurator_.GetConfig();
293 RTC_LOG(LS_INFO) << "Network route changed on transport " << transport_name
294 << ": new local network id "
295 << network_route.local_network_id
296 << " new remote network id "
297 << network_route.remote_network_id
298 << " Reset bitrates to min: "
299 << bitrate_config.min_bitrate_bps
300 << " bps, start: " << bitrate_config.start_bitrate_bps
301 << " bps, max: " << bitrate_config.max_bitrate_bps
302 << " bps.";
303 RTC_DCHECK_GT(bitrate_config.start_bitrate_bps, 0);
Sebastian Jansson87609be2018-12-05 17:35:35 +0100304
305 if (reset_feedback_on_route_change_)
306 transport_feedback_adapter_.SetNetworkIds(
307 network_route.local_network_id, network_route.remote_network_id);
308 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
309
310 NetworkRouteChange msg;
311 msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
312 msg.constraints = ConvertConstraints(bitrate_config, clock_);
313 task_queue_.PostTask([this, msg] {
314 RTC_DCHECK_RUN_ON(&task_queue_);
315 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100316 PostUpdates(controller_->OnNetworkRouteChange(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100317 } else {
318 UpdateInitialConstraints(msg.constraints);
319 }
320 pacer_.UpdateOutstandingData(0);
321 });
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100322 }
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100323}
324void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100325 RTC_LOG(LS_INFO) << "SignalNetworkState "
326 << (network_available ? "Up" : "Down");
327 NetworkAvailability msg;
328 msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
329 msg.network_available = network_available;
330 task_queue_.PostTask([this, msg]() {
331 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson16180952018-12-12 16:49:10 +0100332 if (network_available_ == msg.network_available)
333 return;
Sebastian Jansson87609be2018-12-05 17:35:35 +0100334 network_available_ = msg.network_available;
Sebastian Jansson16180952018-12-12 16:49:10 +0100335 if (network_available_) {
336 pacer_.Resume();
337 } else {
338 pacer_.Pause();
339 }
340 pacer_.UpdateOutstandingData(0);
341
Sebastian Jansson87609be2018-12-05 17:35:35 +0100342 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100343 control_handler_->SetNetworkAvailability(network_available_);
344 PostUpdates(controller_->OnNetworkAvailability(msg));
345 UpdateControlState();
Sebastian Jansson87609be2018-12-05 17:35:35 +0100346 } else {
347 MaybeCreateControllers();
348 }
349 });
350
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200351 for (auto& rtp_sender : video_rtp_senders_) {
352 rtp_sender->OnNetworkAvailability(network_available);
353 }
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100354}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100355RtcpBandwidthObserver* RtpTransportControllerSend::GetBandwidthObserver() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100356 return this;
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100357}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100358int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const {
Sebastian Janssona06e9192018-03-07 18:49:55 +0100359 return pacer_.QueueInMs();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100360}
361int64_t RtpTransportControllerSend::GetFirstPacketTimeMs() const {
Sebastian Janssona06e9192018-03-07 18:49:55 +0100362 return pacer_.FirstSentPacketTimeMs();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100363}
Sebastian Jansson12130bb2018-03-21 12:48:43 +0100364void RtpTransportControllerSend::SetPerPacketFeedbackAvailable(bool available) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100365 RTC_DCHECK_RUN_ON(&task_queue_);
366 packet_feedback_available_ = available;
367 if (!controller_)
368 MaybeCreateControllers();
Sebastian Jansson12130bb2018-03-21 12:48:43 +0100369}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100370void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100371 task_queue_.PostTask([this, enable]() {
372 RTC_DCHECK_RUN_ON(&task_queue_);
373 streams_config_.requests_alr_probing = enable;
374 UpdateStreamsConfig();
375 });
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100376}
377void RtpTransportControllerSend::OnSentPacket(
378 const rtc::SentPacket& sent_packet) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100379 absl::optional<SentPacket> packet_msg =
380 transport_feedback_adapter_.ProcessSentPacket(sent_packet);
381 if (packet_msg) {
382 task_queue_.PostTask([this, packet_msg]() {
383 RTC_DCHECK_RUN_ON(&task_queue_);
384 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100385 PostUpdates(controller_->OnSentPacket(*packet_msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100386 });
387 }
Sebastian Jansson16180952018-12-12 16:49:10 +0100388 pacer_.UpdateOutstandingData(
389 transport_feedback_adapter_.GetOutstandingData().bytes());
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100390}
sprangdb2a9fc2017-08-09 06:42:32 -0700391
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100392void RtpTransportControllerSend::SetSdpBitrateParameters(
393 const BitrateConstraints& constraints) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200394 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100395 bitrate_configurator_.UpdateWithSdpParameters(constraints);
396 if (updated.has_value()) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100397 TargetRateConstraints msg = ConvertConstraints(*updated, clock_);
398 task_queue_.PostTask([this, msg]() {
399 RTC_DCHECK_RUN_ON(&task_queue_);
400 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100401 PostUpdates(controller_->OnTargetRateConstraints(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100402 } else {
403 UpdateInitialConstraints(msg);
404 }
405 });
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100406 } else {
407 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100408 << "WebRTC.RtpTransportControllerSend.SetSdpBitrateParameters: "
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100409 << "nothing to update";
410 }
411}
412
413void RtpTransportControllerSend::SetClientBitratePreferences(
Niels Möller0c4f7be2018-05-07 14:01:37 +0200414 const BitrateSettings& preferences) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200415 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100416 bitrate_configurator_.UpdateWithClientPreferences(preferences);
417 if (updated.has_value()) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100418 TargetRateConstraints msg = ConvertConstraints(*updated, clock_);
419 task_queue_.PostTask([this, msg]() {
420 RTC_DCHECK_RUN_ON(&task_queue_);
421 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100422 PostUpdates(controller_->OnTargetRateConstraints(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100423 } else {
424 UpdateInitialConstraints(msg);
425 }
426 });
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100427 } else {
428 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100429 << "WebRTC.RtpTransportControllerSend.SetClientBitratePreferences: "
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100430 << "nothing to update";
431 }
432}
Alex Narestbcf91802018-06-25 16:08:36 +0200433
434void RtpTransportControllerSend::SetAllocatedBitrateWithoutFeedback(
435 uint32_t bitrate_bps) {
Sebastian Jansson35fa2802018-10-01 09:16:12 +0200436 // Audio transport feedback will not be reported in this mode, instead update
437 // acknowledged bitrate estimator with the bitrate allocated for audio.
438 if (field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC")) {
439 // TODO(srte): Make sure it's safe to always report this and remove the
440 // field trial check.
Sebastian Jansson87609be2018-12-05 17:35:35 +0100441 task_queue_.PostTask([this, bitrate_bps]() {
442 RTC_DCHECK_RUN_ON(&task_queue_);
443 streams_config_.unacknowledged_rate_allocation =
444 DataRate::bps(bitrate_bps);
445 UpdateStreamsConfig();
446 });
Sebastian Jansson35fa2802018-10-01 09:16:12 +0200447 }
Alex Narestbcf91802018-06-25 16:08:36 +0200448}
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200449
450void RtpTransportControllerSend::OnTransportOverheadChanged(
451 size_t transport_overhead_bytes_per_packet) {
452 if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) {
453 RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes;
454 return;
455 }
456
457 // TODO(holmer): Call AudioRtpSenders when they have been moved to
458 // RtpTransportControllerSend.
459 for (auto& rtp_video_sender : video_rtp_senders_) {
460 rtp_video_sender->OnTransportOverheadChanged(
461 transport_overhead_bytes_per_packet);
462 }
463}
Sebastian Jansson87609be2018-12-05 17:35:35 +0100464
465void RtpTransportControllerSend::OnReceivedEstimatedBitrate(uint32_t bitrate) {
466 RemoteBitrateReport msg;
467 msg.receive_time = Timestamp::ms(clock_->TimeInMilliseconds());
468 msg.bandwidth = DataRate::bps(bitrate);
469 task_queue_.PostTask([this, msg]() {
470 RTC_DCHECK_RUN_ON(&task_queue_);
471 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100472 PostUpdates(controller_->OnRemoteBitrateReport(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100473 });
474}
475
476void RtpTransportControllerSend::OnReceivedRtcpReceiverReport(
477 const ReportBlockList& report_blocks,
478 int64_t rtt_ms,
479 int64_t now_ms) {
480 task_queue_.PostTask([this, report_blocks, now_ms]() {
481 RTC_DCHECK_RUN_ON(&task_queue_);
482 OnReceivedRtcpReceiverReportBlocks(report_blocks, now_ms);
483 });
484
485 task_queue_.PostTask([this, now_ms, rtt_ms]() {
486 RTC_DCHECK_RUN_ON(&task_queue_);
487 RoundTripTimeUpdate report;
488 report.receive_time = Timestamp::ms(now_ms);
489 report.round_trip_time = TimeDelta::ms(rtt_ms);
490 report.smoothed = false;
491 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100492 PostUpdates(controller_->OnRoundTripTimeUpdate(report));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100493 });
494}
495
496void RtpTransportControllerSend::AddPacket(uint32_t ssrc,
497 uint16_t sequence_number,
498 size_t length,
499 const PacedPacketInfo& pacing_info) {
500 if (send_side_bwe_with_overhead_) {
501 length += transport_overhead_bytes_per_packet_;
502 }
503 transport_feedback_adapter_.AddPacket(ssrc, sequence_number, length,
504 pacing_info);
505}
506
507void RtpTransportControllerSend::OnTransportFeedback(
508 const rtcp::TransportFeedback& feedback) {
509 RTC_DCHECK_RUNS_SERIALIZED(&worker_race_);
510
511 absl::optional<TransportPacketsFeedback> feedback_msg =
512 transport_feedback_adapter_.ProcessTransportFeedback(feedback);
513 if (feedback_msg) {
514 task_queue_.PostTask([this, feedback_msg]() {
515 RTC_DCHECK_RUN_ON(&task_queue_);
516 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100517 PostUpdates(controller_->OnTransportPacketsFeedback(*feedback_msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100518 });
519 }
Sebastian Jansson16180952018-12-12 16:49:10 +0100520 pacer_.UpdateOutstandingData(
521 transport_feedback_adapter_.GetOutstandingData().bytes());
Sebastian Jansson87609be2018-12-05 17:35:35 +0100522}
523
524void RtpTransportControllerSend::OnRttUpdate(int64_t avg_rtt_ms,
525 int64_t max_rtt_ms) {
526 int64_t now_ms = clock_->TimeInMilliseconds();
527 RoundTripTimeUpdate report;
528 report.receive_time = Timestamp::ms(now_ms);
529 report.round_trip_time = TimeDelta::ms(avg_rtt_ms);
530 report.smoothed = true;
531 task_queue_.PostTask([this, report]() {
532 RTC_DCHECK_RUN_ON(&task_queue_);
533 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100534 PostUpdates(controller_->OnRoundTripTimeUpdate(report));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100535 });
536}
537
538void RtpTransportControllerSend::MaybeCreateControllers() {
539 RTC_DCHECK(!controller_);
540 RTC_DCHECK(!control_handler_);
541
542 if (!network_available_ || !observer_)
543 return;
Sebastian Jansson16180952018-12-12 16:49:10 +0100544 control_handler_ = absl::make_unique<CongestionControlHandler>();
Sebastian Jansson87609be2018-12-05 17:35:35 +0100545
546 initial_config_.constraints.at_time =
547 Timestamp::ms(clock_->TimeInMilliseconds());
548 initial_config_.stream_based_config = streams_config_;
549
550 // TODO(srte): Use fallback controller if no feedback is available.
551 if (controller_factory_override_) {
552 RTC_LOG(LS_INFO) << "Creating overridden congestion controller";
553 controller_ = controller_factory_override_->Create(initial_config_);
554 process_interval_ = controller_factory_override_->GetProcessInterval();
555 } else {
556 RTC_LOG(LS_INFO) << "Creating fallback congestion controller";
557 controller_ = controller_factory_fallback_->Create(initial_config_);
558 process_interval_ = controller_factory_fallback_->GetProcessInterval();
559 }
560 UpdateControllerWithTimeInterval();
561 StartProcessPeriodicTasks();
562}
563
564void RtpTransportControllerSend::UpdateInitialConstraints(
565 TargetRateConstraints new_contraints) {
566 if (!new_contraints.starting_rate)
567 new_contraints.starting_rate = initial_config_.constraints.starting_rate;
568 RTC_DCHECK(new_contraints.starting_rate);
569 initial_config_.constraints = new_contraints;
570}
571
572void RtpTransportControllerSend::StartProcessPeriodicTasks() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100573 if (!pacer_queue_update_task_) {
574 pacer_queue_update_task_ =
575 StartPeriodicTask(&task_queue_, PacerQueueUpdateIntervalMs, [this]() {
576 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson16180952018-12-12 16:49:10 +0100577 TimeDelta expected_queue_time =
578 TimeDelta::ms(pacer_.ExpectedQueueTimeMs());
579 control_handler_->SetPacerQueue(expected_queue_time);
580 UpdateControlState();
Sebastian Jansson87609be2018-12-05 17:35:35 +0100581 });
582 }
583 if (controller_task_) {
584 // Stop is not synchronous, but is guaranteed to occur before the first
585 // invocation of the new controller task started below.
586 controller_task_->Stop();
587 controller_task_ = nullptr;
588 }
589 if (process_interval_.IsFinite()) {
590 // The controller task is owned by the task queue and lives until the task
591 // queue is destroyed or some time after Stop() is called, whichever comes
592 // first.
593 controller_task_ =
594 StartPeriodicTask(&task_queue_, process_interval_.ms(), [this]() {
595 RTC_DCHECK_RUN_ON(&task_queue_);
596 UpdateControllerWithTimeInterval();
597 });
598 }
599}
600
601void RtpTransportControllerSend::UpdateControllerWithTimeInterval() {
Sebastian Jansson16180952018-12-12 16:49:10 +0100602 RTC_DCHECK(controller_);
603 ProcessInterval msg;
604 msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
Christoffer Rodbroc610e262019-01-08 10:49:19 +0100605 if (add_pacing_to_cwin_)
606 msg.pacer_queue = DataSize::bytes(pacer_.QueueSizeBytes());
Sebastian Jansson16180952018-12-12 16:49:10 +0100607 PostUpdates(controller_->OnProcessInterval(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100608}
609
610void RtpTransportControllerSend::UpdateStreamsConfig() {
611 streams_config_.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
612 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100613 PostUpdates(controller_->OnStreamsConfig(streams_config_));
614}
615
616void RtpTransportControllerSend::PostUpdates(NetworkControlUpdate update) {
617 if (update.congestion_window) {
618 if (update.congestion_window->IsFinite())
619 pacer_.SetCongestionWindow(update.congestion_window->bytes());
620 else
621 pacer_.SetCongestionWindow(PacedSender::kNoCongestionWindow);
622 }
623 if (update.pacer_config) {
624 pacer_.SetPacingRates(update.pacer_config->data_rate().bps(),
625 update.pacer_config->pad_rate().bps());
626 }
627 for (const auto& probe : update.probe_cluster_configs) {
628 int64_t bitrate_bps = probe.target_data_rate.bps();
629 pacer_.CreateProbeCluster(bitrate_bps);
630 }
631 if (update.target_rate) {
632 control_handler_->SetTargetRate(*update.target_rate);
633 UpdateControlState();
634 }
Sebastian Jansson87609be2018-12-05 17:35:35 +0100635}
636
637void RtpTransportControllerSend::OnReceivedRtcpReceiverReportBlocks(
638 const ReportBlockList& report_blocks,
639 int64_t now_ms) {
640 if (report_blocks.empty())
641 return;
642
643 int total_packets_lost_delta = 0;
644 int total_packets_delta = 0;
645
646 // Compute the packet loss from all report blocks.
647 for (const RTCPReportBlock& report_block : report_blocks) {
648 auto it = last_report_blocks_.find(report_block.source_ssrc);
649 if (it != last_report_blocks_.end()) {
650 auto number_of_packets = report_block.extended_highest_sequence_number -
651 it->second.extended_highest_sequence_number;
652 total_packets_delta += number_of_packets;
653 auto lost_delta = report_block.packets_lost - it->second.packets_lost;
654 total_packets_lost_delta += lost_delta;
655 }
656 last_report_blocks_[report_block.source_ssrc] = report_block;
657 }
658 // Can only compute delta if there has been previous blocks to compare to. If
659 // not, total_packets_delta will be unchanged and there's nothing more to do.
660 if (!total_packets_delta)
661 return;
662 int packets_received_delta = total_packets_delta - total_packets_lost_delta;
663 // To detect lost packets, at least one packet has to be received. This check
664 // is needed to avoid bandwith detection update in
665 // VideoSendStreamTest.SuspendBelowMinBitrate
666
667 if (packets_received_delta < 1)
668 return;
669 Timestamp now = Timestamp::ms(now_ms);
670 TransportLossReport msg;
671 msg.packets_lost_delta = total_packets_lost_delta;
672 msg.packets_received_delta = packets_received_delta;
673 msg.receive_time = now;
674 msg.start_time = last_report_block_time_;
675 msg.end_time = now;
676 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100677 PostUpdates(controller_->OnTransportLossReport(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100678 last_report_block_time_ = now;
679}
680
nissecae45d02017-04-24 05:53:20 -0700681} // namespace webrtc