blob: 3cfdee2ccba8c2569a724c0261c16a4f953a2746 [file] [log] [blame]
Sebastian Jansson8e0b15b2018-04-18 19:19:22 +02001/*
2 * Copyright 2018 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 */
10#include "video/video_send_stream_impl.h"
11
12#include <algorithm>
13#include <string>
14#include <utility>
15
16#include "call/rtp_transport_controller_send_interface.h"
17#include "modules/pacing/packet_router.h"
18#include "modules/rtp_rtcp/include/rtp_rtcp.h"
19#include "modules/rtp_rtcp/source/rtp_sender.h"
20#include "rtc_base/checks.h"
21#include "rtc_base/experiments/alr_experiment.h"
22#include "rtc_base/file.h"
23#include "rtc_base/location.h"
24#include "rtc_base/logging.h"
25#include "rtc_base/numerics/safe_conversions.h"
26#include "rtc_base/trace_event.h"
27#include "system_wrappers/include/field_trial.h"
28
29namespace webrtc {
30namespace internal {
31namespace {
32static const int kMinSendSidePacketHistorySize = 600;
33
34// Assume an average video stream has around 3 packets per frame (1 mbps / 30
35// fps / 1400B) A sequence number set with size 5500 will be able to store
36// packet sequence number for at least last 60 seconds.
37static const int kSendSideSeqNumSetMaxSize = 5500;
38
39// We don't do MTU discovery, so assume that we have the standard ethernet MTU.
40const size_t kPathMTU = 1500;
41
42std::vector<RtpRtcp*> CreateRtpRtcpModules(
43 const VideoSendStream::Config& config,
44 RtcpIntraFrameObserver* intra_frame_callback,
45 RtcpBandwidthObserver* bandwidth_callback,
46 RtpTransportControllerSendInterface* transport,
47 RtcpRttStats* rtt_stats,
48 FlexfecSender* flexfec_sender,
49 SendStatisticsProxy* stats_proxy,
50 SendDelayStats* send_delay_stats,
51 RtcEventLog* event_log,
52 RateLimiter* retransmission_rate_limiter,
53 OverheadObserver* overhead_observer,
54 RtpKeepAliveConfig keepalive_config) {
55 RTC_DCHECK_GT(config.rtp.ssrcs.size(), 0);
56 RtpRtcp::Configuration configuration;
57 configuration.audio = false;
58 configuration.receiver_only = false;
59 configuration.outgoing_transport = config.send_transport;
60 configuration.intra_frame_callback = intra_frame_callback;
61 configuration.bandwidth_callback = bandwidth_callback;
62 configuration.transport_feedback_callback =
63 transport->transport_feedback_observer();
64 configuration.rtt_stats = rtt_stats;
65 configuration.rtcp_packet_type_counter_observer = stats_proxy;
66 configuration.paced_sender = transport->packet_sender();
67 configuration.transport_sequence_number_allocator =
68 transport->packet_router();
69 configuration.send_bitrate_observer = stats_proxy;
70 configuration.send_frame_count_observer = stats_proxy;
71 configuration.send_side_delay_observer = stats_proxy;
72 configuration.send_packet_observer = send_delay_stats;
73 configuration.event_log = event_log;
74 configuration.retransmission_rate_limiter = retransmission_rate_limiter;
75 configuration.overhead_observer = overhead_observer;
76 configuration.keepalive_config = keepalive_config;
77 configuration.rtcp_interval_config.video_interval_ms =
78 config.rtcp.video_report_interval_ms;
79 configuration.rtcp_interval_config.audio_interval_ms =
80 config.rtcp.audio_report_interval_ms;
81 std::vector<RtpRtcp*> modules;
82 const std::vector<uint32_t>& flexfec_protected_ssrcs =
83 config.rtp.flexfec.protected_media_ssrcs;
84 for (uint32_t ssrc : config.rtp.ssrcs) {
85 bool enable_flexfec = flexfec_sender != nullptr &&
86 std::find(flexfec_protected_ssrcs.begin(),
87 flexfec_protected_ssrcs.end(),
88 ssrc) != flexfec_protected_ssrcs.end();
89 configuration.flexfec_sender = enable_flexfec ? flexfec_sender : nullptr;
90 RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration);
91 rtp_rtcp->SetSendingStatus(false);
92 rtp_rtcp->SetSendingMediaStatus(false);
93 rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
94 modules.push_back(rtp_rtcp);
95 }
96 return modules;
97}
98
99// TODO(brandtr): Update this function when we support multistream protection.
100std::unique_ptr<FlexfecSender> MaybeCreateFlexfecSender(
101 const VideoSendStream::Config& config,
102 const std::map<uint32_t, RtpState>& suspended_ssrcs) {
103 if (config.rtp.flexfec.payload_type < 0) {
104 return nullptr;
105 }
106 RTC_DCHECK_GE(config.rtp.flexfec.payload_type, 0);
107 RTC_DCHECK_LE(config.rtp.flexfec.payload_type, 127);
108 if (config.rtp.flexfec.ssrc == 0) {
109 RTC_LOG(LS_WARNING) << "FlexFEC is enabled, but no FlexFEC SSRC given. "
110 "Therefore disabling FlexFEC.";
111 return nullptr;
112 }
113 if (config.rtp.flexfec.protected_media_ssrcs.empty()) {
114 RTC_LOG(LS_WARNING)
115 << "FlexFEC is enabled, but no protected media SSRC given. "
116 "Therefore disabling FlexFEC.";
117 return nullptr;
118 }
119
120 if (config.rtp.flexfec.protected_media_ssrcs.size() > 1) {
121 RTC_LOG(LS_WARNING)
122 << "The supplied FlexfecConfig contained multiple protected "
123 "media streams, but our implementation currently only "
124 "supports protecting a single media stream. "
125 "To avoid confusion, disabling FlexFEC completely.";
126 return nullptr;
127 }
128
129 const RtpState* rtp_state = nullptr;
130 auto it = suspended_ssrcs.find(config.rtp.flexfec.ssrc);
131 if (it != suspended_ssrcs.end()) {
132 rtp_state = &it->second;
133 }
134
135 RTC_DCHECK_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
136 return rtc::MakeUnique<FlexfecSender>(
137 config.rtp.flexfec.payload_type, config.rtp.flexfec.ssrc,
138 config.rtp.flexfec.protected_media_ssrcs[0], config.rtp.mid,
139 config.rtp.extensions, RTPSender::FecExtensionSizes(), rtp_state,
140 Clock::GetRealTimeClock());
141}
142
143bool TransportSeqNumExtensionConfigured(const VideoSendStream::Config& config) {
144 const std::vector<RtpExtension>& extensions = config.rtp.extensions;
145 return std::find_if(
146 extensions.begin(), extensions.end(), [](const RtpExtension& ext) {
147 return ext.uri == RtpExtension::kTransportSequenceNumberUri;
148 }) != extensions.end();
149}
150
151const char kForcedFallbackFieldTrial[] =
152 "WebRTC-VP8-Forced-Fallback-Encoder-v2";
153
154rtc::Optional<int> GetFallbackMinBpsFromFieldTrial() {
155 if (!webrtc::field_trial::IsEnabled(kForcedFallbackFieldTrial))
156 return rtc::nullopt;
157
158 std::string group =
159 webrtc::field_trial::FindFullName(kForcedFallbackFieldTrial);
160 if (group.empty())
161 return rtc::nullopt;
162
163 int min_pixels;
164 int max_pixels;
165 int min_bps;
166 if (sscanf(group.c_str(), "Enabled-%d,%d,%d", &min_pixels, &max_pixels,
167 &min_bps) != 3) {
168 return rtc::nullopt;
169 }
170
171 if (min_bps <= 0)
172 return rtc::nullopt;
173
174 return min_bps;
175}
176
177int GetEncoderMinBitrateBps() {
178 const int kDefaultEncoderMinBitrateBps = 30000;
179 return GetFallbackMinBpsFromFieldTrial().value_or(
180 kDefaultEncoderMinBitrateBps);
181}
182
183bool PayloadTypeSupportsSkippingFecPackets(const std::string& payload_name) {
184 const VideoCodecType codecType = PayloadStringToCodecType(payload_name);
185 if (codecType == kVideoCodecVP8 || codecType == kVideoCodecVP9) {
186 return true;
187 }
188 return false;
189}
190
191int CalculateMaxPadBitrateBps(std::vector<VideoStream> streams,
192 int min_transmit_bitrate_bps,
193 bool pad_to_min_bitrate) {
194 int pad_up_to_bitrate_bps = 0;
195 // Calculate max padding bitrate for a multi layer codec.
196 if (streams.size() > 1) {
197 // Pad to min bitrate of the highest layer.
198 pad_up_to_bitrate_bps = streams[streams.size() - 1].min_bitrate_bps;
199 // Add target_bitrate_bps of the lower layers.
200 for (size_t i = 0; i < streams.size() - 1; ++i)
201 pad_up_to_bitrate_bps += streams[i].target_bitrate_bps;
202 } else if (pad_to_min_bitrate) {
203 pad_up_to_bitrate_bps = streams[0].min_bitrate_bps;
204 }
205
206 pad_up_to_bitrate_bps =
207 std::max(pad_up_to_bitrate_bps, min_transmit_bitrate_bps);
208
209 return pad_up_to_bitrate_bps;
210}
211
212uint32_t CalculateOverheadRateBps(int packets_per_second,
213 size_t overhead_bytes_per_packet,
214 uint32_t max_overhead_bps) {
215 uint32_t overhead_bps =
216 static_cast<uint32_t>(8 * overhead_bytes_per_packet * packets_per_second);
217 return std::min(overhead_bps, max_overhead_bps);
218}
219
220int CalculatePacketRate(uint32_t bitrate_bps, size_t packet_size_bytes) {
221 size_t packet_size_bits = 8 * packet_size_bytes;
222 // Ceil for int value of bitrate_bps / packet_size_bits.
223 return static_cast<int>((bitrate_bps + packet_size_bits - 1) /
224 packet_size_bits);
225}
226
227} // namespace
228
229// CheckEncoderActivityTask is used for tracking when the encoder last produced
230// and encoded video frame. If the encoder has not produced anything the last
231// kEncoderTimeOutMs we also want to stop sending padding.
232class VideoSendStreamImpl::CheckEncoderActivityTask : public rtc::QueuedTask {
233 public:
234 static const int kEncoderTimeOutMs = 2000;
235 explicit CheckEncoderActivityTask(
236 const rtc::WeakPtr<VideoSendStreamImpl>& send_stream)
237 : activity_(0), send_stream_(std::move(send_stream)), timed_out_(false) {}
238
239 void Stop() {
240 RTC_CHECK(task_checker_.CalledSequentially());
241 send_stream_.reset();
242 }
243
244 void UpdateEncoderActivity() {
245 // UpdateEncoderActivity is called from VideoSendStreamImpl::Encoded on
246 // whatever thread the real encoder implementation run on. In the case of
247 // hardware encoders, there might be several encoders
248 // running in parallel on different threads.
249 rtc::AtomicOps::ReleaseStore(&activity_, 1);
250 }
251
252 private:
253 bool Run() override {
254 RTC_CHECK(task_checker_.CalledSequentially());
255 if (!send_stream_)
256 return true;
257 if (!rtc::AtomicOps::AcquireLoad(&activity_)) {
258 if (!timed_out_) {
259 send_stream_->SignalEncoderTimedOut();
260 }
261 timed_out_ = true;
262 } else if (timed_out_) {
263 send_stream_->SignalEncoderActive();
264 timed_out_ = false;
265 }
266 rtc::AtomicOps::ReleaseStore(&activity_, 0);
267
268 rtc::TaskQueue::Current()->PostDelayedTask(
269 std::unique_ptr<rtc::QueuedTask>(this), kEncoderTimeOutMs);
270 // Return false to prevent this task from being deleted. Ownership has been
271 // transferred to the task queue when PostDelayedTask was called.
272 return false;
273 }
274 volatile int activity_;
275
276 rtc::SequencedTaskChecker task_checker_;
277 rtc::WeakPtr<VideoSendStreamImpl> send_stream_;
278 bool timed_out_;
279};
280
281VideoSendStreamImpl::VideoSendStreamImpl(
282 SendStatisticsProxy* stats_proxy,
283 rtc::TaskQueue* worker_queue,
284 CallStats* call_stats,
285 RtpTransportControllerSendInterface* transport,
286 BitrateAllocator* bitrate_allocator,
287 SendDelayStats* send_delay_stats,
288 VideoStreamEncoder* video_stream_encoder,
289 RtcEventLog* event_log,
290 const VideoSendStream::Config* config,
291 int initial_encoder_max_bitrate,
292 double initial_encoder_bitrate_priority,
293 std::map<uint32_t, RtpState> suspended_ssrcs,
294 std::map<uint32_t, RtpPayloadState> suspended_payload_states,
295 VideoEncoderConfig::ContentType content_type,
296 std::unique_ptr<FecController> fec_controller,
297 RateLimiter* retransmission_limiter)
298 : send_side_bwe_with_overhead_(
299 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
300 stats_proxy_(stats_proxy),
301 config_(config),
302 suspended_ssrcs_(std::move(suspended_ssrcs)),
303 fec_controller_(std::move(fec_controller)),
304 module_process_thread_(nullptr),
305 worker_queue_(worker_queue),
306 check_encoder_activity_task_(nullptr),
307 call_stats_(call_stats),
308 transport_(transport),
309 bitrate_allocator_(bitrate_allocator),
310 flexfec_sender_(MaybeCreateFlexfecSender(*config_, suspended_ssrcs_)),
311 max_padding_bitrate_(0),
312 encoder_min_bitrate_bps_(0),
313 encoder_target_rate_bps_(0),
314 encoder_bitrate_priority_(initial_encoder_bitrate_priority),
315 has_packet_feedback_(false),
316 video_stream_encoder_(video_stream_encoder),
317 encoder_feedback_(Clock::GetRealTimeClock(),
318 config_->rtp.ssrcs,
319 video_stream_encoder),
320 bandwidth_observer_(transport->GetBandwidthObserver()),
321 rtp_rtcp_modules_(CreateRtpRtcpModules(*config_,
322 &encoder_feedback_,
323 bandwidth_observer_,
324 transport,
325 call_stats,
326 flexfec_sender_.get(),
327 stats_proxy_,
328 send_delay_stats,
329 event_log,
330 retransmission_limiter,
331 this,
332 transport->keepalive_config())),
333 payload_router_(rtp_rtcp_modules_,
334 config_->rtp.ssrcs,
335 config_->rtp.payload_type,
336 suspended_payload_states),
337 weak_ptr_factory_(this),
338 overhead_bytes_per_packet_(0),
339 transport_overhead_bytes_per_packet_(0) {
340 RTC_DCHECK_RUN_ON(worker_queue_);
341 RTC_LOG(LS_INFO) << "VideoSendStreamInternal: " << config_->ToString();
342 weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
343 module_process_thread_checker_.DetachFromThread();
344
345 RTC_DCHECK(!config_->rtp.ssrcs.empty());
346 RTC_DCHECK(call_stats_);
347 RTC_DCHECK(transport_);
348 RTC_DCHECK_NE(initial_encoder_max_bitrate, 0);
349
350 if (initial_encoder_max_bitrate > 0) {
351 encoder_max_bitrate_bps_ =
352 rtc::dchecked_cast<uint32_t>(initial_encoder_max_bitrate);
353 } else {
354 // TODO(srte): Make sure max bitrate is not set to negative values. We don't
355 // have any way to handle unset values in downstream code, such as the
356 // bitrate allocator. Previously -1 was implicitly casted to UINT32_MAX, a
357 // behaviour that is not safe. Converting to 10 Mbps should be safe for
358 // reasonable use cases as it allows adding the max of multiple streams
359 // without wrappping around.
360 const int kFallbackMaxBitrateBps = 10000000;
361 RTC_DLOG(LS_ERROR) << "ERROR: Initial encoder max bitrate = "
362 << initial_encoder_max_bitrate << " which is <= 0!";
363 RTC_DLOG(LS_INFO) << "Using default encoder max bitrate = 10 Mbps";
364 encoder_max_bitrate_bps_ = kFallbackMaxBitrateBps;
365 }
366
367 RTC_CHECK(AlrExperimentSettings::MaxOneFieldTrialEnabled());
368 // If send-side BWE is enabled, check if we should apply updated probing and
369 // pacing settings.
370 if (TransportSeqNumExtensionConfigured(*config_)) {
371 has_packet_feedback_ = true;
372
373 rtc::Optional<AlrExperimentSettings> alr_settings;
374 if (content_type == VideoEncoderConfig::ContentType::kScreen) {
375 alr_settings = AlrExperimentSettings::CreateFromFieldTrial(
376 AlrExperimentSettings::kScreenshareProbingBweExperimentName);
377 } else {
378 alr_settings = AlrExperimentSettings::CreateFromFieldTrial(
379 AlrExperimentSettings::kStrictPacingAndProbingExperimentName);
380 }
381 if (alr_settings) {
382 transport->EnablePeriodicAlrProbing(true);
383 transport->SetPacingFactor(alr_settings->pacing_factor);
384 configured_pacing_factor_ = alr_settings->pacing_factor;
385 transport->SetQueueTimeLimit(alr_settings->max_paced_queue_time);
386 } else {
387 transport->EnablePeriodicAlrProbing(false);
388 transport->SetPacingFactor(PacedSender::kDefaultPaceMultiplier);
389 configured_pacing_factor_ = PacedSender::kDefaultPaceMultiplier;
390 transport->SetQueueTimeLimit(PacedSender::kMaxQueueLengthMs);
391 }
392 }
393
394 if (config_->periodic_alr_bandwidth_probing) {
395 transport->EnablePeriodicAlrProbing(true);
396 }
397
398 // RTP/RTCP initialization.
399
400 // We add the highest spatial layer first to ensure it'll be prioritized
401 // when sending padding, with the hope that the packet rate will be smaller,
402 // and that it's more important to protect than the lower layers.
403 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
404 constexpr bool remb_candidate = true;
405 transport->packet_router()->AddSendRtpModule(rtp_rtcp, remb_candidate);
406 }
407
408 for (size_t i = 0; i < config_->rtp.extensions.size(); ++i) {
409 const std::string& extension = config_->rtp.extensions[i].uri;
410 int id = config_->rtp.extensions[i].id;
411 // One-byte-extension local identifiers are in the range 1-14 inclusive.
412 RTC_DCHECK_GE(id, 1);
413 RTC_DCHECK_LE(id, 14);
414 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension));
415 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
416 RTC_CHECK_EQ(0, rtp_rtcp->RegisterSendRtpHeaderExtension(
417 StringToRtpExtensionType(extension), id));
418 }
419 }
420
421 ConfigureProtection();
422 ConfigureSsrcs();
423
424 if (!config_->rtp.mid.empty()) {
425 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
426 rtp_rtcp->SetMid(config_->rtp.mid);
427 }
428 }
429
430 // TODO(pbos): Should we set CNAME on all RTP modules?
431 rtp_rtcp_modules_.front()->SetCNAME(config_->rtp.c_name.c_str());
432
433 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
434 rtp_rtcp->RegisterRtcpStatisticsCallback(stats_proxy_);
435 rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(stats_proxy_);
436 rtp_rtcp->SetMaxRtpPacketSize(config_->rtp.max_packet_size);
437 rtp_rtcp->RegisterVideoSendPayload(config_->rtp.payload_type,
438 config_->rtp.payload_name.c_str());
439 }
440
441 fec_controller_->SetProtectionCallback(this);
442 // Signal congestion controller this object is ready for OnPacket* callbacks.
443 if (fec_controller_->UseLossVectorMask()) {
444 transport_->RegisterPacketFeedbackObserver(this);
445 }
446
447 RTC_DCHECK(config_->encoder_settings.encoder);
448 RTC_DCHECK_GE(config_->rtp.payload_type, 0);
449 RTC_DCHECK_LE(config_->rtp.payload_type, 127);
450
451 video_stream_encoder_->SetStartBitrate(
452 bitrate_allocator_->GetStartBitrate(this));
453
454 // Only request rotation at the source when we positively know that the remote
455 // side doesn't support the rotation extension. This allows us to prepare the
456 // encoder in the expectation that rotation is supported - which is the common
457 // case.
458 bool rotation_applied =
459 std::find_if(config_->rtp.extensions.begin(),
460 config_->rtp.extensions.end(),
461 [](const RtpExtension& extension) {
462 return extension.uri == RtpExtension::kVideoRotationUri;
463 }) == config_->rtp.extensions.end();
464
465 video_stream_encoder_->SetSink(this, rotation_applied);
466}
467
468void VideoSendStreamImpl::RegisterProcessThread(
469 ProcessThread* module_process_thread) {
470 RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
471 RTC_DCHECK(!module_process_thread_);
472 module_process_thread_ = module_process_thread;
473
474 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
475 module_process_thread_->RegisterModule(rtp_rtcp, RTC_FROM_HERE);
476}
477
478void VideoSendStreamImpl::DeRegisterProcessThread() {
479 RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
480 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
481 module_process_thread_->DeRegisterModule(rtp_rtcp);
482}
483
484VideoSendStreamImpl::~VideoSendStreamImpl() {
485 RTC_DCHECK_RUN_ON(worker_queue_);
486 RTC_DCHECK(!payload_router_.IsActive())
487 << "VideoSendStreamImpl::Stop not called";
488 RTC_LOG(LS_INFO) << "~VideoSendStreamInternal: " << config_->ToString();
489 if (fec_controller_->UseLossVectorMask()) {
490 transport_->DeRegisterPacketFeedbackObserver(this);
491 }
492 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
493 transport_->packet_router()->RemoveSendRtpModule(rtp_rtcp);
494 delete rtp_rtcp;
495 }
496}
497
498bool VideoSendStreamImpl::DeliverRtcp(const uint8_t* packet, size_t length) {
499 // Runs on a network thread.
500 RTC_DCHECK(!worker_queue_->IsCurrent());
501 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
502 rtp_rtcp->IncomingRtcpPacket(packet, length);
503 return true;
504}
505
506void VideoSendStreamImpl::UpdateActiveSimulcastLayers(
507 const std::vector<bool> active_layers) {
508 RTC_DCHECK_RUN_ON(worker_queue_);
509 RTC_DCHECK_EQ(rtp_rtcp_modules_.size(), active_layers.size());
510 RTC_LOG(LS_INFO) << "VideoSendStream::UpdateActiveSimulcastLayers";
511 bool previously_active = payload_router_.IsActive();
512 payload_router_.SetActiveModules(active_layers);
513 if (!payload_router_.IsActive() && previously_active) {
514 // Payload router switched from active to inactive.
515 StopVideoSendStream();
516 } else if (payload_router_.IsActive() && !previously_active) {
517 // Payload router switched from inactive to active.
518 StartupVideoSendStream();
519 }
520}
521
522void VideoSendStreamImpl::Start() {
523 RTC_DCHECK_RUN_ON(worker_queue_);
524 RTC_LOG(LS_INFO) << "VideoSendStream::Start";
525 if (payload_router_.IsActive())
526 return;
527 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start");
528 payload_router_.SetActive(true);
529 StartupVideoSendStream();
530}
531
532void VideoSendStreamImpl::StartupVideoSendStream() {
533 RTC_DCHECK_RUN_ON(worker_queue_);
534 bitrate_allocator_->AddObserver(
535 this, encoder_min_bitrate_bps_, encoder_max_bitrate_bps_,
536 max_padding_bitrate_, !config_->suspend_below_min_bitrate,
537 config_->track_id, encoder_bitrate_priority_, has_packet_feedback_);
538 // Start monitoring encoder activity.
539 {
540 rtc::CritScope lock(&encoder_activity_crit_sect_);
541 RTC_DCHECK(!check_encoder_activity_task_);
542 check_encoder_activity_task_ = new CheckEncoderActivityTask(weak_ptr_);
543 worker_queue_->PostDelayedTask(
544 std::unique_ptr<rtc::QueuedTask>(check_encoder_activity_task_),
545 CheckEncoderActivityTask::kEncoderTimeOutMs);
546 }
547
548 video_stream_encoder_->SendKeyFrame();
549}
550
551void VideoSendStreamImpl::Stop() {
552 RTC_DCHECK_RUN_ON(worker_queue_);
553 RTC_LOG(LS_INFO) << "VideoSendStream::Stop";
554 if (!payload_router_.IsActive())
555 return;
556 TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
557 payload_router_.SetActive(false);
558 StopVideoSendStream();
559}
560
561void VideoSendStreamImpl::StopVideoSendStream() {
562 bitrate_allocator_->RemoveObserver(this);
563 {
564 rtc::CritScope lock(&encoder_activity_crit_sect_);
565 check_encoder_activity_task_->Stop();
566 check_encoder_activity_task_ = nullptr;
567 }
568 video_stream_encoder_->OnBitrateUpdated(0, 0, 0);
569 stats_proxy_->OnSetEncoderTargetRate(0);
570}
571
572void VideoSendStreamImpl::SignalEncoderTimedOut() {
573 RTC_DCHECK_RUN_ON(worker_queue_);
574 // If the encoder has not produced anything the last kEncoderTimeOutMs and it
575 // is supposed to, deregister as BitrateAllocatorObserver. This can happen
576 // if a camera stops producing frames.
577 if (encoder_target_rate_bps_ > 0) {
578 RTC_LOG(LS_INFO) << "SignalEncoderTimedOut, Encoder timed out.";
579 bitrate_allocator_->RemoveObserver(this);
580 }
581}
582
583void VideoSendStreamImpl::OnBitrateAllocationUpdated(
584 const BitrateAllocation& allocation) {
585 payload_router_.OnBitrateAllocationUpdated(allocation);
586}
587
588void VideoSendStreamImpl::SignalEncoderActive() {
589 RTC_DCHECK_RUN_ON(worker_queue_);
590 RTC_LOG(LS_INFO) << "SignalEncoderActive, Encoder is active.";
591 bitrate_allocator_->AddObserver(
592 this, encoder_min_bitrate_bps_, encoder_max_bitrate_bps_,
593 max_padding_bitrate_, !config_->suspend_below_min_bitrate,
594 config_->track_id, encoder_bitrate_priority_, has_packet_feedback_);
595}
596
597void VideoSendStreamImpl::OnEncoderConfigurationChanged(
598 std::vector<VideoStream> streams,
599 int min_transmit_bitrate_bps) {
600 if (!worker_queue_->IsCurrent()) {
601 rtc::WeakPtr<VideoSendStreamImpl> send_stream = weak_ptr_;
602 worker_queue_->PostTask([send_stream, streams, min_transmit_bitrate_bps]() {
603 if (send_stream)
604 send_stream->OnEncoderConfigurationChanged(std::move(streams),
605 min_transmit_bitrate_bps);
606 });
607 return;
608 }
609 RTC_DCHECK_GE(config_->rtp.ssrcs.size(), streams.size());
610 TRACE_EVENT0("webrtc", "VideoSendStream::OnEncoderConfigurationChanged");
611 RTC_DCHECK_GE(config_->rtp.ssrcs.size(), streams.size());
612 RTC_DCHECK_RUN_ON(worker_queue_);
613
614 encoder_min_bitrate_bps_ =
615 std::max(streams[0].min_bitrate_bps, GetEncoderMinBitrateBps());
616 encoder_max_bitrate_bps_ = 0;
617 double stream_bitrate_priority_sum = 0;
618 for (const auto& stream : streams) {
619 // We don't want to allocate more bitrate than needed to inactive streams.
620 encoder_max_bitrate_bps_ += stream.active ? stream.max_bitrate_bps : 0;
621 if (stream.bitrate_priority) {
622 RTC_DCHECK_GT(*stream.bitrate_priority, 0);
623 stream_bitrate_priority_sum += *stream.bitrate_priority;
624 }
625 }
626 RTC_DCHECK_GT(stream_bitrate_priority_sum, 0);
627 encoder_bitrate_priority_ = stream_bitrate_priority_sum;
628 encoder_max_bitrate_bps_ =
629 std::max(static_cast<uint32_t>(encoder_min_bitrate_bps_),
630 encoder_max_bitrate_bps_);
631 max_padding_bitrate_ = CalculateMaxPadBitrateBps(
632 streams, min_transmit_bitrate_bps, config_->suspend_below_min_bitrate);
633
634 // Clear stats for disabled layers.
635 for (size_t i = streams.size(); i < config_->rtp.ssrcs.size(); ++i) {
636 stats_proxy_->OnInactiveSsrc(config_->rtp.ssrcs[i]);
637 }
638
639 const size_t num_temporal_layers =
640 streams.back().num_temporal_layers.value_or(1);
641 fec_controller_->SetEncodingData(streams[0].width, streams[0].height,
642 num_temporal_layers,
643 config_->rtp.max_packet_size);
644
645 if (payload_router_.IsActive()) {
646 // The send stream is started already. Update the allocator with new bitrate
647 // limits.
648 bitrate_allocator_->AddObserver(
649 this, encoder_min_bitrate_bps_, encoder_max_bitrate_bps_,
650 max_padding_bitrate_, !config_->suspend_below_min_bitrate,
651 config_->track_id, encoder_bitrate_priority_, has_packet_feedback_);
652 }
653}
654
655EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage(
656 const EncodedImage& encoded_image,
657 const CodecSpecificInfo* codec_specific_info,
658 const RTPFragmentationHeader* fragmentation) {
659 // Encoded is called on whatever thread the real encoder implementation run
660 // on. In the case of hardware encoders, there might be several encoders
661 // running in parallel on different threads.
662 size_t simulcast_idx = 0;
663 if (codec_specific_info->codecType == kVideoCodecVP8) {
664 simulcast_idx = codec_specific_info->codecSpecific.VP8.simulcastIdx;
665 }
666 if (config_->post_encode_callback) {
667 config_->post_encode_callback->EncodedFrameCallback(EncodedFrame(
668 encoded_image._buffer, encoded_image._length, encoded_image._frameType,
669 simulcast_idx, encoded_image._timeStamp));
670 }
671 {
672 rtc::CritScope lock(&encoder_activity_crit_sect_);
673 if (check_encoder_activity_task_)
674 check_encoder_activity_task_->UpdateEncoderActivity();
675 }
676
677 fec_controller_->UpdateWithEncodedData(encoded_image._length,
678 encoded_image._frameType);
679 EncodedImageCallback::Result result = payload_router_.OnEncodedImage(
680 encoded_image, codec_specific_info, fragmentation);
681
682 RTC_DCHECK(codec_specific_info);
683
684 int layer = codec_specific_info->codecType == kVideoCodecVP8
685 ? codec_specific_info->codecSpecific.VP8.simulcastIdx
686 : 0;
687 {
688 rtc::CritScope lock(&ivf_writers_crit_);
689 if (file_writers_[layer].get()) {
690 bool ok = file_writers_[layer]->WriteFrame(
691 encoded_image, codec_specific_info->codecType);
692 RTC_DCHECK(ok);
693 }
694 }
695
696 return result;
697}
698
699void VideoSendStreamImpl::ConfigureProtection() {
700 RTC_DCHECK_RUN_ON(worker_queue_);
701
702 // Consistency of FlexFEC parameters is checked in MaybeCreateFlexfecSender.
703 const bool flexfec_enabled = (flexfec_sender_ != nullptr);
704
705 // Consistency of NACK and RED+ULPFEC parameters is checked in this function.
706 const bool nack_enabled = config_->rtp.nack.rtp_history_ms > 0;
707 int red_payload_type = config_->rtp.ulpfec.red_payload_type;
708 int ulpfec_payload_type = config_->rtp.ulpfec.ulpfec_payload_type;
709
710 // Shorthands.
711 auto IsRedEnabled = [&]() { return red_payload_type >= 0; };
712 auto DisableRed = [&]() { red_payload_type = -1; };
713 auto IsUlpfecEnabled = [&]() { return ulpfec_payload_type >= 0; };
714 auto DisableUlpfec = [&]() { ulpfec_payload_type = -1; };
715
716 if (webrtc::field_trial::IsEnabled("WebRTC-DisableUlpFecExperiment")) {
717 RTC_LOG(LS_INFO) << "Experiment to disable sending ULPFEC is enabled.";
718 DisableUlpfec();
719 }
720
721 // If enabled, FlexFEC takes priority over RED+ULPFEC.
722 if (flexfec_enabled) {
723 // We can safely disable RED here, because if the remote supports FlexFEC,
724 // we know that it has a receiver without the RED/RTX workaround.
725 // See http://crbug.com/webrtc/6650 for more information.
726 if (IsRedEnabled()) {
727 RTC_LOG(LS_INFO) << "Both FlexFEC and RED are configured. Disabling RED.";
728 DisableRed();
729 }
730 if (IsUlpfecEnabled()) {
731 RTC_LOG(LS_INFO)
732 << "Both FlexFEC and ULPFEC are configured. Disabling ULPFEC.";
733 DisableUlpfec();
734 }
735 }
736
737 // Payload types without picture ID cannot determine that a stream is complete
738 // without retransmitting FEC, so using ULPFEC + NACK for H.264 (for instance)
739 // is a waste of bandwidth since FEC packets still have to be transmitted.
740 // Note that this is not the case with FlexFEC.
741 if (nack_enabled && IsUlpfecEnabled() &&
742 !PayloadTypeSupportsSkippingFecPackets(config_->rtp.payload_name)) {
743 RTC_LOG(LS_WARNING)
744 << "Transmitting payload type without picture ID using "
745 "NACK+ULPFEC is a waste of bandwidth since ULPFEC packets "
746 "also have to be retransmitted. Disabling ULPFEC.";
747 DisableUlpfec();
748 }
749
750 // Verify payload types.
751 //
752 // Due to how old receivers work, we need to always send RED if it has been
753 // negotiated. This is a remnant of an old RED/RTX workaround, see
754 // https://codereview.webrtc.org/2469093003.
755 // TODO(brandtr): This change went into M56, so we can remove it in ~M59.
756 // At that time, we can disable RED whenever ULPFEC is disabled, as there is
757 // no point in using RED without ULPFEC.
758 if (IsRedEnabled()) {
759 RTC_DCHECK_GE(red_payload_type, 0);
760 RTC_DCHECK_LE(red_payload_type, 127);
761 }
762 if (IsUlpfecEnabled()) {
763 RTC_DCHECK_GE(ulpfec_payload_type, 0);
764 RTC_DCHECK_LE(ulpfec_payload_type, 127);
765 if (!IsRedEnabled()) {
766 RTC_LOG(LS_WARNING)
767 << "ULPFEC is enabled but RED is disabled. Disabling ULPFEC.";
768 DisableUlpfec();
769 }
770 }
771
772 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
773 // Set NACK.
774 rtp_rtcp->SetStorePacketsStatus(true, kMinSendSidePacketHistorySize);
775 // Set RED/ULPFEC information.
776 rtp_rtcp->SetUlpfecConfig(red_payload_type, ulpfec_payload_type);
777 }
778
779 // Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic,
780 // so enable that logic if either of those FEC schemes are enabled.
781 fec_controller_->SetProtectionMethod(flexfec_enabled || IsUlpfecEnabled(),
782 nack_enabled);
783}
784
785void VideoSendStreamImpl::ConfigureSsrcs() {
786 RTC_DCHECK_RUN_ON(worker_queue_);
787 // Configure regular SSRCs.
788 for (size_t i = 0; i < config_->rtp.ssrcs.size(); ++i) {
789 uint32_t ssrc = config_->rtp.ssrcs[i];
790 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i];
791 rtp_rtcp->SetSSRC(ssrc);
792
793 // Restore RTP state if previous existed.
794 VideoSendStream::RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
795 if (it != suspended_ssrcs_.end())
796 rtp_rtcp->SetRtpState(it->second);
797 }
798
799 // Set up RTX if available.
800 if (config_->rtp.rtx.ssrcs.empty())
801 return;
802
803 // Configure RTX SSRCs.
804 RTC_DCHECK_EQ(config_->rtp.rtx.ssrcs.size(), config_->rtp.ssrcs.size());
805 for (size_t i = 0; i < config_->rtp.rtx.ssrcs.size(); ++i) {
806 uint32_t ssrc = config_->rtp.rtx.ssrcs[i];
807 RtpRtcp* const rtp_rtcp = rtp_rtcp_modules_[i];
808 rtp_rtcp->SetRtxSsrc(ssrc);
809 VideoSendStream::RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
810 if (it != suspended_ssrcs_.end())
811 rtp_rtcp->SetRtxState(it->second);
812 }
813
814 // Configure RTX payload types.
815 RTC_DCHECK_GE(config_->rtp.rtx.payload_type, 0);
816 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
817 rtp_rtcp->SetRtxSendPayloadType(config_->rtp.rtx.payload_type,
818 config_->rtp.payload_type);
819 rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads);
820 }
821 if (config_->rtp.ulpfec.red_payload_type != -1 &&
822 config_->rtp.ulpfec.red_rtx_payload_type != -1) {
823 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
824 rtp_rtcp->SetRtxSendPayloadType(config_->rtp.ulpfec.red_rtx_payload_type,
825 config_->rtp.ulpfec.red_payload_type);
826 }
827 }
828}
829
830std::map<uint32_t, RtpState> VideoSendStreamImpl::GetRtpStates() const {
831 RTC_DCHECK_RUN_ON(worker_queue_);
832 std::map<uint32_t, RtpState> rtp_states;
833
834 for (size_t i = 0; i < config_->rtp.ssrcs.size(); ++i) {
835 uint32_t ssrc = config_->rtp.ssrcs[i];
836 RTC_DCHECK_EQ(ssrc, rtp_rtcp_modules_[i]->SSRC());
837 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtpState();
838 }
839
840 for (size_t i = 0; i < config_->rtp.rtx.ssrcs.size(); ++i) {
841 uint32_t ssrc = config_->rtp.rtx.ssrcs[i];
842 rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtxState();
843 }
844
845 if (flexfec_sender_) {
846 uint32_t ssrc = config_->rtp.flexfec.ssrc;
847 rtp_states[ssrc] = flexfec_sender_->GetRtpState();
848 }
849
850 return rtp_states;
851}
852
853std::map<uint32_t, RtpPayloadState> VideoSendStreamImpl::GetRtpPayloadStates()
854 const {
855 RTC_DCHECK_RUN_ON(worker_queue_);
856 return payload_router_.GetRtpPayloadStates();
857}
858
859void VideoSendStreamImpl::SignalNetworkState(NetworkState state) {
860 RTC_DCHECK_RUN_ON(worker_queue_);
861 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
862 rtp_rtcp->SetRTCPStatus(state == kNetworkUp ? config_->rtp.rtcp_mode
863 : RtcpMode::kOff);
864 }
865}
866
867uint32_t VideoSendStreamImpl::OnBitrateUpdated(uint32_t bitrate_bps,
868 uint8_t fraction_loss,
869 int64_t rtt,
870 int64_t probing_interval_ms) {
871 RTC_DCHECK_RUN_ON(worker_queue_);
872 RTC_DCHECK(payload_router_.IsActive())
873 << "VideoSendStream::Start has not been called.";
874
875 // Substract overhead from bitrate.
876 rtc::CritScope lock(&overhead_bytes_per_packet_crit_);
877 uint32_t payload_bitrate_bps = bitrate_bps;
878 if (send_side_bwe_with_overhead_) {
879 payload_bitrate_bps -= CalculateOverheadRateBps(
880 CalculatePacketRate(bitrate_bps,
881 config_->rtp.max_packet_size +
882 transport_overhead_bytes_per_packet_),
883 overhead_bytes_per_packet_ + transport_overhead_bytes_per_packet_,
884 bitrate_bps);
885 }
886
887 // Get the encoder target rate. It is the estimated network rate -
888 // protection overhead.
889 encoder_target_rate_bps_ = fec_controller_->UpdateFecRates(
890 payload_bitrate_bps, stats_proxy_->GetSendFrameRate(), fraction_loss,
891 loss_mask_vector_, rtt);
892 loss_mask_vector_.clear();
893
894 uint32_t encoder_overhead_rate_bps =
895 send_side_bwe_with_overhead_
896 ? CalculateOverheadRateBps(
897 CalculatePacketRate(encoder_target_rate_bps_,
898 config_->rtp.max_packet_size +
899 transport_overhead_bytes_per_packet_ -
900 overhead_bytes_per_packet_),
901 overhead_bytes_per_packet_ +
902 transport_overhead_bytes_per_packet_,
903 bitrate_bps - encoder_target_rate_bps_)
904 : 0;
905
906 // When the field trial "WebRTC-SendSideBwe-WithOverhead" is enabled
907 // protection_bitrate includes overhead.
908 uint32_t protection_bitrate =
909 bitrate_bps - (encoder_target_rate_bps_ + encoder_overhead_rate_bps);
910
911 encoder_target_rate_bps_ =
912 std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps_);
913 video_stream_encoder_->OnBitrateUpdated(encoder_target_rate_bps_,
914 fraction_loss, rtt);
915 stats_proxy_->OnSetEncoderTargetRate(encoder_target_rate_bps_);
916 return protection_bitrate;
917}
918
919void VideoSendStreamImpl::EnableEncodedFrameRecording(
920 const std::vector<rtc::PlatformFile>& files,
921 size_t byte_limit) {
922 {
923 rtc::CritScope lock(&ivf_writers_crit_);
924 for (unsigned int i = 0; i < kMaxSimulcastStreams; ++i) {
925 if (i < files.size()) {
926 file_writers_[i] = IvfFileWriter::Wrap(rtc::File(files[i]), byte_limit);
927 } else {
928 file_writers_[i].reset();
929 }
930 }
931 }
932
933 if (!files.empty()) {
934 // Make a keyframe appear as early as possible in the logs, to give actually
935 // decodable output.
936 video_stream_encoder_->SendKeyFrame();
937 }
938}
939
940int VideoSendStreamImpl::ProtectionRequest(
941 const FecProtectionParams* delta_params,
942 const FecProtectionParams* key_params,
943 uint32_t* sent_video_rate_bps,
944 uint32_t* sent_nack_rate_bps,
945 uint32_t* sent_fec_rate_bps) {
946 RTC_DCHECK_RUN_ON(worker_queue_);
947 *sent_video_rate_bps = 0;
948 *sent_nack_rate_bps = 0;
949 *sent_fec_rate_bps = 0;
950 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
951 uint32_t not_used = 0;
952 uint32_t module_video_rate = 0;
953 uint32_t module_fec_rate = 0;
954 uint32_t module_nack_rate = 0;
955 rtp_rtcp->SetFecParameters(*delta_params, *key_params);
956 rtp_rtcp->BitrateSent(&not_used, &module_video_rate, &module_fec_rate,
957 &module_nack_rate);
958 *sent_video_rate_bps += module_video_rate;
959 *sent_nack_rate_bps += module_nack_rate;
960 *sent_fec_rate_bps += module_fec_rate;
961 }
962 return 0;
963}
964
965void VideoSendStreamImpl::OnOverheadChanged(size_t overhead_bytes_per_packet) {
966 rtc::CritScope lock(&overhead_bytes_per_packet_crit_);
967 overhead_bytes_per_packet_ = overhead_bytes_per_packet;
968}
969
970void VideoSendStreamImpl::SetTransportOverhead(
971 size_t transport_overhead_bytes_per_packet) {
972 if (transport_overhead_bytes_per_packet >= static_cast<int>(kPathMTU)) {
973 RTC_LOG(LS_ERROR) << "Transport overhead exceeds size of ethernet frame";
974 return;
975 }
976
977 transport_overhead_bytes_per_packet_ = transport_overhead_bytes_per_packet;
978
979 size_t rtp_packet_size =
980 std::min(config_->rtp.max_packet_size,
981 kPathMTU - transport_overhead_bytes_per_packet_);
982
983 for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
984 rtp_rtcp->SetMaxRtpPacketSize(rtp_packet_size);
985 }
986}
987
988void VideoSendStreamImpl::OnPacketAdded(uint32_t ssrc, uint16_t seq_num) {
989 if (!worker_queue_->IsCurrent()) {
990 auto ptr = weak_ptr_;
991 worker_queue_->PostTask([=] {
992 if (!ptr.get())
993 return;
994 ptr->OnPacketAdded(ssrc, seq_num);
995 });
996 return;
997 }
998 const auto ssrcs = config_->rtp.ssrcs;
999 if (std::find(ssrcs.begin(), ssrcs.end(), ssrc) != ssrcs.end()) {
1000 feedback_packet_seq_num_set_.insert(seq_num);
1001 if (feedback_packet_seq_num_set_.size() > kSendSideSeqNumSetMaxSize) {
1002 RTC_LOG(LS_WARNING) << "Feedback packet sequence number set exceed it's "
1003 "max size', will get reset.";
1004 feedback_packet_seq_num_set_.clear();
1005 }
1006 }
1007}
1008
1009void VideoSendStreamImpl::OnPacketFeedbackVector(
1010 const std::vector<PacketFeedback>& packet_feedback_vector) {
1011 if (!worker_queue_->IsCurrent()) {
1012 auto ptr = weak_ptr_;
1013 worker_queue_->PostTask([=] {
1014 if (!ptr.get())
1015 return;
1016 ptr->OnPacketFeedbackVector(packet_feedback_vector);
1017 });
1018 return;
1019 }
1020 // Lost feedbacks are not considered to be lost packets.
1021 for (const PacketFeedback& packet : packet_feedback_vector) {
1022 if (auto it = feedback_packet_seq_num_set_.find(packet.sequence_number) !=
1023 feedback_packet_seq_num_set_.end()) {
1024 const bool lost = packet.arrival_time_ms == PacketFeedback::kNotReceived;
1025 loss_mask_vector_.push_back(lost);
1026 feedback_packet_seq_num_set_.erase(it);
1027 }
1028 }
1029}
1030} // namespace internal
1031} // namespace webrtc