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