1 /*
2 * Copyright (c) 2012 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
11 #include "modules/rtp_rtcp/source/rtcp_sender.h"
12
13 #include <string.h> // memcpy
14
15 #include <algorithm> // std::min
16 #include <memory>
17 #include <utility>
18
19 #include "absl/strings/string_view.h"
20 #include "absl/types/optional.h"
21 #include "api/rtc_event_log/rtc_event_log.h"
22 #include "api/rtp_headers.h"
23 #include "api/units/time_delta.h"
24 #include "api/units/timestamp.h"
25 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
26 #include "modules/rtp_rtcp/source/rtcp_packet/app.h"
27 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
28 #include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
29 #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
30 #include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
31 #include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h"
32 #include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
33 #include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
34 #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
35 #include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
36 #include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
37 #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
38 #include "modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
39 #include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
40 #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
41 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
42 #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
43 #include "modules/rtp_rtcp/source/time_util.h"
44 #include "modules/rtp_rtcp/source/tmmbr_help.h"
45 #include "rtc_base/checks.h"
46 #include "rtc_base/logging.h"
47 #include "rtc_base/numerics/safe_conversions.h"
48 #include "rtc_base/trace_event.h"
49
50 namespace webrtc {
51
52 namespace {
53 const uint32_t kRtcpAnyExtendedReports = kRtcpXrReceiverReferenceTime |
54 kRtcpXrDlrrReportBlock |
55 kRtcpXrTargetBitrate;
56 constexpr int32_t kDefaultVideoReportInterval = 1000;
57 constexpr int32_t kDefaultAudioReportInterval = 5000;
58 } // namespace
59
60 // Helper to put several RTCP packets into lower layer datagram RTCP packet.
61 class RTCPSender::PacketSender {
62 public:
PacketSender(rtcp::RtcpPacket::PacketReadyCallback callback,size_t max_packet_size)63 PacketSender(rtcp::RtcpPacket::PacketReadyCallback callback,
64 size_t max_packet_size)
65 : callback_(callback), max_packet_size_(max_packet_size) {
66 RTC_CHECK_LE(max_packet_size, IP_PACKET_SIZE);
67 }
~PacketSender()68 ~PacketSender() { RTC_DCHECK_EQ(index_, 0) << "Unsent rtcp packet."; }
69
70 // Appends a packet to pending compound packet.
71 // Sends rtcp packet if buffer is full and resets the buffer.
AppendPacket(const rtcp::RtcpPacket & packet)72 void AppendPacket(const rtcp::RtcpPacket& packet) {
73 packet.Create(buffer_, &index_, max_packet_size_, callback_);
74 }
75
76 // Sends pending rtcp packet.
Send()77 void Send() {
78 if (index_ > 0) {
79 callback_(rtc::ArrayView<const uint8_t>(buffer_, index_));
80 index_ = 0;
81 }
82 }
83
84 private:
85 const rtcp::RtcpPacket::PacketReadyCallback callback_;
86 const size_t max_packet_size_;
87 size_t index_ = 0;
88 uint8_t buffer_[IP_PACKET_SIZE];
89 };
90
FeedbackState()91 RTCPSender::FeedbackState::FeedbackState()
92 : packets_sent(0),
93 media_bytes_sent(0),
94 send_bitrate(0),
95 last_rr_ntp_secs(0),
96 last_rr_ntp_frac(0),
97 remote_sr(0),
98 receiver(nullptr) {}
99
100 RTCPSender::FeedbackState::FeedbackState(const FeedbackState&) = default;
101
102 RTCPSender::FeedbackState::FeedbackState(FeedbackState&&) = default;
103
104 RTCPSender::FeedbackState::~FeedbackState() = default;
105
106 class RTCPSender::RtcpContext {
107 public:
RtcpContext(const FeedbackState & feedback_state,int32_t nack_size,const uint16_t * nack_list,Timestamp now)108 RtcpContext(const FeedbackState& feedback_state,
109 int32_t nack_size,
110 const uint16_t* nack_list,
111 Timestamp now)
112 : feedback_state_(feedback_state),
113 nack_size_(nack_size),
114 nack_list_(nack_list),
115 now_(now) {}
116
117 const FeedbackState& feedback_state_;
118 const int32_t nack_size_;
119 const uint16_t* nack_list_;
120 const Timestamp now_;
121 };
122
FromRtpRtcpConfiguration(const RtpRtcpInterface::Configuration & configuration)123 RTCPSender::Configuration RTCPSender::Configuration::FromRtpRtcpConfiguration(
124 const RtpRtcpInterface::Configuration& configuration) {
125 RTCPSender::Configuration result;
126 result.audio = configuration.audio;
127 result.local_media_ssrc = configuration.local_media_ssrc;
128 result.clock = configuration.clock;
129 result.outgoing_transport = configuration.outgoing_transport;
130 result.non_sender_rtt_measurement = configuration.non_sender_rtt_measurement;
131 result.event_log = configuration.event_log;
132 if (configuration.rtcp_report_interval_ms) {
133 result.rtcp_report_interval =
134 TimeDelta::Millis(configuration.rtcp_report_interval_ms);
135 }
136 result.receive_statistics = configuration.receive_statistics;
137 result.rtcp_packet_type_counter_observer =
138 configuration.rtcp_packet_type_counter_observer;
139 return result;
140 }
141
RTCPSender(Configuration config)142 RTCPSender::RTCPSender(Configuration config)
143 : audio_(config.audio),
144 ssrc_(config.local_media_ssrc),
145 clock_(config.clock),
146 random_(clock_->TimeInMicroseconds()),
147 method_(RtcpMode::kOff),
148 event_log_(config.event_log),
149 transport_(config.outgoing_transport),
150 report_interval_(config.rtcp_report_interval.value_or(
151 TimeDelta::Millis(config.audio ? kDefaultAudioReportInterval
152 : kDefaultVideoReportInterval))),
153 schedule_next_rtcp_send_evaluation_function_(
154 std::move(config.schedule_next_rtcp_send_evaluation_function)),
155 sending_(false),
156 timestamp_offset_(0),
157 last_rtp_timestamp_(0),
158 remote_ssrc_(0),
159 receive_statistics_(config.receive_statistics),
160
161 sequence_number_fir_(0),
162
163 remb_bitrate_(0),
164
165 tmmbr_send_bps_(0),
166 packet_oh_send_(0),
167 max_packet_size_(IP_PACKET_SIZE - 28), // IPv4 + UDP by default.
168
169 xr_send_receiver_reference_time_enabled_(
170 config.non_sender_rtt_measurement),
171 packet_type_counter_observer_(config.rtcp_packet_type_counter_observer),
172 send_video_bitrate_allocation_(false),
173 last_payload_type_(-1) {
174 RTC_DCHECK(transport_ != nullptr);
175
176 builders_[kRtcpSr] = &RTCPSender::BuildSR;
177 builders_[kRtcpRr] = &RTCPSender::BuildRR;
178 builders_[kRtcpSdes] = &RTCPSender::BuildSDES;
179 builders_[kRtcpPli] = &RTCPSender::BuildPLI;
180 builders_[kRtcpFir] = &RTCPSender::BuildFIR;
181 builders_[kRtcpRemb] = &RTCPSender::BuildREMB;
182 builders_[kRtcpBye] = &RTCPSender::BuildBYE;
183 builders_[kRtcpLossNotification] = &RTCPSender::BuildLossNotification;
184 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR;
185 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN;
186 builders_[kRtcpNack] = &RTCPSender::BuildNACK;
187 builders_[kRtcpAnyExtendedReports] = &RTCPSender::BuildExtendedReports;
188 }
189
~RTCPSender()190 RTCPSender::~RTCPSender() {}
191
Status() const192 RtcpMode RTCPSender::Status() const {
193 MutexLock lock(&mutex_rtcp_sender_);
194 return method_;
195 }
196
SetRTCPStatus(RtcpMode new_method)197 void RTCPSender::SetRTCPStatus(RtcpMode new_method) {
198 MutexLock lock(&mutex_rtcp_sender_);
199
200 if (new_method == RtcpMode::kOff) {
201 next_time_to_send_rtcp_ = absl::nullopt;
202 } else if (method_ == RtcpMode::kOff) {
203 // When switching on, reschedule the next packet
204 SetNextRtcpSendEvaluationDuration(report_interval_ / 2);
205 }
206 method_ = new_method;
207 }
208
Sending() const209 bool RTCPSender::Sending() const {
210 MutexLock lock(&mutex_rtcp_sender_);
211 return sending_;
212 }
213
SetSendingStatus(const FeedbackState & feedback_state,bool sending)214 void RTCPSender::SetSendingStatus(const FeedbackState& feedback_state,
215 bool sending) {
216 bool sendRTCPBye = false;
217 {
218 MutexLock lock(&mutex_rtcp_sender_);
219
220 if (method_ != RtcpMode::kOff) {
221 if (sending == false && sending_ == true) {
222 // Trigger RTCP bye
223 sendRTCPBye = true;
224 }
225 }
226 sending_ = sending;
227 }
228 if (sendRTCPBye) {
229 if (SendRTCP(feedback_state, kRtcpBye) != 0) {
230 RTC_LOG(LS_WARNING) << "Failed to send RTCP BYE";
231 }
232 }
233 }
234
SetNonSenderRttMeasurement(bool enabled)235 void RTCPSender::SetNonSenderRttMeasurement(bool enabled) {
236 MutexLock lock(&mutex_rtcp_sender_);
237 xr_send_receiver_reference_time_enabled_ = enabled;
238 }
239
SendLossNotification(const FeedbackState & feedback_state,uint16_t last_decoded_seq_num,uint16_t last_received_seq_num,bool decodability_flag,bool buffering_allowed)240 int32_t RTCPSender::SendLossNotification(const FeedbackState& feedback_state,
241 uint16_t last_decoded_seq_num,
242 uint16_t last_received_seq_num,
243 bool decodability_flag,
244 bool buffering_allowed) {
245 int32_t error_code = -1;
246 auto callback = [&](rtc::ArrayView<const uint8_t> packet) {
247 transport_->SendRtcp(packet.data(), packet.size());
248 error_code = 0;
249 if (event_log_) {
250 event_log_->Log(std::make_unique<RtcEventRtcpPacketOutgoing>(packet));
251 }
252 };
253 absl::optional<PacketSender> sender;
254 {
255 MutexLock lock(&mutex_rtcp_sender_);
256
257 if (!loss_notification_.Set(last_decoded_seq_num, last_received_seq_num,
258 decodability_flag)) {
259 return -1;
260 }
261
262 SetFlag(kRtcpLossNotification, /*is_volatile=*/true);
263
264 if (buffering_allowed) {
265 // The loss notification will be batched with additional feedback
266 // messages.
267 return 0;
268 }
269
270 sender.emplace(callback, max_packet_size_);
271 auto result = ComputeCompoundRTCPPacket(
272 feedback_state, RTCPPacketType::kRtcpLossNotification, 0, nullptr,
273 *sender);
274 if (result) {
275 return *result;
276 }
277 }
278 sender->Send();
279
280 return error_code;
281 }
282
SetRemb(int64_t bitrate_bps,std::vector<uint32_t> ssrcs)283 void RTCPSender::SetRemb(int64_t bitrate_bps, std::vector<uint32_t> ssrcs) {
284 RTC_CHECK_GE(bitrate_bps, 0);
285 MutexLock lock(&mutex_rtcp_sender_);
286 if (method_ == RtcpMode::kOff) {
287 RTC_LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
288 return;
289 }
290 remb_bitrate_ = bitrate_bps;
291 remb_ssrcs_ = std::move(ssrcs);
292
293 SetFlag(kRtcpRemb, /*is_volatile=*/false);
294 // Send a REMB immediately if we have a new REMB. The frequency of REMBs is
295 // throttled by the caller.
296 SetNextRtcpSendEvaluationDuration(TimeDelta::Zero());
297 }
298
UnsetRemb()299 void RTCPSender::UnsetRemb() {
300 MutexLock lock(&mutex_rtcp_sender_);
301 // Stop sending REMB each report until it is reenabled and REMB data set.
302 ConsumeFlag(kRtcpRemb, /*forced=*/true);
303 }
304
TMMBR() const305 bool RTCPSender::TMMBR() const {
306 MutexLock lock(&mutex_rtcp_sender_);
307 return IsFlagPresent(RTCPPacketType::kRtcpTmmbr);
308 }
309
SetMaxRtpPacketSize(size_t max_packet_size)310 void RTCPSender::SetMaxRtpPacketSize(size_t max_packet_size) {
311 MutexLock lock(&mutex_rtcp_sender_);
312 max_packet_size_ = max_packet_size;
313 }
314
SetTimestampOffset(uint32_t timestamp_offset)315 void RTCPSender::SetTimestampOffset(uint32_t timestamp_offset) {
316 MutexLock lock(&mutex_rtcp_sender_);
317 timestamp_offset_ = timestamp_offset;
318 }
319
SetLastRtpTime(uint32_t rtp_timestamp,absl::optional<Timestamp> capture_time,absl::optional<int8_t> payload_type)320 void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp,
321 absl::optional<Timestamp> capture_time,
322 absl::optional<int8_t> payload_type) {
323 MutexLock lock(&mutex_rtcp_sender_);
324 // For compatibility with clients who don't set payload type correctly on all
325 // calls.
326 if (payload_type.has_value()) {
327 last_payload_type_ = *payload_type;
328 }
329 last_rtp_timestamp_ = rtp_timestamp;
330 if (!capture_time.has_value()) {
331 // We don't currently get a capture time from VoiceEngine.
332 last_frame_capture_time_ = clock_->CurrentTime();
333 } else {
334 last_frame_capture_time_ = *capture_time;
335 }
336 }
337
SetRtpClockRate(int8_t payload_type,int rtp_clock_rate_hz)338 void RTCPSender::SetRtpClockRate(int8_t payload_type, int rtp_clock_rate_hz) {
339 MutexLock lock(&mutex_rtcp_sender_);
340 rtp_clock_rates_khz_[payload_type] = rtp_clock_rate_hz / 1000;
341 }
342
SSRC() const343 uint32_t RTCPSender::SSRC() const {
344 MutexLock lock(&mutex_rtcp_sender_);
345 return ssrc_;
346 }
347
SetSsrc(uint32_t ssrc)348 void RTCPSender::SetSsrc(uint32_t ssrc) {
349 MutexLock lock(&mutex_rtcp_sender_);
350 ssrc_ = ssrc;
351 }
352
SetRemoteSSRC(uint32_t ssrc)353 void RTCPSender::SetRemoteSSRC(uint32_t ssrc) {
354 MutexLock lock(&mutex_rtcp_sender_);
355 remote_ssrc_ = ssrc;
356 }
357
SetCNAME(absl::string_view c_name)358 int32_t RTCPSender::SetCNAME(absl::string_view c_name) {
359 RTC_DCHECK_LT(c_name.size(), RTCP_CNAME_SIZE);
360 MutexLock lock(&mutex_rtcp_sender_);
361 cname_ = std::string(c_name);
362 return 0;
363 }
364
TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const365 bool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const {
366 /*
367 For audio we use a configurable interval (default: 5 seconds)
368
369 For video we use a configurable interval (default: 1 second) for a BW
370 smaller than 360 kbit/s, technicaly we break the max 5% RTCP BW for
371 video below 10 kbit/s but that should be extremely rare
372
373
374 From RFC 3550
375
376 MAX RTCP BW is 5% if the session BW
377 A send report is approximately 65 bytes inc CNAME
378 A receiver report is approximately 28 bytes
379
380 The RECOMMENDED value for the reduced minimum in seconds is 360
381 divided by the session bandwidth in kilobits/second. This minimum
382 is smaller than 5 seconds for bandwidths greater than 72 kb/s.
383
384 If the participant has not yet sent an RTCP packet (the variable
385 initial is true), the constant Tmin is set to half of the configured
386 interval.
387
388 The interval between RTCP packets is varied randomly over the
389 range [0.5,1.5] times the calculated interval to avoid unintended
390 synchronization of all participants
391
392 if we send
393 If the participant is a sender (we_sent true), the constant C is
394 set to the average RTCP packet size (avg_rtcp_size) divided by 25%
395 of the RTCP bandwidth (rtcp_bw), and the constant n is set to the
396 number of senders.
397
398 if we receive only
399 If we_sent is not true, the constant C is set
400 to the average RTCP packet size divided by 75% of the RTCP
401 bandwidth. The constant n is set to the number of receivers
402 (members - senders). If the number of senders is greater than
403 25%, senders and receivers are treated together.
404
405 reconsideration NOT required for peer-to-peer
406 "timer reconsideration" is
407 employed. This algorithm implements a simple back-off mechanism
408 which causes users to hold back RTCP packet transmission if the
409 group sizes are increasing.
410
411 n = number of members
412 C = avg_size/(rtcpBW/4)
413
414 3. The deterministic calculated interval Td is set to max(Tmin, n*C).
415
416 4. The calculated interval T is set to a number uniformly distributed
417 between 0.5 and 1.5 times the deterministic calculated interval.
418
419 5. The resulting value of T is divided by e-3/2=1.21828 to compensate
420 for the fact that the timer reconsideration algorithm converges to
421 a value of the RTCP bandwidth below the intended average
422 */
423
424 Timestamp now = clock_->CurrentTime();
425
426 MutexLock lock(&mutex_rtcp_sender_);
427 RTC_DCHECK(
428 (method_ == RtcpMode::kOff && !next_time_to_send_rtcp_.has_value()) ||
429 (method_ != RtcpMode::kOff && next_time_to_send_rtcp_.has_value()));
430 if (method_ == RtcpMode::kOff)
431 return false;
432
433 if (!audio_ && sendKeyframeBeforeRTP) {
434 // for video key-frames we want to send the RTCP before the large key-frame
435 // if we have a 100 ms margin
436 now += RTCP_SEND_BEFORE_KEY_FRAME;
437 }
438
439 return now >= *next_time_to_send_rtcp_;
440 }
441
BuildSR(const RtcpContext & ctx,PacketSender & sender)442 void RTCPSender::BuildSR(const RtcpContext& ctx, PacketSender& sender) {
443 // Timestamp shouldn't be estimated before first media frame.
444 RTC_DCHECK(last_frame_capture_time_.has_value());
445 // The timestamp of this RTCP packet should be estimated as the timestamp of
446 // the frame being captured at this moment. We are calculating that
447 // timestamp as the last frame's timestamp + the time since the last frame
448 // was captured.
449 int rtp_rate = rtp_clock_rates_khz_[last_payload_type_];
450 if (rtp_rate <= 0) {
451 rtp_rate =
452 (audio_ ? kBogusRtpRateForAudioRtcp : kVideoPayloadTypeFrequency) /
453 1000;
454 }
455 // Round now_us_ to the closest millisecond, because Ntp time is rounded
456 // when converted to milliseconds,
457 uint32_t rtp_timestamp =
458 timestamp_offset_ + last_rtp_timestamp_ +
459 ((ctx.now_.us() + 500) / 1000 - last_frame_capture_time_->ms()) *
460 rtp_rate;
461
462 rtcp::SenderReport report;
463 report.SetSenderSsrc(ssrc_);
464 report.SetNtp(clock_->ConvertTimestampToNtpTime(ctx.now_));
465 report.SetRtpTimestamp(rtp_timestamp);
466 report.SetPacketCount(ctx.feedback_state_.packets_sent);
467 report.SetOctetCount(ctx.feedback_state_.media_bytes_sent);
468 report.SetReportBlocks(CreateReportBlocks(ctx.feedback_state_));
469 sender.AppendPacket(report);
470 }
471
BuildSDES(const RtcpContext & ctx,PacketSender & sender)472 void RTCPSender::BuildSDES(const RtcpContext& ctx, PacketSender& sender) {
473 size_t length_cname = cname_.length();
474 RTC_CHECK_LT(length_cname, RTCP_CNAME_SIZE);
475
476 rtcp::Sdes sdes;
477 sdes.AddCName(ssrc_, cname_);
478 sender.AppendPacket(sdes);
479 }
480
BuildRR(const RtcpContext & ctx,PacketSender & sender)481 void RTCPSender::BuildRR(const RtcpContext& ctx, PacketSender& sender) {
482 rtcp::ReceiverReport report;
483 report.SetSenderSsrc(ssrc_);
484 report.SetReportBlocks(CreateReportBlocks(ctx.feedback_state_));
485 if (method_ == RtcpMode::kCompound || !report.report_blocks().empty()) {
486 sender.AppendPacket(report);
487 }
488 }
489
BuildPLI(const RtcpContext & ctx,PacketSender & sender)490 void RTCPSender::BuildPLI(const RtcpContext& ctx, PacketSender& sender) {
491 rtcp::Pli pli;
492 pli.SetSenderSsrc(ssrc_);
493 pli.SetMediaSsrc(remote_ssrc_);
494
495 ++packet_type_counter_.pli_packets;
496 sender.AppendPacket(pli);
497 }
498
BuildFIR(const RtcpContext & ctx,PacketSender & sender)499 void RTCPSender::BuildFIR(const RtcpContext& ctx, PacketSender& sender) {
500 ++sequence_number_fir_;
501
502 rtcp::Fir fir;
503 fir.SetSenderSsrc(ssrc_);
504 fir.AddRequestTo(remote_ssrc_, sequence_number_fir_);
505
506 ++packet_type_counter_.fir_packets;
507 sender.AppendPacket(fir);
508 }
509
BuildREMB(const RtcpContext & ctx,PacketSender & sender)510 void RTCPSender::BuildREMB(const RtcpContext& ctx, PacketSender& sender) {
511 rtcp::Remb remb;
512 remb.SetSenderSsrc(ssrc_);
513 remb.SetBitrateBps(remb_bitrate_);
514 remb.SetSsrcs(remb_ssrcs_);
515 sender.AppendPacket(remb);
516 }
517
SetTargetBitrate(unsigned int target_bitrate)518 void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) {
519 MutexLock lock(&mutex_rtcp_sender_);
520 tmmbr_send_bps_ = target_bitrate;
521 }
522
BuildTMMBR(const RtcpContext & ctx,PacketSender & sender)523 void RTCPSender::BuildTMMBR(const RtcpContext& ctx, PacketSender& sender) {
524 if (ctx.feedback_state_.receiver == nullptr)
525 return;
526 // Before sending the TMMBR check the received TMMBN, only an owner is
527 // allowed to raise the bitrate:
528 // * If the sender is an owner of the TMMBN -> send TMMBR
529 // * If not an owner but the TMMBR would enter the TMMBN -> send TMMBR
530
531 // get current bounding set from RTCP receiver
532 bool tmmbr_owner = false;
533
534 // holding mutex_rtcp_sender_ while calling RTCPreceiver which
535 // will accuire criticalSectionRTCPReceiver_ is a potental deadlock but
536 // since RTCPreceiver is not doing the reverse we should be fine
537 std::vector<rtcp::TmmbItem> candidates =
538 ctx.feedback_state_.receiver->BoundingSet(&tmmbr_owner);
539
540 if (!candidates.empty()) {
541 for (const auto& candidate : candidates) {
542 if (candidate.bitrate_bps() == tmmbr_send_bps_ &&
543 candidate.packet_overhead() == packet_oh_send_) {
544 // Do not send the same tuple.
545 return;
546 }
547 }
548 if (!tmmbr_owner) {
549 // Use received bounding set as candidate set.
550 // Add current tuple.
551 candidates.emplace_back(ssrc_, tmmbr_send_bps_, packet_oh_send_);
552
553 // Find bounding set.
554 std::vector<rtcp::TmmbItem> bounding =
555 TMMBRHelp::FindBoundingSet(std::move(candidates));
556 tmmbr_owner = TMMBRHelp::IsOwner(bounding, ssrc_);
557 if (!tmmbr_owner) {
558 // Did not enter bounding set, no meaning to send this request.
559 return;
560 }
561 }
562 }
563
564 if (!tmmbr_send_bps_)
565 return;
566
567 rtcp::Tmmbr tmmbr;
568 tmmbr.SetSenderSsrc(ssrc_);
569 rtcp::TmmbItem request;
570 request.set_ssrc(remote_ssrc_);
571 request.set_bitrate_bps(tmmbr_send_bps_);
572 request.set_packet_overhead(packet_oh_send_);
573 tmmbr.AddTmmbr(request);
574 sender.AppendPacket(tmmbr);
575 }
576
BuildTMMBN(const RtcpContext & ctx,PacketSender & sender)577 void RTCPSender::BuildTMMBN(const RtcpContext& ctx, PacketSender& sender) {
578 rtcp::Tmmbn tmmbn;
579 tmmbn.SetSenderSsrc(ssrc_);
580 for (const rtcp::TmmbItem& tmmbr : tmmbn_to_send_) {
581 if (tmmbr.bitrate_bps() > 0) {
582 tmmbn.AddTmmbr(tmmbr);
583 }
584 }
585 sender.AppendPacket(tmmbn);
586 }
587
BuildAPP(const RtcpContext & ctx,PacketSender & sender)588 void RTCPSender::BuildAPP(const RtcpContext& ctx, PacketSender& sender) {
589 rtcp::App app;
590 app.SetSenderSsrc(ssrc_);
591 sender.AppendPacket(app);
592 }
593
BuildLossNotification(const RtcpContext & ctx,PacketSender & sender)594 void RTCPSender::BuildLossNotification(const RtcpContext& ctx,
595 PacketSender& sender) {
596 loss_notification_.SetSenderSsrc(ssrc_);
597 loss_notification_.SetMediaSsrc(remote_ssrc_);
598 sender.AppendPacket(loss_notification_);
599 }
600
BuildNACK(const RtcpContext & ctx,PacketSender & sender)601 void RTCPSender::BuildNACK(const RtcpContext& ctx, PacketSender& sender) {
602 rtcp::Nack nack;
603 nack.SetSenderSsrc(ssrc_);
604 nack.SetMediaSsrc(remote_ssrc_);
605 nack.SetPacketIds(ctx.nack_list_, ctx.nack_size_);
606
607 // Report stats.
608 for (int idx = 0; idx < ctx.nack_size_; ++idx) {
609 nack_stats_.ReportRequest(ctx.nack_list_[idx]);
610 }
611 packet_type_counter_.nack_requests = nack_stats_.requests();
612 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
613
614 ++packet_type_counter_.nack_packets;
615 sender.AppendPacket(nack);
616 }
617
BuildBYE(const RtcpContext & ctx,PacketSender & sender)618 void RTCPSender::BuildBYE(const RtcpContext& ctx, PacketSender& sender) {
619 rtcp::Bye bye;
620 bye.SetSenderSsrc(ssrc_);
621 bye.SetCsrcs(csrcs_);
622 sender.AppendPacket(bye);
623 }
624
BuildExtendedReports(const RtcpContext & ctx,PacketSender & sender)625 void RTCPSender::BuildExtendedReports(const RtcpContext& ctx,
626 PacketSender& sender) {
627 rtcp::ExtendedReports xr;
628 xr.SetSenderSsrc(ssrc_);
629
630 if (!sending_ && xr_send_receiver_reference_time_enabled_) {
631 rtcp::Rrtr rrtr;
632 rrtr.SetNtp(clock_->ConvertTimestampToNtpTime(ctx.now_));
633 xr.SetRrtr(rrtr);
634 }
635
636 for (const rtcp::ReceiveTimeInfo& rti : ctx.feedback_state_.last_xr_rtis) {
637 xr.AddDlrrItem(rti);
638 }
639
640 if (send_video_bitrate_allocation_) {
641 rtcp::TargetBitrate target_bitrate;
642
643 for (int sl = 0; sl < kMaxSpatialLayers; ++sl) {
644 for (int tl = 0; tl < kMaxTemporalStreams; ++tl) {
645 if (video_bitrate_allocation_.HasBitrate(sl, tl)) {
646 target_bitrate.AddTargetBitrate(
647 sl, tl, video_bitrate_allocation_.GetBitrate(sl, tl) / 1000);
648 }
649 }
650 }
651
652 xr.SetTargetBitrate(target_bitrate);
653 send_video_bitrate_allocation_ = false;
654 }
655 sender.AppendPacket(xr);
656 }
657
SendRTCP(const FeedbackState & feedback_state,RTCPPacketType packet_type,int32_t nack_size,const uint16_t * nack_list)658 int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state,
659 RTCPPacketType packet_type,
660 int32_t nack_size,
661 const uint16_t* nack_list) {
662 int32_t error_code = -1;
663 auto callback = [&](rtc::ArrayView<const uint8_t> packet) {
664 if (transport_->SendRtcp(packet.data(), packet.size())) {
665 error_code = 0;
666 if (event_log_) {
667 event_log_->Log(std::make_unique<RtcEventRtcpPacketOutgoing>(packet));
668 }
669 }
670 };
671 absl::optional<PacketSender> sender;
672 {
673 MutexLock lock(&mutex_rtcp_sender_);
674 sender.emplace(callback, max_packet_size_);
675 auto result = ComputeCompoundRTCPPacket(feedback_state, packet_type,
676 nack_size, nack_list, *sender);
677 if (result) {
678 return *result;
679 }
680 }
681 sender->Send();
682
683 return error_code;
684 }
685
ComputeCompoundRTCPPacket(const FeedbackState & feedback_state,RTCPPacketType packet_type,int32_t nack_size,const uint16_t * nack_list,PacketSender & sender)686 absl::optional<int32_t> RTCPSender::ComputeCompoundRTCPPacket(
687 const FeedbackState& feedback_state,
688 RTCPPacketType packet_type,
689 int32_t nack_size,
690 const uint16_t* nack_list,
691 PacketSender& sender) {
692 if (method_ == RtcpMode::kOff) {
693 RTC_LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
694 return -1;
695 }
696 // Add the flag as volatile. Non volatile entries will not be overwritten.
697 // The new volatile flag will be consumed by the end of this call.
698 SetFlag(packet_type, true);
699
700 // Prevent sending streams to send SR before any media has been sent.
701 const bool can_calculate_rtp_timestamp = last_frame_capture_time_.has_value();
702 if (!can_calculate_rtp_timestamp) {
703 bool consumed_sr_flag = ConsumeFlag(kRtcpSr);
704 bool consumed_report_flag = sending_ && ConsumeFlag(kRtcpReport);
705 bool sender_report = consumed_report_flag || consumed_sr_flag;
706 if (sender_report && AllVolatileFlagsConsumed()) {
707 // This call was for Sender Report and nothing else.
708 return 0;
709 }
710 if (sending_ && method_ == RtcpMode::kCompound) {
711 // Not allowed to send any RTCP packet without sender report.
712 return -1;
713 }
714 }
715
716 // We need to send our NTP even if we haven't received any reports.
717 RtcpContext context(feedback_state, nack_size, nack_list,
718 clock_->CurrentTime());
719
720 PrepareReport(feedback_state);
721
722 bool create_bye = false;
723
724 auto it = report_flags_.begin();
725 while (it != report_flags_.end()) {
726 uint32_t rtcp_packet_type = it->type;
727
728 if (it->is_volatile) {
729 report_flags_.erase(it++);
730 } else {
731 ++it;
732 }
733
734 // If there is a BYE, don't append now - save it and append it
735 // at the end later.
736 if (rtcp_packet_type == kRtcpBye) {
737 create_bye = true;
738 continue;
739 }
740 auto builder_it = builders_.find(rtcp_packet_type);
741 if (builder_it == builders_.end()) {
742 RTC_DCHECK_NOTREACHED()
743 << "Could not find builder for packet type " << rtcp_packet_type;
744 } else {
745 BuilderFunc func = builder_it->second;
746 (this->*func)(context, sender);
747 }
748 }
749
750 // Append the BYE now at the end
751 if (create_bye) {
752 BuildBYE(context, sender);
753 }
754
755 if (packet_type_counter_observer_ != nullptr) {
756 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
757 remote_ssrc_, packet_type_counter_);
758 }
759
760 RTC_DCHECK(AllVolatileFlagsConsumed());
761 return absl::nullopt;
762 }
763
PrepareReport(const FeedbackState & feedback_state)764 void RTCPSender::PrepareReport(const FeedbackState& feedback_state) {
765 bool generate_report;
766 if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) {
767 // Report type already explicitly set, don't automatically populate.
768 generate_report = true;
769 RTC_DCHECK(ConsumeFlag(kRtcpReport) == false);
770 } else {
771 generate_report =
772 (ConsumeFlag(kRtcpReport) && method_ == RtcpMode::kReducedSize) ||
773 method_ == RtcpMode::kCompound;
774 if (generate_report)
775 SetFlag(sending_ ? kRtcpSr : kRtcpRr, true);
776 }
777
778 if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty()))
779 SetFlag(kRtcpSdes, true);
780
781 if (generate_report) {
782 if ((!sending_ && xr_send_receiver_reference_time_enabled_) ||
783 !feedback_state.last_xr_rtis.empty() ||
784 send_video_bitrate_allocation_) {
785 SetFlag(kRtcpAnyExtendedReports, true);
786 }
787
788 // generate next time to send an RTCP report
789 TimeDelta min_interval = report_interval_;
790
791 if (!audio_ && sending_) {
792 // Calculate bandwidth for video; 360 / send bandwidth in kbit/s.
793 int send_bitrate_kbit = feedback_state.send_bitrate / 1000;
794 if (send_bitrate_kbit != 0) {
795 min_interval = std::min(TimeDelta::Millis(360000 / send_bitrate_kbit),
796 report_interval_);
797 }
798 }
799
800 // The interval between RTCP packets is varied randomly over the
801 // range [1/2,3/2] times the calculated interval.
802 int min_interval_int = rtc::dchecked_cast<int>(min_interval.ms());
803 TimeDelta time_to_next = TimeDelta::Millis(
804 random_.Rand(min_interval_int * 1 / 2, min_interval_int * 3 / 2));
805
806 RTC_DCHECK(!time_to_next.IsZero());
807 SetNextRtcpSendEvaluationDuration(time_to_next);
808
809 // RtcpSender expected to be used for sending either just sender reports
810 // or just receiver reports.
811 RTC_DCHECK(!(IsFlagPresent(kRtcpSr) && IsFlagPresent(kRtcpRr)));
812 }
813 }
814
CreateReportBlocks(const FeedbackState & feedback_state)815 std::vector<rtcp::ReportBlock> RTCPSender::CreateReportBlocks(
816 const FeedbackState& feedback_state) {
817 std::vector<rtcp::ReportBlock> result;
818 if (!receive_statistics_)
819 return result;
820
821 // TODO(danilchap): Support sending more than `RTCP_MAX_REPORT_BLOCKS` per
822 // compound rtcp packet when single rtcp module is used for multiple media
823 // streams.
824 result = receive_statistics_->RtcpReportBlocks(RTCP_MAX_REPORT_BLOCKS);
825
826 if (!result.empty() && ((feedback_state.last_rr_ntp_secs != 0) ||
827 (feedback_state.last_rr_ntp_frac != 0))) {
828 // Get our NTP as late as possible to avoid a race.
829 uint32_t now = CompactNtp(clock_->CurrentNtpTime());
830
831 uint32_t receive_time = feedback_state.last_rr_ntp_secs & 0x0000FFFF;
832 receive_time <<= 16;
833 receive_time += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;
834
835 uint32_t delay_since_last_sr = now - receive_time;
836 // TODO(danilchap): Instead of setting same value on all report blocks,
837 // set only when media_ssrc match sender ssrc of the sender report
838 // remote times were taken from.
839 for (auto& report_block : result) {
840 report_block.SetLastSr(feedback_state.remote_sr);
841 report_block.SetDelayLastSr(delay_since_last_sr);
842 }
843 }
844 return result;
845 }
846
SetCsrcs(const std::vector<uint32_t> & csrcs)847 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) {
848 RTC_DCHECK_LE(csrcs.size(), kRtpCsrcSize);
849 MutexLock lock(&mutex_rtcp_sender_);
850 csrcs_ = csrcs;
851 }
852
SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set)853 void RTCPSender::SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set) {
854 MutexLock lock(&mutex_rtcp_sender_);
855 tmmbn_to_send_ = std::move(bounding_set);
856 SetFlag(kRtcpTmmbn, true);
857 }
858
SetFlag(uint32_t type,bool is_volatile)859 void RTCPSender::SetFlag(uint32_t type, bool is_volatile) {
860 if (type & kRtcpAnyExtendedReports) {
861 report_flags_.insert(ReportFlag(kRtcpAnyExtendedReports, is_volatile));
862 } else {
863 report_flags_.insert(ReportFlag(type, is_volatile));
864 }
865 }
866
IsFlagPresent(uint32_t type) const867 bool RTCPSender::IsFlagPresent(uint32_t type) const {
868 return report_flags_.find(ReportFlag(type, false)) != report_flags_.end();
869 }
870
ConsumeFlag(uint32_t type,bool forced)871 bool RTCPSender::ConsumeFlag(uint32_t type, bool forced) {
872 auto it = report_flags_.find(ReportFlag(type, false));
873 if (it == report_flags_.end())
874 return false;
875 if (it->is_volatile || forced)
876 report_flags_.erase((it));
877 return true;
878 }
879
AllVolatileFlagsConsumed() const880 bool RTCPSender::AllVolatileFlagsConsumed() const {
881 for (const ReportFlag& flag : report_flags_) {
882 if (flag.is_volatile)
883 return false;
884 }
885 return true;
886 }
887
SetVideoBitrateAllocation(const VideoBitrateAllocation & bitrate)888 void RTCPSender::SetVideoBitrateAllocation(
889 const VideoBitrateAllocation& bitrate) {
890 MutexLock lock(&mutex_rtcp_sender_);
891 if (method_ == RtcpMode::kOff) {
892 RTC_LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
893 return;
894 }
895 // Check if this allocation is first ever, or has a different set of
896 // spatial/temporal layers signaled and enabled, if so trigger an rtcp report
897 // as soon as possible.
898 absl::optional<VideoBitrateAllocation> new_bitrate =
899 CheckAndUpdateLayerStructure(bitrate);
900 if (new_bitrate) {
901 video_bitrate_allocation_ = *new_bitrate;
902 RTC_LOG(LS_INFO) << "Emitting TargetBitrate XR for SSRC " << ssrc_
903 << " with new layers enabled/disabled: "
904 << video_bitrate_allocation_.ToString();
905 SetNextRtcpSendEvaluationDuration(TimeDelta::Zero());
906 } else {
907 video_bitrate_allocation_ = bitrate;
908 }
909
910 send_video_bitrate_allocation_ = true;
911 SetFlag(kRtcpAnyExtendedReports, true);
912 }
913
CheckAndUpdateLayerStructure(const VideoBitrateAllocation & bitrate) const914 absl::optional<VideoBitrateAllocation> RTCPSender::CheckAndUpdateLayerStructure(
915 const VideoBitrateAllocation& bitrate) const {
916 absl::optional<VideoBitrateAllocation> updated_bitrate;
917 for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
918 for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
919 if (!updated_bitrate &&
920 (bitrate.HasBitrate(si, ti) !=
921 video_bitrate_allocation_.HasBitrate(si, ti) ||
922 (bitrate.GetBitrate(si, ti) == 0) !=
923 (video_bitrate_allocation_.GetBitrate(si, ti) == 0))) {
924 updated_bitrate = bitrate;
925 }
926 if (video_bitrate_allocation_.GetBitrate(si, ti) > 0 &&
927 bitrate.GetBitrate(si, ti) == 0) {
928 // Make sure this stream disabling is explicitly signaled.
929 updated_bitrate->SetBitrate(si, ti, 0);
930 }
931 }
932 }
933
934 return updated_bitrate;
935 }
936
SendCombinedRtcpPacket(std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets)937 void RTCPSender::SendCombinedRtcpPacket(
938 std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) {
939 size_t max_packet_size;
940 uint32_t ssrc;
941 {
942 MutexLock lock(&mutex_rtcp_sender_);
943 if (method_ == RtcpMode::kOff) {
944 RTC_LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
945 return;
946 }
947
948 max_packet_size = max_packet_size_;
949 ssrc = ssrc_;
950 }
951 RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE);
952 auto callback = [&](rtc::ArrayView<const uint8_t> packet) {
953 if (transport_->SendRtcp(packet.data(), packet.size())) {
954 if (event_log_)
955 event_log_->Log(std::make_unique<RtcEventRtcpPacketOutgoing>(packet));
956 }
957 };
958 PacketSender sender(callback, max_packet_size);
959 for (auto& rtcp_packet : rtcp_packets) {
960 rtcp_packet->SetSenderSsrc(ssrc);
961 sender.AppendPacket(*rtcp_packet);
962 }
963 sender.Send();
964 }
965
SetNextRtcpSendEvaluationDuration(TimeDelta duration)966 void RTCPSender::SetNextRtcpSendEvaluationDuration(TimeDelta duration) {
967 next_time_to_send_rtcp_ = clock_->CurrentTime() + duration;
968 // TODO(bugs.webrtc.org/11581): make unconditional once downstream consumers
969 // are using the callback method.
970 if (schedule_next_rtcp_send_evaluation_function_)
971 schedule_next_rtcp_send_evaluation_function_(duration);
972 }
973
974 } // namespace webrtc
975