Home | History | Annotate | Download | only in source
      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_receiver.h"
     12 
     13 #include <assert.h> //assert
     14 #include <string.h> //memset
     15 
     16 #include <algorithm>
     17 
     18 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.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/logging.h"
     22 #include "webrtc/system_wrappers/interface/trace_event.h"
     23 
     24 namespace webrtc {
     25 using namespace RTCPUtility;
     26 using namespace RTCPHelp;
     27 
     28 // The number of RTCP time intervals needed to trigger a timeout.
     29 const int kRrTimeoutIntervals = 3;
     30 
     31 RTCPReceiver::RTCPReceiver(const int32_t id, Clock* clock,
     32                            ModuleRtpRtcpImpl* owner)
     33     : TMMBRHelp(),
     34     _id(id),
     35     _clock(clock),
     36     _method(kRtcpOff),
     37     _lastReceived(0),
     38     _rtpRtcp(*owner),
     39       _criticalSectionFeedbacks(
     40           CriticalSectionWrapper::CreateCriticalSection()),
     41     _cbRtcpFeedback(NULL),
     42     _cbRtcpBandwidthObserver(NULL),
     43     _cbRtcpIntraFrameObserver(NULL),
     44     _criticalSectionRTCPReceiver(
     45         CriticalSectionWrapper::CreateCriticalSection()),
     46     main_ssrc_(0),
     47     _remoteSSRC(0),
     48     _remoteSenderInfo(),
     49     _lastReceivedSRNTPsecs(0),
     50     _lastReceivedSRNTPfrac(0),
     51     _lastReceivedXRNTPsecs(0),
     52     _lastReceivedXRNTPfrac(0),
     53     xr_rr_rtt_ms_(0),
     54     _receivedInfoMap(),
     55     _packetTimeOutMS(0),
     56     _lastReceivedRrMs(0),
     57     _lastIncreasedSequenceNumberMs(0),
     58     stats_callback_(NULL) {
     59     memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
     60 }
     61 
     62 RTCPReceiver::~RTCPReceiver() {
     63   delete _criticalSectionRTCPReceiver;
     64   delete _criticalSectionFeedbacks;
     65 
     66   while (!_receivedReportBlockMap.empty()) {
     67     std::map<uint32_t, RTCPReportBlockInformation*>::iterator first =
     68         _receivedReportBlockMap.begin();
     69     delete first->second;
     70     _receivedReportBlockMap.erase(first);
     71   }
     72   while (!_receivedInfoMap.empty()) {
     73     std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
     74         _receivedInfoMap.begin();
     75     delete first->second;
     76     _receivedInfoMap.erase(first);
     77   }
     78   while (!_receivedCnameMap.empty()) {
     79     std::map<uint32_t, RTCPCnameInformation*>::iterator first =
     80         _receivedCnameMap.begin();
     81     delete first->second;
     82     _receivedCnameMap.erase(first);
     83   }
     84 }
     85 
     86 void
     87 RTCPReceiver::ChangeUniqueId(const int32_t id)
     88 {
     89     _id = id;
     90 }
     91 
     92 RTCPMethod
     93 RTCPReceiver::Status() const
     94 {
     95     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
     96     return _method;
     97 }
     98 
     99 int32_t
    100 RTCPReceiver::SetRTCPStatus(const RTCPMethod method)
    101 {
    102     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    103     _method = method;
    104     return 0;
    105 }
    106 
    107 int64_t
    108 RTCPReceiver::LastReceived()
    109 {
    110     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    111     return _lastReceived;
    112 }
    113 
    114 int64_t
    115 RTCPReceiver::LastReceivedReceiverReport() const {
    116     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    117     int64_t last_received_rr = -1;
    118     for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
    119          it != _receivedInfoMap.end(); ++it) {
    120       if (it->second->lastTimeReceived > last_received_rr) {
    121         last_received_rr = it->second->lastTimeReceived;
    122       }
    123     }
    124     return last_received_rr;
    125 }
    126 
    127 int32_t
    128 RTCPReceiver::SetRemoteSSRC( const uint32_t ssrc)
    129 {
    130     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    131 
    132     // new SSRC reset old reports
    133     memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
    134     _lastReceivedSRNTPsecs = 0;
    135     _lastReceivedSRNTPfrac = 0;
    136 
    137     _remoteSSRC = ssrc;
    138     return 0;
    139 }
    140 
    141 uint32_t RTCPReceiver::RemoteSSRC() const {
    142   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    143   return _remoteSSRC;
    144 }
    145 
    146 void RTCPReceiver::RegisterRtcpObservers(
    147     RtcpIntraFrameObserver* intra_frame_callback,
    148     RtcpBandwidthObserver* bandwidth_callback,
    149     RtcpFeedback* feedback_callback) {
    150   CriticalSectionScoped lock(_criticalSectionFeedbacks);
    151   _cbRtcpIntraFrameObserver = intra_frame_callback;
    152   _cbRtcpBandwidthObserver = bandwidth_callback;
    153   _cbRtcpFeedback = feedback_callback;
    154 }
    155 
    156 void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
    157                             const std::set<uint32_t>& registered_ssrcs) {
    158   uint32_t old_ssrc = 0;
    159   {
    160     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    161     old_ssrc = main_ssrc_;
    162     main_ssrc_ = main_ssrc;
    163     registered_ssrcs_ = registered_ssrcs;
    164   }
    165   {
    166     CriticalSectionScoped lock(_criticalSectionFeedbacks);
    167     if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
    168       _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
    169     }
    170   }
    171 }
    172 
    173 int32_t RTCPReceiver::ResetRTT(const uint32_t remoteSSRC) {
    174   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    175   RTCPReportBlockInformation* reportBlock =
    176       GetReportBlockInformation(remoteSSRC);
    177   if (reportBlock == NULL) {
    178     LOG(LS_WARNING) << "Failed to reset rtt for ssrc " << remoteSSRC;
    179     return -1;
    180   }
    181   reportBlock->RTT = 0;
    182   reportBlock->avgRTT = 0;
    183   reportBlock->minRTT = 0;
    184   reportBlock->maxRTT = 0;
    185   return 0;
    186 }
    187 
    188 int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
    189                           uint16_t* RTT,
    190                           uint16_t* avgRTT,
    191                           uint16_t* minRTT,
    192                           uint16_t* maxRTT) const {
    193   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    194 
    195   RTCPReportBlockInformation* reportBlock =
    196       GetReportBlockInformation(remoteSSRC);
    197 
    198   if (reportBlock == NULL) {
    199     return -1;
    200   }
    201   if (RTT) {
    202     *RTT = reportBlock->RTT;
    203   }
    204   if (avgRTT) {
    205     *avgRTT = reportBlock->avgRTT;
    206   }
    207   if (minRTT) {
    208     *minRTT = reportBlock->minRTT;
    209   }
    210   if (maxRTT) {
    211     *maxRTT = reportBlock->maxRTT;
    212   }
    213   return 0;
    214 }
    215 
    216 bool RTCPReceiver::GetAndResetXrRrRtt(uint16_t* rtt_ms) {
    217   assert(rtt_ms);
    218   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    219   if (xr_rr_rtt_ms_ == 0) {
    220     return false;
    221   }
    222   *rtt_ms = xr_rr_rtt_ms_;
    223   xr_rr_rtt_ms_ = 0;
    224   return true;
    225 }
    226 
    227 int32_t
    228 RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs,
    229                   uint32_t *ReceivedNTPfrac,
    230                   uint32_t *RTCPArrivalTimeSecs,
    231                   uint32_t *RTCPArrivalTimeFrac,
    232                   uint32_t *rtcp_timestamp) const
    233 {
    234     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    235     if(ReceivedNTPsecs)
    236     {
    237         *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
    238     }
    239     if(ReceivedNTPfrac)
    240     {
    241         *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
    242     }
    243     if(RTCPArrivalTimeFrac)
    244     {
    245         *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
    246     }
    247     if(RTCPArrivalTimeSecs)
    248     {
    249         *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
    250     }
    251     if (rtcp_timestamp) {
    252       *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
    253     }
    254     return 0;
    255 }
    256 
    257 bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
    258     RtcpReceiveTimeInfo* info) const {
    259   assert(info);
    260   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    261   if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
    262     return false;
    263   }
    264 
    265   info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
    266   info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
    267 
    268   // Get the delay since last received report (RFC 3611).
    269   uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
    270                                               _lastReceivedXRNTPfrac);
    271 
    272   uint32_t ntp_sec = 0;
    273   uint32_t ntp_frac = 0;
    274   _clock->CurrentNtp(ntp_sec, ntp_frac);
    275   uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
    276 
    277   info->delaySinceLastRR = now - receive_time;
    278   return true;
    279 }
    280 
    281 int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
    282   assert(senderInfo);
    283   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    284   if (_lastReceivedSRNTPsecs == 0) {
    285     return -1;
    286   }
    287   memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
    288   return 0;
    289 }
    290 
    291 // statistics
    292 // we can get multiple receive reports when we receive the report from a CE
    293 int32_t RTCPReceiver::StatisticsReceived(
    294     std::vector<RTCPReportBlock>* receiveBlocks) const {
    295   assert(receiveBlocks);
    296   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    297 
    298   std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
    299       _receivedReportBlockMap.begin();
    300 
    301   while (it != _receivedReportBlockMap.end()) {
    302     receiveBlocks->push_back(it->second->remoteReceiveBlock);
    303     it++;
    304   }
    305   return 0;
    306 }
    307 
    308 void RTCPReceiver::GetPacketTypeCounter(
    309     RtcpPacketTypeCounter* packet_counter) const {
    310   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    311   *packet_counter = packet_type_counter_;
    312 }
    313 
    314 int32_t
    315 RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
    316                                  RTCPUtility::RTCPParserV2* rtcpParser)
    317 {
    318     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    319 
    320     _lastReceived = _clock->TimeInMilliseconds();
    321 
    322     RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
    323     while (pktType != RTCPUtility::kRtcpNotValidCode)
    324     {
    325         // Each "case" is responsible for iterate the parser to the
    326         // next top level packet.
    327         switch (pktType)
    328         {
    329         case RTCPUtility::kRtcpSrCode:
    330         case RTCPUtility::kRtcpRrCode:
    331             HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
    332             break;
    333         case RTCPUtility::kRtcpSdesCode:
    334             HandleSDES(*rtcpParser);
    335             break;
    336         case RTCPUtility::kRtcpXrHeaderCode:
    337             HandleXrHeader(*rtcpParser, rtcpPacketInformation);
    338             break;
    339         case RTCPUtility::kRtcpXrReceiverReferenceTimeCode:
    340             HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
    341             break;
    342         case RTCPUtility::kRtcpXrDlrrReportBlockCode:
    343             HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
    344             break;
    345         case RTCPUtility::kRtcpXrVoipMetricCode:
    346             HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
    347             break;
    348         case RTCPUtility::kRtcpByeCode:
    349             HandleBYE(*rtcpParser);
    350             break;
    351         case RTCPUtility::kRtcpRtpfbNackCode:
    352             HandleNACK(*rtcpParser, rtcpPacketInformation);
    353             break;
    354         case RTCPUtility::kRtcpRtpfbTmmbrCode:
    355             HandleTMMBR(*rtcpParser, rtcpPacketInformation);
    356             break;
    357         case RTCPUtility::kRtcpRtpfbTmmbnCode:
    358             HandleTMMBN(*rtcpParser, rtcpPacketInformation);
    359             break;
    360         case RTCPUtility::kRtcpRtpfbSrReqCode:
    361             HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
    362             break;
    363         case RTCPUtility::kRtcpPsfbPliCode:
    364             HandlePLI(*rtcpParser, rtcpPacketInformation);
    365             break;
    366         case RTCPUtility::kRtcpPsfbSliCode:
    367             HandleSLI(*rtcpParser, rtcpPacketInformation);
    368             break;
    369         case RTCPUtility::kRtcpPsfbRpsiCode:
    370             HandleRPSI(*rtcpParser, rtcpPacketInformation);
    371             break;
    372         case RTCPUtility::kRtcpExtendedIjCode:
    373             HandleIJ(*rtcpParser, rtcpPacketInformation);
    374             break;
    375         case RTCPUtility::kRtcpPsfbFirCode:
    376             HandleFIR(*rtcpParser, rtcpPacketInformation);
    377             break;
    378         case RTCPUtility::kRtcpPsfbAppCode:
    379             HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
    380             break;
    381         case RTCPUtility::kRtcpAppCode:
    382             // generic application messages
    383             HandleAPP(*rtcpParser, rtcpPacketInformation);
    384             break;
    385         case RTCPUtility::kRtcpAppItemCode:
    386             // generic application messages
    387             HandleAPPItem(*rtcpParser, rtcpPacketInformation);
    388             break;
    389         default:
    390             rtcpParser->Iterate();
    391             break;
    392         }
    393         pktType = rtcpParser->PacketType();
    394     }
    395     return 0;
    396 }
    397 
    398 // no need for critsect we have _criticalSectionRTCPReceiver
    399 void
    400 RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
    401                                          RTCPPacketInformation& rtcpPacketInformation)
    402 {
    403     RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
    404     const RTCPUtility::RTCPPacket& rtcpPacket   = rtcpParser.Packet();
    405 
    406     assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
    407 
    408     // SR.SenderSSRC
    409     // The synchronization source identifier for the originator of this SR packet
    410 
    411     // rtcpPacket.RR.SenderSSRC
    412     // The source of the packet sender, same as of SR? or is this a CE?
    413 
    414     const uint32_t remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
    415     const uint8_t  numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
    416 
    417     rtcpPacketInformation.remoteSSRC = remoteSSRC;
    418 
    419     RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
    420     if (!ptrReceiveInfo)
    421     {
    422         rtcpParser.Iterate();
    423         return;
    424     }
    425 
    426     if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
    427     {
    428         TRACE_EVENT_INSTANT2("webrtc_rtp", "SR",
    429                              "remote_ssrc", remoteSSRC,
    430                              "ssrc", main_ssrc_);
    431 
    432         if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
    433         {
    434             // only signal that we have received a SR when we accept one
    435             rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
    436 
    437             rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
    438             rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
    439             rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
    440 
    441             // We will only store the send report from one source, but
    442             // we will store all the receive block
    443 
    444             // Save the NTP time of this report
    445             _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
    446             _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
    447             _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
    448             _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
    449             _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
    450 
    451             _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
    452         }
    453         else
    454         {
    455             rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
    456         }
    457     } else
    458     {
    459         TRACE_EVENT_INSTANT2("webrtc_rtp", "RR",
    460                              "remote_ssrc", remoteSSRC,
    461                              "ssrc", main_ssrc_);
    462 
    463         rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
    464     }
    465     UpdateReceiveInformation(*ptrReceiveInfo);
    466 
    467     rtcpPacketType = rtcpParser.Iterate();
    468 
    469     while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
    470     {
    471         HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
    472         rtcpPacketType = rtcpParser.Iterate();
    473     }
    474 }
    475 
    476 // no need for critsect we have _criticalSectionRTCPReceiver
    477 void RTCPReceiver::HandleReportBlock(
    478     const RTCPUtility::RTCPPacket& rtcpPacket,
    479     RTCPPacketInformation& rtcpPacketInformation,
    480     const uint32_t remoteSSRC,
    481     const uint8_t numberOfReportBlocks)
    482     EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
    483   // This will be called once per report block in the RTCP packet.
    484   // We filter out all report blocks that are not for us.
    485   // Each packet has max 31 RR blocks.
    486   //
    487   // We can calc RTT if we send a send report and get a report block back.
    488 
    489   // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
    490   // which the information in this reception report block pertains.
    491 
    492   // Filter out all report blocks that are not for us.
    493   if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
    494       registered_ssrcs_.end()) {
    495     // This block is not for us ignore it.
    496     return;
    497   }
    498 
    499   // To avoid problem with acquiring _criticalSectionRTCPSender while holding
    500   // _criticalSectionRTCPReceiver.
    501   _criticalSectionRTCPReceiver->Leave();
    502   uint32_t sendTimeMS =
    503       _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
    504   _criticalSectionRTCPReceiver->Enter();
    505 
    506   RTCPReportBlockInformation* reportBlock =
    507       CreateReportBlockInformation(remoteSSRC);
    508   if (reportBlock == NULL) {
    509     LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
    510                     << remoteSSRC << ")";
    511     return;
    512   }
    513 
    514   _lastReceivedRrMs = _clock->TimeInMilliseconds();
    515   const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
    516   reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
    517   reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
    518   reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
    519   reportBlock->remoteReceiveBlock.cumulativeLost =
    520       rb.CumulativeNumOfPacketsLost;
    521   if (rb.ExtendedHighestSequenceNumber >
    522       reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
    523     // We have successfully delivered new RTP packets to the remote side after
    524     // the last RR was sent from the remote side.
    525     _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
    526   }
    527   reportBlock->remoteReceiveBlock.extendedHighSeqNum =
    528       rb.ExtendedHighestSequenceNumber;
    529   reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
    530   reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
    531   reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
    532 
    533   if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
    534     reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
    535   }
    536 
    537   uint32_t delaySinceLastSendReport =
    538       rtcpPacket.ReportBlockItem.DelayLastSR;
    539 
    540   // local NTP time when we received this
    541   uint32_t lastReceivedRRNTPsecs = 0;
    542   uint32_t lastReceivedRRNTPfrac = 0;
    543 
    544   _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
    545 
    546   // time when we received this in MS
    547   uint32_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
    548                                           lastReceivedRRNTPfrac);
    549 
    550   // Estimate RTT
    551   uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
    552   d /= 65536;
    553   d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
    554 
    555   int32_t RTT = 0;
    556 
    557   if (sendTimeMS > 0) {
    558     RTT = receiveTimeMS - d - sendTimeMS;
    559     if (RTT <= 0) {
    560       RTT = 1;
    561     }
    562     if (RTT > reportBlock->maxRTT) {
    563       // store max RTT
    564       reportBlock->maxRTT = (uint16_t) RTT;
    565     }
    566     if (reportBlock->minRTT == 0) {
    567       // first RTT
    568       reportBlock->minRTT = (uint16_t) RTT;
    569     } else if (RTT < reportBlock->minRTT) {
    570       // Store min RTT
    571       reportBlock->minRTT = (uint16_t) RTT;
    572     }
    573     // store last RTT
    574     reportBlock->RTT = (uint16_t) RTT;
    575 
    576     // store average RTT
    577     if (reportBlock->numAverageCalcs != 0) {
    578       float ac = static_cast<float> (reportBlock->numAverageCalcs);
    579       float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
    580           + ((1 / (ac + 1)) * RTT);
    581       reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
    582     } else {
    583       // first RTT
    584       reportBlock->avgRTT = (uint16_t) RTT;
    585     }
    586     reportBlock->numAverageCalcs++;
    587   }
    588 
    589   TRACE_COUNTER_ID1("webrtc_rtp", "RR_RTT", rb.SSRC, RTT);
    590 
    591   rtcpPacketInformation.AddReportInfo(*reportBlock);
    592 }
    593 
    594 RTCPReportBlockInformation*
    595 RTCPReceiver::CreateReportBlockInformation(uint32_t remoteSSRC) {
    596   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    597 
    598   std::map<uint32_t, RTCPReportBlockInformation*>::iterator it =
    599       _receivedReportBlockMap.find(remoteSSRC);
    600 
    601   RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
    602   if (it != _receivedReportBlockMap.end()) {
    603     ptrReportBlockInfo = it->second;
    604   } else {
    605     ptrReportBlockInfo = new RTCPReportBlockInformation;
    606     _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
    607   }
    608   return ptrReportBlockInfo;
    609 }
    610 
    611 RTCPReportBlockInformation*
    612 RTCPReceiver::GetReportBlockInformation(uint32_t remoteSSRC) const {
    613   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    614 
    615   std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
    616       _receivedReportBlockMap.find(remoteSSRC);
    617 
    618   if (it == _receivedReportBlockMap.end()) {
    619     return NULL;
    620   }
    621   return it->second;
    622 }
    623 
    624 RTCPCnameInformation*
    625 RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
    626   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    627 
    628   std::map<uint32_t, RTCPCnameInformation*>::iterator it =
    629       _receivedCnameMap.find(remoteSSRC);
    630 
    631   if (it != _receivedCnameMap.end()) {
    632     return it->second;
    633   }
    634   RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
    635   memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
    636   _receivedCnameMap[remoteSSRC] = cnameInfo;
    637   return cnameInfo;
    638 }
    639 
    640 RTCPCnameInformation*
    641 RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
    642   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    643 
    644   std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
    645       _receivedCnameMap.find(remoteSSRC);
    646 
    647   if (it == _receivedCnameMap.end()) {
    648     return NULL;
    649   }
    650   return it->second;
    651 }
    652 
    653 RTCPReceiveInformation*
    654 RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
    655   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    656 
    657   std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
    658       _receivedInfoMap.find(remoteSSRC);
    659 
    660   if (it != _receivedInfoMap.end()) {
    661     return it->second;
    662   }
    663   RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
    664   _receivedInfoMap[remoteSSRC] = receiveInfo;
    665   return receiveInfo;
    666 }
    667 
    668 RTCPReceiveInformation*
    669 RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
    670   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    671 
    672   std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
    673       _receivedInfoMap.find(remoteSSRC);
    674   if (it == _receivedInfoMap.end()) {
    675     return NULL;
    676   }
    677   return it->second;
    678 }
    679 
    680 void RTCPReceiver::UpdateReceiveInformation(
    681     RTCPReceiveInformation& receiveInformation) {
    682   // Update that this remote is alive
    683   receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
    684 }
    685 
    686 bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
    687   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    688   if (_lastReceivedRrMs == 0)
    689     return false;
    690 
    691   int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
    692   if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
    693     // Reset the timer to only trigger one log.
    694     _lastReceivedRrMs = 0;
    695     return true;
    696   }
    697   return false;
    698 }
    699 
    700 bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
    701   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    702   if (_lastIncreasedSequenceNumberMs == 0)
    703     return false;
    704 
    705   int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
    706   if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
    707       time_out_ms) {
    708     // Reset the timer to only trigger one log.
    709     _lastIncreasedSequenceNumberMs = 0;
    710     return true;
    711   }
    712   return false;
    713 }
    714 
    715 bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
    716   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    717 
    718   bool updateBoundingSet = false;
    719   int64_t timeNow = _clock->TimeInMilliseconds();
    720 
    721   std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
    722       _receivedInfoMap.begin();
    723 
    724   while (receiveInfoIt != _receivedInfoMap.end()) {
    725     RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
    726     if (receiveInfo == NULL) {
    727       return updateBoundingSet;
    728     }
    729     // time since last received rtcp packet
    730     // when we dont have a lastTimeReceived and the object is marked
    731     // readyForDelete it's removed from the map
    732     if (receiveInfo->lastTimeReceived) {
    733       /// use audio define since we don't know what interval the remote peer is
    734       // using
    735       if ((timeNow - receiveInfo->lastTimeReceived) >
    736           5 * RTCP_INTERVAL_AUDIO_MS) {
    737         // no rtcp packet for the last five regular intervals, reset limitations
    738         receiveInfo->TmmbrSet.clearSet();
    739         // prevent that we call this over and over again
    740         receiveInfo->lastTimeReceived = 0;
    741         // send new TMMBN to all channels using the default codec
    742         updateBoundingSet = true;
    743       }
    744       receiveInfoIt++;
    745     } else if (receiveInfo->readyForDelete) {
    746       // store our current receiveInfoItem
    747       std::map<uint32_t, RTCPReceiveInformation*>::iterator
    748       receiveInfoItemToBeErased = receiveInfoIt;
    749       receiveInfoIt++;
    750       delete receiveInfoItemToBeErased->second;
    751       _receivedInfoMap.erase(receiveInfoItemToBeErased);
    752     } else {
    753       receiveInfoIt++;
    754     }
    755   }
    756   return updateBoundingSet;
    757 }
    758 
    759 int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
    760   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    761 
    762   std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
    763       _receivedInfoMap.find(_remoteSSRC);
    764 
    765   if (receiveInfoIt == _receivedInfoMap.end()) {
    766     return -1;
    767   }
    768   RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
    769   if (receiveInfo == NULL) {
    770     return -1;
    771   }
    772   if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
    773     boundingSetRec->VerifyAndAllocateSet(
    774         receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
    775     for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
    776         i++) {
    777       if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
    778         // owner of bounding set
    779         tmmbrOwner = true;
    780       }
    781       boundingSetRec->SetEntry(i,
    782                                receiveInfo->TmmbnBoundingSet.Tmmbr(i),
    783                                receiveInfo->TmmbnBoundingSet.PacketOH(i),
    784                                receiveInfo->TmmbnBoundingSet.Ssrc(i));
    785     }
    786   }
    787   return receiveInfo->TmmbnBoundingSet.lengthOfSet();
    788 }
    789 
    790 // no need for critsect we have _criticalSectionRTCPReceiver
    791 void
    792 RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
    793 {
    794     RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
    795     while (pktType == RTCPUtility::kRtcpSdesChunkCode)
    796     {
    797         HandleSDESChunk(rtcpParser);
    798         pktType = rtcpParser.Iterate();
    799     }
    800 }
    801 
    802 // no need for critsect we have _criticalSectionRTCPReceiver
    803 void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
    804   const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
    805   RTCPCnameInformation* cnameInfo =
    806       CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
    807   assert(cnameInfo);
    808 
    809   cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
    810   strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
    811 }
    812 
    813 // no need for critsect we have _criticalSectionRTCPReceiver
    814 void
    815 RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
    816                          RTCPPacketInformation& rtcpPacketInformation)
    817 {
    818     const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
    819     if (main_ssrc_ != rtcpPacket.NACK.MediaSSRC)
    820     {
    821         // Not to us.
    822         rtcpParser.Iterate();
    823         return;
    824     }
    825     rtcpPacketInformation.ResetNACKPacketIdArray();
    826 
    827     RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
    828     while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
    829     {
    830         HandleNACKItem(rtcpPacket, rtcpPacketInformation);
    831         pktType = rtcpParser.Iterate();
    832     }
    833 
    834     if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
    835       ++packet_type_counter_.nack_packets;
    836     }
    837 }
    838 
    839 // no need for critsect we have _criticalSectionRTCPReceiver
    840 void
    841 RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
    842                              RTCPPacketInformation& rtcpPacketInformation)
    843 {
    844     rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
    845 
    846     uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
    847     if(bitMask)
    848     {
    849         for(int i=1; i <= 16; ++i)
    850         {
    851             if(bitMask & 0x01)
    852             {
    853                 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
    854             }
    855             bitMask = bitMask >>1;
    856         }
    857     }
    858 
    859     rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
    860 }
    861 
    862 // no need for critsect we have _criticalSectionRTCPReceiver
    863 void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
    864   const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
    865 
    866   // clear our lists
    867   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    868   std::map<uint32_t, RTCPReportBlockInformation*>::iterator
    869       reportBlockInfoIt = _receivedReportBlockMap.find(
    870           rtcpPacket.BYE.SenderSSRC);
    871 
    872   if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
    873     delete reportBlockInfoIt->second;
    874     _receivedReportBlockMap.erase(reportBlockInfoIt);
    875   }
    876   //  we can't delete it due to TMMBR
    877   std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
    878       _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
    879 
    880   if (receiveInfoIt != _receivedInfoMap.end()) {
    881     receiveInfoIt->second->readyForDelete = true;
    882   }
    883 
    884   std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
    885       _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
    886 
    887   if (cnameInfoIt != _receivedCnameMap.end()) {
    888     delete cnameInfoIt->second;
    889     _receivedCnameMap.erase(cnameInfoIt);
    890   }
    891   xr_rr_rtt_ms_ = 0;
    892   rtcpParser.Iterate();
    893 }
    894 
    895 void RTCPReceiver::HandleXrHeader(
    896     RTCPUtility::RTCPParserV2& parser,
    897     RTCPPacketInformation& rtcpPacketInformation) {
    898   const RTCPUtility::RTCPPacket& packet = parser.Packet();
    899 
    900   rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
    901 
    902   parser.Iterate();
    903 }
    904 
    905 void RTCPReceiver::HandleXrReceiveReferenceTime(
    906     RTCPUtility::RTCPParserV2& parser,
    907     RTCPPacketInformation& rtcpPacketInformation) {
    908   const RTCPUtility::RTCPPacket& packet = parser.Packet();
    909 
    910   _remoteXRReceiveTimeInfo.sourceSSRC =
    911       rtcpPacketInformation.xr_originator_ssrc;
    912 
    913   _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
    914       packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
    915       packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
    916 
    917   _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
    918 
    919   rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
    920 
    921   parser.Iterate();
    922 }
    923 
    924 void RTCPReceiver::HandleXrDlrrReportBlock(
    925     RTCPUtility::RTCPParserV2& parser,
    926     RTCPPacketInformation& rtcpPacketInformation) {
    927   const RTCPUtility::RTCPPacket& packet = parser.Packet();
    928   // Iterate through sub-block(s), if any.
    929   RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
    930 
    931   while (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) {
    932     HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
    933     packet_type = parser.Iterate();
    934   }
    935 }
    936 
    937 void RTCPReceiver::HandleXrDlrrReportBlockItem(
    938     const RTCPUtility::RTCPPacket& packet,
    939     RTCPPacketInformation& rtcpPacketInformation)
    940     EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
    941   if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
    942       registered_ssrcs_.end()) {
    943     // Not to us.
    944     return;
    945   }
    946 
    947   rtcpPacketInformation.xr_dlrr_item = true;
    948 
    949   // To avoid problem with acquiring _criticalSectionRTCPSender while holding
    950   // _criticalSectionRTCPReceiver.
    951   _criticalSectionRTCPReceiver->Leave();
    952 
    953   int64_t send_time_ms;
    954   bool found = _rtpRtcp.SendTimeOfXrRrReport(
    955       packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
    956 
    957   _criticalSectionRTCPReceiver->Enter();
    958 
    959   if (!found) {
    960     return;
    961   }
    962 
    963   // The DelayLastRR field is in units of 1/65536 sec.
    964   uint32_t delay_rr_ms =
    965       (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
    966       (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
    967 
    968   int32_t rtt = _clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
    969 
    970   xr_rr_rtt_ms_ = static_cast<uint16_t>(std::max(rtt, 1));
    971 
    972   rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
    973 }
    974 
    975 // no need for critsect we have _criticalSectionRTCPReceiver
    976 void
    977 RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
    978                                  RTCPPacketInformation& rtcpPacketInformation)
    979 {
    980     const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
    981 
    982     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
    983 
    984     if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
    985     {
    986         // Store VoIP metrics block if it's about me
    987         // from OriginatorSSRC do we filter it?
    988         // rtcpPacket.XR.OriginatorSSRC;
    989 
    990         RTCPVoIPMetric receivedVoIPMetrics;
    991         receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
    992         receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
    993         receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
    994         receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
    995         receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
    996         receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
    997         receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
    998         receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
    999         receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
   1000         receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
   1001         receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
   1002         receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
   1003         receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
   1004         receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
   1005         receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
   1006         receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
   1007         receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
   1008         receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
   1009         receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
   1010         receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
   1011 
   1012         rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
   1013 
   1014         rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
   1015     }
   1016     rtcpParser.Iterate();
   1017 }
   1018 
   1019 // no need for critsect we have _criticalSectionRTCPReceiver
   1020 void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
   1021                              RTCPPacketInformation& rtcpPacketInformation) {
   1022   const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1023   if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
   1024     TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
   1025 
   1026     ++packet_type_counter_.pli_packets;
   1027     // Received a signal that we need to send a new key frame.
   1028     rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
   1029   }
   1030   rtcpParser.Iterate();
   1031 }
   1032 
   1033 // no need for critsect we have _criticalSectionRTCPReceiver
   1034 void
   1035 RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
   1036                           RTCPPacketInformation& rtcpPacketInformation)
   1037 {
   1038     const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1039 
   1040     uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
   1041     RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
   1042     if (ptrReceiveInfo == NULL)
   1043     {
   1044         // This remote SSRC must be saved before.
   1045         rtcpParser.Iterate();
   1046         return;
   1047     }
   1048     if(rtcpPacket.TMMBR.MediaSSRC)
   1049     {
   1050         // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
   1051         // in relay mode this is a valid number
   1052         senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
   1053     }
   1054 
   1055     // Use packet length to calc max number of TMMBR blocks
   1056     // each TMMBR block is 8 bytes
   1057     ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
   1058 
   1059     // sanity
   1060     if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
   1061     {
   1062         assert(false);
   1063         rtcpParser.Iterate();
   1064         return;
   1065     }
   1066     ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
   1067 
   1068     RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
   1069     while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
   1070     {
   1071         HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
   1072         pktType = rtcpParser.Iterate();
   1073     }
   1074 }
   1075 
   1076 // no need for critsect we have _criticalSectionRTCPReceiver
   1077 void
   1078 RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
   1079                               const RTCPUtility::RTCPPacket& rtcpPacket,
   1080                               RTCPPacketInformation& rtcpPacketInformation,
   1081                               const uint32_t senderSSRC)
   1082 {
   1083     if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
   1084         rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
   1085     {
   1086         receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
   1087                                     _clock->TimeInMilliseconds());
   1088         rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
   1089     }
   1090 }
   1091 
   1092 // no need for critsect we have _criticalSectionRTCPReceiver
   1093 void
   1094 RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
   1095                           RTCPPacketInformation& rtcpPacketInformation)
   1096 {
   1097     const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1098     RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
   1099     if (ptrReceiveInfo == NULL)
   1100     {
   1101         // This remote SSRC must be saved before.
   1102         rtcpParser.Iterate();
   1103         return;
   1104     }
   1105     rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
   1106     // Use packet length to calc max number of TMMBN blocks
   1107     // each TMMBN block is 8 bytes
   1108     ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
   1109 
   1110     // sanity
   1111     if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
   1112     {
   1113         assert(false);
   1114         rtcpParser.Iterate();
   1115         return;
   1116     }
   1117 
   1118     ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
   1119 
   1120     RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
   1121     while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
   1122     {
   1123         HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
   1124         pktType = rtcpParser.Iterate();
   1125     }
   1126 }
   1127 
   1128 // no need for critsect we have _criticalSectionRTCPReceiver
   1129 void
   1130 RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
   1131                            RTCPPacketInformation& rtcpPacketInformation)
   1132 {
   1133     rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
   1134     rtcpParser.Iterate();
   1135 }
   1136 
   1137 // no need for critsect we have _criticalSectionRTCPReceiver
   1138 void
   1139 RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
   1140                               const RTCPUtility::RTCPPacket& rtcpPacket)
   1141 {
   1142     receiveInfo.TmmbnBoundingSet.AddEntry(
   1143         rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
   1144         rtcpPacket.TMMBNItem.MeasuredOverhead,
   1145         rtcpPacket.TMMBNItem.SSRC);
   1146 }
   1147 
   1148 // no need for critsect we have _criticalSectionRTCPReceiver
   1149 void
   1150 RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
   1151                         RTCPPacketInformation& rtcpPacketInformation)
   1152 {
   1153     const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1154     RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
   1155     while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
   1156     {
   1157         HandleSLIItem(rtcpPacket, rtcpPacketInformation);
   1158         pktType = rtcpParser.Iterate();
   1159     }
   1160 }
   1161 
   1162 // no need for critsect we have _criticalSectionRTCPReceiver
   1163 void
   1164 RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
   1165                             RTCPPacketInformation& rtcpPacketInformation)
   1166 {
   1167     // in theory there could be multiple slices lost
   1168     rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
   1169     rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
   1170 }
   1171 
   1172 void
   1173 RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
   1174                          RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
   1175 {
   1176     const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1177     RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
   1178     if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
   1179     {
   1180         rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
   1181         if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
   1182         {
   1183             // to us unknown
   1184             // continue
   1185             rtcpParser.Iterate();
   1186             return;
   1187         }
   1188         rtcpPacketInformation.rpsiPictureId = 0;
   1189 
   1190         // convert NativeBitString to rpsiPictureId
   1191         uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
   1192         for(uint8_t n = 0; n < (numberOfBytes-1); n++)
   1193         {
   1194             rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
   1195             rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
   1196         }
   1197         rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
   1198     }
   1199 }
   1200 
   1201 // no need for critsect we have _criticalSectionRTCPReceiver
   1202 void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
   1203                                  RTCPPacketInformation& rtcpPacketInformation) {
   1204   RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
   1205   if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
   1206     pktType = rtcpParser.Iterate();
   1207     if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
   1208       HandleREMBItem(rtcpParser, rtcpPacketInformation);
   1209       rtcpParser.Iterate();
   1210     }
   1211   }
   1212 }
   1213 
   1214 // no need for critsect we have _criticalSectionRTCPReceiver
   1215 void
   1216 RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
   1217                        RTCPPacketInformation& rtcpPacketInformation)
   1218 {
   1219     const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1220 
   1221     RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
   1222     while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
   1223     {
   1224         HandleIJItem(rtcpPacket, rtcpPacketInformation);
   1225         pktType = rtcpParser.Iterate();
   1226     }
   1227 }
   1228 
   1229 void
   1230 RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
   1231                            RTCPPacketInformation& rtcpPacketInformation)
   1232 {
   1233     rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
   1234     rtcpPacketInformation.interArrivalJitter =
   1235     rtcpPacket.ExtendedJitterReportItem.Jitter;
   1236 }
   1237 
   1238 void RTCPReceiver::HandleREMBItem(
   1239     RTCPUtility::RTCPParserV2& rtcpParser,
   1240     RTCPPacketInformation& rtcpPacketInformation) {
   1241   const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1242   rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
   1243   rtcpPacketInformation.receiverEstimatedMaxBitrate =
   1244       rtcpPacket.REMBItem.BitRate;
   1245 }
   1246 
   1247 // no need for critsect we have _criticalSectionRTCPReceiver
   1248 void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
   1249                              RTCPPacketInformation& rtcpPacketInformation) {
   1250   const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1251   RTCPReceiveInformation* ptrReceiveInfo =
   1252       GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
   1253 
   1254   RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
   1255   while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
   1256     HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
   1257     pktType = rtcpParser.Iterate();
   1258   }
   1259 }
   1260 
   1261 // no need for critsect we have _criticalSectionRTCPReceiver
   1262 void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
   1263                                  const RTCPUtility::RTCPPacket& rtcpPacket,
   1264                                  RTCPPacketInformation& rtcpPacketInformation) {
   1265   // Is it our sender that is requested to generate a new keyframe
   1266   if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
   1267     return;
   1268   }
   1269 
   1270   ++packet_type_counter_.fir_packets;
   1271 
   1272   // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
   1273   // we don't know who this originate from
   1274   if (receiveInfo) {
   1275     // check if we have reported this FIRSequenceNumber before
   1276     if (rtcpPacket.FIRItem.CommandSequenceNumber !=
   1277         receiveInfo->lastFIRSequenceNumber) {
   1278       int64_t now = _clock->TimeInMilliseconds();
   1279       // sanity; don't go crazy with the callbacks
   1280       if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
   1281         receiveInfo->lastFIRRequest = now;
   1282         receiveInfo->lastFIRSequenceNumber =
   1283             rtcpPacket.FIRItem.CommandSequenceNumber;
   1284         // received signal that we need to send a new key frame
   1285         rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
   1286       }
   1287     }
   1288   } else {
   1289     // received signal that we need to send a new key frame
   1290     rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
   1291   }
   1292 }
   1293 
   1294 void
   1295 RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
   1296                         RTCPPacketInformation& rtcpPacketInformation)
   1297 {
   1298     const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1299 
   1300     rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
   1301     rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
   1302     rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
   1303 
   1304     rtcpParser.Iterate();
   1305 }
   1306 
   1307 void
   1308 RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
   1309                            RTCPPacketInformation& rtcpPacketInformation)
   1310 {
   1311     const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
   1312 
   1313     rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
   1314 
   1315     rtcpParser.Iterate();
   1316 }
   1317 
   1318 int32_t RTCPReceiver::UpdateTMMBR() {
   1319   int32_t numBoundingSet = 0;
   1320   uint32_t bitrate = 0;
   1321   uint32_t accNumCandidates = 0;
   1322 
   1323   int32_t size = TMMBRReceived(0, 0, NULL);
   1324   if (size > 0) {
   1325     TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
   1326     // Get candidate set from receiver.
   1327     accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
   1328   } else {
   1329     // Candidate set empty.
   1330     VerifyAndAllocateCandidateSet(0);  // resets candidate set
   1331   }
   1332   // Find bounding set
   1333   TMMBRSet* boundingSet = NULL;
   1334   numBoundingSet = FindTMMBRBoundingSet(boundingSet);
   1335   if (numBoundingSet == -1) {
   1336     LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
   1337     return -1;
   1338   }
   1339   // Set bounding set
   1340   // Inform remote clients about the new bandwidth
   1341   // inform the remote client
   1342   _rtpRtcp.SetTMMBN(boundingSet);
   1343 
   1344   // might trigger a TMMBN
   1345   if (numBoundingSet == 0) {
   1346     // owner of max bitrate request has timed out
   1347     // empty bounding set has been sent
   1348     return 0;
   1349   }
   1350   // Get net bitrate from bounding set depending on sent packet rate
   1351   if (CalcMinBitRate(&bitrate)) {
   1352     // we have a new bandwidth estimate on this channel
   1353     CriticalSectionScoped lock(_criticalSectionFeedbacks);
   1354     if (_cbRtcpBandwidthObserver) {
   1355         _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
   1356     }
   1357   }
   1358   return 0;
   1359 }
   1360 
   1361 void RTCPReceiver::RegisterRtcpStatisticsCallback(
   1362     RtcpStatisticsCallback* callback) {
   1363   CriticalSectionScoped cs(_criticalSectionFeedbacks);
   1364   if (callback != NULL)
   1365     assert(stats_callback_ == NULL);
   1366   stats_callback_ = callback;
   1367 }
   1368 
   1369 RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
   1370   CriticalSectionScoped cs(_criticalSectionFeedbacks);
   1371   return stats_callback_;
   1372 }
   1373 
   1374 // Holding no Critical section
   1375 void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
   1376     RTCPPacketInformation& rtcpPacketInformation) {
   1377   // Process TMMBR and REMB first to avoid multiple callbacks
   1378   // to OnNetworkChanged.
   1379   if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
   1380     // Might trigger a OnReceivedBandwidthEstimateUpdate.
   1381     UpdateTMMBR();
   1382   }
   1383   unsigned int local_ssrc = 0;
   1384   {
   1385     // We don't want to hold this critsect when triggering the callbacks below.
   1386     CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
   1387     local_ssrc = main_ssrc_;
   1388   }
   1389   if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
   1390     _rtpRtcp.OnRequestSendReport();
   1391   }
   1392   if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
   1393     if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
   1394       LOG(LS_VERBOSE) << "Incoming NACK length: "
   1395                    << rtcpPacketInformation.nackSequenceNumbers.size();
   1396       _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
   1397     }
   1398   }
   1399   {
   1400     CriticalSectionScoped lock(_criticalSectionFeedbacks);
   1401 
   1402     // We need feedback that we have received a report block(s) so that we
   1403     // can generate a new packet in a conference relay scenario, one received
   1404     // report can generate several RTCP packets, based on number relayed/mixed
   1405     // a send report block should go out to all receivers.
   1406     if (_cbRtcpIntraFrameObserver) {
   1407       if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
   1408           (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
   1409         if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
   1410           LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
   1411                        << rtcpPacketInformation.remoteSSRC;
   1412         } else {
   1413           LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
   1414                        << rtcpPacketInformation.remoteSSRC;
   1415         }
   1416         _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
   1417       }
   1418       if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
   1419         _cbRtcpIntraFrameObserver->OnReceivedSLI(
   1420             local_ssrc, rtcpPacketInformation.sliPictureId);
   1421       }
   1422       if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
   1423         _cbRtcpIntraFrameObserver->OnReceivedRPSI(
   1424             local_ssrc, rtcpPacketInformation.rpsiPictureId);
   1425       }
   1426     }
   1427     if (_cbRtcpBandwidthObserver) {
   1428       if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
   1429         LOG(LS_VERBOSE) << "Incoming REMB: "
   1430                      << rtcpPacketInformation.receiverEstimatedMaxBitrate;
   1431         _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
   1432             rtcpPacketInformation.receiverEstimatedMaxBitrate);
   1433       }
   1434       if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
   1435           rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) {
   1436         int64_t now = _clock->TimeInMilliseconds();
   1437         _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
   1438             rtcpPacketInformation.report_blocks,
   1439             rtcpPacketInformation.rtt,
   1440             now);
   1441       }
   1442     }
   1443     if(_cbRtcpFeedback) {
   1444       if(!(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)) {
   1445         _cbRtcpFeedback->OnReceiveReportReceived(_id,
   1446             rtcpPacketInformation.remoteSSRC);
   1447       }
   1448       if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
   1449         _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
   1450             rtcpPacketInformation.VoIPMetric);
   1451       }
   1452       if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
   1453         _cbRtcpFeedback->OnApplicationDataReceived(_id,
   1454             rtcpPacketInformation.applicationSubType,
   1455             rtcpPacketInformation.applicationName,
   1456             rtcpPacketInformation.applicationLength,
   1457             rtcpPacketInformation.applicationData);
   1458       }
   1459     }
   1460   }
   1461 
   1462   {
   1463     CriticalSectionScoped cs(_criticalSectionFeedbacks);
   1464     if (stats_callback_) {
   1465       for (ReportBlockList::const_iterator it =
   1466           rtcpPacketInformation.report_blocks.begin();
   1467           it != rtcpPacketInformation.report_blocks.end();
   1468           ++it) {
   1469         RtcpStatistics stats;
   1470         stats.cumulative_lost = it->cumulativeLost;
   1471         stats.extended_max_sequence_number = it->extendedHighSeqNum;
   1472         stats.fraction_lost = it->fractionLost;
   1473         stats.jitter = it->jitter;
   1474 
   1475         stats_callback_->StatisticsUpdated(stats, local_ssrc);
   1476       }
   1477     }
   1478   }
   1479 }
   1480 
   1481 int32_t RTCPReceiver::CNAME(const uint32_t remoteSSRC,
   1482                             char cName[RTCP_CNAME_SIZE]) const {
   1483   assert(cName);
   1484 
   1485   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
   1486   RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
   1487   if (cnameInfo == NULL) {
   1488     return -1;
   1489   }
   1490   cName[RTCP_CNAME_SIZE - 1] = 0;
   1491   strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
   1492   return 0;
   1493 }
   1494 
   1495 // no callbacks allowed inside this function
   1496 int32_t RTCPReceiver::TMMBRReceived(const uint32_t size,
   1497                                     const uint32_t accNumCandidates,
   1498                                     TMMBRSet* candidateSet) const {
   1499   CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
   1500 
   1501   std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
   1502       receiveInfoIt = _receivedInfoMap.begin();
   1503   if (receiveInfoIt == _receivedInfoMap.end()) {
   1504     return -1;
   1505   }
   1506   uint32_t num = accNumCandidates;
   1507   if (candidateSet) {
   1508     while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
   1509       RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
   1510       if (receiveInfo == NULL) {
   1511         return 0;
   1512       }
   1513       for (uint32_t i = 0;
   1514            (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
   1515         if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
   1516                                      _clock->TimeInMilliseconds()) == 0) {
   1517           num++;
   1518         }
   1519       }
   1520       receiveInfoIt++;
   1521     }
   1522   } else {
   1523     while (receiveInfoIt != _receivedInfoMap.end()) {
   1524       RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
   1525       if(receiveInfo == NULL) {
   1526         return -1;
   1527       }
   1528       num += receiveInfo->TmmbrSet.lengthOfSet();
   1529       receiveInfoIt++;
   1530     }
   1531   }
   1532   return num;
   1533 }
   1534 
   1535 }  // namespace webrtc
   1536