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