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