• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
12 
13 #include <assert.h>  // assert
14 #include <stdlib.h>  // rand
15 #include <string.h>  // memcpy
16 
17 #include <algorithm>  // min
18 
19 #include "webrtc/common_types.h"
20 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
21 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
22 #include "webrtc/system_wrappers/interface/logging.h"
23 #include "webrtc/system_wrappers/interface/trace_event.h"
24 
25 namespace webrtc {
26 
27 using RTCPUtility::RTCPCnameInformation;
28 
NACKStringBuilder()29 NACKStringBuilder::NACKStringBuilder() :
30     _stream(""), _count(0), _consecutive(false)
31 {
32     // Empty.
33 }
34 
~NACKStringBuilder()35 NACKStringBuilder::~NACKStringBuilder() {}
36 
PushNACK(uint16_t nack)37 void NACKStringBuilder::PushNACK(uint16_t nack)
38 {
39     if (_count == 0)
40     {
41         _stream << nack;
42     } else if (nack == _prevNack + 1)
43     {
44         _consecutive = true;
45     } else
46     {
47         if (_consecutive)
48         {
49             _stream << "-" << _prevNack;
50             _consecutive = false;
51         }
52         _stream << "," << nack;
53     }
54     _count++;
55     _prevNack = nack;
56 }
57 
GetResult()58 std::string NACKStringBuilder::GetResult()
59 {
60     if (_consecutive)
61     {
62         _stream << "-" << _prevNack;
63         _consecutive = false;
64     }
65     return _stream.str();
66 }
67 
FeedbackState()68 RTCPSender::FeedbackState::FeedbackState()
69     : send_payload_type(0),
70       frequency_hz(0),
71       packets_sent(0),
72       media_bytes_sent(0),
73       send_bitrate(0),
74       last_rr_ntp_secs(0),
75       last_rr_ntp_frac(0),
76       remote_sr(0),
77       has_last_xr_rr(false) {}
78 
RTCPSender(const int32_t id,const bool audio,Clock * clock,ReceiveStatistics * receive_statistics)79 RTCPSender::RTCPSender(const int32_t id,
80                        const bool audio,
81                        Clock* clock,
82                        ReceiveStatistics* receive_statistics) :
83     _id(id),
84     _audio(audio),
85     _clock(clock),
86     _method(kRtcpOff),
87     _criticalSectionTransport(CriticalSectionWrapper::CreateCriticalSection()),
88     _cbTransport(NULL),
89 
90     _criticalSectionRTCPSender(CriticalSectionWrapper::CreateCriticalSection()),
91     _usingNack(false),
92     _sending(false),
93     _sendTMMBN(false),
94     _REMB(false),
95     _sendREMB(false),
96     _TMMBR(false),
97     _IJ(false),
98     _nextTimeToSendRTCP(0),
99     start_timestamp_(0),
100     last_rtp_timestamp_(0),
101     last_frame_capture_time_ms_(-1),
102     _SSRC(0),
103     _remoteSSRC(0),
104     _CNAME(),
105     receive_statistics_(receive_statistics),
106     internal_report_blocks_(),
107     external_report_blocks_(),
108     _csrcCNAMEs(),
109 
110     _cameraDelayMS(0),
111 
112     _lastSendReport(),
113     _lastRTCPTime(),
114 
115     last_xr_rr_(),
116 
117     _CSRCs(0),
118     _CSRC(),
119     _includeCSRCs(true),
120 
121     _sequenceNumberFIR(0),
122 
123     _lengthRembSSRC(0),
124     _sizeRembSSRC(0),
125     _rembSSRC(NULL),
126     _rembBitrate(0),
127 
128     _tmmbrHelp(),
129     _tmmbr_Send(0),
130     _packetOH_Send(0),
131 
132     _appSend(false),
133     _appSubType(0),
134     _appName(),
135     _appData(NULL),
136     _appLength(0),
137 
138     xrSendReceiverReferenceTimeEnabled_(false),
139     _xrSendVoIPMetric(false),
140     _xrVoIPMetric()
141 {
142     memset(_CNAME, 0, sizeof(_CNAME));
143     memset(_lastSendReport, 0, sizeof(_lastSendReport));
144     memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime));
145 }
146 
~RTCPSender()147 RTCPSender::~RTCPSender() {
148   delete [] _rembSSRC;
149   delete [] _appData;
150 
151   while (!internal_report_blocks_.empty()) {
152     delete internal_report_blocks_.begin()->second;
153     internal_report_blocks_.erase(internal_report_blocks_.begin());
154   }
155   while (!external_report_blocks_.empty()) {
156     std::map<uint32_t, RTCPReportBlock*>::iterator it =
157         external_report_blocks_.begin();
158     delete it->second;
159     external_report_blocks_.erase(it);
160   }
161   while (!_csrcCNAMEs.empty()) {
162     std::map<uint32_t, RTCPCnameInformation*>::iterator it =
163         _csrcCNAMEs.begin();
164     delete it->second;
165     _csrcCNAMEs.erase(it);
166   }
167   delete _criticalSectionTransport;
168   delete _criticalSectionRTCPSender;
169 }
170 
171 int32_t
RegisterSendTransport(Transport * outgoingTransport)172 RTCPSender::RegisterSendTransport(Transport* outgoingTransport)
173 {
174     CriticalSectionScoped lock(_criticalSectionTransport);
175     _cbTransport = outgoingTransport;
176     return 0;
177 }
178 
179 RTCPMethod
Status() const180 RTCPSender::Status() const
181 {
182     CriticalSectionScoped lock(_criticalSectionRTCPSender);
183     return _method;
184 }
185 
186 int32_t
SetRTCPStatus(const RTCPMethod method)187 RTCPSender::SetRTCPStatus(const RTCPMethod method)
188 {
189     CriticalSectionScoped lock(_criticalSectionRTCPSender);
190     if(method != kRtcpOff)
191     {
192         if(_audio)
193         {
194             _nextTimeToSendRTCP = _clock->TimeInMilliseconds() +
195                 (RTCP_INTERVAL_AUDIO_MS/2);
196         } else
197         {
198             _nextTimeToSendRTCP = _clock->TimeInMilliseconds() +
199                 (RTCP_INTERVAL_VIDEO_MS/2);
200         }
201     }
202     _method = method;
203     return 0;
204 }
205 
206 bool
Sending() const207 RTCPSender::Sending() const
208 {
209     CriticalSectionScoped lock(_criticalSectionRTCPSender);
210     return _sending;
211 }
212 
213 int32_t
SetSendingStatus(const FeedbackState & feedback_state,bool sending)214 RTCPSender::SetSendingStatus(const FeedbackState& feedback_state, bool sending)
215 {
216     bool sendRTCPBye = false;
217     {
218         CriticalSectionScoped lock(_criticalSectionRTCPSender);
219 
220         if(_method != kRtcpOff)
221         {
222             if(sending == false && _sending == true)
223             {
224                 // Trigger RTCP bye
225                 sendRTCPBye = true;
226             }
227         }
228         _sending = sending;
229     }
230     if(sendRTCPBye)
231     {
232         return SendRTCP(feedback_state, kRtcpBye);
233     }
234     return 0;
235 }
236 
237 bool
REMB() const238 RTCPSender::REMB() const
239 {
240     CriticalSectionScoped lock(_criticalSectionRTCPSender);
241     return _REMB;
242 }
243 
244 int32_t
SetREMBStatus(const bool enable)245 RTCPSender::SetREMBStatus(const bool enable)
246 {
247     CriticalSectionScoped lock(_criticalSectionRTCPSender);
248     _REMB = enable;
249     return 0;
250 }
251 
252 int32_t
SetREMBData(const uint32_t bitrate,const uint8_t numberOfSSRC,const uint32_t * SSRC)253 RTCPSender::SetREMBData(const uint32_t bitrate,
254                         const uint8_t numberOfSSRC,
255                         const uint32_t* SSRC)
256 {
257     CriticalSectionScoped lock(_criticalSectionRTCPSender);
258     _rembBitrate = bitrate;
259 
260     if(_sizeRembSSRC < numberOfSSRC)
261     {
262         delete [] _rembSSRC;
263         _rembSSRC = new uint32_t[numberOfSSRC];
264         _sizeRembSSRC = numberOfSSRC;
265     }
266 
267     _lengthRembSSRC = numberOfSSRC;
268     for (int i = 0; i < numberOfSSRC; i++)
269     {
270         _rembSSRC[i] = SSRC[i];
271     }
272     _sendREMB = true;
273     // Send a REMB immediately if we have a new REMB. The frequency of REMBs is
274     // throttled by the caller.
275     _nextTimeToSendRTCP = _clock->TimeInMilliseconds();
276     return 0;
277 }
278 
279 bool
TMMBR() const280 RTCPSender::TMMBR() const
281 {
282     CriticalSectionScoped lock(_criticalSectionRTCPSender);
283     return _TMMBR;
284 }
285 
286 int32_t
SetTMMBRStatus(const bool enable)287 RTCPSender::SetTMMBRStatus(const bool enable)
288 {
289     CriticalSectionScoped lock(_criticalSectionRTCPSender);
290     _TMMBR = enable;
291     return 0;
292 }
293 
294 bool
IJ() const295 RTCPSender::IJ() const
296 {
297     CriticalSectionScoped lock(_criticalSectionRTCPSender);
298     return _IJ;
299 }
300 
301 int32_t
SetIJStatus(const bool enable)302 RTCPSender::SetIJStatus(const bool enable)
303 {
304     CriticalSectionScoped lock(_criticalSectionRTCPSender);
305     _IJ = enable;
306     return 0;
307 }
308 
SetStartTimestamp(uint32_t start_timestamp)309 void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) {
310   CriticalSectionScoped lock(_criticalSectionRTCPSender);
311   start_timestamp_ = start_timestamp;
312 }
313 
SetLastRtpTime(uint32_t rtp_timestamp,int64_t capture_time_ms)314 void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp,
315                                 int64_t capture_time_ms) {
316   CriticalSectionScoped lock(_criticalSectionRTCPSender);
317   last_rtp_timestamp_ = rtp_timestamp;
318   if (capture_time_ms < 0) {
319     // We don't currently get a capture time from VoiceEngine.
320     last_frame_capture_time_ms_ = _clock->TimeInMilliseconds();
321   } else {
322     last_frame_capture_time_ms_ = capture_time_ms;
323   }
324 }
325 
326 void
SetSSRC(const uint32_t ssrc)327 RTCPSender::SetSSRC( const uint32_t ssrc)
328 {
329     CriticalSectionScoped lock(_criticalSectionRTCPSender);
330 
331     if(_SSRC != 0)
332     {
333         // not first SetSSRC, probably due to a collision
334         // schedule a new RTCP report
335         // make sure that we send a RTP packet
336         _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + 100;
337     }
338     _SSRC = ssrc;
339 }
340 
SetRemoteSSRC(uint32_t ssrc)341 void RTCPSender::SetRemoteSSRC(uint32_t ssrc)
342 {
343     CriticalSectionScoped lock(_criticalSectionRTCPSender);
344     _remoteSSRC = ssrc;
345 }
346 
347 int32_t
SetCameraDelay(const int32_t delayMS)348 RTCPSender::SetCameraDelay(const int32_t delayMS)
349 {
350     CriticalSectionScoped lock(_criticalSectionRTCPSender);
351     if(delayMS > 1000 || delayMS < -1000)
352     {
353         LOG(LS_WARNING) << "Delay can't be larger than 1 second: "
354                         << delayMS << " ms";
355         return -1;
356     }
357     _cameraDelayMS = delayMS;
358     return 0;
359 }
360 
SetCNAME(const char cName[RTCP_CNAME_SIZE])361 int32_t RTCPSender::SetCNAME(const char cName[RTCP_CNAME_SIZE]) {
362   if (!cName)
363     return -1;
364 
365   CriticalSectionScoped lock(_criticalSectionRTCPSender);
366   _CNAME[RTCP_CNAME_SIZE - 1] = 0;
367   strncpy(_CNAME, cName, RTCP_CNAME_SIZE - 1);
368   return 0;
369 }
370 
AddMixedCNAME(const uint32_t SSRC,const char cName[RTCP_CNAME_SIZE])371 int32_t RTCPSender::AddMixedCNAME(const uint32_t SSRC,
372                                   const char cName[RTCP_CNAME_SIZE]) {
373   assert(cName);
374   CriticalSectionScoped lock(_criticalSectionRTCPSender);
375   if (_csrcCNAMEs.size() >= kRtpCsrcSize) {
376     return -1;
377   }
378   RTCPCnameInformation* ptr = new RTCPCnameInformation();
379   ptr->name[RTCP_CNAME_SIZE - 1] = 0;
380   strncpy(ptr->name, cName, RTCP_CNAME_SIZE - 1);
381   _csrcCNAMEs[SSRC] = ptr;
382   return 0;
383 }
384 
RemoveMixedCNAME(const uint32_t SSRC)385 int32_t RTCPSender::RemoveMixedCNAME(const uint32_t SSRC) {
386   CriticalSectionScoped lock(_criticalSectionRTCPSender);
387   std::map<uint32_t, RTCPCnameInformation*>::iterator it =
388       _csrcCNAMEs.find(SSRC);
389 
390   if (it == _csrcCNAMEs.end()) {
391     return -1;
392   }
393   delete it->second;
394   _csrcCNAMEs.erase(it);
395   return 0;
396 }
397 
398 bool
TimeToSendRTCPReport(const bool sendKeyframeBeforeRTP) const399 RTCPSender::TimeToSendRTCPReport(const bool sendKeyframeBeforeRTP) const
400 {
401 /*
402     For audio we use a fix 5 sec interval
403 
404     For video we use 1 sec interval fo a BW smaller than 360 kbit/s,
405         technicaly we break the max 5% RTCP BW for video below 10 kbit/s but
406         that should be extremely rare
407 
408 
409 From RFC 3550
410 
411     MAX RTCP BW is 5% if the session BW
412         A send report is approximately 65 bytes inc CNAME
413         A receiver report is approximately 28 bytes
414 
415     The RECOMMENDED value for the reduced minimum in seconds is 360
416       divided by the session bandwidth in kilobits/second.  This minimum
417       is smaller than 5 seconds for bandwidths greater than 72 kb/s.
418 
419     If the participant has not yet sent an RTCP packet (the variable
420       initial is true), the constant Tmin is set to 2.5 seconds, else it
421       is set to 5 seconds.
422 
423     The interval between RTCP packets is varied randomly over the
424       range [0.5,1.5] times the calculated interval to avoid unintended
425       synchronization of all participants
426 
427     if we send
428     If the participant is a sender (we_sent true), the constant C is
429       set to the average RTCP packet size (avg_rtcp_size) divided by 25%
430       of the RTCP bandwidth (rtcp_bw), and the constant n is set to the
431       number of senders.
432 
433     if we receive only
434       If we_sent is not true, the constant C is set
435       to the average RTCP packet size divided by 75% of the RTCP
436       bandwidth.  The constant n is set to the number of receivers
437       (members - senders).  If the number of senders is greater than
438       25%, senders and receivers are treated together.
439 
440     reconsideration NOT required for peer-to-peer
441       "timer reconsideration" is
442       employed.  This algorithm implements a simple back-off mechanism
443       which causes users to hold back RTCP packet transmission if the
444       group sizes are increasing.
445 
446       n = number of members
447       C = avg_size/(rtcpBW/4)
448 
449    3. The deterministic calculated interval Td is set to max(Tmin, n*C).
450 
451    4. The calculated interval T is set to a number uniformly distributed
452       between 0.5 and 1.5 times the deterministic calculated interval.
453 
454    5. The resulting value of T is divided by e-3/2=1.21828 to compensate
455       for the fact that the timer reconsideration algorithm converges to
456       a value of the RTCP bandwidth below the intended average
457 */
458 
459     int64_t now = _clock->TimeInMilliseconds();
460 
461     CriticalSectionScoped lock(_criticalSectionRTCPSender);
462 
463     if(_method == kRtcpOff)
464     {
465         return false;
466     }
467 
468     if(!_audio && sendKeyframeBeforeRTP)
469     {
470         // for video key-frames we want to send the RTCP before the large key-frame
471         // if we have a 100 ms margin
472         now += RTCP_SEND_BEFORE_KEY_FRAME_MS;
473     }
474 
475     if(now >= _nextTimeToSendRTCP)
476     {
477         return true;
478 
479     } else if(now < 0x0000ffff && _nextTimeToSendRTCP > 0xffff0000) // 65 sec margin
480     {
481         // wrap
482         return true;
483     }
484     return false;
485 }
486 
487 uint32_t
LastSendReport(uint32_t & lastRTCPTime)488 RTCPSender::LastSendReport( uint32_t& lastRTCPTime)
489 {
490     CriticalSectionScoped lock(_criticalSectionRTCPSender);
491 
492     lastRTCPTime = _lastRTCPTime[0];
493     return _lastSendReport[0];
494 }
495 
496 uint32_t
SendTimeOfSendReport(const uint32_t sendReport)497 RTCPSender::SendTimeOfSendReport(const uint32_t sendReport)
498 {
499     CriticalSectionScoped lock(_criticalSectionRTCPSender);
500 
501     // This is only saved when we are the sender
502     if((_lastSendReport[0] == 0) || (sendReport == 0))
503     {
504         return 0; // will be ignored
505     } else
506     {
507         for(int i = 0; i < RTCP_NUMBER_OF_SR; ++i)
508         {
509             if( _lastSendReport[i] == sendReport)
510             {
511                 return _lastRTCPTime[i];
512             }
513         }
514     }
515     return 0;
516 }
517 
SendTimeOfXrRrReport(uint32_t mid_ntp,int64_t * time_ms) const518 bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp,
519                                       int64_t* time_ms) const {
520   CriticalSectionScoped lock(_criticalSectionRTCPSender);
521 
522   if (last_xr_rr_.empty()) {
523     return false;
524   }
525   std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp);
526   if (it == last_xr_rr_.end()) {
527     return false;
528   }
529   *time_ms = it->second;
530   return true;
531 }
532 
GetPacketTypeCounter(RtcpPacketTypeCounter * packet_counter) const533 void RTCPSender::GetPacketTypeCounter(
534     RtcpPacketTypeCounter* packet_counter) const {
535   CriticalSectionScoped lock(_criticalSectionRTCPSender);
536   *packet_counter = packet_type_counter_;
537 }
538 
AddExternalReportBlock(uint32_t SSRC,const RTCPReportBlock * reportBlock)539 int32_t RTCPSender::AddExternalReportBlock(
540     uint32_t SSRC,
541     const RTCPReportBlock* reportBlock) {
542   CriticalSectionScoped lock(_criticalSectionRTCPSender);
543   return AddReportBlock(SSRC, &external_report_blocks_, reportBlock);
544 }
545 
AddReportBlock(uint32_t SSRC,std::map<uint32_t,RTCPReportBlock * > * report_blocks,const RTCPReportBlock * reportBlock)546 int32_t RTCPSender::AddReportBlock(
547     uint32_t SSRC,
548     std::map<uint32_t, RTCPReportBlock*>* report_blocks,
549     const RTCPReportBlock* reportBlock) {
550   assert(reportBlock);
551 
552   if (report_blocks->size() >= RTCP_MAX_REPORT_BLOCKS) {
553     LOG(LS_WARNING) << "Too many report blocks.";
554     return -1;
555   }
556   std::map<uint32_t, RTCPReportBlock*>::iterator it =
557       report_blocks->find(SSRC);
558   if (it != report_blocks->end()) {
559     delete it->second;
560     report_blocks->erase(it);
561   }
562   RTCPReportBlock* copyReportBlock = new RTCPReportBlock();
563   memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock));
564   (*report_blocks)[SSRC] = copyReportBlock;
565   return 0;
566 }
567 
RemoveExternalReportBlock(uint32_t SSRC)568 int32_t RTCPSender::RemoveExternalReportBlock(uint32_t SSRC) {
569   CriticalSectionScoped lock(_criticalSectionRTCPSender);
570 
571   std::map<uint32_t, RTCPReportBlock*>::iterator it =
572       external_report_blocks_.find(SSRC);
573 
574   if (it == external_report_blocks_.end()) {
575     return -1;
576   }
577   delete it->second;
578   external_report_blocks_.erase(it);
579   return 0;
580 }
581 
BuildSR(const FeedbackState & feedback_state,uint8_t * rtcpbuffer,int & pos,uint32_t NTPsec,uint32_t NTPfrac)582 int32_t RTCPSender::BuildSR(const FeedbackState& feedback_state,
583                             uint8_t* rtcpbuffer,
584                             int& pos,
585                             uint32_t NTPsec,
586                             uint32_t NTPfrac)
587 {
588     // sanity
589     if(pos + 52 >= IP_PACKET_SIZE)
590     {
591         LOG(LS_WARNING) << "Failed to build Sender Report.";
592         return -2;
593     }
594     uint32_t RTPtime;
595 
596     uint32_t posNumberOfReportBlocks = pos;
597     rtcpbuffer[pos++]=(uint8_t)0x80;
598 
599     // Sender report
600     rtcpbuffer[pos++]=(uint8_t)200;
601 
602     for(int i = (RTCP_NUMBER_OF_SR-2); i >= 0; i--)
603     {
604         // shift old
605         _lastSendReport[i+1] = _lastSendReport[i];
606         _lastRTCPTime[i+1] =_lastRTCPTime[i];
607     }
608 
609     _lastRTCPTime[0] = Clock::NtpToMs(NTPsec, NTPfrac);
610     _lastSendReport[0] = (NTPsec << 16) + (NTPfrac >> 16);
611 
612     // The timestamp of this RTCP packet should be estimated as the timestamp of
613     // the frame being captured at this moment. We are calculating that
614     // timestamp as the last frame's timestamp + the time since the last frame
615     // was captured.
616     RTPtime = start_timestamp_ + last_rtp_timestamp_ +
617               (_clock->TimeInMilliseconds() - last_frame_capture_time_ms_) *
618                   (feedback_state.frequency_hz / 1000);
619 
620     // Add sender data
621     // Save  for our length field
622     pos++;
623     pos++;
624 
625     // Add our own SSRC
626     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
627     pos += 4;
628     // NTP
629     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, NTPsec);
630     pos += 4;
631     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, NTPfrac);
632     pos += 4;
633     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, RTPtime);
634     pos += 4;
635 
636     //sender's packet count
637     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos,
638                                       feedback_state.packets_sent);
639     pos += 4;
640 
641     //sender's octet count
642     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos,
643                                       feedback_state.media_bytes_sent);
644     pos += 4;
645 
646     uint8_t numberOfReportBlocks = 0;
647     int32_t retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos,
648                                                   numberOfReportBlocks,
649                                                   NTPsec, NTPfrac);
650     if(retVal < 0)
651     {
652         //
653         return retVal ;
654     }
655     pos = retVal;
656     rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks;
657 
658     uint16_t len = uint16_t((pos/4) -1);
659     RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + 2, len);
660     return 0;
661 }
662 
663 
BuildSDEC(uint8_t * rtcpbuffer,int & pos)664 int32_t RTCPSender::BuildSDEC(uint8_t* rtcpbuffer, int& pos) {
665   size_t lengthCname = strlen(_CNAME);
666   assert(lengthCname < RTCP_CNAME_SIZE);
667 
668   // sanity
669   if(pos + 12 + lengthCname  >= IP_PACKET_SIZE) {
670     LOG(LS_WARNING) << "Failed to build SDEC.";
671     return -2;
672   }
673   // SDEC Source Description
674 
675   // We always need to add SDES CNAME
676   rtcpbuffer[pos++] = static_cast<uint8_t>(0x80 + 1 + _csrcCNAMEs.size());
677   rtcpbuffer[pos++] = static_cast<uint8_t>(202);
678 
679   // handle SDES length later on
680   uint32_t SDESLengthPos = pos;
681   pos++;
682   pos++;
683 
684   // Add our own SSRC
685   RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
686   pos += 4;
687 
688   // CNAME = 1
689   rtcpbuffer[pos++] = static_cast<uint8_t>(1);
690 
691   //
692   rtcpbuffer[pos++] = static_cast<uint8_t>(lengthCname);
693 
694   uint16_t SDESLength = 10;
695 
696   memcpy(&rtcpbuffer[pos], _CNAME, lengthCname);
697   pos += lengthCname;
698   SDESLength += (uint16_t)lengthCname;
699 
700   uint16_t padding = 0;
701   // We must have a zero field even if we have an even multiple of 4 bytes
702   if ((pos % 4) == 0) {
703     padding++;
704     rtcpbuffer[pos++]=0;
705   }
706   while ((pos % 4) != 0) {
707     padding++;
708     rtcpbuffer[pos++]=0;
709   }
710   SDESLength += padding;
711 
712   std::map<uint32_t, RTCPUtility::RTCPCnameInformation*>::iterator it =
713       _csrcCNAMEs.begin();
714 
715   for(; it != _csrcCNAMEs.end(); it++) {
716     RTCPCnameInformation* cname = it->second;
717     uint32_t SSRC = it->first;
718 
719     // Add SSRC
720     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, SSRC);
721     pos += 4;
722 
723     // CNAME = 1
724     rtcpbuffer[pos++] = static_cast<uint8_t>(1);
725 
726     size_t length = strlen(cname->name);
727     assert(length < RTCP_CNAME_SIZE);
728 
729     rtcpbuffer[pos++]= static_cast<uint8_t>(length);
730     SDESLength += 6;
731 
732     memcpy(&rtcpbuffer[pos],cname->name, length);
733 
734     pos += length;
735     SDESLength += length;
736     uint16_t padding = 0;
737 
738     // We must have a zero field even if we have an even multiple of 4 bytes
739     if((pos % 4) == 0){
740       padding++;
741       rtcpbuffer[pos++]=0;
742     }
743     while((pos % 4) != 0){
744       padding++;
745       rtcpbuffer[pos++] = 0;
746     }
747     SDESLength += padding;
748   }
749   // in 32-bit words minus one and we don't count the header
750   uint16_t buffer_length = (SDESLength / 4) - 1;
751   RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + SDESLengthPos, buffer_length);
752   return 0;
753 }
754 
755 int32_t
BuildRR(uint8_t * rtcpbuffer,int & pos,const uint32_t NTPsec,const uint32_t NTPfrac)756 RTCPSender::BuildRR(uint8_t* rtcpbuffer,
757                     int& pos,
758                     const uint32_t NTPsec,
759                     const uint32_t NTPfrac)
760 {
761     // sanity one block
762     if(pos + 32 >= IP_PACKET_SIZE)
763     {
764         return -2;
765     }
766     uint32_t posNumberOfReportBlocks = pos;
767 
768     rtcpbuffer[pos++]=(uint8_t)0x80;
769     rtcpbuffer[pos++]=(uint8_t)201;
770 
771     // Save  for our length field
772     pos++;
773     pos++;
774 
775     // Add our own SSRC
776     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
777     pos += 4;
778 
779     uint8_t numberOfReportBlocks = 0;
780     int retVal = WriteAllReportBlocksToBuffer(rtcpbuffer, pos,
781                                               numberOfReportBlocks,
782                                               NTPsec, NTPfrac);
783     if(retVal < 0)
784     {
785         return pos;
786     }
787     pos = retVal;
788     rtcpbuffer[posNumberOfReportBlocks] += numberOfReportBlocks;
789 
790     uint16_t len = uint16_t((pos)/4 -1);
791     RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + 2, len);
792     return 0;
793 }
794 
795 // From RFC 5450: Transmission Time Offsets in RTP Streams.
796 //        0                   1                   2                   3
797 //        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
798 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
799 //   hdr |V=2|P|    RC   |   PT=IJ=195   |             length            |
800 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
801 //       |                      inter-arrival jitter                     |
802 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
803 //       .                                                               .
804 //       .                                                               .
805 //       .                                                               .
806 //       |                      inter-arrival jitter                     |
807 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
808 //
809 //  If present, this RTCP packet must be placed after a receiver report
810 //  (inside a compound RTCP packet), and MUST have the same value for RC
811 //  (reception report count) as the receiver report.
812 
813 int32_t
BuildExtendedJitterReport(uint8_t * rtcpbuffer,int & pos,const uint32_t jitterTransmissionTimeOffset)814 RTCPSender::BuildExtendedJitterReport(
815     uint8_t* rtcpbuffer,
816     int& pos,
817     const uint32_t jitterTransmissionTimeOffset)
818 {
819     if (external_report_blocks_.size() > 0)
820     {
821         // TODO(andresp): Remove external report blocks since they are not
822         // supported.
823         LOG(LS_ERROR) << "Handling of external report blocks not implemented.";
824         return 0;
825     }
826 
827     // sanity
828     if(pos + 8 >= IP_PACKET_SIZE)
829     {
830         return -2;
831     }
832     // add picture loss indicator
833     uint8_t RC = 1;
834     rtcpbuffer[pos++]=(uint8_t)0x80 + RC;
835     rtcpbuffer[pos++]=(uint8_t)195;
836 
837     // Used fixed length of 2
838     rtcpbuffer[pos++]=(uint8_t)0;
839     rtcpbuffer[pos++]=(uint8_t)(1);
840 
841     // Add inter-arrival jitter
842     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos,
843                                       jitterTransmissionTimeOffset);
844     pos += 4;
845     return 0;
846 }
847 
848 int32_t
BuildPLI(uint8_t * rtcpbuffer,int & pos)849 RTCPSender::BuildPLI(uint8_t* rtcpbuffer, int& pos)
850 {
851     // sanity
852     if(pos + 12 >= IP_PACKET_SIZE)
853     {
854         return -2;
855     }
856     // add picture loss indicator
857     uint8_t FMT = 1;
858     rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
859     rtcpbuffer[pos++]=(uint8_t)206;
860 
861     //Used fixed length of 2
862     rtcpbuffer[pos++]=(uint8_t)0;
863     rtcpbuffer[pos++]=(uint8_t)(2);
864 
865     // Add our own SSRC
866     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
867     pos += 4;
868 
869     // Add the remote SSRC
870     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
871     pos += 4;
872     return 0;
873 }
874 
BuildFIR(uint8_t * rtcpbuffer,int & pos,bool repeat)875 int32_t RTCPSender::BuildFIR(uint8_t* rtcpbuffer,
876                              int& pos,
877                              bool repeat) {
878   // sanity
879   if(pos + 20 >= IP_PACKET_SIZE)  {
880     return -2;
881   }
882   if (!repeat) {
883     _sequenceNumberFIR++;   // do not increase if repetition
884   }
885 
886   // add full intra request indicator
887   uint8_t FMT = 4;
888   rtcpbuffer[pos++] = (uint8_t)0x80 + FMT;
889   rtcpbuffer[pos++] = (uint8_t)206;
890 
891   //Length of 4
892   rtcpbuffer[pos++] = (uint8_t)0;
893   rtcpbuffer[pos++] = (uint8_t)(4);
894 
895   // Add our own SSRC
896   RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
897   pos += 4;
898 
899   // RFC 5104     4.3.1.2.  Semantics
900   // SSRC of media source
901   rtcpbuffer[pos++] = (uint8_t)0;
902   rtcpbuffer[pos++] = (uint8_t)0;
903   rtcpbuffer[pos++] = (uint8_t)0;
904   rtcpbuffer[pos++] = (uint8_t)0;
905 
906   // Additional Feedback Control Information (FCI)
907   RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
908   pos += 4;
909 
910   rtcpbuffer[pos++] = (uint8_t)(_sequenceNumberFIR);
911   rtcpbuffer[pos++] = (uint8_t)0;
912   rtcpbuffer[pos++] = (uint8_t)0;
913   rtcpbuffer[pos++] = (uint8_t)0;
914   return 0;
915 }
916 
917 /*
918     0                   1                   2                   3
919     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
920    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
921    |            First        |        Number           | PictureID |
922    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
923 */
924 int32_t
BuildSLI(uint8_t * rtcpbuffer,int & pos,const uint8_t pictureID)925 RTCPSender::BuildSLI(uint8_t* rtcpbuffer, int& pos, const uint8_t pictureID)
926 {
927     // sanity
928     if(pos + 16 >= IP_PACKET_SIZE)
929     {
930         return -2;
931     }
932     // add slice loss indicator
933     uint8_t FMT = 2;
934     rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
935     rtcpbuffer[pos++]=(uint8_t)206;
936 
937     //Used fixed length of 3
938     rtcpbuffer[pos++]=(uint8_t)0;
939     rtcpbuffer[pos++]=(uint8_t)(3);
940 
941     // Add our own SSRC
942     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
943     pos += 4;
944 
945     // Add the remote SSRC
946     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
947     pos += 4;
948 
949     // Add first, number & picture ID 6 bits
950     // first  = 0, 13 - bits
951     // number = 0x1fff, 13 - bits only ones for now
952     uint32_t sliField = (0x1fff << 6)+ (0x3f & pictureID);
953     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, sliField);
954     pos += 4;
955     return 0;
956 }
957 
958 /*
959     0                   1                   2                   3
960     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
961    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
962    |      PB       |0| Payload Type|    Native RPSI bit string     |
963    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
964    |   defined per codec          ...                | Padding (0) |
965    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
966 */
967 /*
968 *    Note: not generic made for VP8
969 */
970 int32_t
BuildRPSI(uint8_t * rtcpbuffer,int & pos,const uint64_t pictureID,const uint8_t payloadType)971 RTCPSender::BuildRPSI(uint8_t* rtcpbuffer,
972                      int& pos,
973                      const uint64_t pictureID,
974                      const uint8_t payloadType)
975 {
976     // sanity
977     if(pos + 24 >= IP_PACKET_SIZE)
978     {
979         return -2;
980     }
981     // add Reference Picture Selection Indication
982     uint8_t FMT = 3;
983     rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
984     rtcpbuffer[pos++]=(uint8_t)206;
985 
986     // calc length
987     uint32_t bitsRequired = 7;
988     uint8_t bytesRequired = 1;
989     while((pictureID>>bitsRequired) > 0)
990     {
991         bitsRequired += 7;
992         bytesRequired++;
993     }
994 
995     uint8_t size = 3;
996     if(bytesRequired > 6)
997     {
998         size = 5;
999     } else if(bytesRequired > 2)
1000     {
1001         size = 4;
1002     }
1003     rtcpbuffer[pos++]=(uint8_t)0;
1004     rtcpbuffer[pos++]=size;
1005 
1006     // Add our own SSRC
1007     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1008     pos += 4;
1009 
1010     // Add the remote SSRC
1011     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
1012     pos += 4;
1013 
1014     // calc padding length
1015     uint8_t paddingBytes = 4-((2+bytesRequired)%4);
1016     if(paddingBytes == 4)
1017     {
1018         paddingBytes = 0;
1019     }
1020     // add padding length in bits
1021     rtcpbuffer[pos] = paddingBytes*8; // padding can be 0, 8, 16 or 24
1022     pos++;
1023 
1024     // add payload type
1025     rtcpbuffer[pos] = payloadType;
1026     pos++;
1027 
1028     // add picture ID
1029     for(int i = bytesRequired-1; i > 0; i--)
1030     {
1031         rtcpbuffer[pos] = 0x80 | uint8_t(pictureID >> (i*7));
1032         pos++;
1033     }
1034     // add last byte of picture ID
1035     rtcpbuffer[pos] = uint8_t(pictureID & 0x7f);
1036     pos++;
1037 
1038     // add padding
1039     for(int j = 0; j <paddingBytes; j++)
1040     {
1041         rtcpbuffer[pos] = 0;
1042         pos++;
1043     }
1044     return 0;
1045 }
1046 
1047 int32_t
BuildREMB(uint8_t * rtcpbuffer,int & pos)1048 RTCPSender::BuildREMB(uint8_t* rtcpbuffer, int& pos)
1049 {
1050     // sanity
1051     if(pos + 20 + 4 * _lengthRembSSRC >= IP_PACKET_SIZE)
1052     {
1053         return -2;
1054     }
1055     // add application layer feedback
1056     uint8_t FMT = 15;
1057     rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
1058     rtcpbuffer[pos++]=(uint8_t)206;
1059 
1060     rtcpbuffer[pos++]=(uint8_t)0;
1061     rtcpbuffer[pos++]=_lengthRembSSRC + 4;
1062 
1063     // Add our own SSRC
1064     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1065     pos += 4;
1066 
1067     // Remote SSRC must be 0
1068     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, 0);
1069     pos += 4;
1070 
1071     rtcpbuffer[pos++]='R';
1072     rtcpbuffer[pos++]='E';
1073     rtcpbuffer[pos++]='M';
1074     rtcpbuffer[pos++]='B';
1075 
1076     rtcpbuffer[pos++] = _lengthRembSSRC;
1077     // 6 bit Exp
1078     // 18 bit mantissa
1079     uint8_t brExp = 0;
1080     for(uint32_t i=0; i<64; i++)
1081     {
1082         if(_rembBitrate <= ((uint32_t)262143 << i))
1083         {
1084             brExp = i;
1085             break;
1086         }
1087     }
1088     const uint32_t brMantissa = (_rembBitrate >> brExp);
1089     rtcpbuffer[pos++]=(uint8_t)((brExp << 2) + ((brMantissa >> 16) & 0x03));
1090     rtcpbuffer[pos++]=(uint8_t)(brMantissa >> 8);
1091     rtcpbuffer[pos++]=(uint8_t)(brMantissa);
1092 
1093     for (int i = 0; i < _lengthRembSSRC; i++)
1094     {
1095       RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _rembSSRC[i]);
1096         pos += 4;
1097     }
1098     return 0;
1099 }
1100 
1101 void
SetTargetBitrate(unsigned int target_bitrate)1102 RTCPSender::SetTargetBitrate(unsigned int target_bitrate)
1103 {
1104     CriticalSectionScoped lock(_criticalSectionRTCPSender);
1105     _tmmbr_Send = target_bitrate / 1000;
1106 }
1107 
BuildTMMBR(ModuleRtpRtcpImpl * rtp_rtcp_module,uint8_t * rtcpbuffer,int & pos)1108 int32_t RTCPSender::BuildTMMBR(ModuleRtpRtcpImpl* rtp_rtcp_module,
1109                                uint8_t* rtcpbuffer,
1110                                int& pos) {
1111     if (rtp_rtcp_module == NULL)
1112       return -1;
1113     // Before sending the TMMBR check the received TMMBN, only an owner is allowed to raise the bitrate
1114     // If the sender is an owner of the TMMBN -> send TMMBR
1115     // If not an owner but the TMMBR would enter the TMMBN -> send TMMBR
1116 
1117     // get current bounding set from RTCP receiver
1118     bool tmmbrOwner = false;
1119     // store in candidateSet, allocates one extra slot
1120     TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet();
1121 
1122     // holding _criticalSectionRTCPSender while calling RTCPreceiver which
1123     // will accuire _criticalSectionRTCPReceiver is a potental deadlock but
1124     // since RTCPreceiver is not doing the reverse we should be fine
1125     int32_t lengthOfBoundingSet =
1126         rtp_rtcp_module->BoundingSet(tmmbrOwner, candidateSet);
1127 
1128     if(lengthOfBoundingSet > 0)
1129     {
1130         for (int32_t i = 0; i < lengthOfBoundingSet; i++)
1131         {
1132             if( candidateSet->Tmmbr(i) == _tmmbr_Send &&
1133                 candidateSet->PacketOH(i) == _packetOH_Send)
1134             {
1135                 // do not send the same tuple
1136                 return 0;
1137             }
1138         }
1139         if(!tmmbrOwner)
1140         {
1141             // use received bounding set as candidate set
1142             // add current tuple
1143             candidateSet->SetEntry(lengthOfBoundingSet,
1144                                    _tmmbr_Send,
1145                                    _packetOH_Send,
1146                                    _SSRC);
1147             int numCandidates = lengthOfBoundingSet+ 1;
1148 
1149             // find bounding set
1150             TMMBRSet* boundingSet = NULL;
1151             int numBoundingSet = _tmmbrHelp.FindTMMBRBoundingSet(boundingSet);
1152             if(numBoundingSet > 0 || numBoundingSet <= numCandidates)
1153             {
1154                 tmmbrOwner = _tmmbrHelp.IsOwner(_SSRC, numBoundingSet);
1155             }
1156             if(!tmmbrOwner)
1157             {
1158                 // did not enter bounding set, no meaning to send this request
1159                 return 0;
1160             }
1161         }
1162     }
1163 
1164     if(_tmmbr_Send)
1165     {
1166         // sanity
1167         if(pos + 20 >= IP_PACKET_SIZE)
1168         {
1169             return -2;
1170         }
1171         // add TMMBR indicator
1172         uint8_t FMT = 3;
1173         rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
1174         rtcpbuffer[pos++]=(uint8_t)205;
1175 
1176         //Length of 4
1177         rtcpbuffer[pos++]=(uint8_t)0;
1178         rtcpbuffer[pos++]=(uint8_t)(4);
1179 
1180         // Add our own SSRC
1181         RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1182         pos += 4;
1183 
1184         // RFC 5104     4.2.1.2.  Semantics
1185 
1186         // SSRC of media source
1187         rtcpbuffer[pos++]=(uint8_t)0;
1188         rtcpbuffer[pos++]=(uint8_t)0;
1189         rtcpbuffer[pos++]=(uint8_t)0;
1190         rtcpbuffer[pos++]=(uint8_t)0;
1191 
1192         // Additional Feedback Control Information (FCI)
1193         RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
1194         pos += 4;
1195 
1196         uint32_t bitRate = _tmmbr_Send*1000;
1197         uint32_t mmbrExp = 0;
1198         for(uint32_t i=0;i<64;i++)
1199         {
1200             if(bitRate <= ((uint32_t)131071 << i))
1201             {
1202                 mmbrExp = i;
1203                 break;
1204             }
1205         }
1206         uint32_t mmbrMantissa = (bitRate >> mmbrExp);
1207 
1208         rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03));
1209         rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7);
1210         rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((_packetOH_Send >> 8)& 0x01));
1211         rtcpbuffer[pos++]=(uint8_t)(_packetOH_Send);
1212     }
1213     return 0;
1214 }
1215 
1216 int32_t
BuildTMMBN(uint8_t * rtcpbuffer,int & pos)1217 RTCPSender::BuildTMMBN(uint8_t* rtcpbuffer, int& pos)
1218 {
1219     TMMBRSet* boundingSet = _tmmbrHelp.BoundingSetToSend();
1220     if(boundingSet == NULL)
1221     {
1222         return -1;
1223     }
1224     // sanity
1225     if(pos + 12 + boundingSet->lengthOfSet()*8 >= IP_PACKET_SIZE)
1226     {
1227         LOG(LS_WARNING) << "Failed to build TMMBN.";
1228         return -2;
1229     }
1230     uint8_t FMT = 4;
1231     // add TMMBN indicator
1232     rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
1233     rtcpbuffer[pos++]=(uint8_t)205;
1234 
1235     //Add length later
1236     int posLength = pos;
1237     pos++;
1238     pos++;
1239 
1240     // Add our own SSRC
1241     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1242     pos += 4;
1243 
1244     // RFC 5104     4.2.2.2.  Semantics
1245 
1246     // SSRC of media source
1247     rtcpbuffer[pos++]=(uint8_t)0;
1248     rtcpbuffer[pos++]=(uint8_t)0;
1249     rtcpbuffer[pos++]=(uint8_t)0;
1250     rtcpbuffer[pos++]=(uint8_t)0;
1251 
1252     // Additional Feedback Control Information (FCI)
1253     int numBoundingSet = 0;
1254     for(uint32_t n=0; n< boundingSet->lengthOfSet(); n++)
1255     {
1256         if (boundingSet->Tmmbr(n) > 0)
1257         {
1258             uint32_t tmmbrSSRC = boundingSet->Ssrc(n);
1259             RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, tmmbrSSRC);
1260             pos += 4;
1261 
1262             uint32_t bitRate = boundingSet->Tmmbr(n) * 1000;
1263             uint32_t mmbrExp = 0;
1264             for(int i=0; i<64; i++)
1265             {
1266                 if(bitRate <=  ((uint32_t)131071 << i))
1267                 {
1268                     mmbrExp = i;
1269                     break;
1270                 }
1271             }
1272             uint32_t mmbrMantissa = (bitRate >> mmbrExp);
1273             uint32_t measuredOH = boundingSet->PacketOH(n);
1274 
1275             rtcpbuffer[pos++]=(uint8_t)((mmbrExp << 2) + ((mmbrMantissa >> 15) & 0x03));
1276             rtcpbuffer[pos++]=(uint8_t)(mmbrMantissa >> 7);
1277             rtcpbuffer[pos++]=(uint8_t)((mmbrMantissa << 1) + ((measuredOH >> 8)& 0x01));
1278             rtcpbuffer[pos++]=(uint8_t)(measuredOH);
1279             numBoundingSet++;
1280         }
1281     }
1282     uint16_t length= (uint16_t)(2+2*numBoundingSet);
1283     rtcpbuffer[posLength++]=(uint8_t)(length>>8);
1284     rtcpbuffer[posLength]=(uint8_t)(length);
1285     return 0;
1286 }
1287 
1288 int32_t
BuildAPP(uint8_t * rtcpbuffer,int & pos)1289 RTCPSender::BuildAPP(uint8_t* rtcpbuffer, int& pos)
1290 {
1291     // sanity
1292     if(_appData == NULL)
1293     {
1294         LOG(LS_WARNING) << "Failed to build app specific.";
1295         return -1;
1296     }
1297     if(pos + 12 + _appLength >= IP_PACKET_SIZE)
1298     {
1299         LOG(LS_WARNING) << "Failed to build app specific.";
1300         return -2;
1301     }
1302     rtcpbuffer[pos++]=(uint8_t)0x80 + _appSubType;
1303 
1304     // Add APP ID
1305     rtcpbuffer[pos++]=(uint8_t)204;
1306 
1307     uint16_t length = (_appLength>>2) + 2; // include SSRC and name
1308     rtcpbuffer[pos++]=(uint8_t)(length>>8);
1309     rtcpbuffer[pos++]=(uint8_t)(length);
1310 
1311     // Add our own SSRC
1312     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1313     pos += 4;
1314 
1315     // Add our application name
1316     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _appName);
1317     pos += 4;
1318 
1319     // Add the data
1320     memcpy(rtcpbuffer +pos, _appData,_appLength);
1321     pos += _appLength;
1322     return 0;
1323 }
1324 
1325 int32_t
BuildNACK(uint8_t * rtcpbuffer,int & pos,const int32_t nackSize,const uint16_t * nackList,std::string * nackString)1326 RTCPSender::BuildNACK(uint8_t* rtcpbuffer,
1327                       int& pos,
1328                       const int32_t nackSize,
1329                       const uint16_t* nackList,
1330                       std::string* nackString)
1331 {
1332     // sanity
1333     if(pos + 16 >= IP_PACKET_SIZE)
1334     {
1335         LOG(LS_WARNING) << "Failed to build NACK.";
1336         return -2;
1337     }
1338 
1339     // int size, uint16_t* nackList
1340     // add nack list
1341     uint8_t FMT = 1;
1342     rtcpbuffer[pos++]=(uint8_t)0x80 + FMT;
1343     rtcpbuffer[pos++]=(uint8_t)205;
1344 
1345     rtcpbuffer[pos++]=(uint8_t) 0;
1346     int nackSizePos = pos;
1347     rtcpbuffer[pos++]=(uint8_t)(3); //setting it to one kNACK signal as default
1348 
1349     // Add our own SSRC
1350     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1351     pos += 4;
1352 
1353     // Add the remote SSRC
1354     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
1355     pos += 4;
1356 
1357     NACKStringBuilder stringBuilder;
1358     // Build NACK bitmasks and write them to the RTCP message.
1359     // The nack list should be sorted and not contain duplicates if one
1360     // wants to build the smallest rtcp nack packet.
1361     int numOfNackFields = 0;
1362     int maxNackFields = std::min<int>(kRtcpMaxNackFields,
1363                                       (IP_PACKET_SIZE - pos) / 4);
1364     int i = 0;
1365     while (i < nackSize && numOfNackFields < maxNackFields) {
1366       stringBuilder.PushNACK(nackList[i]);
1367       uint16_t nack = nackList[i++];
1368       uint16_t bitmask = 0;
1369       while (i < nackSize) {
1370         int shift = static_cast<uint16_t>(nackList[i] - nack) - 1;
1371         if (shift >= 0 && shift <= 15) {
1372           stringBuilder.PushNACK(nackList[i]);
1373           bitmask |= (1 << shift);
1374           ++i;
1375         } else {
1376           break;
1377         }
1378       }
1379       // Write the sequence number and the bitmask to the packet.
1380       assert(pos + 4 < IP_PACKET_SIZE);
1381       RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + pos, nack);
1382       pos += 2;
1383       RtpUtility::AssignUWord16ToBuffer(rtcpbuffer + pos, bitmask);
1384       pos += 2;
1385       numOfNackFields++;
1386     }
1387     if (i != nackSize) {
1388       LOG(LS_WARNING) << "Nack list to large for one packet.";
1389     }
1390     rtcpbuffer[nackSizePos] = static_cast<uint8_t>(2 + numOfNackFields);
1391     *nackString = stringBuilder.GetResult();
1392     return 0;
1393 }
1394 
1395 int32_t
BuildBYE(uint8_t * rtcpbuffer,int & pos)1396 RTCPSender::BuildBYE(uint8_t* rtcpbuffer, int& pos)
1397 {
1398     // sanity
1399     if(pos + 8 >= IP_PACKET_SIZE)
1400     {
1401         return -2;
1402     }
1403     if(_includeCSRCs)
1404     {
1405         // Add a bye packet
1406         rtcpbuffer[pos++]=(uint8_t)0x80 + 1 + _CSRCs;  // number of SSRC+CSRCs
1407         rtcpbuffer[pos++]=(uint8_t)203;
1408 
1409         // length
1410         rtcpbuffer[pos++]=(uint8_t)0;
1411         rtcpbuffer[pos++]=(uint8_t)(1 + _CSRCs);
1412 
1413         // Add our own SSRC
1414         RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1415         pos += 4;
1416 
1417         // add CSRCs
1418         for(int i = 0; i < _CSRCs; i++)
1419         {
1420           RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _CSRC[i]);
1421             pos += 4;
1422         }
1423     } else
1424     {
1425         // Add a bye packet
1426         rtcpbuffer[pos++]=(uint8_t)0x80 + 1;  // number of SSRC+CSRCs
1427         rtcpbuffer[pos++]=(uint8_t)203;
1428 
1429         // length
1430         rtcpbuffer[pos++]=(uint8_t)0;
1431         rtcpbuffer[pos++]=(uint8_t)1;
1432 
1433         // Add our own SSRC
1434         RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1435         pos += 4;
1436     }
1437     return 0;
1438 }
1439 
BuildReceiverReferenceTime(uint8_t * buffer,int & pos,uint32_t ntp_sec,uint32_t ntp_frac)1440 int32_t RTCPSender::BuildReceiverReferenceTime(uint8_t* buffer,
1441                                                int& pos,
1442                                                uint32_t ntp_sec,
1443                                                uint32_t ntp_frac) {
1444   const int kRrTimeBlockLength = 20;
1445   if (pos + kRrTimeBlockLength >= IP_PACKET_SIZE) {
1446     return -2;
1447   }
1448 
1449   if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR) {
1450     last_xr_rr_.erase(last_xr_rr_.begin());
1451   }
1452   last_xr_rr_.insert(std::pair<uint32_t, int64_t>(
1453       RTCPUtility::MidNtp(ntp_sec, ntp_frac),
1454       Clock::NtpToMs(ntp_sec, ntp_frac)));
1455 
1456   // Add XR header.
1457   buffer[pos++] = 0x80;
1458   buffer[pos++] = 207;
1459   buffer[pos++] = 0;  // XR packet length.
1460   buffer[pos++] = 4;  // XR packet length.
1461 
1462   // Add our own SSRC.
1463   RtpUtility::AssignUWord32ToBuffer(buffer + pos, _SSRC);
1464   pos += 4;
1465 
1466   //    0                   1                   2                   3
1467   //    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
1468   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1469   //   |     BT=4      |   reserved    |       block length = 2        |
1470   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1471   //   |              NTP timestamp, most significant word             |
1472   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1473   //   |             NTP timestamp, least significant word             |
1474   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1475 
1476   // Add Receiver Reference Time Report block.
1477   buffer[pos++] = 4;  // BT.
1478   buffer[pos++] = 0;  // Reserved.
1479   buffer[pos++] = 0;  // Block length.
1480   buffer[pos++] = 2;  // Block length.
1481 
1482   // NTP timestamp.
1483   RtpUtility::AssignUWord32ToBuffer(buffer + pos, ntp_sec);
1484   pos += 4;
1485   RtpUtility::AssignUWord32ToBuffer(buffer + pos, ntp_frac);
1486   pos += 4;
1487 
1488   return 0;
1489 }
1490 
BuildDlrr(uint8_t * buffer,int & pos,const RtcpReceiveTimeInfo & info)1491 int32_t RTCPSender::BuildDlrr(uint8_t* buffer,
1492                               int& pos,
1493                               const RtcpReceiveTimeInfo& info) {
1494   const int kDlrrBlockLength = 24;
1495   if (pos + kDlrrBlockLength >= IP_PACKET_SIZE) {
1496     return -2;
1497   }
1498 
1499   // Add XR header.
1500   buffer[pos++] = 0x80;
1501   buffer[pos++] = 207;
1502   buffer[pos++] = 0;  // XR packet length.
1503   buffer[pos++] = 5;  // XR packet length.
1504 
1505   // Add our own SSRC.
1506   RtpUtility::AssignUWord32ToBuffer(buffer + pos, _SSRC);
1507   pos += 4;
1508 
1509   //   0                   1                   2                   3
1510   //   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
1511   //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1512   //  |     BT=5      |   reserved    |         block length          |
1513   //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1514   //  |                 SSRC_1 (SSRC of first receiver)               | sub-
1515   //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
1516   //  |                         last RR (LRR)                         |   1
1517   //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1518   //  |                   delay since last RR (DLRR)                  |
1519   //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
1520   //  |                 SSRC_2 (SSRC of second receiver)              | sub-
1521   //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
1522   //  :                               ...                             :   2
1523 
1524   // Add DLRR sub block.
1525   buffer[pos++] = 5;  // BT.
1526   buffer[pos++] = 0;  // Reserved.
1527   buffer[pos++] = 0;  // Block length.
1528   buffer[pos++] = 3;  // Block length.
1529 
1530   // NTP timestamp.
1531   RtpUtility::AssignUWord32ToBuffer(buffer + pos, info.sourceSSRC);
1532   pos += 4;
1533   RtpUtility::AssignUWord32ToBuffer(buffer + pos, info.lastRR);
1534   pos += 4;
1535   RtpUtility::AssignUWord32ToBuffer(buffer + pos, info.delaySinceLastRR);
1536   pos += 4;
1537 
1538   return 0;
1539 }
1540 
1541 int32_t
BuildVoIPMetric(uint8_t * rtcpbuffer,int & pos)1542 RTCPSender::BuildVoIPMetric(uint8_t* rtcpbuffer, int& pos)
1543 {
1544     // sanity
1545     if(pos + 44 >= IP_PACKET_SIZE)
1546     {
1547         return -2;
1548     }
1549 
1550     // Add XR header
1551     rtcpbuffer[pos++]=(uint8_t)0x80;
1552     rtcpbuffer[pos++]=(uint8_t)207;
1553 
1554     uint32_t XRLengthPos = pos;
1555 
1556     // handle length later on
1557     pos++;
1558     pos++;
1559 
1560     // Add our own SSRC
1561     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _SSRC);
1562     pos += 4;
1563 
1564     // Add a VoIP metrics block
1565     rtcpbuffer[pos++]=7;
1566     rtcpbuffer[pos++]=0;
1567     rtcpbuffer[pos++]=0;
1568     rtcpbuffer[pos++]=8;
1569 
1570     // Add the remote SSRC
1571     RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _remoteSSRC);
1572     pos += 4;
1573 
1574     rtcpbuffer[pos++] = _xrVoIPMetric.lossRate;
1575     rtcpbuffer[pos++] = _xrVoIPMetric.discardRate;
1576     rtcpbuffer[pos++] = _xrVoIPMetric.burstDensity;
1577     rtcpbuffer[pos++] = _xrVoIPMetric.gapDensity;
1578 
1579     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration >> 8);
1580     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.burstDuration);
1581     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration >> 8);
1582     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.gapDuration);
1583 
1584     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay >> 8);
1585     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.roundTripDelay);
1586     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay >> 8);
1587     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.endSystemDelay);
1588 
1589     rtcpbuffer[pos++] = _xrVoIPMetric.signalLevel;
1590     rtcpbuffer[pos++] = _xrVoIPMetric.noiseLevel;
1591     rtcpbuffer[pos++] = _xrVoIPMetric.RERL;
1592     rtcpbuffer[pos++] = _xrVoIPMetric.Gmin;
1593 
1594     rtcpbuffer[pos++] = _xrVoIPMetric.Rfactor;
1595     rtcpbuffer[pos++] = _xrVoIPMetric.extRfactor;
1596     rtcpbuffer[pos++] = _xrVoIPMetric.MOSLQ;
1597     rtcpbuffer[pos++] = _xrVoIPMetric.MOSCQ;
1598 
1599     rtcpbuffer[pos++] = _xrVoIPMetric.RXconfig;
1600     rtcpbuffer[pos++] = 0; // reserved
1601     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal >> 8);
1602     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBnominal);
1603 
1604     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax >> 8);
1605     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBmax);
1606     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax >> 8);
1607     rtcpbuffer[pos++] = (uint8_t)(_xrVoIPMetric.JBabsMax);
1608 
1609     rtcpbuffer[XRLengthPos]=(uint8_t)(0);
1610     rtcpbuffer[XRLengthPos+1]=(uint8_t)(10);
1611     return 0;
1612 }
1613 
SendRTCP(const FeedbackState & feedback_state,uint32_t packetTypeFlags,int32_t nackSize,const uint16_t * nackList,bool repeat,uint64_t pictureID)1614 int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state,
1615                              uint32_t packetTypeFlags,
1616                              int32_t nackSize,
1617                              const uint16_t* nackList,
1618                              bool repeat,
1619                              uint64_t pictureID) {
1620   {
1621     CriticalSectionScoped lock(_criticalSectionRTCPSender);
1622     if(_method == kRtcpOff)
1623     {
1624         LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
1625         return -1;
1626     }
1627   }
1628   uint8_t rtcp_buffer[IP_PACKET_SIZE];
1629   int rtcp_length = PrepareRTCP(feedback_state,
1630                                 packetTypeFlags,
1631                                 nackSize,
1632                                 nackList,
1633                                 repeat,
1634                                 pictureID,
1635                                 rtcp_buffer,
1636                                 IP_PACKET_SIZE);
1637   if (rtcp_length < 0) {
1638     return -1;
1639   }
1640   // Sanity don't send empty packets.
1641   if (rtcp_length == 0)
1642   {
1643       return -1;
1644   }
1645   return SendToNetwork(rtcp_buffer, static_cast<uint16_t>(rtcp_length));
1646 }
1647 
PrepareRTCP(const FeedbackState & feedback_state,uint32_t packetTypeFlags,int32_t nackSize,const uint16_t * nackList,bool repeat,uint64_t pictureID,uint8_t * rtcp_buffer,int buffer_size)1648 int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state,
1649                             uint32_t packetTypeFlags,
1650                             int32_t nackSize,
1651                             const uint16_t* nackList,
1652                             bool repeat,
1653                             uint64_t pictureID,
1654                             uint8_t* rtcp_buffer,
1655                             int buffer_size) {
1656   uint32_t rtcpPacketTypeFlags = packetTypeFlags;
1657   // Collect the received information.
1658   uint32_t NTPsec = 0;
1659   uint32_t NTPfrac = 0;
1660   uint32_t jitterTransmissionOffset = 0;
1661   int position = 0;
1662 
1663   CriticalSectionScoped lock(_criticalSectionRTCPSender);
1664 
1665   if(_TMMBR )  // Attach TMMBR to send and receive reports.
1666   {
1667       rtcpPacketTypeFlags |= kRtcpTmmbr;
1668   }
1669   if(_appSend)
1670   {
1671       rtcpPacketTypeFlags |= kRtcpApp;
1672       _appSend = false;
1673   }
1674   if(_REMB && _sendREMB)
1675   {
1676       // Always attach REMB to SR if that is configured. Note that REMB is
1677       // only sent on one of the RTP modules in the REMB group.
1678       rtcpPacketTypeFlags |= kRtcpRemb;
1679   }
1680   if(_xrSendVoIPMetric)
1681   {
1682       rtcpPacketTypeFlags |= kRtcpXrVoipMetric;
1683       _xrSendVoIPMetric = false;
1684   }
1685   if(_sendTMMBN)  // Set when having received a TMMBR.
1686   {
1687       rtcpPacketTypeFlags |= kRtcpTmmbn;
1688       _sendTMMBN = false;
1689   }
1690   if (rtcpPacketTypeFlags & kRtcpReport)
1691   {
1692       if (xrSendReceiverReferenceTimeEnabled_ && !_sending)
1693       {
1694           rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
1695       }
1696       if (feedback_state.has_last_xr_rr)
1697       {
1698           rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
1699       }
1700   }
1701   if(_method == kRtcpCompound)
1702   {
1703       if(_sending)
1704       {
1705           rtcpPacketTypeFlags |= kRtcpSr;
1706       } else
1707       {
1708           rtcpPacketTypeFlags |= kRtcpRr;
1709       }
1710   } else if(_method == kRtcpNonCompound)
1711   {
1712       if(rtcpPacketTypeFlags & kRtcpReport)
1713       {
1714           if(_sending)
1715           {
1716               rtcpPacketTypeFlags |= kRtcpSr;
1717           } else
1718           {
1719               rtcpPacketTypeFlags |= kRtcpRr;
1720           }
1721       }
1722   }
1723   if( rtcpPacketTypeFlags & kRtcpRr ||
1724       rtcpPacketTypeFlags & kRtcpSr)
1725   {
1726       // generate next time to send a RTCP report
1727       // seeded from RTP constructor
1728       int32_t random = rand() % 1000;
1729       int32_t timeToNext = RTCP_INTERVAL_AUDIO_MS;
1730 
1731       if(_audio)
1732       {
1733           timeToNext = (RTCP_INTERVAL_AUDIO_MS/2) +
1734               (RTCP_INTERVAL_AUDIO_MS*random/1000);
1735       }else
1736       {
1737           uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS;
1738           if(_sending)
1739           {
1740             // Calculate bandwidth for video; 360 / send bandwidth in kbit/s.
1741             uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000;
1742             if (send_bitrate_kbit != 0)
1743               minIntervalMs = 360000 / send_bitrate_kbit;
1744           }
1745           if(minIntervalMs > RTCP_INTERVAL_VIDEO_MS)
1746           {
1747               minIntervalMs = RTCP_INTERVAL_VIDEO_MS;
1748           }
1749           timeToNext = (minIntervalMs/2) + (minIntervalMs*random/1000);
1750       }
1751       _nextTimeToSendRTCP = _clock->TimeInMilliseconds() + timeToNext;
1752   }
1753 
1754   // If the data does not fit in the packet we fill it as much as possible.
1755   int32_t buildVal = 0;
1756 
1757   // We need to send our NTP even if we haven't received any reports.
1758   _clock->CurrentNtp(NTPsec, NTPfrac);
1759   if (ShouldSendReportBlocks(rtcpPacketTypeFlags)) {
1760     StatisticianMap statisticians =
1761         receive_statistics_->GetActiveStatisticians();
1762     if (!statisticians.empty()) {
1763       StatisticianMap::const_iterator it;
1764       int i;
1765       for (it = statisticians.begin(), i = 0; it != statisticians.end();
1766            ++it, ++i) {
1767         RTCPReportBlock report_block;
1768         if (PrepareReport(
1769                 feedback_state, it->second, &report_block, &NTPsec, &NTPfrac))
1770           AddReportBlock(it->first, &internal_report_blocks_, &report_block);
1771       }
1772       if (_IJ && !statisticians.empty()) {
1773         rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1774       }
1775     }
1776   }
1777 
1778   if(rtcpPacketTypeFlags & kRtcpSr)
1779   {
1780     buildVal = BuildSR(feedback_state, rtcp_buffer, position, NTPsec, NTPfrac);
1781       if (buildVal == -1) {
1782         return -1;
1783       } else if (buildVal == -2) {
1784         return position;
1785       }
1786       buildVal = BuildSDEC(rtcp_buffer, position);
1787       if (buildVal == -1) {
1788         return -1;
1789       } else if (buildVal == -2) {
1790         return position;
1791       }
1792   }else if(rtcpPacketTypeFlags & kRtcpRr)
1793   {
1794       buildVal = BuildRR(rtcp_buffer, position, NTPsec, NTPfrac);
1795       if (buildVal == -1) {
1796         return -1;
1797       } else if (buildVal == -2) {
1798         return position;
1799       }
1800       // only of set
1801       if(_CNAME[0] != 0)
1802       {
1803           buildVal = BuildSDEC(rtcp_buffer, position);
1804           if (buildVal == -1) {
1805             return -1;
1806           }
1807       }
1808   }
1809   if(rtcpPacketTypeFlags & kRtcpTransmissionTimeOffset)
1810   {
1811       // If present, this RTCP packet must be placed after a
1812       // receiver report.
1813       buildVal = BuildExtendedJitterReport(rtcp_buffer,
1814                                            position,
1815                                            jitterTransmissionOffset);
1816       if (buildVal == -1) {
1817         return -1;
1818       } else if (buildVal == -2) {
1819         return position;
1820       }
1821   }
1822   if(rtcpPacketTypeFlags & kRtcpPli)
1823   {
1824       buildVal = BuildPLI(rtcp_buffer, position);
1825       if (buildVal == -1) {
1826         return -1;
1827       } else if (buildVal == -2) {
1828         return position;
1829       }
1830       TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::PLI");
1831       ++packet_type_counter_.pli_packets;
1832       TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_PLICount", _SSRC,
1833                         packet_type_counter_.pli_packets);
1834   }
1835   if(rtcpPacketTypeFlags & kRtcpFir)
1836   {
1837       buildVal = BuildFIR(rtcp_buffer, position, repeat);
1838       if (buildVal == -1) {
1839         return -1;
1840       } else if (buildVal == -2) {
1841         return position;
1842       }
1843       TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::FIR");
1844       ++packet_type_counter_.fir_packets;
1845       TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_FIRCount", _SSRC,
1846                         packet_type_counter_.fir_packets);
1847   }
1848   if(rtcpPacketTypeFlags & kRtcpSli)
1849   {
1850       buildVal = BuildSLI(rtcp_buffer, position, (uint8_t)pictureID);
1851       if (buildVal == -1) {
1852         return -1;
1853       } else if (buildVal == -2) {
1854         return position;
1855       }
1856   }
1857   if(rtcpPacketTypeFlags & kRtcpRpsi)
1858   {
1859       const int8_t payloadType = feedback_state.send_payload_type;
1860       if (payloadType == -1) {
1861         return -1;
1862       }
1863       buildVal = BuildRPSI(rtcp_buffer, position, pictureID,
1864                            (uint8_t)payloadType);
1865       if (buildVal == -1) {
1866         return -1;
1867       } else if (buildVal == -2) {
1868         return position;
1869       }
1870   }
1871   if(rtcpPacketTypeFlags & kRtcpRemb)
1872   {
1873       buildVal = BuildREMB(rtcp_buffer, position);
1874       if (buildVal == -1) {
1875         return -1;
1876       } else if (buildVal == -2) {
1877         return position;
1878       }
1879       TRACE_EVENT_INSTANT0("webrtc_rtp", "RTCPSender::REMB");
1880   }
1881   if(rtcpPacketTypeFlags & kRtcpBye)
1882   {
1883       buildVal = BuildBYE(rtcp_buffer, position);
1884       if (buildVal == -1) {
1885         return -1;
1886       } else if (buildVal == -2) {
1887         return position;
1888       }
1889   }
1890   if(rtcpPacketTypeFlags & kRtcpApp)
1891   {
1892       buildVal = BuildAPP(rtcp_buffer, position);
1893       if (buildVal == -1) {
1894         return -1;
1895       } else if (buildVal == -2) {
1896         return position;
1897       }
1898   }
1899   if(rtcpPacketTypeFlags & kRtcpTmmbr)
1900   {
1901       buildVal = BuildTMMBR(feedback_state.module, rtcp_buffer, position);
1902       if (buildVal == -1) {
1903         return -1;
1904       } else if (buildVal == -2) {
1905         return position;
1906       }
1907   }
1908   if(rtcpPacketTypeFlags & kRtcpTmmbn)
1909   {
1910       buildVal = BuildTMMBN(rtcp_buffer, position);
1911       if (buildVal == -1) {
1912         return -1;
1913       } else if (buildVal == -2) {
1914         return position;
1915       }
1916   }
1917   if(rtcpPacketTypeFlags & kRtcpNack)
1918   {
1919       std::string nackString;
1920       buildVal = BuildNACK(rtcp_buffer, position, nackSize, nackList,
1921                            &nackString);
1922       if (buildVal == -1) {
1923         return -1;
1924       } else if (buildVal == -2) {
1925         return position;
1926       }
1927       TRACE_EVENT_INSTANT1("webrtc_rtp", "RTCPSender::NACK",
1928                            "nacks", TRACE_STR_COPY(nackString.c_str()));
1929       ++packet_type_counter_.nack_packets;
1930       TRACE_COUNTER_ID1("webrtc_rtp", "RTCP_NACKCount", _SSRC,
1931                         packet_type_counter_.nack_packets);
1932   }
1933   if(rtcpPacketTypeFlags & kRtcpXrVoipMetric)
1934   {
1935       buildVal = BuildVoIPMetric(rtcp_buffer, position);
1936       if (buildVal == -1) {
1937         return -1;
1938       } else if (buildVal == -2) {
1939         return position;
1940       }
1941   }
1942   if (rtcpPacketTypeFlags & kRtcpXrReceiverReferenceTime)
1943   {
1944       buildVal = BuildReceiverReferenceTime(rtcp_buffer,
1945                                             position,
1946                                             NTPsec,
1947                                             NTPfrac);
1948       if (buildVal == -1) {
1949         return -1;
1950       } else if (buildVal == -2) {
1951         return position;
1952       }
1953   }
1954   if (rtcpPacketTypeFlags & kRtcpXrDlrrReportBlock)
1955   {
1956       buildVal = BuildDlrr(rtcp_buffer, position, feedback_state.last_xr_rr);
1957       if (buildVal == -1) {
1958         return -1;
1959       } else if (buildVal == -2) {
1960         return position;
1961       }
1962   }
1963   return position;
1964 }
1965 
ShouldSendReportBlocks(uint32_t rtcp_packet_type) const1966 bool RTCPSender::ShouldSendReportBlocks(uint32_t rtcp_packet_type) const {
1967   return Status() == kRtcpCompound ||
1968       (rtcp_packet_type & kRtcpReport) ||
1969       (rtcp_packet_type & kRtcpSr) ||
1970       (rtcp_packet_type & kRtcpRr);
1971 }
1972 
PrepareReport(const FeedbackState & feedback_state,StreamStatistician * statistician,RTCPReportBlock * report_block,uint32_t * ntp_secs,uint32_t * ntp_frac)1973 bool RTCPSender::PrepareReport(const FeedbackState& feedback_state,
1974                                StreamStatistician* statistician,
1975                                RTCPReportBlock* report_block,
1976                                uint32_t* ntp_secs, uint32_t* ntp_frac) {
1977   // Do we have receive statistics to send?
1978   RtcpStatistics stats;
1979   if (!statistician->GetStatistics(&stats, true))
1980     return false;
1981   report_block->fractionLost = stats.fraction_lost;
1982   report_block->cumulativeLost = stats.cumulative_lost;
1983   report_block->extendedHighSeqNum =
1984       stats.extended_max_sequence_number;
1985   report_block->jitter = stats.jitter;
1986 
1987   // get our NTP as late as possible to avoid a race
1988   _clock->CurrentNtp(*ntp_secs, *ntp_frac);
1989 
1990   // Delay since last received report
1991   uint32_t delaySinceLastReceivedSR = 0;
1992   if ((feedback_state.last_rr_ntp_secs != 0) ||
1993       (feedback_state.last_rr_ntp_frac != 0)) {
1994     // get the 16 lowest bits of seconds and the 16 higest bits of fractions
1995     uint32_t now=*ntp_secs&0x0000FFFF;
1996     now <<=16;
1997     now += (*ntp_frac&0xffff0000)>>16;
1998 
1999     uint32_t receiveTime = feedback_state.last_rr_ntp_secs&0x0000FFFF;
2000     receiveTime <<=16;
2001     receiveTime += (feedback_state.last_rr_ntp_frac&0xffff0000)>>16;
2002 
2003     delaySinceLastReceivedSR = now-receiveTime;
2004   }
2005   report_block->delaySinceLastSR = delaySinceLastReceivedSR;
2006   report_block->lastSR = feedback_state.remote_sr;
2007   return true;
2008 }
2009 
2010 int32_t
SendToNetwork(const uint8_t * dataBuffer,const uint16_t length)2011 RTCPSender::SendToNetwork(const uint8_t* dataBuffer,
2012                           const uint16_t length)
2013 {
2014     CriticalSectionScoped lock(_criticalSectionTransport);
2015     if(_cbTransport)
2016     {
2017         if(_cbTransport->SendRTCPPacket(_id, dataBuffer, length) > 0)
2018         {
2019             return 0;
2020         }
2021     }
2022     return -1;
2023 }
2024 
2025 int32_t
SetCSRCStatus(const bool include)2026 RTCPSender::SetCSRCStatus(const bool include)
2027 {
2028     CriticalSectionScoped lock(_criticalSectionRTCPSender);
2029     _includeCSRCs = include;
2030     return 0;
2031 }
2032 
2033 int32_t
SetCSRCs(const uint32_t arrOfCSRC[kRtpCsrcSize],const uint8_t arrLength)2034 RTCPSender::SetCSRCs(const uint32_t arrOfCSRC[kRtpCsrcSize],
2035                     const uint8_t arrLength)
2036 {
2037     assert(arrLength <= kRtpCsrcSize);
2038     CriticalSectionScoped lock(_criticalSectionRTCPSender);
2039 
2040     for(int i = 0; i < arrLength;i++)
2041     {
2042         _CSRC[i] = arrOfCSRC[i];
2043     }
2044     _CSRCs = arrLength;
2045     return 0;
2046 }
2047 
2048 int32_t
SetApplicationSpecificData(const uint8_t subType,const uint32_t name,const uint8_t * data,const uint16_t length)2049 RTCPSender::SetApplicationSpecificData(const uint8_t subType,
2050                                        const uint32_t name,
2051                                        const uint8_t* data,
2052                                        const uint16_t length)
2053 {
2054     if(length %4 != 0)
2055     {
2056         LOG(LS_ERROR) << "Failed to SetApplicationSpecificData.";
2057         return -1;
2058     }
2059     CriticalSectionScoped lock(_criticalSectionRTCPSender);
2060 
2061     if(_appData)
2062     {
2063         delete [] _appData;
2064     }
2065 
2066     _appSend = true;
2067     _appSubType = subType;
2068     _appName = name;
2069     _appData = new uint8_t[length];
2070     _appLength = length;
2071     memcpy(_appData, data, length);
2072     return 0;
2073 }
2074 
2075 int32_t
SetRTCPVoIPMetrics(const RTCPVoIPMetric * VoIPMetric)2076 RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric)
2077 {
2078     CriticalSectionScoped lock(_criticalSectionRTCPSender);
2079     memcpy(&_xrVoIPMetric, VoIPMetric, sizeof(RTCPVoIPMetric));
2080 
2081     _xrSendVoIPMetric = true;
2082     return 0;
2083 }
2084 
SendRtcpXrReceiverReferenceTime(bool enable)2085 void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) {
2086   CriticalSectionScoped lock(_criticalSectionRTCPSender);
2087   xrSendReceiverReferenceTimeEnabled_ = enable;
2088 }
2089 
RtcpXrReceiverReferenceTime() const2090 bool RTCPSender::RtcpXrReceiverReferenceTime() const {
2091   CriticalSectionScoped lock(_criticalSectionRTCPSender);
2092   return xrSendReceiverReferenceTimeEnabled_;
2093 }
2094 
2095 // called under critsect _criticalSectionRTCPSender
WriteAllReportBlocksToBuffer(uint8_t * rtcpbuffer,int pos,uint8_t & numberOfReportBlocks,const uint32_t NTPsec,const uint32_t NTPfrac)2096 int32_t RTCPSender::WriteAllReportBlocksToBuffer(
2097     uint8_t* rtcpbuffer,
2098     int pos,
2099     uint8_t& numberOfReportBlocks,
2100     const uint32_t NTPsec,
2101     const uint32_t NTPfrac) {
2102   numberOfReportBlocks = external_report_blocks_.size();
2103   numberOfReportBlocks += internal_report_blocks_.size();
2104   if ((pos + numberOfReportBlocks * 24) >= IP_PACKET_SIZE) {
2105     LOG(LS_WARNING) << "Can't fit all report blocks.";
2106     return -1;
2107   }
2108   pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, internal_report_blocks_);
2109   while (!internal_report_blocks_.empty()) {
2110     delete internal_report_blocks_.begin()->second;
2111     internal_report_blocks_.erase(internal_report_blocks_.begin());
2112   }
2113   pos = WriteReportBlocksToBuffer(rtcpbuffer, pos, external_report_blocks_);
2114   return pos;
2115 }
2116 
WriteReportBlocksToBuffer(uint8_t * rtcpbuffer,int32_t position,const std::map<uint32_t,RTCPReportBlock * > & report_blocks)2117 int32_t RTCPSender::WriteReportBlocksToBuffer(
2118     uint8_t* rtcpbuffer,
2119     int32_t position,
2120     const std::map<uint32_t, RTCPReportBlock*>& report_blocks) {
2121   std::map<uint32_t, RTCPReportBlock*>::const_iterator it =
2122       report_blocks.begin();
2123   for (; it != report_blocks.end(); it++) {
2124     uint32_t remoteSSRC = it->first;
2125     RTCPReportBlock* reportBlock = it->second;
2126     if (reportBlock) {
2127       // Remote SSRC
2128       RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position, remoteSSRC);
2129       position += 4;
2130 
2131       // fraction lost
2132       rtcpbuffer[position++] = reportBlock->fractionLost;
2133 
2134       // cumulative loss
2135       RtpUtility::AssignUWord24ToBuffer(rtcpbuffer + position,
2136                                         reportBlock->cumulativeLost);
2137       position += 3;
2138 
2139       // extended highest seq_no, contain the highest sequence number received
2140       RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position,
2141                                         reportBlock->extendedHighSeqNum);
2142       position += 4;
2143 
2144       // Jitter
2145       RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position,
2146                                         reportBlock->jitter);
2147       position += 4;
2148 
2149       RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position,
2150                                         reportBlock->lastSR);
2151       position += 4;
2152 
2153       RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + position,
2154                                         reportBlock->delaySinceLastSR);
2155       position += 4;
2156     }
2157   }
2158   return position;
2159 }
2160 
2161 // no callbacks allowed inside this function
2162 int32_t
SetTMMBN(const TMMBRSet * boundingSet,const uint32_t maxBitrateKbit)2163 RTCPSender::SetTMMBN(const TMMBRSet* boundingSet,
2164                      const uint32_t maxBitrateKbit)
2165 {
2166     CriticalSectionScoped lock(_criticalSectionRTCPSender);
2167 
2168     if (0 == _tmmbrHelp.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit))
2169     {
2170         _sendTMMBN = true;
2171         return 0;
2172     }
2173     return -1;
2174 }
2175 }  // namespace webrtc
2176