LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/rtp_rtcp/source - rtcp_sender.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 538 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 69 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
      12             : 
      13             : #include <string.h>  // memcpy
      14             : 
      15             : #include <utility>
      16             : 
      17             : #include "webrtc/base/checks.h"
      18             : #include "webrtc/base/constructormagic.h"
      19             : #include "webrtc/base/logging.h"
      20             : #include "webrtc/base/trace_event.h"
      21             : #include "webrtc/call/call.h"
      22             : #include "webrtc/common_types.h"
      23             : #include "webrtc/logging/rtc_event_log/rtc_event_log.h"
      24             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h"
      25             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h"
      26             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
      27             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
      28             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/fir.h"
      29             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h"
      30             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h"
      31             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
      32             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/remb.h"
      33             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rpsi.h"
      34             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h"
      35             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
      36             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h"
      37             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
      38             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
      39             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
      40             : #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
      41             : #include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"
      42             : 
      43             : namespace webrtc {
      44             : 
      45             : namespace {
      46             : const uint32_t kRtcpAnyExtendedReports =
      47             :     kRtcpXrVoipMetric | kRtcpXrReceiverReferenceTime | kRtcpXrDlrrReportBlock |
      48             :     kRtcpXrTargetBitrate;
      49             : }  // namespace
      50             : 
      51           0 : NACKStringBuilder::NACKStringBuilder()
      52           0 :     : stream_(""), count_(0), prevNack_(0), consecutive_(false) {}
      53             : 
      54           0 : NACKStringBuilder::~NACKStringBuilder() {}
      55             : 
      56           0 : void NACKStringBuilder::PushNACK(uint16_t nack) {
      57           0 :   if (count_ == 0) {
      58           0 :     stream_ << nack;
      59           0 :   } else if (nack == prevNack_ + 1) {
      60           0 :     consecutive_ = true;
      61             :   } else {
      62           0 :     if (consecutive_) {
      63           0 :       stream_ << "-" << prevNack_;
      64           0 :       consecutive_ = false;
      65             :     }
      66           0 :     stream_ << "," << nack;
      67             :   }
      68           0 :   count_++;
      69           0 :   prevNack_ = nack;
      70           0 : }
      71             : 
      72           0 : std::string NACKStringBuilder::GetResult() {
      73           0 :   if (consecutive_) {
      74           0 :     stream_ << "-" << prevNack_;
      75           0 :     consecutive_ = false;
      76             :   }
      77           0 :   return stream_.str();
      78             : }
      79             : 
      80           0 : RTCPSender::FeedbackState::FeedbackState()
      81             :     : send_payload_type(0),
      82             :       packets_sent(0),
      83             :       media_bytes_sent(0),
      84             :       send_bitrate(0),
      85             :       last_rr_ntp_secs(0),
      86             :       last_rr_ntp_frac(0),
      87             :       remote_sr(0),
      88             :       has_last_xr_rr(false),
      89           0 :       module(nullptr) {}
      90             : 
      91             : class PacketContainer : public rtcp::CompoundPacket,
      92             :                         public rtcp::RtcpPacket::PacketReadyCallback {
      93             :  public:
      94           0 :   PacketContainer(Transport* transport, RtcEventLog* event_log)
      95           0 :       : transport_(transport), event_log_(event_log), bytes_sent_(0) {}
      96           0 :   virtual ~PacketContainer() {
      97           0 :     for (RtcpPacket* packet : appended_packets_)
      98           0 :       delete packet;
      99           0 :   }
     100             : 
     101           0 :   void OnPacketReady(uint8_t* data, size_t length) override {
     102           0 :     if (transport_->SendRtcp(data, length)) {
     103           0 :       bytes_sent_ += length;
     104           0 :       if (event_log_) {
     105           0 :         event_log_->LogRtcpPacket(kOutgoingPacket, MediaType::ANY, data,
     106           0 :                                   length);
     107             :       }
     108             :     }
     109           0 :   }
     110             : 
     111           0 :   size_t SendPackets(size_t max_payload_length) {
     112           0 :     RTC_DCHECK_LE(max_payload_length, IP_PACKET_SIZE);
     113             :     uint8_t buffer[IP_PACKET_SIZE];
     114           0 :     BuildExternalBuffer(buffer, max_payload_length, this);
     115           0 :     return bytes_sent_;
     116             :   }
     117             : 
     118             :  private:
     119             :   Transport* transport_;
     120             :   RtcEventLog* const event_log_;
     121             :   size_t bytes_sent_;
     122             : 
     123             :   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(PacketContainer);
     124             : };
     125             : 
     126             : class RTCPSender::RtcpContext {
     127             :  public:
     128           0 :   RtcpContext(const FeedbackState& feedback_state,
     129             :               int32_t nack_size,
     130             :               const uint16_t* nack_list,
     131             :               bool repeat,
     132             :               uint64_t picture_id,
     133             :               NtpTime now)
     134           0 :       : feedback_state_(feedback_state),
     135             :         nack_size_(nack_size),
     136             :         nack_list_(nack_list),
     137             :         repeat_(repeat),
     138             :         picture_id_(picture_id),
     139           0 :         now_(now) {}
     140             : 
     141             :   const FeedbackState& feedback_state_;
     142             :   const int32_t nack_size_;
     143             :   const uint16_t* nack_list_;
     144             :   const bool repeat_;
     145             :   const uint64_t picture_id_;
     146             :   const NtpTime now_;
     147             : };
     148             : 
     149           0 : RTCPSender::RTCPSender(
     150             :     bool audio,
     151             :     Clock* clock,
     152             :     ReceiveStatistics* receive_statistics,
     153             :     RtcpPacketTypeCounterObserver* packet_type_counter_observer,
     154             :     RtcEventLog* event_log,
     155           0 :     Transport* outgoing_transport)
     156             :     : audio_(audio),
     157             :       clock_(clock),
     158           0 :       random_(clock_->TimeInMicroseconds()),
     159             :       method_(RtcpMode::kOff),
     160             :       event_log_(event_log),
     161             :       transport_(outgoing_transport),
     162             :       using_nack_(false),
     163             :       sending_(false),
     164             :       remb_enabled_(false),
     165           0 :       next_time_to_send_rtcp_(clock->TimeInMilliseconds()),
     166             :       timestamp_offset_(0),
     167             :       last_rtp_timestamp_(0),
     168             :       last_frame_capture_time_ms_(-1),
     169             :       ssrc_(0),
     170             :       remote_ssrc_(0),
     171             :       receive_statistics_(receive_statistics),
     172             : 
     173             :       sequence_number_fir_(0),
     174             : 
     175             :       remb_bitrate_(0),
     176             : 
     177             :       tmmbr_send_bps_(0),
     178             :       packet_oh_send_(0),
     179             :       max_packet_size_(IP_PACKET_SIZE - 28),  // IPv4 + UDP by default.
     180             : 
     181             :       app_sub_type_(0),
     182             :       app_name_(0),
     183             :       app_data_(nullptr),
     184             :       app_length_(0),
     185             : 
     186             :       xr_send_receiver_reference_time_enabled_(false),
     187           0 :       packet_type_counter_observer_(packet_type_counter_observer) {
     188           0 :   memset(last_send_report_, 0, sizeof(last_send_report_));
     189           0 :   memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_));
     190           0 :   memset(lastSRPacketCount_, 0, sizeof(lastSRPacketCount_));
     191           0 :   memset(lastSROctetCount_, 0, sizeof(lastSROctetCount_));
     192           0 :   RTC_DCHECK(transport_ != nullptr);
     193             : 
     194           0 :   builders_[kRtcpSr] = &RTCPSender::BuildSR;
     195           0 :   builders_[kRtcpRr] = &RTCPSender::BuildRR;
     196           0 :   builders_[kRtcpSdes] = &RTCPSender::BuildSDES;
     197           0 :   builders_[kRtcpPli] = &RTCPSender::BuildPLI;
     198           0 :   builders_[kRtcpFir] = &RTCPSender::BuildFIR;
     199           0 :   builders_[kRtcpSli] = &RTCPSender::BuildSLI;
     200           0 :   builders_[kRtcpRpsi] = &RTCPSender::BuildRPSI;
     201           0 :   builders_[kRtcpRemb] = &RTCPSender::BuildREMB;
     202           0 :   builders_[kRtcpBye] = &RTCPSender::BuildBYE;
     203           0 :   builders_[kRtcpApp] = &RTCPSender::BuildAPP;
     204           0 :   builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR;
     205           0 :   builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN;
     206           0 :   builders_[kRtcpNack] = &RTCPSender::BuildNACK;
     207           0 :   builders_[kRtcpAnyExtendedReports] = &RTCPSender::BuildExtendedReports;
     208           0 : }
     209             : 
     210           0 : RTCPSender::~RTCPSender() {}
     211             : 
     212           0 : RtcpMode RTCPSender::Status() const {
     213           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     214           0 :   return method_;
     215             : }
     216             : 
     217           0 : void RTCPSender::SetRTCPStatus(RtcpMode new_method) {
     218           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     219             : 
     220           0 :   if (method_ == RtcpMode::kOff && new_method != RtcpMode::kOff) {
     221             :     // When switching on, reschedule the next packet
     222           0 :     next_time_to_send_rtcp_ =
     223           0 :       clock_->TimeInMilliseconds() + RTCP_INTERVAL_RAPID_SYNC_MS / 2;
     224             :   }
     225           0 :   method_ = new_method;
     226           0 : }
     227             : 
     228           0 : bool RTCPSender::Sending() const {
     229           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     230           0 :   return sending_;
     231             : }
     232             : 
     233           0 : int32_t RTCPSender::SetSendingStatus(const FeedbackState& feedback_state,
     234             :                                      bool sending) {
     235           0 :   bool sendRTCPBye = false;
     236             :   {
     237           0 :     rtc::CritScope lock(&critical_section_rtcp_sender_);
     238             : 
     239           0 :     if (method_ != RtcpMode::kOff) {
     240           0 :       if (sending == false && sending_ == true) {
     241             :         // Trigger RTCP bye
     242           0 :         sendRTCPBye = true;
     243             :       }
     244             :     }
     245           0 :     sending_ = sending;
     246             :   }
     247           0 :   if (sendRTCPBye)
     248           0 :     return SendRTCP(feedback_state, kRtcpBye);
     249           0 :   return 0;
     250             : }
     251             : 
     252           0 : bool RTCPSender::REMB() const {
     253           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     254           0 :   return remb_enabled_;
     255             : }
     256             : 
     257           0 : void RTCPSender::SetREMBStatus(bool enable) {
     258           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     259           0 :   remb_enabled_ = enable;
     260           0 : }
     261             : 
     262           0 : void RTCPSender::SetREMBData(uint32_t bitrate,
     263             :                              const std::vector<uint32_t>& ssrcs) {
     264           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     265           0 :   remb_bitrate_ = bitrate;
     266           0 :   remb_ssrcs_ = ssrcs;
     267             : 
     268           0 :   if (remb_enabled_)
     269           0 :     SetFlag(kRtcpRemb, false);
     270             :   // Send a REMB immediately if we have a new REMB. The frequency of REMBs is
     271             :   // throttled by the caller.
     272           0 :   next_time_to_send_rtcp_ = clock_->TimeInMilliseconds();
     273           0 : }
     274             : 
     275           0 : bool RTCPSender::TMMBR() const {
     276           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     277           0 :   return IsFlagPresent(RTCPPacketType::kRtcpTmmbr);
     278             : }
     279             : 
     280           0 : void RTCPSender::SetTMMBRStatus(bool enable) {
     281           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     282           0 :   if (enable) {
     283           0 :     SetFlag(RTCPPacketType::kRtcpTmmbr, false);
     284             :   } else {
     285           0 :     ConsumeFlag(RTCPPacketType::kRtcpTmmbr, true);
     286             :   }
     287           0 : }
     288             : 
     289           0 : void RTCPSender::SetMaxRtpPacketSize(size_t max_packet_size) {
     290           0 :   max_packet_size_ = max_packet_size;
     291           0 : }
     292             : 
     293           0 : void RTCPSender::SetTimestampOffset(uint32_t timestamp_offset) {
     294           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     295           0 :   timestamp_offset_ = timestamp_offset;
     296           0 : }
     297             : 
     298           0 : void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp,
     299             :                                 int64_t capture_time_ms) {
     300           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     301           0 :   last_rtp_timestamp_ = rtp_timestamp;
     302           0 :   if (capture_time_ms < 0) {
     303             :     // We don't currently get a capture time from VoiceEngine.
     304           0 :     last_frame_capture_time_ms_ = clock_->TimeInMilliseconds();
     305             :   } else {
     306           0 :     last_frame_capture_time_ms_ = capture_time_ms;
     307             :   }
     308           0 : }
     309             : 
     310           0 : void RTCPSender::SetSSRC(uint32_t ssrc) {
     311           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     312             : 
     313           0 :   if (ssrc_ != 0) {
     314             :     // not first SetSSRC, probably due to a collision
     315             :     // schedule a new RTCP report
     316             :     // make sure that we send a RTP packet
     317           0 :     next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + 100;
     318             :   }
     319           0 :   ssrc_ = ssrc;
     320           0 : }
     321             : 
     322           0 : void RTCPSender::SetRemoteSSRC(uint32_t ssrc) {
     323           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     324           0 :   remote_ssrc_ = ssrc;
     325           0 : }
     326             : 
     327           0 : int32_t RTCPSender::SetCNAME(const char* c_name) {
     328           0 :   if (!c_name)
     329           0 :     return -1;
     330             : 
     331           0 :   RTC_DCHECK_LT(strlen(c_name), RTCP_CNAME_SIZE);
     332           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     333           0 :   cname_ = c_name;
     334           0 :   return 0;
     335             : }
     336             : 
     337           0 : int32_t RTCPSender::AddMixedCNAME(uint32_t SSRC, const char* c_name) {
     338           0 :   RTC_DCHECK(c_name);
     339           0 :   RTC_DCHECK_LT(strlen(c_name), RTCP_CNAME_SIZE);
     340           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     341           0 :   if (csrc_cnames_.size() >= kRtpCsrcSize)
     342           0 :     return -1;
     343             : 
     344           0 :   csrc_cnames_[SSRC] = c_name;
     345           0 :   return 0;
     346             : }
     347             : 
     348           0 : int32_t RTCPSender::RemoveMixedCNAME(uint32_t SSRC) {
     349           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     350           0 :   auto it = csrc_cnames_.find(SSRC);
     351             : 
     352           0 :   if (it == csrc_cnames_.end())
     353           0 :     return -1;
     354             : 
     355           0 :   csrc_cnames_.erase(it);
     356           0 :   return 0;
     357             : }
     358             : 
     359           0 : bool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const {
     360             :   /*
     361             :       For audio we use a fix 5 sec interval
     362             : 
     363             :       For video we use 1 sec interval fo a BW smaller than 360 kbit/s,
     364             :           technicaly we break the max 5% RTCP BW for video below 10 kbit/s but
     365             :           that should be extremely rare
     366             : 
     367             : 
     368             :   From RFC 3550
     369             : 
     370             :       MAX RTCP BW is 5% if the session BW
     371             :           A send report is approximately 65 bytes inc CNAME
     372             :           A receiver report is approximately 28 bytes
     373             : 
     374             :       The RECOMMENDED value for the reduced minimum in seconds is 360
     375             :         divided by the session bandwidth in kilobits/second.  This minimum
     376             :         is smaller than 5 seconds for bandwidths greater than 72 kb/s.
     377             : 
     378             :       If the participant has not yet sent an RTCP packet (the variable
     379             :         initial is true), the constant Tmin is set to 2.5 seconds, else it
     380             :         is set to 5 seconds.
     381             : 
     382             :       The interval between RTCP packets is varied randomly over the
     383             :         range [0.5,1.5] times the calculated interval to avoid unintended
     384             :         synchronization of all participants
     385             : 
     386             :       if we send
     387             :       If the participant is a sender (we_sent true), the constant C is
     388             :         set to the average RTCP packet size (avg_rtcp_size) divided by 25%
     389             :         of the RTCP bandwidth (rtcp_bw), and the constant n is set to the
     390             :         number of senders.
     391             : 
     392             :       if we receive only
     393             :         If we_sent is not true, the constant C is set
     394             :         to the average RTCP packet size divided by 75% of the RTCP
     395             :         bandwidth.  The constant n is set to the number of receivers
     396             :         (members - senders).  If the number of senders is greater than
     397             :         25%, senders and receivers are treated together.
     398             : 
     399             :       reconsideration NOT required for peer-to-peer
     400             :         "timer reconsideration" is
     401             :         employed.  This algorithm implements a simple back-off mechanism
     402             :         which causes users to hold back RTCP packet transmission if the
     403             :         group sizes are increasing.
     404             : 
     405             :         n = number of members
     406             :         C = avg_size/(rtcpBW/4)
     407             : 
     408             :      3. The deterministic calculated interval Td is set to max(Tmin, n*C).
     409             : 
     410             :      4. The calculated interval T is set to a number uniformly distributed
     411             :         between 0.5 and 1.5 times the deterministic calculated interval.
     412             : 
     413             :      5. The resulting value of T is divided by e-3/2=1.21828 to compensate
     414             :         for the fact that the timer reconsideration algorithm converges to
     415             :         a value of the RTCP bandwidth below the intended average
     416             :   */
     417             : 
     418           0 :   int64_t now = clock_->TimeInMilliseconds();
     419             : 
     420           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     421             : 
     422           0 :   if (method_ == RtcpMode::kOff)
     423           0 :     return false;
     424             : 
     425           0 :   if (!audio_ && sendKeyframeBeforeRTP) {
     426             :     // for video key-frames we want to send the RTCP before the large key-frame
     427             :     // if we have a 100 ms margin
     428           0 :     now += RTCP_SEND_BEFORE_KEY_FRAME_MS;
     429             :   }
     430             : 
     431           0 :   if (now >= next_time_to_send_rtcp_) {
     432           0 :     return true;
     433           0 :   } else if (now < 0x0000ffff &&
     434           0 :              next_time_to_send_rtcp_ > 0xffff0000) {  // 65 sec margin
     435             :     // wrap
     436           0 :     return true;
     437             :   }
     438           0 :   return false;
     439             : }
     440             : 
     441             : bool
     442           0 : RTCPSender::GetSendReportMetadata(const uint32_t sendReport,
     443             :                                   uint64_t *timeOfSend,
     444             :                                   uint32_t *packetCount,
     445             :                                   uint64_t *octetCount)
     446             : {
     447           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     448             : 
     449             :   // This is only saved when we are the sender
     450           0 :   if ((last_send_report_[0] == 0) || (sendReport == 0)) {
     451           0 :     return false;
     452             :   } else {
     453           0 :     for (int i = 0; i < RTCP_NUMBER_OF_SR; ++i) {
     454           0 :       if (last_send_report_[i] == sendReport) {
     455           0 :         *timeOfSend = last_rtcp_time_[i];
     456           0 :         *packetCount = lastSRPacketCount_[i];
     457           0 :         *octetCount = lastSROctetCount_[i];
     458           0 :         return true;
     459             :       }
     460             :     }
     461             :   }
     462           0 :   return false;
     463             : }
     464             : 
     465           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) {
     466           0 :   for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) {
     467             :     // shift old
     468           0 :     last_send_report_[i + 1] = last_send_report_[i];
     469           0 :     last_rtcp_time_[i + 1] = last_rtcp_time_[i];
     470           0 :     lastSRPacketCount_[i+1] = lastSRPacketCount_[i];
     471           0 :     lastSROctetCount_[i+1] = lastSROctetCount_[i];
     472             :   }
     473             : 
     474           0 :   last_rtcp_time_[0] = ctx.now_.ToMs();
     475           0 :   last_send_report_[0] = (ctx.now_.seconds() << 16) + (ctx.now_.fractions() >> 16);
     476           0 :   lastSRPacketCount_[0] = ctx.feedback_state_.packets_sent;
     477           0 :   lastSROctetCount_[0] = ctx.feedback_state_.media_bytes_sent;
     478             : 
     479             :   // Timestamp shouldn't be estimated before first media frame.
     480           0 :   RTC_DCHECK_GE(last_frame_capture_time_ms_, 0);
     481             :   // The timestamp of this RTCP packet should be estimated as the timestamp of
     482             :   // the frame being captured at this moment. We are calculating that
     483             :   // timestamp as the last frame's timestamp + the time since the last frame
     484             :   // was captured.
     485             :   uint32_t rtp_rate =
     486           0 :       (audio_ ? kBogusRtpRateForAudioRtcp : kVideoPayloadTypeFrequency) / 1000;
     487             :   uint32_t rtp_timestamp =
     488           0 :       timestamp_offset_ + last_rtp_timestamp_ +
     489           0 :       (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * rtp_rate;
     490             : 
     491           0 :   rtcp::SenderReport* report = new rtcp::SenderReport();
     492           0 :   report->SetSenderSsrc(ssrc_);
     493           0 :   report->SetNtp(ctx.now_);
     494           0 :   report->SetRtpTimestamp(rtp_timestamp);
     495           0 :   report->SetPacketCount(ctx.feedback_state_.packets_sent);
     496           0 :   report->SetOctetCount(ctx.feedback_state_.media_bytes_sent);
     497             : 
     498           0 :   for (auto it : report_blocks_)
     499           0 :     report->AddReportBlock(it.second);
     500             : 
     501           0 :   report_blocks_.clear();
     502             : 
     503           0 :   return std::unique_ptr<rtcp::RtcpPacket>(report);
     504             : }
     505             : 
     506           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildSDES(
     507             :     const RtcpContext& ctx) {
     508           0 :   size_t length_cname = cname_.length();
     509           0 :   RTC_CHECK_LT(length_cname, RTCP_CNAME_SIZE);
     510             : 
     511           0 :   rtcp::Sdes* sdes = new rtcp::Sdes();
     512           0 :   sdes->AddCName(ssrc_, cname_);
     513             : 
     514           0 :   for (const auto it : csrc_cnames_)
     515           0 :     sdes->AddCName(it.first, it.second);
     516             : 
     517           0 :   return std::unique_ptr<rtcp::RtcpPacket>(sdes);
     518             : }
     519             : 
     520           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildRR(const RtcpContext& ctx) {
     521           0 :   rtcp::ReceiverReport* report = new rtcp::ReceiverReport();
     522           0 :   report->SetSenderSsrc(ssrc_);
     523           0 :   for (auto it : report_blocks_)
     524           0 :     report->AddReportBlock(it.second);
     525             : 
     526           0 :   report_blocks_.clear();
     527           0 :   return std::unique_ptr<rtcp::RtcpPacket>(report);
     528             : }
     529             : 
     530           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildPLI(const RtcpContext& ctx) {
     531           0 :   rtcp::Pli* pli = new rtcp::Pli();
     532           0 :   pli->SetSenderSsrc(ssrc_);
     533           0 :   pli->SetMediaSsrc(remote_ssrc_);
     534             : 
     535           0 :   TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
     536             :                        "RTCPSender::PLI");
     537           0 :   ++packet_type_counter_.pli_packets;
     538           0 :   TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_PLICount",
     539             :                     ssrc_, packet_type_counter_.pli_packets);
     540             : 
     541           0 :   return std::unique_ptr<rtcp::RtcpPacket>(pli);
     542             : }
     543             : 
     544           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildFIR(const RtcpContext& ctx) {
     545           0 :   if (!ctx.repeat_)
     546           0 :     ++sequence_number_fir_;  // Do not increase if repetition.
     547             : 
     548           0 :   rtcp::Fir* fir = new rtcp::Fir();
     549           0 :   fir->SetSenderSsrc(ssrc_);
     550           0 :   fir->AddRequestTo(remote_ssrc_, sequence_number_fir_);
     551             : 
     552           0 :   TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
     553             :                        "RTCPSender::FIR");
     554           0 :   ++packet_type_counter_.fir_packets;
     555           0 :   TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_FIRCount",
     556             :                     ssrc_, packet_type_counter_.fir_packets);
     557             : 
     558           0 :   return std::unique_ptr<rtcp::RtcpPacket>(fir);
     559             : }
     560             : 
     561             : /*
     562             :     0                   1                   2                   3
     563             :     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     564             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     565             :    |            First        |        Number           | PictureID |
     566             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     567             : */
     568           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildSLI(const RtcpContext& ctx) {
     569           0 :   rtcp::Sli* sli = new rtcp::Sli();
     570           0 :   sli->SetSenderSsrc(ssrc_);
     571           0 :   sli->SetMediaSsrc(remote_ssrc_);
     572             :   // Crop picture id to 6 least significant bits.
     573           0 :   sli->AddPictureId(ctx.picture_id_ & 0x3F);
     574             : 
     575           0 :   return std::unique_ptr<rtcp::RtcpPacket>(sli);
     576             : }
     577             : 
     578             : /*
     579             :     0                   1                   2                   3
     580             :     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     581             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     582             :    |      PB       |0| Payload Type|    Native RPSI bit string     |
     583             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     584             :    |   defined per codec          ...                | Padding (0) |
     585             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     586             : */
     587             : /*
     588             : *    Note: not generic made for VP8
     589             : */
     590           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildRPSI(
     591             :     const RtcpContext& ctx) {
     592           0 :   if (ctx.feedback_state_.send_payload_type == 0xFF)
     593           0 :     return nullptr;
     594             : 
     595           0 :   rtcp::Rpsi* rpsi = new rtcp::Rpsi();
     596           0 :   rpsi->SetSenderSsrc(ssrc_);
     597           0 :   rpsi->SetMediaSsrc(remote_ssrc_);
     598           0 :   rpsi->SetPayloadType(ctx.feedback_state_.send_payload_type);
     599           0 :   rpsi->SetPictureId(ctx.picture_id_);
     600             : 
     601           0 :   return std::unique_ptr<rtcp::RtcpPacket>(rpsi);
     602             : }
     603             : 
     604           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildREMB(
     605             :     const RtcpContext& ctx) {
     606           0 :   rtcp::Remb* remb = new rtcp::Remb();
     607           0 :   remb->SetSenderSsrc(ssrc_);
     608           0 :   remb->SetBitrateBps(remb_bitrate_);
     609           0 :   remb->SetSsrcs(remb_ssrcs_);
     610             : 
     611           0 :   TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
     612             :                        "RTCPSender::REMB");
     613             : 
     614           0 :   return std::unique_ptr<rtcp::RtcpPacket>(remb);
     615             : }
     616             : 
     617           0 : void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) {
     618           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     619           0 :   tmmbr_send_bps_ = target_bitrate;
     620           0 : }
     621             : 
     622           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildTMMBR(
     623             :     const RtcpContext& ctx) {
     624           0 :   if (ctx.feedback_state_.module == nullptr)
     625           0 :     return nullptr;
     626             :   // Before sending the TMMBR check the received TMMBN, only an owner is
     627             :   // allowed to raise the bitrate:
     628             :   // * If the sender is an owner of the TMMBN -> send TMMBR
     629             :   // * If not an owner but the TMMBR would enter the TMMBN -> send TMMBR
     630             : 
     631             :   // get current bounding set from RTCP receiver
     632           0 :   bool tmmbr_owner = false;
     633             : 
     634             :   // holding critical_section_rtcp_sender_ while calling RTCPreceiver which
     635             :   // will accuire criticalSectionRTCPReceiver_ is a potental deadlock but
     636             :   // since RTCPreceiver is not doing the reverse we should be fine
     637             :   std::vector<rtcp::TmmbItem> candidates =
     638           0 :       ctx.feedback_state_.module->BoundingSet(&tmmbr_owner);
     639             : 
     640           0 :   if (!candidates.empty()) {
     641           0 :     for (const auto& candidate : candidates) {
     642           0 :       if (candidate.bitrate_bps() == tmmbr_send_bps_ &&
     643           0 :           candidate.packet_overhead() == packet_oh_send_) {
     644             :         // Do not send the same tuple.
     645           0 :         return nullptr;
     646             :       }
     647             :     }
     648           0 :     if (!tmmbr_owner) {
     649             :       // Use received bounding set as candidate set.
     650             :       // Add current tuple.
     651           0 :       candidates.emplace_back(ssrc_, tmmbr_send_bps_, packet_oh_send_);
     652             : 
     653             :       // Find bounding set.
     654             :       std::vector<rtcp::TmmbItem> bounding =
     655           0 :           TMMBRHelp::FindBoundingSet(std::move(candidates));
     656           0 :       tmmbr_owner = TMMBRHelp::IsOwner(bounding, ssrc_);
     657           0 :       if (!tmmbr_owner) {
     658             :         // Did not enter bounding set, no meaning to send this request.
     659           0 :         return nullptr;
     660             :       }
     661             :     }
     662             :   }
     663             : 
     664           0 :   if (!tmmbr_send_bps_)
     665           0 :     return nullptr;
     666             : 
     667           0 :   rtcp::Tmmbr* tmmbr = new rtcp::Tmmbr();
     668           0 :   tmmbr->SetSenderSsrc(ssrc_);
     669           0 :   rtcp::TmmbItem request;
     670           0 :   request.set_ssrc(remote_ssrc_);
     671           0 :   request.set_bitrate_bps(tmmbr_send_bps_);
     672           0 :   request.set_packet_overhead(packet_oh_send_);
     673           0 :   tmmbr->AddTmmbr(request);
     674             : 
     675           0 :   return std::unique_ptr<rtcp::RtcpPacket>(tmmbr);
     676             : }
     677             : 
     678           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildTMMBN(
     679             :     const RtcpContext& ctx) {
     680           0 :   rtcp::Tmmbn* tmmbn = new rtcp::Tmmbn();
     681           0 :   tmmbn->SetSenderSsrc(ssrc_);
     682           0 :   for (const rtcp::TmmbItem& tmmbr : tmmbn_to_send_) {
     683           0 :     if (tmmbr.bitrate_bps() > 0) {
     684           0 :       tmmbn->AddTmmbr(tmmbr);
     685             :     }
     686             :   }
     687             : 
     688           0 :   return std::unique_ptr<rtcp::RtcpPacket>(tmmbn);
     689             : }
     690             : 
     691           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildAPP(const RtcpContext& ctx) {
     692           0 :   rtcp::App* app = new rtcp::App();
     693           0 :   app->SetSsrc(ssrc_);
     694           0 :   app->SetSubType(app_sub_type_);
     695           0 :   app->SetName(app_name_);
     696           0 :   app->SetData(app_data_.get(), app_length_);
     697             : 
     698           0 :   return std::unique_ptr<rtcp::RtcpPacket>(app);
     699             : }
     700             : 
     701           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildNACK(
     702             :     const RtcpContext& ctx) {
     703           0 :   rtcp::Nack* nack = new rtcp::Nack();
     704           0 :   nack->SetSenderSsrc(ssrc_);
     705           0 :   nack->SetMediaSsrc(remote_ssrc_);
     706           0 :   nack->SetPacketIds(ctx.nack_list_, ctx.nack_size_);
     707             : 
     708             :   // Report stats.
     709           0 :   NACKStringBuilder stringBuilder;
     710           0 :   for (int idx = 0; idx < ctx.nack_size_; ++idx) {
     711           0 :     stringBuilder.PushNACK(ctx.nack_list_[idx]);
     712           0 :     nack_stats_.ReportRequest(ctx.nack_list_[idx]);
     713             :   }
     714           0 :   packet_type_counter_.nack_requests = nack_stats_.requests();
     715           0 :   packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
     716             : 
     717           0 :   TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
     718             :                        "RTCPSender::NACK", "nacks",
     719             :                        TRACE_STR_COPY(stringBuilder.GetResult().c_str()));
     720           0 :   ++packet_type_counter_.nack_packets;
     721           0 :   TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount",
     722             :                     ssrc_, packet_type_counter_.nack_packets);
     723             : 
     724           0 :   return std::unique_ptr<rtcp::RtcpPacket>(nack);
     725             : }
     726             : 
     727           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildBYE(const RtcpContext& ctx) {
     728           0 :   rtcp::Bye* bye = new rtcp::Bye();
     729           0 :   bye->SetSenderSsrc(ssrc_);
     730           0 :   bye->SetCsrcs(csrcs_);
     731             : 
     732           0 :   return std::unique_ptr<rtcp::RtcpPacket>(bye);
     733             : }
     734             : 
     735           0 : std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildExtendedReports(
     736             :     const RtcpContext& ctx) {
     737           0 :   std::unique_ptr<rtcp::ExtendedReports> xr(new rtcp::ExtendedReports());
     738           0 :   xr->SetSenderSsrc(ssrc_);
     739             : 
     740           0 :   if (!sending_ && xr_send_receiver_reference_time_enabled_) {
     741           0 :     rtcp::Rrtr rrtr;
     742           0 :     rrtr.SetNtp(ctx.now_);
     743           0 :     xr->SetRrtr(rrtr);
     744             :   }
     745             : 
     746           0 :   if (ctx.feedback_state_.has_last_xr_rr) {
     747           0 :     xr->AddDlrrItem(ctx.feedback_state_.last_xr_rr);
     748             :   }
     749             : 
     750           0 :   if (video_bitrate_allocation_) {
     751           0 :     rtcp::TargetBitrate target_bitrate;
     752             : 
     753           0 :     for (int sl = 0; sl < kMaxSpatialLayers; ++sl) {
     754           0 :       for (int tl = 0; tl < kMaxTemporalStreams; ++tl) {
     755             :         uint32_t layer_bitrate_bps =
     756           0 :             video_bitrate_allocation_->GetBitrate(sl, tl);
     757           0 :         if (layer_bitrate_bps > 0)
     758           0 :           target_bitrate.AddTargetBitrate(sl, tl, layer_bitrate_bps / 1000);
     759             :       }
     760             :     }
     761             : 
     762           0 :     xr->SetTargetBitrate(target_bitrate);
     763           0 :     video_bitrate_allocation_.reset();
     764             :   }
     765             : 
     766           0 :   if (xr_voip_metric_) {
     767           0 :     rtcp::VoipMetric voip;
     768           0 :     voip.SetMediaSsrc(remote_ssrc_);
     769           0 :     voip.SetVoipMetric(*xr_voip_metric_);
     770           0 :     xr_voip_metric_.reset();
     771             : 
     772           0 :     xr->SetVoipMetric(voip);
     773             :   }
     774             : 
     775           0 :   return std::move(xr);
     776             : }
     777             : 
     778           0 : int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state,
     779             :                              RTCPPacketType packetType,
     780             :                              int32_t nack_size,
     781             :                              const uint16_t* nack_list,
     782             :                              bool repeat,
     783             :                              uint64_t pictureID) {
     784           0 :   return SendCompoundRTCP(
     785           0 :       feedback_state, std::set<RTCPPacketType>(&packetType, &packetType + 1),
     786           0 :       nack_size, nack_list, repeat, pictureID);
     787             : }
     788             : 
     789           0 : int32_t RTCPSender::SendCompoundRTCP(
     790             :     const FeedbackState& feedback_state,
     791             :     const std::set<RTCPPacketType>& packet_types,
     792             :     int32_t nack_size,
     793             :     const uint16_t* nack_list,
     794             :     bool repeat,
     795             :     uint64_t pictureID) {
     796           0 :   PacketContainer container(transport_, event_log_);
     797             :   {
     798           0 :     rtc::CritScope lock(&critical_section_rtcp_sender_);
     799           0 :     if (method_ == RtcpMode::kOff) {
     800           0 :       LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
     801           0 :       return -1;
     802             :     }
     803             :     // Add all flags as volatile. Non volatile entries will not be overwritten.
     804             :     // All new volatile flags added will be consumed by the end of this call.
     805           0 :     SetFlags(packet_types, true);
     806             : 
     807             :     // Prevent sending streams to send SR before any media has been sent.
     808           0 :     const bool can_calculate_rtp_timestamp = (last_frame_capture_time_ms_ >= 0);
     809           0 :     if (!can_calculate_rtp_timestamp) {
     810           0 :       bool consumed_sr_flag = ConsumeFlag(kRtcpSr);
     811           0 :       bool consumed_report_flag = sending_ && ConsumeFlag(kRtcpReport);
     812           0 :       bool sender_report = consumed_report_flag || consumed_sr_flag;
     813           0 :       if (sender_report && AllVolatileFlagsConsumed()) {
     814             :         // This call was for Sender Report and nothing else.
     815           0 :         return 0;
     816             :       }
     817           0 :       if (sending_ && method_ == RtcpMode::kCompound) {
     818             :         // Not allowed to send any RTCP packet without sender report.
     819           0 :         return -1;
     820             :       }
     821             :     }
     822             : 
     823           0 :     if (packet_type_counter_.first_packet_time_ms == -1)
     824           0 :       packet_type_counter_.first_packet_time_ms = clock_->TimeInMilliseconds();
     825             : 
     826             :     // We need to send our NTP even if we haven't received any reports.
     827             :     RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID,
     828           0 :                         NtpTime(*clock_));
     829             : 
     830           0 :     PrepareReport(feedback_state);
     831             : 
     832           0 :     std::unique_ptr<rtcp::RtcpPacket> packet_bye;
     833             : 
     834           0 :     auto it = report_flags_.begin();
     835           0 :     while (it != report_flags_.end()) {
     836           0 :       auto builder_it = builders_.find(it->type);
     837           0 :       RTC_DCHECK(builder_it != builders_.end())
     838           0 :           << "Could not find builder for packet type " << it->type;
     839           0 :       if (it->is_volatile) {
     840           0 :         report_flags_.erase(it++);
     841             :       } else {
     842           0 :         ++it;
     843             :       }
     844             : 
     845           0 :       BuilderFunc func = builder_it->second;
     846           0 :       std::unique_ptr<rtcp::RtcpPacket> packet = (this->*func)(context);
     847           0 :       if (packet.get() == nullptr)
     848           0 :         return -1;
     849             :       // If there is a BYE, don't append now - save it and append it
     850             :       // at the end later.
     851           0 :       if (builder_it->first == kRtcpBye) {
     852           0 :         packet_bye = std::move(packet);
     853             :       } else {
     854           0 :         container.Append(packet.release());
     855             :       }
     856             :     }
     857             : 
     858             :     // Append the BYE now at the end
     859           0 :     if (packet_bye) {
     860           0 :       container.Append(packet_bye.release());
     861             :     }
     862             : 
     863           0 :     if (packet_type_counter_observer_ != nullptr) {
     864           0 :       packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
     865           0 :           remote_ssrc_, packet_type_counter_);
     866             :     }
     867             : 
     868           0 :     RTC_DCHECK(AllVolatileFlagsConsumed());
     869             :   }
     870             : 
     871           0 :   size_t bytes_sent = container.SendPackets(max_packet_size_);
     872           0 :   return bytes_sent == 0 ? -1 : 0;
     873             : }
     874             : 
     875           0 : void RTCPSender::PrepareReport(const FeedbackState& feedback_state) {
     876             :   bool generate_report;
     877           0 :   if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) {
     878             :     // Report type already explicitly set, don't automatically populate.
     879           0 :     generate_report = true;
     880           0 :     RTC_DCHECK(ConsumeFlag(kRtcpReport) == false);
     881             :   } else {
     882           0 :     generate_report =
     883           0 :         (ConsumeFlag(kRtcpReport) && method_ == RtcpMode::kReducedSize) ||
     884           0 :         method_ == RtcpMode::kCompound;
     885           0 :     if (generate_report)
     886           0 :       SetFlag(sending_ ? kRtcpSr : kRtcpRr, true);
     887             :   }
     888             : 
     889           0 :   if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty()))
     890           0 :     SetFlag(kRtcpSdes, true);
     891             : 
     892           0 :   if (generate_report) {
     893           0 :     if ((!sending_ && xr_send_receiver_reference_time_enabled_) ||
     894           0 :         feedback_state.has_last_xr_rr || video_bitrate_allocation_) {
     895           0 :       SetFlag(kRtcpAnyExtendedReports, true);
     896             :     }
     897             : 
     898             :     // generate next time to send an RTCP report
     899           0 :     uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS;
     900             : 
     901           0 :     if (!audio_) {
     902           0 :       if (sending_) {
     903             :         // Calculate bandwidth for video; 360 / send bandwidth in kbit/s.
     904           0 :         uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000;
     905           0 :         if (send_bitrate_kbit != 0)
     906           0 :           minIntervalMs = 360000 / send_bitrate_kbit;
     907             :       }
     908           0 :       if (minIntervalMs > RTCP_INTERVAL_VIDEO_MS)
     909           0 :         minIntervalMs = RTCP_INTERVAL_VIDEO_MS;
     910             :     }
     911             :     // The interval between RTCP packets is varied randomly over the
     912             :     // range [1/2,3/2] times the calculated interval.
     913             :     uint32_t timeToNext =
     914           0 :         random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2);
     915           0 :     next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext;
     916             : 
     917           0 :     if (receive_statistics_) {
     918             :       StatisticianMap statisticians =
     919           0 :           receive_statistics_->GetActiveStatisticians();
     920           0 :       RTC_DCHECK(report_blocks_.empty());
     921           0 :       for (auto& it : statisticians) {
     922           0 :         AddReportBlock(feedback_state, it.first, it.second);
     923             :       }
     924             :     }
     925             :   }
     926           0 : }
     927             : 
     928           0 : bool RTCPSender::AddReportBlock(const FeedbackState& feedback_state,
     929             :                                 uint32_t ssrc,
     930             :                                 StreamStatistician* statistician) {
     931             :   // Do we have receive statistics to send?
     932           0 :   RtcpStatistics stats;
     933           0 :   if (!statistician->GetStatistics(&stats, true))
     934           0 :     return false;
     935             : 
     936           0 :   if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) {
     937           0 :     LOG(LS_WARNING) << "Too many report blocks.";
     938           0 :     return false;
     939             :   }
     940           0 :   RTC_DCHECK(report_blocks_.find(ssrc) == report_blocks_.end());
     941           0 :   rtcp::ReportBlock* block = &report_blocks_[ssrc];
     942           0 :   block->SetMediaSsrc(ssrc);
     943           0 :   block->SetFractionLost(stats.fraction_lost);
     944           0 :   if (!block->SetCumulativeLost(stats.cumulative_lost)) {
     945           0 :     report_blocks_.erase(ssrc);
     946           0 :     LOG(LS_WARNING) << "Cumulative lost is oversized.";
     947           0 :     return false;
     948             :   }
     949           0 :   block->SetExtHighestSeqNum(stats.extended_max_sequence_number);
     950           0 :   block->SetJitter(stats.jitter);
     951           0 :   block->SetLastSr(feedback_state.remote_sr);
     952             : 
     953             :   // TODO(sprang): Do we really need separate time stamps for each report?
     954             :   // Get our NTP as late as possible to avoid a race.
     955             :   uint32_t ntp_secs;
     956             :   uint32_t ntp_frac;
     957           0 :   clock_->CurrentNtp(ntp_secs, ntp_frac);
     958             : 
     959             :   // Delay since last received report.
     960           0 :   if ((feedback_state.last_rr_ntp_secs != 0) ||
     961           0 :       (feedback_state.last_rr_ntp_frac != 0)) {
     962             :     // Get the 16 lowest bits of seconds and the 16 highest bits of fractions.
     963           0 :     uint32_t now = ntp_secs & 0x0000FFFF;
     964           0 :     now <<= 16;
     965           0 :     now += (ntp_frac & 0xffff0000) >> 16;
     966             : 
     967           0 :     uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF;
     968           0 :     receiveTime <<= 16;
     969           0 :     receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;
     970             : 
     971           0 :     block->SetDelayLastSr(now - receiveTime);
     972             :   }
     973           0 :   return true;
     974             : }
     975             : 
     976           0 : void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) {
     977           0 :   RTC_DCHECK_LE(csrcs.size(), kRtpCsrcSize);
     978           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     979           0 :   csrcs_ = csrcs;
     980           0 : }
     981             : 
     982           0 : int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType,
     983             :                                                uint32_t name,
     984             :                                                const uint8_t* data,
     985             :                                                uint16_t length) {
     986           0 :   if (length % 4 != 0) {
     987           0 :     LOG(LS_ERROR) << "Failed to SetApplicationSpecificData.";
     988           0 :     return -1;
     989             :   }
     990           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
     991             : 
     992           0 :   SetFlag(kRtcpApp, true);
     993           0 :   app_sub_type_ = subType;
     994           0 :   app_name_ = name;
     995           0 :   app_data_.reset(new uint8_t[length]);
     996           0 :   app_length_ = length;
     997           0 :   memcpy(app_data_.get(), data, length);
     998           0 :   return 0;
     999             : }
    1000             : 
    1001             : // TODO(sprang): Remove support for VoIP metrics? (Not used in receiver.)
    1002           0 : int32_t RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) {
    1003           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
    1004           0 :   xr_voip_metric_.emplace(*VoIPMetric);
    1005             : 
    1006           0 :   SetFlag(kRtcpAnyExtendedReports, true);
    1007           0 :   return 0;
    1008             : }
    1009             : 
    1010           0 : void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) {
    1011           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
    1012           0 :   xr_send_receiver_reference_time_enabled_ = enable;
    1013           0 : }
    1014             : 
    1015           0 : bool RTCPSender::RtcpXrReceiverReferenceTime() const {
    1016           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
    1017           0 :   return xr_send_receiver_reference_time_enabled_;
    1018             : }
    1019             : 
    1020           0 : void RTCPSender::SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set) {
    1021           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
    1022           0 :   tmmbn_to_send_ = std::move(bounding_set);
    1023           0 :   SetFlag(kRtcpTmmbn, true);
    1024           0 : }
    1025             : 
    1026           0 : void RTCPSender::SetFlag(uint32_t type, bool is_volatile) {
    1027           0 :   if (type & kRtcpAnyExtendedReports) {
    1028           0 :     report_flags_.insert(ReportFlag(kRtcpAnyExtendedReports, is_volatile));
    1029             :   } else {
    1030           0 :     report_flags_.insert(ReportFlag(type, is_volatile));
    1031             :   }
    1032           0 : }
    1033             : 
    1034           0 : void RTCPSender::SetFlags(const std::set<RTCPPacketType>& types,
    1035             :                           bool is_volatile) {
    1036           0 :   for (RTCPPacketType type : types)
    1037           0 :     SetFlag(type, is_volatile);
    1038           0 : }
    1039             : 
    1040           0 : bool RTCPSender::IsFlagPresent(uint32_t type) const {
    1041           0 :   return report_flags_.find(ReportFlag(type, false)) != report_flags_.end();
    1042             : }
    1043             : 
    1044           0 : bool RTCPSender::ConsumeFlag(uint32_t type, bool forced) {
    1045           0 :   auto it = report_flags_.find(ReportFlag(type, false));
    1046           0 :   if (it == report_flags_.end())
    1047           0 :     return false;
    1048           0 :   if (it->is_volatile || forced)
    1049           0 :     report_flags_.erase((it));
    1050           0 :   return true;
    1051             : }
    1052             : 
    1053           0 : bool RTCPSender::AllVolatileFlagsConsumed() const {
    1054           0 :   for (const ReportFlag& flag : report_flags_) {
    1055           0 :     if (flag.is_volatile)
    1056           0 :       return false;
    1057             :   }
    1058           0 :   return true;
    1059             : }
    1060             : 
    1061           0 : void RTCPSender::SetVideoBitrateAllocation(const BitrateAllocation& bitrate) {
    1062           0 :   rtc::CritScope lock(&critical_section_rtcp_sender_);
    1063           0 :   video_bitrate_allocation_.emplace(bitrate);
    1064           0 :   SetFlag(kRtcpAnyExtendedReports, true);
    1065           0 : }
    1066             : 
    1067           0 : bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) {
    1068           0 :   class Sender : public rtcp::RtcpPacket::PacketReadyCallback {
    1069             :    public:
    1070           0 :     Sender(Transport* transport, RtcEventLog* event_log)
    1071           0 :         : transport_(transport), event_log_(event_log), send_failure_(false) {}
    1072             : 
    1073           0 :     void OnPacketReady(uint8_t* data, size_t length) override {
    1074           0 :       if (transport_->SendRtcp(data, length)) {
    1075           0 :         if (event_log_) {
    1076           0 :           event_log_->LogRtcpPacket(kOutgoingPacket, MediaType::ANY, data,
    1077           0 :                                     length);
    1078             :         }
    1079             :       } else {
    1080           0 :         send_failure_ = true;
    1081             :       }
    1082           0 :     }
    1083             : 
    1084             :     Transport* const transport_;
    1085             :     RtcEventLog* const event_log_;
    1086             :     bool send_failure_;
    1087             :     // TODO(terelius): We would like to
    1088             :     // RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Sender);
    1089             :     // but we can't because of an incorrect warning (C4822) in MVS 2013.
    1090           0 :   } sender(transport_, event_log_);
    1091             : 
    1092           0 :   RTC_DCHECK_LE(max_packet_size_, IP_PACKET_SIZE);
    1093             :   uint8_t buffer[IP_PACKET_SIZE];
    1094           0 :   return packet.BuildExternalBuffer(buffer, max_packet_size_, &sender) &&
    1095           0 :          !sender.send_failure_;
    1096             : }
    1097             : 
    1098             : }  // namespace webrtc

Generated by: LCOV version 1.13