blob: a5fe7d513cf3ceec06b20d0ba1638c4e81972fd5 [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 Jansson19bea512018-03-13 19:07:46 +010029namespace {
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020030static const int64_t kRetransmitWindowSizeMs = 500;
Stefan Holmer64be7fa2018-10-04 15:21:55 +020031static const size_t kMaxOverheadBytes = 500;
Sebastian Jansson19bea512018-03-13 19:07:46 +010032
Sebastian Janssonecb68972019-01-18 10:30:54 +010033constexpr TimeDelta kPacerQueueUpdateInterval = TimeDelta::Millis<25>();
Sebastian Jansson87609be2018-12-05 17:35:35 +010034
35TargetRateConstraints ConvertConstraints(int min_bitrate_bps,
36 int max_bitrate_bps,
37 int start_bitrate_bps,
38 const Clock* clock) {
39 TargetRateConstraints msg;
40 msg.at_time = Timestamp::ms(clock->TimeInMilliseconds());
41 msg.min_data_rate =
42 min_bitrate_bps >= 0 ? DataRate::bps(min_bitrate_bps) : DataRate::Zero();
43 msg.max_data_rate = max_bitrate_bps > 0 ? DataRate::bps(max_bitrate_bps)
44 : DataRate::Infinity();
45 if (start_bitrate_bps > 0)
46 msg.starting_rate = DataRate::bps(start_bitrate_bps);
47 return msg;
48}
49
50TargetRateConstraints ConvertConstraints(const BitrateConstraints& contraints,
51 const Clock* clock) {
52 return ConvertConstraints(contraints.min_bitrate_bps,
53 contraints.max_bitrate_bps,
54 contraints.start_bitrate_bps, clock);
55}
Sebastian Jansson19bea512018-03-13 19:07:46 +010056} // namespace
nissecae45d02017-04-24 05:53:20 -070057
58RtpTransportControllerSend::RtpTransportControllerSend(
59 Clock* clock,
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010060 webrtc::RtcEventLog* event_log,
Sebastian Janssondfce03a2018-05-18 18:05:10 +020061 NetworkControllerFactoryInterface* controller_factory,
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010062 const BitrateConstraints& bitrate_config)
Sebastian Jansson19704ec2018-03-12 15:59:12 +010063 : clock_(clock),
64 pacer_(clock, &packet_router_, event_log),
Sebastian Jansson317a5222018-03-16 15:36:37 +010065 bitrate_configurator_(bitrate_config),
66 process_thread_(ProcessThread::Create("SendControllerThread")),
67 observer_(nullptr),
Sebastian Jansson87609be2018-12-05 17:35:35 +010068 transport_feedback_adapter_(clock_),
69 controller_factory_override_(controller_factory),
70 controller_factory_fallback_(
71 absl::make_unique<GoogCcNetworkControllerFactory>(event_log)),
72 process_interval_(controller_factory_fallback_->GetProcessInterval()),
73 last_report_block_time_(Timestamp::ms(clock_->TimeInMilliseconds())),
74 reset_feedback_on_route_change_(
75 !field_trial::IsEnabled("WebRTC-Bwe-NoFeedbackReset")),
76 send_side_bwe_with_overhead_(
77 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
Christoffer Rodbroc610e262019-01-08 10:49:19 +010078 add_pacing_to_cwin_(
79 field_trial::IsEnabled("WebRTC-AddPacingToCongestionWindowPushback")),
Sebastian Jansson87609be2018-12-05 17:35:35 +010080 transport_overhead_bytes_per_packet_(0),
81 network_available_(false),
Sebastian Jansson87609be2018-12-05 17:35:35 +010082 packet_feedback_available_(false),
Stefan Holmerdbdb3a02018-07-17 16:03:46 +020083 retransmission_rate_limiter_(clock, kRetransmitWindowSizeMs),
Sebastian Janssone6256052018-05-04 14:08:15 +020084 task_queue_("rtp_send_controller") {
Sebastian Jansson87609be2018-12-05 17:35:35 +010085 initial_config_.constraints = ConvertConstraints(bitrate_config, clock_);
86 RTC_DCHECK(bitrate_config.start_bitrate_bps > 0);
87
Sebastian Jansson02c4f152018-12-20 09:41:03 +010088 pacer_.SetPacingRates(bitrate_config.start_bitrate_bps, 0);
Sebastian Janssonbd9fe092018-05-07 16:33:50 +020089
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010090 process_thread_->RegisterModule(&pacer_, RTC_FROM_HERE);
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010091 process_thread_->Start();
Sebastian Jansson97f61ea2018-02-21 13:01:55 +010092}
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010093
94RtpTransportControllerSend::~RtpTransportControllerSend() {
95 process_thread_->Stop();
Sebastian Janssonc33c0fc2018-02-22 11:10:18 +010096 process_thread_->DeRegisterModule(&pacer_);
97}
nissecae45d02017-04-24 05:53:20 -070098
Stefan Holmer9416ef82018-07-19 10:34:38 +020099RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender(
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200100 std::map<uint32_t, RtpState> suspended_ssrcs,
101 const std::map<uint32_t, RtpPayloadState>& states,
102 const RtpConfig& rtp_config,
Jiawei Ou55718122018-11-09 13:17:39 -0800103 int rtcp_report_interval_ms,
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200104 Transport* send_transport,
105 const RtpSenderObservers& observers,
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200106 RtcEventLog* event_log,
Benjamin Wright192eeec2018-10-17 17:27:25 -0700107 std::unique_ptr<FecController> fec_controller,
108 const RtpSenderFrameEncryptionConfig& frame_encryption_config) {
Stefan Holmer9416ef82018-07-19 10:34:38 +0200109 video_rtp_senders_.push_back(absl::make_unique<RtpVideoSender>(
Amit Hilbuch0fc28432018-12-18 13:01:47 -0800110 suspended_ssrcs, states, rtp_config, rtcp_report_interval_ms,
Jiawei Ou55718122018-11-09 13:17:39 -0800111 send_transport, observers,
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200112 // TODO(holmer): Remove this circular dependency by injecting
113 // the parts of RtpTransportControllerSendInterface that are really used.
Benjamin Wright192eeec2018-10-17 17:27:25 -0700114 this, event_log, &retransmission_rate_limiter_, std::move(fec_controller),
115 frame_encryption_config.frame_encryptor,
116 frame_encryption_config.crypto_options));
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200117 return video_rtp_senders_.back().get();
118}
119
Stefan Holmer9416ef82018-07-19 10:34:38 +0200120void RtpTransportControllerSend::DestroyRtpVideoSender(
121 RtpVideoSenderInterface* rtp_video_sender) {
122 std::vector<std::unique_ptr<RtpVideoSenderInterface>>::iterator it =
Stefan Holmer5ed25af2018-07-18 15:17:14 +0200123 video_rtp_senders_.end();
124 for (it = video_rtp_senders_.begin(); it != video_rtp_senders_.end(); ++it) {
125 if (it->get() == rtp_video_sender) {
126 break;
127 }
128 }
129 RTC_DCHECK(it != video_rtp_senders_.end());
130 video_rtp_senders_.erase(it);
131}
132
Sebastian Jansson16180952018-12-12 16:49:10 +0100133void RtpTransportControllerSend::UpdateControlState() {
134 absl::optional<TargetTransferRate> update = control_handler_->GetUpdate();
135 if (!update)
136 return;
137 retransmission_rate_limiter_.SetMaxRate(
138 update->network_estimate.bandwidth.bps());
139 // We won't create control_handler_ until we have an observers.
Sebastian Jansson87609be2018-12-05 17:35:35 +0100140 RTC_DCHECK(observer_ != nullptr);
Sebastian Jansson16180952018-12-12 16:49:10 +0100141 observer_->OnTargetTransferRate(*update);
Sebastian Janssone6256052018-05-04 14:08:15 +0200142}
143
144rtc::TaskQueue* RtpTransportControllerSend::GetWorkerQueue() {
145 return &task_queue_;
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100146}
147
nisse76e62b02017-05-31 02:24:52 -0700148PacketRouter* RtpTransportControllerSend::packet_router() {
149 return &packet_router_;
150}
151
nisse76e62b02017-05-31 02:24:52 -0700152TransportFeedbackObserver*
153RtpTransportControllerSend::transport_feedback_observer() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100154 return this;
nisse76e62b02017-05-31 02:24:52 -0700155}
156
157RtpPacketSender* RtpTransportControllerSend::packet_sender() {
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200158 return &pacer_;
nisse76e62b02017-05-31 02:24:52 -0700159}
160
sprangdb2a9fc2017-08-09 06:42:32 -0700161const RtpKeepAliveConfig& RtpTransportControllerSend::keepalive_config() const {
162 return keepalive_;
163}
164
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200165void RtpTransportControllerSend::SetAllocatedSendBitrateLimits(
166 int min_send_bitrate_bps,
philipel832b1c82018-02-28 17:04:18 +0100167 int max_padding_bitrate_bps,
philipeldb4fa4b2018-03-06 18:29:22 +0100168 int max_total_bitrate_bps) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100169 RTC_DCHECK_RUN_ON(&task_queue_);
170 streams_config_.min_pacing_rate = DataRate::bps(min_send_bitrate_bps);
171 streams_config_.max_padding_rate = DataRate::bps(max_padding_bitrate_bps);
172 streams_config_.max_total_allocated_bitrate =
173 DataRate::bps(max_total_bitrate_bps);
174 UpdateStreamsConfig();
Stefan Holmer5c8942a2017-08-22 16:16:44 +0200175}
176
sprangdb2a9fc2017-08-09 06:42:32 -0700177void RtpTransportControllerSend::SetKeepAliveConfig(
178 const RtpKeepAliveConfig& config) {
179 keepalive_ = config;
180}
Sebastian Jansson4c1ffb82018-02-15 16:51:58 +0100181void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100182 RTC_DCHECK_RUN_ON(&task_queue_);
183 streams_config_.pacing_factor = pacing_factor;
184 UpdateStreamsConfig();
Sebastian Jansson4c1ffb82018-02-15 16:51:58 +0100185}
186void RtpTransportControllerSend::SetQueueTimeLimit(int limit_ms) {
187 pacer_.SetQueueTimeLimit(limit_ms);
188}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100189CallStatsObserver* RtpTransportControllerSend::GetCallStatsObserver() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100190 return this;
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100191}
192void RtpTransportControllerSend::RegisterPacketFeedbackObserver(
193 PacketFeedbackObserver* observer) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100194 transport_feedback_adapter_.RegisterPacketFeedbackObserver(observer);
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100195}
196void RtpTransportControllerSend::DeRegisterPacketFeedbackObserver(
197 PacketFeedbackObserver* observer) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100198 transport_feedback_adapter_.DeRegisterPacketFeedbackObserver(observer);
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100199}
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100200
201void RtpTransportControllerSend::RegisterTargetTransferRateObserver(
202 TargetTransferRateObserver* observer) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100203 task_queue_.PostTask([this, observer] {
204 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson19704ec2018-03-12 15:59:12 +0100205 RTC_DCHECK(observer_ == nullptr);
206 observer_ = observer;
Sebastian Jansson2701bc92018-12-11 15:02:47 +0100207 observer_->OnStartRateUpdate(*initial_config_.constraints.starting_rate);
Sebastian Jansson87609be2018-12-05 17:35:35 +0100208 MaybeCreateControllers();
209 });
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100210}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100211void RtpTransportControllerSend::OnNetworkRouteChanged(
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100212 const std::string& transport_name,
213 const rtc::NetworkRoute& network_route) {
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100214 // Check if the network route is connected.
215 if (!network_route.connected) {
216 RTC_LOG(LS_INFO) << "Transport " << transport_name << " is disconnected";
217 // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and
218 // consider merging these two methods.
219 return;
220 }
221
222 // Check whether the network route has changed on each transport.
223 auto result =
224 network_routes_.insert(std::make_pair(transport_name, network_route));
225 auto kv = result.first;
226 bool inserted = result.second;
227 if (inserted) {
228 // No need to reset BWE if this is the first time the network connects.
229 return;
230 }
Sebastian Janssonaf2adda2018-12-04 11:16:19 +0100231 if (kv->second.connected != network_route.connected ||
232 kv->second.local_network_id != network_route.local_network_id ||
233 kv->second.remote_network_id != network_route.remote_network_id) {
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100234 kv->second = network_route;
235 BitrateConstraints bitrate_config = bitrate_configurator_.GetConfig();
236 RTC_LOG(LS_INFO) << "Network route changed on transport " << transport_name
237 << ": new local network id "
238 << network_route.local_network_id
239 << " new remote network id "
240 << network_route.remote_network_id
241 << " Reset bitrates to min: "
242 << bitrate_config.min_bitrate_bps
243 << " bps, start: " << bitrate_config.start_bitrate_bps
244 << " bps, max: " << bitrate_config.max_bitrate_bps
245 << " bps.";
246 RTC_DCHECK_GT(bitrate_config.start_bitrate_bps, 0);
Sebastian Jansson87609be2018-12-05 17:35:35 +0100247
248 if (reset_feedback_on_route_change_)
249 transport_feedback_adapter_.SetNetworkIds(
250 network_route.local_network_id, network_route.remote_network_id);
251 transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
252
253 NetworkRouteChange msg;
254 msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
255 msg.constraints = ConvertConstraints(bitrate_config, clock_);
256 task_queue_.PostTask([this, msg] {
257 RTC_DCHECK_RUN_ON(&task_queue_);
258 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100259 PostUpdates(controller_->OnNetworkRouteChange(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100260 } else {
261 UpdateInitialConstraints(msg.constraints);
262 }
263 pacer_.UpdateOutstandingData(0);
264 });
Sebastian Jansson91bb6672018-02-21 13:02:51 +0100265 }
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100266}
267void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100268 RTC_LOG(LS_INFO) << "SignalNetworkState "
269 << (network_available ? "Up" : "Down");
270 NetworkAvailability msg;
271 msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
272 msg.network_available = network_available;
273 task_queue_.PostTask([this, msg]() {
274 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson16180952018-12-12 16:49:10 +0100275 if (network_available_ == msg.network_available)
276 return;
Sebastian Jansson87609be2018-12-05 17:35:35 +0100277 network_available_ = msg.network_available;
Sebastian Jansson16180952018-12-12 16:49:10 +0100278 if (network_available_) {
279 pacer_.Resume();
280 } else {
281 pacer_.Pause();
282 }
283 pacer_.UpdateOutstandingData(0);
284
Sebastian Jansson87609be2018-12-05 17:35:35 +0100285 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100286 control_handler_->SetNetworkAvailability(network_available_);
287 PostUpdates(controller_->OnNetworkAvailability(msg));
288 UpdateControlState();
Sebastian Jansson87609be2018-12-05 17:35:35 +0100289 } else {
290 MaybeCreateControllers();
291 }
292 });
293
Stefan Holmerdbdb3a02018-07-17 16:03:46 +0200294 for (auto& rtp_sender : video_rtp_senders_) {
295 rtp_sender->OnNetworkAvailability(network_available);
296 }
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100297}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100298RtcpBandwidthObserver* RtpTransportControllerSend::GetBandwidthObserver() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100299 return this;
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100300}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100301int64_t RtpTransportControllerSend::GetPacerQueuingDelayMs() const {
Sebastian Janssona06e9192018-03-07 18:49:55 +0100302 return pacer_.QueueInMs();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100303}
304int64_t RtpTransportControllerSend::GetFirstPacketTimeMs() const {
Sebastian Janssona06e9192018-03-07 18:49:55 +0100305 return pacer_.FirstSentPacketTimeMs();
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100306}
Sebastian Jansson12130bb2018-03-21 12:48:43 +0100307void RtpTransportControllerSend::SetPerPacketFeedbackAvailable(bool available) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100308 RTC_DCHECK_RUN_ON(&task_queue_);
309 packet_feedback_available_ = available;
310 if (!controller_)
311 MaybeCreateControllers();
Sebastian Jansson12130bb2018-03-21 12:48:43 +0100312}
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100313void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100314 task_queue_.PostTask([this, enable]() {
315 RTC_DCHECK_RUN_ON(&task_queue_);
316 streams_config_.requests_alr_probing = enable;
317 UpdateStreamsConfig();
318 });
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100319}
320void RtpTransportControllerSend::OnSentPacket(
321 const rtc::SentPacket& sent_packet) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100322 absl::optional<SentPacket> packet_msg =
323 transport_feedback_adapter_.ProcessSentPacket(sent_packet);
324 if (packet_msg) {
325 task_queue_.PostTask([this, packet_msg]() {
326 RTC_DCHECK_RUN_ON(&task_queue_);
327 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100328 PostUpdates(controller_->OnSentPacket(*packet_msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100329 });
330 }
Sebastian Jansson16180952018-12-12 16:49:10 +0100331 pacer_.UpdateOutstandingData(
332 transport_feedback_adapter_.GetOutstandingData().bytes());
Sebastian Janssone4be6da2018-02-15 16:51:41 +0100333}
sprangdb2a9fc2017-08-09 06:42:32 -0700334
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100335void RtpTransportControllerSend::SetSdpBitrateParameters(
336 const BitrateConstraints& constraints) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200337 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100338 bitrate_configurator_.UpdateWithSdpParameters(constraints);
339 if (updated.has_value()) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100340 TargetRateConstraints msg = ConvertConstraints(*updated, clock_);
341 task_queue_.PostTask([this, msg]() {
342 RTC_DCHECK_RUN_ON(&task_queue_);
343 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100344 PostUpdates(controller_->OnTargetRateConstraints(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100345 } else {
346 UpdateInitialConstraints(msg);
347 }
348 });
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100349 } else {
350 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100351 << "WebRTC.RtpTransportControllerSend.SetSdpBitrateParameters: "
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100352 << "nothing to update";
353 }
354}
355
356void RtpTransportControllerSend::SetClientBitratePreferences(
Niels Möller0c4f7be2018-05-07 14:01:37 +0200357 const BitrateSettings& preferences) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200358 absl::optional<BitrateConstraints> updated =
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100359 bitrate_configurator_.UpdateWithClientPreferences(preferences);
360 if (updated.has_value()) {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100361 TargetRateConstraints msg = ConvertConstraints(*updated, clock_);
362 task_queue_.PostTask([this, msg]() {
363 RTC_DCHECK_RUN_ON(&task_queue_);
364 if (controller_) {
Sebastian Jansson16180952018-12-12 16:49:10 +0100365 PostUpdates(controller_->OnTargetRateConstraints(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100366 } else {
367 UpdateInitialConstraints(msg);
368 }
369 });
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100370 } else {
371 RTC_LOG(LS_VERBOSE)
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100372 << "WebRTC.RtpTransportControllerSend.SetClientBitratePreferences: "
Sebastian Jansson97f61ea2018-02-21 13:01:55 +0100373 << "nothing to update";
374 }
375}
Alex Narestbcf91802018-06-25 16:08:36 +0200376
377void RtpTransportControllerSend::SetAllocatedBitrateWithoutFeedback(
378 uint32_t bitrate_bps) {
Sebastian Jansson35fa2802018-10-01 09:16:12 +0200379 // Audio transport feedback will not be reported in this mode, instead update
380 // acknowledged bitrate estimator with the bitrate allocated for audio.
381 if (field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC")) {
382 // TODO(srte): Make sure it's safe to always report this and remove the
383 // field trial check.
Sebastian Jansson87609be2018-12-05 17:35:35 +0100384 task_queue_.PostTask([this, bitrate_bps]() {
385 RTC_DCHECK_RUN_ON(&task_queue_);
386 streams_config_.unacknowledged_rate_allocation =
387 DataRate::bps(bitrate_bps);
388 UpdateStreamsConfig();
389 });
Sebastian Jansson35fa2802018-10-01 09:16:12 +0200390 }
Alex Narestbcf91802018-06-25 16:08:36 +0200391}
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200392
393void RtpTransportControllerSend::OnTransportOverheadChanged(
394 size_t transport_overhead_bytes_per_packet) {
395 if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) {
396 RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes;
397 return;
398 }
399
400 // TODO(holmer): Call AudioRtpSenders when they have been moved to
401 // RtpTransportControllerSend.
402 for (auto& rtp_video_sender : video_rtp_senders_) {
403 rtp_video_sender->OnTransportOverheadChanged(
404 transport_overhead_bytes_per_packet);
405 }
406}
Sebastian Jansson87609be2018-12-05 17:35:35 +0100407
408void RtpTransportControllerSend::OnReceivedEstimatedBitrate(uint32_t bitrate) {
409 RemoteBitrateReport msg;
410 msg.receive_time = Timestamp::ms(clock_->TimeInMilliseconds());
411 msg.bandwidth = DataRate::bps(bitrate);
412 task_queue_.PostTask([this, msg]() {
413 RTC_DCHECK_RUN_ON(&task_queue_);
414 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100415 PostUpdates(controller_->OnRemoteBitrateReport(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100416 });
417}
418
419void RtpTransportControllerSend::OnReceivedRtcpReceiverReport(
420 const ReportBlockList& report_blocks,
421 int64_t rtt_ms,
422 int64_t now_ms) {
423 task_queue_.PostTask([this, report_blocks, now_ms]() {
424 RTC_DCHECK_RUN_ON(&task_queue_);
425 OnReceivedRtcpReceiverReportBlocks(report_blocks, now_ms);
426 });
427
428 task_queue_.PostTask([this, now_ms, rtt_ms]() {
429 RTC_DCHECK_RUN_ON(&task_queue_);
430 RoundTripTimeUpdate report;
431 report.receive_time = Timestamp::ms(now_ms);
432 report.round_trip_time = TimeDelta::ms(rtt_ms);
433 report.smoothed = false;
434 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100435 PostUpdates(controller_->OnRoundTripTimeUpdate(report));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100436 });
437}
438
439void RtpTransportControllerSend::AddPacket(uint32_t ssrc,
440 uint16_t sequence_number,
441 size_t length,
442 const PacedPacketInfo& pacing_info) {
443 if (send_side_bwe_with_overhead_) {
444 length += transport_overhead_bytes_per_packet_;
445 }
446 transport_feedback_adapter_.AddPacket(ssrc, sequence_number, length,
447 pacing_info);
448}
449
450void RtpTransportControllerSend::OnTransportFeedback(
451 const rtcp::TransportFeedback& feedback) {
452 RTC_DCHECK_RUNS_SERIALIZED(&worker_race_);
453
454 absl::optional<TransportPacketsFeedback> feedback_msg =
455 transport_feedback_adapter_.ProcessTransportFeedback(feedback);
456 if (feedback_msg) {
457 task_queue_.PostTask([this, feedback_msg]() {
458 RTC_DCHECK_RUN_ON(&task_queue_);
459 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100460 PostUpdates(controller_->OnTransportPacketsFeedback(*feedback_msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100461 });
462 }
Sebastian Jansson16180952018-12-12 16:49:10 +0100463 pacer_.UpdateOutstandingData(
464 transport_feedback_adapter_.GetOutstandingData().bytes());
Sebastian Jansson87609be2018-12-05 17:35:35 +0100465}
466
467void RtpTransportControllerSend::OnRttUpdate(int64_t avg_rtt_ms,
468 int64_t max_rtt_ms) {
469 int64_t now_ms = clock_->TimeInMilliseconds();
470 RoundTripTimeUpdate report;
471 report.receive_time = Timestamp::ms(now_ms);
472 report.round_trip_time = TimeDelta::ms(avg_rtt_ms);
473 report.smoothed = true;
474 task_queue_.PostTask([this, report]() {
475 RTC_DCHECK_RUN_ON(&task_queue_);
476 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100477 PostUpdates(controller_->OnRoundTripTimeUpdate(report));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100478 });
479}
480
481void RtpTransportControllerSend::MaybeCreateControllers() {
482 RTC_DCHECK(!controller_);
483 RTC_DCHECK(!control_handler_);
484
485 if (!network_available_ || !observer_)
486 return;
Sebastian Jansson16180952018-12-12 16:49:10 +0100487 control_handler_ = absl::make_unique<CongestionControlHandler>();
Sebastian Jansson87609be2018-12-05 17:35:35 +0100488
489 initial_config_.constraints.at_time =
490 Timestamp::ms(clock_->TimeInMilliseconds());
491 initial_config_.stream_based_config = streams_config_;
492
493 // TODO(srte): Use fallback controller if no feedback is available.
494 if (controller_factory_override_) {
495 RTC_LOG(LS_INFO) << "Creating overridden congestion controller";
496 controller_ = controller_factory_override_->Create(initial_config_);
497 process_interval_ = controller_factory_override_->GetProcessInterval();
498 } else {
499 RTC_LOG(LS_INFO) << "Creating fallback congestion controller";
500 controller_ = controller_factory_fallback_->Create(initial_config_);
501 process_interval_ = controller_factory_fallback_->GetProcessInterval();
502 }
503 UpdateControllerWithTimeInterval();
504 StartProcessPeriodicTasks();
505}
506
507void RtpTransportControllerSend::UpdateInitialConstraints(
508 TargetRateConstraints new_contraints) {
509 if (!new_contraints.starting_rate)
510 new_contraints.starting_rate = initial_config_.constraints.starting_rate;
511 RTC_DCHECK(new_contraints.starting_rate);
512 initial_config_.constraints = new_contraints;
513}
514
515void RtpTransportControllerSend::StartProcessPeriodicTasks() {
Sebastian Janssonecb68972019-01-18 10:30:54 +0100516 if (!pacer_queue_update_task_.Running()) {
517 pacer_queue_update_task_ = RepeatingTaskHandle::DelayedStart(
518 &task_queue_, kPacerQueueUpdateInterval, [this]() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100519 RTC_DCHECK_RUN_ON(&task_queue_);
Sebastian Jansson16180952018-12-12 16:49:10 +0100520 TimeDelta expected_queue_time =
521 TimeDelta::ms(pacer_.ExpectedQueueTimeMs());
522 control_handler_->SetPacerQueue(expected_queue_time);
523 UpdateControlState();
Sebastian Janssonecb68972019-01-18 10:30:54 +0100524 return kPacerQueueUpdateInterval;
Sebastian Jansson87609be2018-12-05 17:35:35 +0100525 });
526 }
Sebastian Janssonecb68972019-01-18 10:30:54 +0100527 controller_task_.Stop();
Sebastian Jansson87609be2018-12-05 17:35:35 +0100528 if (process_interval_.IsFinite()) {
Sebastian Janssonecb68972019-01-18 10:30:54 +0100529 controller_task_ = RepeatingTaskHandle::DelayedStart(
530 &task_queue_, process_interval_, [this]() {
Sebastian Jansson87609be2018-12-05 17:35:35 +0100531 RTC_DCHECK_RUN_ON(&task_queue_);
532 UpdateControllerWithTimeInterval();
Sebastian Janssonecb68972019-01-18 10:30:54 +0100533 return process_interval_;
Sebastian Jansson87609be2018-12-05 17:35:35 +0100534 });
535 }
536}
537
538void RtpTransportControllerSend::UpdateControllerWithTimeInterval() {
Sebastian Jansson16180952018-12-12 16:49:10 +0100539 RTC_DCHECK(controller_);
540 ProcessInterval msg;
541 msg.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
Christoffer Rodbroc610e262019-01-08 10:49:19 +0100542 if (add_pacing_to_cwin_)
543 msg.pacer_queue = DataSize::bytes(pacer_.QueueSizeBytes());
Sebastian Jansson16180952018-12-12 16:49:10 +0100544 PostUpdates(controller_->OnProcessInterval(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100545}
546
547void RtpTransportControllerSend::UpdateStreamsConfig() {
548 streams_config_.at_time = Timestamp::ms(clock_->TimeInMilliseconds());
549 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100550 PostUpdates(controller_->OnStreamsConfig(streams_config_));
551}
552
553void RtpTransportControllerSend::PostUpdates(NetworkControlUpdate update) {
554 if (update.congestion_window) {
555 if (update.congestion_window->IsFinite())
556 pacer_.SetCongestionWindow(update.congestion_window->bytes());
557 else
558 pacer_.SetCongestionWindow(PacedSender::kNoCongestionWindow);
559 }
560 if (update.pacer_config) {
561 pacer_.SetPacingRates(update.pacer_config->data_rate().bps(),
562 update.pacer_config->pad_rate().bps());
563 }
564 for (const auto& probe : update.probe_cluster_configs) {
565 int64_t bitrate_bps = probe.target_data_rate.bps();
566 pacer_.CreateProbeCluster(bitrate_bps);
567 }
568 if (update.target_rate) {
569 control_handler_->SetTargetRate(*update.target_rate);
570 UpdateControlState();
571 }
Sebastian Jansson87609be2018-12-05 17:35:35 +0100572}
573
574void RtpTransportControllerSend::OnReceivedRtcpReceiverReportBlocks(
575 const ReportBlockList& report_blocks,
576 int64_t now_ms) {
577 if (report_blocks.empty())
578 return;
579
580 int total_packets_lost_delta = 0;
581 int total_packets_delta = 0;
582
583 // Compute the packet loss from all report blocks.
584 for (const RTCPReportBlock& report_block : report_blocks) {
585 auto it = last_report_blocks_.find(report_block.source_ssrc);
586 if (it != last_report_blocks_.end()) {
587 auto number_of_packets = report_block.extended_highest_sequence_number -
588 it->second.extended_highest_sequence_number;
589 total_packets_delta += number_of_packets;
590 auto lost_delta = report_block.packets_lost - it->second.packets_lost;
591 total_packets_lost_delta += lost_delta;
592 }
593 last_report_blocks_[report_block.source_ssrc] = report_block;
594 }
595 // Can only compute delta if there has been previous blocks to compare to. If
596 // not, total_packets_delta will be unchanged and there's nothing more to do.
597 if (!total_packets_delta)
598 return;
599 int packets_received_delta = total_packets_delta - total_packets_lost_delta;
600 // To detect lost packets, at least one packet has to be received. This check
601 // is needed to avoid bandwith detection update in
602 // VideoSendStreamTest.SuspendBelowMinBitrate
603
604 if (packets_received_delta < 1)
605 return;
606 Timestamp now = Timestamp::ms(now_ms);
607 TransportLossReport msg;
608 msg.packets_lost_delta = total_packets_lost_delta;
609 msg.packets_received_delta = packets_received_delta;
610 msg.receive_time = now;
611 msg.start_time = last_report_block_time_;
612 msg.end_time = now;
613 if (controller_)
Sebastian Jansson16180952018-12-12 16:49:10 +0100614 PostUpdates(controller_->OnTransportLossReport(msg));
Sebastian Jansson87609be2018-12-05 17:35:35 +0100615 last_report_block_time_ = now;
616}
617
nissecae45d02017-04-24 05:53:20 -0700618} // namespace webrtc