xref: /aosp_15_r20/external/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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