tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rtcp_sender.cc (29847B)


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