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

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
      12             : 
      13             : #include <assert.h>
      14             : #include <math.h>   // ceil
      15             : #include <string.h> // memcpy
      16             : 
      17             : #include <limits>
      18             : 
      19             : #include "webrtc/base/checks.h"
      20             : #include "webrtc/base/logging.h"
      21             : #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
      22             : #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
      23             : 
      24             : namespace webrtc {
      25             : namespace {
      26             : constexpr uint64_t kMaxBitrateBps = std::numeric_limits<uint32_t>::max();
      27             : }  // namespace
      28             : 
      29             : namespace RTCPUtility {
      30             : 
      31           0 : NackStats::NackStats()
      32             :     : max_sequence_number_(0),
      33             :       requests_(0),
      34           0 :       unique_requests_(0) {}
      35             : 
      36           0 : NackStats::~NackStats() {}
      37             : 
      38           0 : void NackStats::ReportRequest(uint16_t sequence_number) {
      39           0 :   if (requests_ == 0 ||
      40           0 :       webrtc::IsNewerSequenceNumber(sequence_number, max_sequence_number_)) {
      41           0 :     max_sequence_number_ =  sequence_number;
      42           0 :     ++unique_requests_;
      43             :   }
      44           0 :   ++requests_;
      45           0 : }
      46             : 
      47           0 : uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac) {
      48           0 :   return (ntp_sec << 16) + (ntp_frac >> 16);
      49             : }
      50             : }  // namespace RTCPUtility
      51             : 
      52             : // RTCPParserV2 : currently read only
      53           0 : RTCPUtility::RTCPParserV2::RTCPParserV2(const uint8_t* rtcpData,
      54             :                                         size_t rtcpDataLength,
      55           0 :                                         bool rtcpReducedSizeEnable)
      56             :     : _ptrRTCPDataBegin(rtcpData),
      57             :       _RTCPReducedSizeEnable(rtcpReducedSizeEnable),
      58           0 :       _ptrRTCPDataEnd(rtcpData + rtcpDataLength),
      59             :       _validPacket(false),
      60             :       _ptrRTCPData(rtcpData),
      61             :       _ptrRTCPBlockEnd(NULL),
      62             :       _state(ParseState::State_TopLevel),
      63             :       _numberOfBlocks(0),
      64             :       num_skipped_blocks_(0),
      65           0 :       _packetType(RTCPPacketTypes::kInvalid) {
      66           0 :   Validate();
      67           0 : }
      68             : 
      69           0 : RTCPUtility::RTCPParserV2::~RTCPParserV2() {
      70           0 : }
      71             : 
      72             : ptrdiff_t
      73           0 : RTCPUtility::RTCPParserV2::LengthLeft() const
      74             : {
      75           0 :     return (_ptrRTCPDataEnd- _ptrRTCPData);
      76             : }
      77             : 
      78             : RTCPUtility::RTCPPacketTypes
      79           0 : RTCPUtility::RTCPParserV2::PacketType() const
      80             : {
      81           0 :     return _packetType;
      82             : }
      83             : 
      84             : const RTCPUtility::RTCPPacket&
      85           0 : RTCPUtility::RTCPParserV2::Packet() const
      86             : {
      87           0 :     return _packet;
      88             : }
      89             : 
      90           0 : rtcp::RtcpPacket* RTCPUtility::RTCPParserV2::ReleaseRtcpPacket() {
      91           0 :   return rtcp_packet_.release();
      92             : }
      93             : RTCPUtility::RTCPPacketTypes
      94           0 : RTCPUtility::RTCPParserV2::Begin()
      95             : {
      96           0 :     _ptrRTCPData = _ptrRTCPDataBegin;
      97             : 
      98           0 :     return Iterate();
      99             : }
     100             : 
     101             : RTCPUtility::RTCPPacketTypes
     102           0 : RTCPUtility::RTCPParserV2::Iterate()
     103             : {
     104             :     // Reset packet type
     105           0 :   _packetType = RTCPPacketTypes::kInvalid;
     106             : 
     107           0 :     if (IsValid())
     108             :     {
     109           0 :         switch (_state)
     110             :         {
     111             :           case ParseState::State_TopLevel:
     112           0 :             IterateTopLevel();
     113           0 :             break;
     114             :           case ParseState::State_ReportBlockItem:
     115           0 :             IterateReportBlockItem();
     116           0 :             break;
     117             :           case ParseState::State_SDESChunk:
     118           0 :             IterateSDESChunk();
     119           0 :             break;
     120             :           case ParseState::State_BYEItem:
     121           0 :             IterateBYEItem();
     122           0 :             break;
     123             :           case ParseState::State_ExtendedJitterItem:
     124           0 :             IterateExtendedJitterItem();
     125           0 :             break;
     126             :           case ParseState::State_RTPFB_NACKItem:
     127           0 :             IterateNACKItem();
     128           0 :             break;
     129             :           case ParseState::State_RTPFB_TMMBRItem:
     130           0 :             IterateTMMBRItem();
     131           0 :             break;
     132             :           case ParseState::State_RTPFB_TMMBNItem:
     133           0 :             IterateTMMBNItem();
     134           0 :             break;
     135             :           case ParseState::State_PSFB_SLIItem:
     136           0 :             IterateSLIItem();
     137           0 :             break;
     138             :           case ParseState::State_PSFB_RPSIItem:
     139           0 :             IterateRPSIItem();
     140           0 :             break;
     141             :           case ParseState::State_PSFB_FIRItem:
     142           0 :             IterateFIRItem();
     143           0 :             break;
     144             :           case ParseState::State_PSFB_AppItem:
     145           0 :             IteratePsfbAppItem();
     146           0 :             break;
     147             :           case ParseState::State_PSFB_REMBItem:
     148           0 :             IteratePsfbREMBItem();
     149           0 :             break;
     150             :           case ParseState::State_XRItem:
     151           0 :             IterateXrItem();
     152           0 :             break;
     153             :           case ParseState::State_XR_DLLRItem:
     154           0 :             IterateXrDlrrItem();
     155           0 :             break;
     156             :           case ParseState::State_AppItem:
     157           0 :             IterateAppItem();
     158           0 :             break;
     159             :         default:
     160           0 :           RTC_NOTREACHED() << "Invalid state!";
     161           0 :             break;
     162             :         }
     163             :     }
     164           0 :     return _packetType;
     165             : }
     166             : 
     167             : void
     168           0 : RTCPUtility::RTCPParserV2::IterateTopLevel()
     169             : {
     170             :     for (;;)
     171             :     {
     172           0 :       RtcpCommonHeader header;
     173           0 :       if (_ptrRTCPDataEnd <= _ptrRTCPData)
     174           0 :         return;
     175             : 
     176           0 :       if (!RtcpParseCommonHeader(_ptrRTCPData, _ptrRTCPDataEnd - _ptrRTCPData,
     177             :                                  &header)) {
     178           0 :             return;
     179             :         }
     180           0 :         _ptrRTCPBlockEnd = _ptrRTCPData + header.BlockSize();
     181           0 :         if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd)
     182             :         {
     183           0 :           ++num_skipped_blocks_;
     184           0 :             return;
     185             :         }
     186             : 
     187           0 :         switch (header.packet_type) {
     188             :         case PT_SR:
     189             :         {
     190             :             // number of Report blocks
     191           0 :             _numberOfBlocks = header.count_or_format;
     192           0 :             ParseSR();
     193           0 :             return;
     194             :         }
     195             :         case PT_RR:
     196             :         {
     197             :             // number of Report blocks
     198           0 :             _numberOfBlocks = header.count_or_format;
     199           0 :             ParseRR();
     200           0 :             return;
     201             :         }
     202             :         case PT_SDES:
     203             :         {
     204             :             // number of SDES blocks
     205           0 :             _numberOfBlocks = header.count_or_format;
     206           0 :             const bool ok = ParseSDES();
     207           0 :             if (!ok)
     208             :             {
     209             :                 // Nothing supported found, continue to next block!
     210           0 :                 break;
     211             :             }
     212           0 :             return;
     213             :         }
     214             :         case PT_BYE:
     215             :         {
     216           0 :           _numberOfBlocks = header.count_or_format;
     217           0 :             const bool ok = ParseBYE();
     218           0 :             if (!ok)
     219             :             {
     220             :                 // Nothing supported found, continue to next block!
     221           0 :                 break;
     222             :             }
     223           0 :             return;
     224             :         }
     225             :         case PT_IJ:
     226             :         {
     227             :             // number of Report blocks
     228           0 :             _numberOfBlocks = header.count_or_format;
     229           0 :             ParseIJ();
     230           0 :             return;
     231             :         }
     232             :         case PT_RTPFB:
     233             :           FALLTHROUGH();
     234             :         case PT_PSFB:
     235             :         {
     236           0 :           if (!ParseFBCommon(header)) {
     237             :             // Nothing supported found, continue to next block!
     238           0 :             EndCurrentBlock();
     239           0 :             break;
     240             :           }
     241           0 :           return;
     242             :         }
     243             :         case PT_APP:
     244             :         {
     245           0 :             const bool ok = ParseAPP(header);
     246           0 :             if (!ok)
     247             :             {
     248             :                 // Nothing supported found, continue to next block!
     249           0 :                 break;
     250             :             }
     251           0 :             return;
     252             :         }
     253             :         case PT_XR:
     254             :         {
     255           0 :             const bool ok = ParseXr();
     256           0 :             if (!ok)
     257             :             {
     258             :                 // Nothing supported found, continue to next block!
     259           0 :                 break;
     260             :             }
     261           0 :             return;
     262             :         }
     263             :         default:
     264             :             // Not supported! Skip!
     265           0 :             ++num_skipped_blocks_;
     266           0 :             EndCurrentBlock();
     267           0 :             break;
     268             :         }
     269           0 :     }
     270             : }
     271             : 
     272             : void
     273           0 : RTCPUtility::RTCPParserV2::IterateXrItem()
     274             : {
     275           0 :     const bool success = ParseXrItem();
     276           0 :     if (!success)
     277             :     {
     278           0 :         Iterate();
     279             :     }
     280           0 : }
     281             : 
     282             : void
     283           0 : RTCPUtility::RTCPParserV2::IterateXrDlrrItem()
     284             : {
     285           0 :     const bool success = ParseXrDlrrItem();
     286           0 :     if (!success)
     287             :     {
     288           0 :         Iterate();
     289             :     }
     290           0 : }
     291             : 
     292             : void
     293           0 : RTCPUtility::RTCPParserV2::IterateReportBlockItem()
     294             : {
     295           0 :     const bool success = ParseReportBlockItem();
     296           0 :     if (!success)
     297             :     {
     298           0 :         Iterate();
     299             :     }
     300           0 : }
     301             : 
     302             : void
     303           0 : RTCPUtility::RTCPParserV2::IterateSDESChunk()
     304             : {
     305           0 :     const bool success = ParseSDESChunk();
     306           0 :     if (!success)
     307             :     {
     308           0 :         Iterate();
     309             :     }
     310           0 : }
     311             : 
     312             : void
     313           0 : RTCPUtility::RTCPParserV2::IterateBYEItem()
     314             : {
     315           0 :     const bool success = ParseBYEItem();
     316           0 :     if (!success)
     317             :     {
     318           0 :         Iterate();
     319             :     }
     320           0 : }
     321             : 
     322             : void
     323           0 : RTCPUtility::RTCPParserV2::IterateExtendedJitterItem()
     324             : {
     325           0 :     const bool success = ParseIJItem();
     326           0 :     if (!success)
     327             :     {
     328           0 :         Iterate();
     329             :     }
     330           0 : }
     331             : 
     332             : void
     333           0 : RTCPUtility::RTCPParserV2::IterateNACKItem()
     334             : {
     335           0 :     const bool success = ParseNACKItem();
     336           0 :     if (!success)
     337             :     {
     338           0 :         Iterate();
     339             :     }
     340           0 : }
     341             : 
     342             : void
     343           0 : RTCPUtility::RTCPParserV2::IterateTMMBRItem()
     344             : {
     345           0 :     const bool success = ParseTMMBRItem();
     346           0 :     if (!success)
     347             :     {
     348           0 :         Iterate();
     349             :     }
     350           0 : }
     351             : 
     352             : void
     353           0 : RTCPUtility::RTCPParserV2::IterateTMMBNItem()
     354             : {
     355           0 :     const bool success = ParseTMMBNItem();
     356           0 :     if (!success)
     357             :     {
     358           0 :         Iterate();
     359             :     }
     360           0 : }
     361             : 
     362             : void
     363           0 : RTCPUtility::RTCPParserV2::IterateSLIItem()
     364             : {
     365           0 :     const bool success = ParseSLIItem();
     366           0 :     if (!success)
     367             :     {
     368           0 :         Iterate();
     369             :     }
     370           0 : }
     371             : 
     372             : void
     373           0 : RTCPUtility::RTCPParserV2::IterateRPSIItem()
     374             : {
     375           0 :     const bool success = ParseRPSIItem();
     376           0 :     if (!success)
     377             :     {
     378           0 :         Iterate();
     379             :     }
     380           0 : }
     381             : 
     382             : void
     383           0 : RTCPUtility::RTCPParserV2::IterateFIRItem()
     384             : {
     385           0 :     const bool success = ParseFIRItem();
     386           0 :     if (!success)
     387             :     {
     388           0 :         Iterate();
     389             :     }
     390           0 : }
     391             : 
     392             : void
     393           0 : RTCPUtility::RTCPParserV2::IteratePsfbAppItem()
     394             : {
     395           0 :     const bool success = ParsePsfbAppItem();
     396           0 :     if (!success)
     397             :     {
     398           0 :         Iterate();
     399             :     }
     400           0 : }
     401             : 
     402             : void
     403           0 : RTCPUtility::RTCPParserV2::IteratePsfbREMBItem()
     404             : {
     405           0 :     const bool success = ParsePsfbREMBItem();
     406           0 :     if (!success)
     407             :     {
     408           0 :         Iterate();
     409             :     }
     410           0 : }
     411             : 
     412             : void
     413           0 : RTCPUtility::RTCPParserV2::IterateAppItem()
     414             : {
     415           0 :     const bool success = ParseAPPItem();
     416           0 :     if (!success)
     417             :     {
     418           0 :         Iterate();
     419             :     }
     420           0 : }
     421             : 
     422             : void
     423           0 : RTCPUtility::RTCPParserV2::Validate()
     424             : {
     425           0 :   if (_ptrRTCPData == nullptr)
     426           0 :     return;  // NOT VALID
     427             : 
     428           0 :   RtcpCommonHeader header;
     429           0 :   if (_ptrRTCPDataEnd <= _ptrRTCPDataBegin)
     430           0 :     return;  // NOT VALID
     431             : 
     432           0 :   if (!RtcpParseCommonHeader(_ptrRTCPDataBegin,
     433           0 :                              _ptrRTCPDataEnd - _ptrRTCPDataBegin, &header))
     434           0 :     return;  // NOT VALID!
     435             : 
     436             :   // * if (!reducedSize) : first packet must be RR or SR.
     437             :   //
     438             :   // * The padding bit (P) should be zero for the first packet of a
     439             :   //   compound RTCP packet because padding should only be applied,
     440             :   //   if it is needed, to the last packet. (NOT CHECKED!)
     441             :   //
     442             :   // * The length fields of the individual RTCP packets must add up
     443             :   //   to the overall length of the compound RTCP packet as
     444             :   //   received.  This is a fairly strong check. (NOT CHECKED!)
     445             : 
     446           0 :   if (!_RTCPReducedSizeEnable) {
     447           0 :     if ((header.packet_type != PT_SR) && (header.packet_type != PT_RR))
     448           0 :       return;  // NOT VALID
     449             :   }
     450             : 
     451           0 :   _validPacket = true;
     452             : }
     453             : 
     454             : bool
     455           0 : RTCPUtility::RTCPParserV2::IsValid() const
     456             : {
     457           0 :     return _validPacket;
     458             : }
     459             : 
     460             : void
     461           0 : RTCPUtility::RTCPParserV2::EndCurrentBlock()
     462             : {
     463           0 :     _ptrRTCPData = _ptrRTCPBlockEnd;
     464           0 : }
     465             : 
     466             : //  0                   1                   2                   3
     467             : //  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
     468             : // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     469             : // |V=2|P|    IC   |      PT       |             length            |
     470             : // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     471             : //
     472             : // Common header for all RTCP packets, 4 octets.
     473             : 
     474           0 : bool RTCPUtility::RtcpParseCommonHeader(const uint8_t* packet,
     475             :                                         size_t size_bytes,
     476             :                                         RtcpCommonHeader* parsed_header) {
     477           0 :   RTC_DCHECK(parsed_header != nullptr);
     478           0 :   if (size_bytes < RtcpCommonHeader::kHeaderSizeBytes) {
     479           0 :     LOG(LS_WARNING) << "Too little data (" << size_bytes << " byte"
     480             :                     << (size_bytes != 1 ? "s" : "")
     481           0 :                     << ") remaining in buffer to parse RTCP header (4 bytes).";
     482           0 :     return false;
     483             :   }
     484             : 
     485           0 :   const uint8_t kRtcpVersion = 2;
     486           0 :   uint8_t version = packet[0] >> 6;
     487           0 :   if (version != kRtcpVersion) {
     488           0 :     LOG(LS_WARNING) << "Invalid RTCP header: Version must be "
     489           0 :                     << static_cast<int>(kRtcpVersion) << " but was "
     490           0 :                     << static_cast<int>(version);
     491           0 :     return false;
     492             :   }
     493             : 
     494           0 :   bool has_padding = (packet[0] & 0x20) != 0;
     495           0 :   uint8_t format = packet[0] & 0x1F;
     496           0 :   uint8_t packet_type = packet[1];
     497             :   size_t packet_size_words =
     498           0 :       ByteReader<uint16_t>::ReadBigEndian(&packet[2]) + 1;
     499             : 
     500           0 :   if (size_bytes < packet_size_words * 4) {
     501           0 :     LOG(LS_WARNING) << "Buffer too small (" << size_bytes
     502           0 :                     << " bytes) to fit an RtcpPacket of " << packet_size_words
     503           0 :                     << " 32bit words.";
     504           0 :     return false;
     505             :   }
     506             : 
     507           0 :   size_t payload_size = packet_size_words * 4;
     508           0 :   size_t padding_bytes = 0;
     509           0 :   if (has_padding) {
     510           0 :     if (payload_size <= RtcpCommonHeader::kHeaderSizeBytes) {
     511           0 :       LOG(LS_WARNING) << "Invalid RTCP header: Padding bit set but 0 payload "
     512           0 :                          "size specified.";
     513           0 :       return false;
     514             :     }
     515             : 
     516           0 :     padding_bytes = packet[payload_size - 1];
     517           0 :     if (RtcpCommonHeader::kHeaderSizeBytes + padding_bytes > payload_size) {
     518           0 :       LOG(LS_WARNING) << "Invalid RTCP header: Too many padding bytes ("
     519           0 :                       << padding_bytes << ") for a packet size of "
     520           0 :                       << payload_size << "bytes.";
     521           0 :       return false;
     522             :     }
     523           0 :     payload_size -= padding_bytes;
     524             :   }
     525           0 :   payload_size -= RtcpCommonHeader::kHeaderSizeBytes;
     526             : 
     527           0 :   parsed_header->version = kRtcpVersion;
     528           0 :   parsed_header->count_or_format = format;
     529           0 :   parsed_header->packet_type = packet_type;
     530           0 :   parsed_header->payload_size_bytes = payload_size;
     531           0 :   parsed_header->padding_bytes = padding_bytes;
     532             : 
     533           0 :   return true;
     534             : }
     535             : 
     536             : bool
     537           0 : RTCPUtility::RTCPParserV2::ParseRR()
     538             : {
     539           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     540             : 
     541           0 :     if (length < 8)
     542             :     {
     543           0 :         return false;
     544             :     }
     545             : 
     546             : 
     547           0 :     _ptrRTCPData += 4; // Skip header
     548             : 
     549           0 :     _packetType = RTCPPacketTypes::kRr;
     550             : 
     551           0 :     _packet.RR.SenderSSRC = *_ptrRTCPData++ << 24;
     552           0 :     _packet.RR.SenderSSRC += *_ptrRTCPData++ << 16;
     553           0 :     _packet.RR.SenderSSRC += *_ptrRTCPData++ << 8;
     554           0 :     _packet.RR.SenderSSRC += *_ptrRTCPData++;
     555             : 
     556           0 :     _packet.RR.NumberOfReportBlocks = _numberOfBlocks;
     557             : 
     558             :     // State transition
     559           0 :     _state = ParseState::State_ReportBlockItem;
     560             : 
     561           0 :     return true;
     562             : }
     563             : 
     564             : bool
     565           0 : RTCPUtility::RTCPParserV2::ParseSR()
     566             : {
     567           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     568             : 
     569           0 :     if (length < 28)
     570             :     {
     571           0 :         EndCurrentBlock();
     572           0 :         return false;
     573             :     }
     574             : 
     575           0 :     _ptrRTCPData += 4; // Skip header
     576             : 
     577           0 :     _packetType = RTCPPacketTypes::kSr;
     578             : 
     579           0 :     _packet.SR.SenderSSRC = *_ptrRTCPData++ << 24;
     580           0 :     _packet.SR.SenderSSRC += *_ptrRTCPData++ << 16;
     581           0 :     _packet.SR.SenderSSRC += *_ptrRTCPData++ << 8;
     582           0 :     _packet.SR.SenderSSRC += *_ptrRTCPData++;
     583             : 
     584           0 :     _packet.SR.NTPMostSignificant = *_ptrRTCPData++ << 24;
     585           0 :     _packet.SR.NTPMostSignificant += *_ptrRTCPData++ << 16;
     586           0 :     _packet.SR.NTPMostSignificant += *_ptrRTCPData++ << 8;
     587           0 :     _packet.SR.NTPMostSignificant += *_ptrRTCPData++;
     588             : 
     589           0 :     _packet.SR.NTPLeastSignificant = *_ptrRTCPData++ << 24;
     590           0 :     _packet.SR.NTPLeastSignificant += *_ptrRTCPData++ << 16;
     591           0 :     _packet.SR.NTPLeastSignificant += *_ptrRTCPData++ << 8;
     592           0 :     _packet.SR.NTPLeastSignificant += *_ptrRTCPData++;
     593             : 
     594           0 :     _packet.SR.RTPTimestamp = *_ptrRTCPData++ << 24;
     595           0 :     _packet.SR.RTPTimestamp += *_ptrRTCPData++ << 16;
     596           0 :     _packet.SR.RTPTimestamp += *_ptrRTCPData++ << 8;
     597           0 :     _packet.SR.RTPTimestamp += *_ptrRTCPData++;
     598             : 
     599           0 :     _packet.SR.SenderPacketCount = *_ptrRTCPData++ << 24;
     600           0 :     _packet.SR.SenderPacketCount += *_ptrRTCPData++ << 16;
     601           0 :     _packet.SR.SenderPacketCount += *_ptrRTCPData++ << 8;
     602           0 :     _packet.SR.SenderPacketCount += *_ptrRTCPData++;
     603             : 
     604           0 :     _packet.SR.SenderOctetCount = *_ptrRTCPData++ << 24;
     605           0 :     _packet.SR.SenderOctetCount += *_ptrRTCPData++ << 16;
     606           0 :     _packet.SR.SenderOctetCount += *_ptrRTCPData++ << 8;
     607           0 :     _packet.SR.SenderOctetCount += *_ptrRTCPData++;
     608             : 
     609           0 :     _packet.SR.NumberOfReportBlocks = _numberOfBlocks;
     610             : 
     611             :     // State transition
     612           0 :     if(_numberOfBlocks != 0)
     613             :     {
     614           0 :       _state = ParseState::State_ReportBlockItem;
     615             :     }else
     616             :     {
     617             :         // don't go to state report block item if 0 report blocks
     618           0 :       _state = ParseState::State_TopLevel;
     619           0 :         EndCurrentBlock();
     620             :     }
     621           0 :     return true;
     622             : }
     623             : 
     624             : bool
     625           0 : RTCPUtility::RTCPParserV2::ParseReportBlockItem()
     626             : {
     627           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     628             : 
     629           0 :     if (length < 24 || _numberOfBlocks <= 0)
     630             :     {
     631           0 :       _state = ParseState::State_TopLevel;
     632             : 
     633           0 :         EndCurrentBlock();
     634           0 :         return false;
     635             :     }
     636           0 :     _packet.ReportBlockItem.SSRC = *_ptrRTCPData++ << 24;
     637           0 :     _packet.ReportBlockItem.SSRC += *_ptrRTCPData++ << 16;
     638           0 :     _packet.ReportBlockItem.SSRC += *_ptrRTCPData++ << 8;
     639           0 :     _packet.ReportBlockItem.SSRC += *_ptrRTCPData++;
     640             : 
     641           0 :     _packet.ReportBlockItem.FractionLost = *_ptrRTCPData++;
     642             : 
     643           0 :     _packet.ReportBlockItem.CumulativeNumOfPacketsLost = *_ptrRTCPData++ << 16;
     644           0 :     _packet.ReportBlockItem.CumulativeNumOfPacketsLost += *_ptrRTCPData++ << 8;
     645           0 :     _packet.ReportBlockItem.CumulativeNumOfPacketsLost += *_ptrRTCPData++;
     646             : 
     647           0 :     _packet.ReportBlockItem.ExtendedHighestSequenceNumber = *_ptrRTCPData++ << 24;
     648           0 :     _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++ << 16;
     649           0 :     _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++ << 8;
     650           0 :     _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++;
     651             : 
     652           0 :     _packet.ReportBlockItem.Jitter = *_ptrRTCPData++ << 24;
     653           0 :     _packet.ReportBlockItem.Jitter += *_ptrRTCPData++ << 16;
     654           0 :     _packet.ReportBlockItem.Jitter += *_ptrRTCPData++ << 8;
     655           0 :     _packet.ReportBlockItem.Jitter += *_ptrRTCPData++;
     656             : 
     657           0 :     _packet.ReportBlockItem.LastSR = *_ptrRTCPData++ << 24;
     658           0 :     _packet.ReportBlockItem.LastSR += *_ptrRTCPData++ << 16;
     659           0 :     _packet.ReportBlockItem.LastSR += *_ptrRTCPData++ << 8;
     660           0 :     _packet.ReportBlockItem.LastSR += *_ptrRTCPData++;
     661             : 
     662           0 :     _packet.ReportBlockItem.DelayLastSR = *_ptrRTCPData++ << 24;
     663           0 :     _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++ << 16;
     664           0 :     _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++ << 8;
     665           0 :     _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++;
     666             : 
     667           0 :     _numberOfBlocks--;
     668           0 :     _packetType = RTCPPacketTypes::kReportBlockItem;
     669           0 :     return true;
     670             : }
     671             : 
     672             : /* From RFC 5450: Transmission Time Offsets in RTP Streams.
     673             :       0                   1                   2                   3
     674             :       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
     675             :      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     676             :  hdr |V=2|P|    RC   |   PT=IJ=195   |             length            |
     677             :      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     678             :      |                      inter-arrival jitter                     |
     679             :      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     680             :      .                                                               .
     681             :      .                                                               .
     682             :      .                                                               .
     683             :      |                      inter-arrival jitter                     |
     684             :      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     685             : */
     686             : 
     687             : bool
     688           0 : RTCPUtility::RTCPParserV2::ParseIJ()
     689             : {
     690           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     691             : 
     692           0 :     if (length < 4)
     693             :     {
     694           0 :         return false;
     695             :     }
     696             : 
     697           0 :     _ptrRTCPData += 4; // Skip header
     698             : 
     699           0 :     _packetType = RTCPPacketTypes::kExtendedIj;
     700             : 
     701             :     // State transition
     702           0 :     _state = ParseState::State_ExtendedJitterItem;
     703           0 :     return true;
     704             : }
     705             : 
     706             : bool
     707           0 : RTCPUtility::RTCPParserV2::ParseIJItem()
     708             : {
     709           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     710             : 
     711           0 :     if (length < 4 || _numberOfBlocks <= 0)
     712             :     {
     713           0 :       _state = ParseState::State_TopLevel;
     714           0 :         EndCurrentBlock();
     715           0 :         return false;
     716             :     }
     717             : 
     718           0 :     _packet.ExtendedJitterReportItem.Jitter = *_ptrRTCPData++ << 24;
     719           0 :     _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++ << 16;
     720           0 :     _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++ << 8;
     721           0 :     _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++;
     722             : 
     723           0 :     _numberOfBlocks--;
     724           0 :     _packetType = RTCPPacketTypes::kExtendedIjItem;
     725           0 :     return true;
     726             : }
     727             : 
     728             : bool
     729           0 : RTCPUtility::RTCPParserV2::ParseSDES()
     730             : {
     731           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     732             : 
     733           0 :     if (length < 8)
     734             :     {
     735           0 :       _state = ParseState::State_TopLevel;
     736             : 
     737           0 :         EndCurrentBlock();
     738           0 :         return false;
     739             :     }
     740           0 :     _ptrRTCPData += 4; // Skip header
     741             : 
     742           0 :     _state = ParseState::State_SDESChunk;
     743           0 :     _packetType = RTCPPacketTypes::kSdes;
     744           0 :     return true;
     745             : }
     746             : 
     747             : bool
     748           0 : RTCPUtility::RTCPParserV2::ParseSDESChunk()
     749             : {
     750           0 :     if(_numberOfBlocks <= 0)
     751             :     {
     752           0 :       _state = ParseState::State_TopLevel;
     753             : 
     754           0 :         EndCurrentBlock();
     755           0 :         return false;
     756             :     }
     757           0 :     _numberOfBlocks--;
     758             : 
     759             :     // Find CName item in a SDES chunk.
     760           0 :     while (_ptrRTCPData < _ptrRTCPBlockEnd)
     761             :     {
     762           0 :         const ptrdiff_t dataLen = _ptrRTCPBlockEnd - _ptrRTCPData;
     763           0 :         if (dataLen < 4)
     764             :         {
     765           0 :           _state = ParseState::State_TopLevel;
     766             : 
     767           0 :             EndCurrentBlock();
     768           0 :             return false;
     769             :         }
     770             : 
     771           0 :         uint32_t SSRC = *_ptrRTCPData++ << 24;
     772           0 :         SSRC += *_ptrRTCPData++ << 16;
     773           0 :         SSRC += *_ptrRTCPData++ << 8;
     774           0 :         SSRC += *_ptrRTCPData++;
     775             : 
     776           0 :         const bool foundCname = ParseSDESItem();
     777           0 :         if (foundCname)
     778             :         {
     779           0 :             _packet.CName.SenderSSRC = SSRC; // Add SSRC
     780           0 :             return true;
     781             :         }
     782             :     }
     783           0 :     _state = ParseState::State_TopLevel;
     784             : 
     785           0 :     EndCurrentBlock();
     786           0 :     return false;
     787             : }
     788             : 
     789             : bool
     790           0 : RTCPUtility::RTCPParserV2::ParseSDESItem()
     791             : {
     792             :     // Find CName
     793             :     // Only the CNAME item is mandatory. RFC 3550 page 46
     794           0 :     bool foundCName = false;
     795             : 
     796           0 :     size_t itemOctetsRead = 0;
     797           0 :     while (_ptrRTCPData < _ptrRTCPBlockEnd)
     798             :     {
     799           0 :         const uint8_t tag = *_ptrRTCPData++;
     800           0 :         ++itemOctetsRead;
     801             : 
     802           0 :         if (tag == 0)
     803             :         {
     804             :             // End tag! 4 oct aligned
     805           0 :             while ((itemOctetsRead++ % 4) != 0)
     806             :             {
     807           0 :                 ++_ptrRTCPData;
     808             :             }
     809           0 :             return foundCName;
     810             :         }
     811             : 
     812           0 :         if (_ptrRTCPData < _ptrRTCPBlockEnd)
     813             :         {
     814           0 :             const uint8_t len = *_ptrRTCPData++;
     815           0 :             ++itemOctetsRead;
     816             : 
     817           0 :             if (tag == 1)
     818             :             {
     819             :                 // CNAME
     820             : 
     821             :                 // Sanity
     822           0 :                 if ((_ptrRTCPData + len) >= _ptrRTCPBlockEnd)
     823             :                 {
     824           0 :                   _state = ParseState::State_TopLevel;
     825             : 
     826           0 :                     EndCurrentBlock();
     827           0 :                     return false;
     828             :                 }
     829           0 :                 uint8_t i = 0;
     830           0 :                 for (; i < len; ++i)
     831             :                 {
     832           0 :                     const uint8_t c = _ptrRTCPData[i];
     833           0 :                     if ((c < ' ') || (c > '{') || (c == '%') || (c == '\\'))
     834             :                     {
     835             :                         // Illegal char
     836           0 :                       _state = ParseState::State_TopLevel;
     837             : 
     838           0 :                         EndCurrentBlock();
     839           0 :                         return false;
     840             :                     }
     841           0 :                     _packet.CName.CName[i] = c;
     842             :                 }
     843             :                 // Make sure we are null terminated.
     844           0 :                 _packet.CName.CName[i] = 0;
     845           0 :                 _packetType = RTCPPacketTypes::kSdesChunk;
     846             : 
     847           0 :                 foundCName = true;
     848             :             }
     849           0 :             _ptrRTCPData += len;
     850           0 :             itemOctetsRead += len;
     851             :         }
     852             :     }
     853             : 
     854             :     // No end tag found!
     855           0 :     _state = ParseState::State_TopLevel;
     856             : 
     857           0 :     EndCurrentBlock();
     858           0 :     return false;
     859             : }
     860             : 
     861             : bool
     862           0 : RTCPUtility::RTCPParserV2::ParseBYE()
     863             : {
     864           0 :     _ptrRTCPData += 4; // Skip header
     865             : 
     866           0 :     _state = ParseState::State_BYEItem;
     867             : 
     868           0 :     return ParseBYEItem();
     869             : }
     870             : 
     871             : bool
     872           0 : RTCPUtility::RTCPParserV2::ParseBYEItem()
     873             : {
     874           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     875           0 :     if (length < 4 || _numberOfBlocks == 0)
     876             :     {
     877           0 :       _state = ParseState::State_TopLevel;
     878             : 
     879           0 :         EndCurrentBlock();
     880           0 :         return false;
     881             :     }
     882             : 
     883           0 :     _packetType = RTCPPacketTypes::kBye;
     884             : 
     885           0 :     _packet.BYE.SenderSSRC = *_ptrRTCPData++ << 24;
     886           0 :     _packet.BYE.SenderSSRC += *_ptrRTCPData++ << 16;
     887           0 :     _packet.BYE.SenderSSRC += *_ptrRTCPData++ << 8;
     888           0 :     _packet.BYE.SenderSSRC += *_ptrRTCPData++;
     889             : 
     890             :     // we can have several CSRCs attached
     891             : 
     892             :     // sanity
     893           0 :     if(length >= 4*_numberOfBlocks)
     894             :     {
     895           0 :         _ptrRTCPData += (_numberOfBlocks -1)*4;
     896             :     }
     897           0 :     _numberOfBlocks = 0;
     898             : 
     899           0 :     return true;
     900             : }
     901             : /*
     902             :     0                   1                   2                   3
     903             :     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
     904             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     905             :    |V=2|P|reserved |   PT=XR=207   |             length            |
     906             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     907             :    |                              SSRC                             |
     908             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     909             :    :                         report blocks                         :
     910             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     911             : */
     912           0 : bool RTCPUtility::RTCPParserV2::ParseXr()
     913             : {
     914           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     915           0 :     if (length < 8)
     916             :     {
     917           0 :         EndCurrentBlock();
     918           0 :         return false;
     919             :     }
     920             : 
     921           0 :     _ptrRTCPData += 4; // Skip header
     922             : 
     923           0 :     _packet.XR.OriginatorSSRC = *_ptrRTCPData++ << 24;
     924           0 :     _packet.XR.OriginatorSSRC += *_ptrRTCPData++ << 16;
     925           0 :     _packet.XR.OriginatorSSRC += *_ptrRTCPData++ << 8;
     926           0 :     _packet.XR.OriginatorSSRC += *_ptrRTCPData++;
     927             : 
     928           0 :     _packetType = RTCPPacketTypes::kXrHeader;
     929           0 :     _state = ParseState::State_XRItem;
     930           0 :     return true;
     931             : }
     932             : 
     933             : /*  Extended report block format (RFC 3611).
     934             :     BT: block type.
     935             :     block length: length of report block in 32-bits words minus one (including
     936             :                   the header).
     937             :     0                   1                   2                   3
     938             :     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
     939             :     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     940             :     |      BT       | type-specific |         block length          |
     941             :     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     942             :     :             type-specific block contents                      :
     943             :     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     944             : */
     945           0 : bool RTCPUtility::RTCPParserV2::ParseXrItem() {
     946           0 :   const int kBlockHeaderLengthInBytes = 4;
     947           0 :   const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     948           0 :   if (length < kBlockHeaderLengthInBytes) {
     949           0 :     _state = ParseState::State_TopLevel;
     950           0 :     EndCurrentBlock();
     951           0 :     return false;
     952             :   }
     953             : 
     954           0 :   uint8_t block_type = *_ptrRTCPData++;
     955           0 :   _ptrRTCPData++;  // Ignore reserved.
     956             : 
     957           0 :   uint16_t block_length_in_4bytes = *_ptrRTCPData++ << 8;
     958           0 :   block_length_in_4bytes += *_ptrRTCPData++;
     959             : 
     960           0 :   switch (block_type) {
     961             :     case kBtReceiverReferenceTime:
     962           0 :       return ParseXrReceiverReferenceTimeItem(block_length_in_4bytes);
     963             :     case kBtDlrr:
     964           0 :       return ParseXrDlrr(block_length_in_4bytes);
     965             :     case kBtVoipMetric:
     966           0 :       return ParseXrVoipMetricItem(block_length_in_4bytes);
     967             :     default:
     968           0 :       return ParseXrUnsupportedBlockType(block_length_in_4bytes);
     969             :   }
     970             : }
     971             : 
     972             : /*  Receiver Reference Time Report Block.
     973             :     0                   1                   2                   3
     974             :     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
     975             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     976             :    |     BT=4      |   reserved    |       block length = 2        |
     977             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     978             :    |              NTP timestamp, most significant word             |
     979             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     980             :    |             NTP timestamp, least significant word             |
     981             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     982             : */
     983           0 : bool RTCPUtility::RTCPParserV2::ParseXrReceiverReferenceTimeItem(
     984             :     int block_length_4bytes) {
     985           0 :   const int kBlockLengthIn4Bytes = 2;
     986           0 :   const int kBlockLengthInBytes = kBlockLengthIn4Bytes * 4;
     987           0 :   const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
     988           0 :   if (block_length_4bytes != kBlockLengthIn4Bytes ||
     989             :       length < kBlockLengthInBytes) {
     990           0 :     _state = ParseState::State_TopLevel;
     991           0 :     EndCurrentBlock();
     992           0 :     return false;
     993             :   }
     994             : 
     995           0 :   _packet.XRReceiverReferenceTimeItem.NTPMostSignificant = *_ptrRTCPData++<<24;
     996           0 :   _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++<<16;
     997           0 :   _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++<<8;
     998           0 :   _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++;
     999             : 
    1000           0 :   _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant = *_ptrRTCPData++<<24;
    1001           0 :   _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++<<16;
    1002           0 :   _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++<<8;
    1003           0 :   _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++;
    1004             : 
    1005           0 :   _packetType = RTCPPacketTypes::kXrReceiverReferenceTime;
    1006           0 :   _state = ParseState::State_XRItem;
    1007           0 :   return true;
    1008             : }
    1009             : 
    1010             : /*  DLRR Report Block.
    1011             :     0                   1                   2                   3
    1012             :     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
    1013             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1014             :    |     BT=5      |   reserved    |         block length          |
    1015             :    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    1016             :    |                 SSRC_1 (SSRC of first receiver)               | sub-
    1017             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
    1018             :    |                         last RR (LRR)                         |   1
    1019             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1020             :    |                   delay since last RR (DLRR)                  |
    1021             :    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    1022             :    |                 SSRC_2 (SSRC of second receiver)              | sub-
    1023             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
    1024             :    :                               ...                             :   2
    1025             :    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    1026             : */
    1027           0 : bool RTCPUtility::RTCPParserV2::ParseXrDlrr(int block_length_4bytes) {
    1028           0 :   const int kSubBlockLengthIn4Bytes = 3;
    1029           0 :   if (block_length_4bytes < 0 ||
    1030           0 :       (block_length_4bytes % kSubBlockLengthIn4Bytes) != 0) {
    1031           0 :     _state = ParseState::State_TopLevel;
    1032           0 :     EndCurrentBlock();
    1033           0 :     return false;
    1034             :   }
    1035           0 :   _packetType = RTCPPacketTypes::kXrDlrrReportBlock;
    1036           0 :   _state = ParseState::State_XR_DLLRItem;
    1037           0 :   _numberOfBlocks = block_length_4bytes / kSubBlockLengthIn4Bytes;
    1038           0 :   return true;
    1039             : }
    1040             : 
    1041           0 : bool RTCPUtility::RTCPParserV2::ParseXrDlrrItem() {
    1042           0 :   if (_numberOfBlocks == 0) {
    1043           0 :     _state = ParseState::State_XRItem;
    1044           0 :     return false;
    1045             :   }
    1046           0 :   const int kSubBlockLengthInBytes = 12;
    1047           0 :   const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1048           0 :   if (length < kSubBlockLengthInBytes) {
    1049           0 :     _state = ParseState::State_TopLevel;
    1050           0 :     EndCurrentBlock();
    1051           0 :     return false;
    1052             :   }
    1053             : 
    1054           0 :   _packet.XRDLRRReportBlockItem.SSRC = *_ptrRTCPData++ << 24;
    1055           0 :   _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++ << 16;
    1056           0 :   _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++ << 8;
    1057           0 :   _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++;
    1058             : 
    1059           0 :   _packet.XRDLRRReportBlockItem.LastRR = *_ptrRTCPData++ << 24;
    1060           0 :   _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++ << 16;
    1061           0 :   _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++ << 8;
    1062           0 :   _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++;
    1063             : 
    1064           0 :   _packet.XRDLRRReportBlockItem.DelayLastRR = *_ptrRTCPData++ << 24;
    1065           0 :   _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++ << 16;
    1066           0 :   _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++ << 8;
    1067           0 :   _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++;
    1068             : 
    1069           0 :   _packetType = RTCPPacketTypes::kXrDlrrReportBlockItem;
    1070           0 :   --_numberOfBlocks;
    1071           0 :   _state = ParseState::State_XR_DLLRItem;
    1072           0 :   return true;
    1073             : }
    1074             : /*  VoIP Metrics Report Block.
    1075             :     0                   1                   2                   3
    1076             :     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
    1077             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1078             :    |     BT=7      |   reserved    |       block length = 8        |
    1079             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1080             :    |                        SSRC of source                         |
    1081             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1082             :    |   loss rate   | discard rate  | burst density |  gap density  |
    1083             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1084             :    |       burst duration          |         gap duration          |
    1085             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1086             :    |     round trip delay          |       end system delay        |
    1087             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1088             :    | signal level  |  noise level  |     RERL      |     Gmin      |
    1089             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1090             :    |   R factor    | ext. R factor |    MOS-LQ     |    MOS-CQ     |
    1091             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1092             :    |   RX config   |   reserved    |          JB nominal           |
    1093             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1094             :    |          JB maximum           |          JB abs max           |
    1095             :    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1096             : */
    1097             : 
    1098           0 : bool RTCPUtility::RTCPParserV2::ParseXrVoipMetricItem(int block_length_4bytes) {
    1099           0 :   const int kBlockLengthIn4Bytes = 8;
    1100           0 :   const int kBlockLengthInBytes = kBlockLengthIn4Bytes * 4;
    1101           0 :   const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1102           0 :   if (block_length_4bytes != kBlockLengthIn4Bytes ||
    1103             :       length < kBlockLengthInBytes) {
    1104           0 :     _state = ParseState::State_TopLevel;
    1105           0 :     EndCurrentBlock();
    1106           0 :     return false;
    1107             :   }
    1108             : 
    1109           0 :   _packet.XRVOIPMetricItem.SSRC = *_ptrRTCPData++ << 24;
    1110           0 :   _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++ << 16;
    1111           0 :   _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++ << 8;
    1112           0 :   _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++;
    1113             : 
    1114           0 :   _packet.XRVOIPMetricItem.lossRate = *_ptrRTCPData++;
    1115           0 :   _packet.XRVOIPMetricItem.discardRate = *_ptrRTCPData++;
    1116           0 :   _packet.XRVOIPMetricItem.burstDensity = *_ptrRTCPData++;
    1117           0 :   _packet.XRVOIPMetricItem.gapDensity = *_ptrRTCPData++;
    1118             : 
    1119           0 :   _packet.XRVOIPMetricItem.burstDuration = *_ptrRTCPData++ << 8;
    1120           0 :   _packet.XRVOIPMetricItem.burstDuration += *_ptrRTCPData++;
    1121             : 
    1122           0 :   _packet.XRVOIPMetricItem.gapDuration = *_ptrRTCPData++ << 8;
    1123           0 :   _packet.XRVOIPMetricItem.gapDuration += *_ptrRTCPData++;
    1124             : 
    1125           0 :   _packet.XRVOIPMetricItem.roundTripDelay = *_ptrRTCPData++ << 8;
    1126           0 :   _packet.XRVOIPMetricItem.roundTripDelay += *_ptrRTCPData++;
    1127             : 
    1128           0 :   _packet.XRVOIPMetricItem.endSystemDelay = *_ptrRTCPData++ << 8;
    1129           0 :   _packet.XRVOIPMetricItem.endSystemDelay += *_ptrRTCPData++;
    1130             : 
    1131           0 :   _packet.XRVOIPMetricItem.signalLevel = *_ptrRTCPData++;
    1132           0 :   _packet.XRVOIPMetricItem.noiseLevel = *_ptrRTCPData++;
    1133           0 :   _packet.XRVOIPMetricItem.RERL = *_ptrRTCPData++;
    1134           0 :   _packet.XRVOIPMetricItem.Gmin = *_ptrRTCPData++;
    1135           0 :   _packet.XRVOIPMetricItem.Rfactor = *_ptrRTCPData++;
    1136           0 :   _packet.XRVOIPMetricItem.extRfactor = *_ptrRTCPData++;
    1137           0 :   _packet.XRVOIPMetricItem.MOSLQ = *_ptrRTCPData++;
    1138           0 :   _packet.XRVOIPMetricItem.MOSCQ = *_ptrRTCPData++;
    1139           0 :   _packet.XRVOIPMetricItem.RXconfig = *_ptrRTCPData++;
    1140           0 :   _ptrRTCPData++; // skip reserved
    1141             : 
    1142           0 :   _packet.XRVOIPMetricItem.JBnominal = *_ptrRTCPData++ << 8;
    1143           0 :   _packet.XRVOIPMetricItem.JBnominal += *_ptrRTCPData++;
    1144             : 
    1145           0 :   _packet.XRVOIPMetricItem.JBmax = *_ptrRTCPData++ << 8;
    1146           0 :   _packet.XRVOIPMetricItem.JBmax += *_ptrRTCPData++;
    1147             : 
    1148           0 :   _packet.XRVOIPMetricItem.JBabsMax = *_ptrRTCPData++ << 8;
    1149           0 :   _packet.XRVOIPMetricItem.JBabsMax += *_ptrRTCPData++;
    1150             : 
    1151           0 :   _packetType = RTCPPacketTypes::kXrVoipMetric;
    1152           0 :   _state = ParseState::State_XRItem;
    1153           0 :   return true;
    1154             : }
    1155             : 
    1156           0 : bool RTCPUtility::RTCPParserV2::ParseXrUnsupportedBlockType(
    1157             :     int block_length_4bytes) {
    1158           0 :   const int32_t kBlockLengthInBytes = block_length_4bytes * 4;
    1159           0 :   const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1160           0 :   if (length < kBlockLengthInBytes) {
    1161           0 :     _state = ParseState::State_TopLevel;
    1162           0 :     EndCurrentBlock();
    1163           0 :     return false;
    1164             :   }
    1165             :   // Skip block.
    1166           0 :   _ptrRTCPData += kBlockLengthInBytes;
    1167           0 :   _state = ParseState::State_XRItem;
    1168           0 :   return false;
    1169             : }
    1170             : 
    1171           0 : bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) {
    1172           0 :   RTC_CHECK((header.packet_type == PT_RTPFB) ||
    1173           0 :             (header.packet_type == PT_PSFB));  // Parser logic check
    1174             : 
    1175           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1176             : 
    1177             :     // 4 * 3, RFC4585 section 6.1
    1178           0 :     if (length < 12) {
    1179           0 :       LOG(LS_WARNING)
    1180           0 :           << "Invalid RTCP packet: Too little data (" << length
    1181           0 :           << " bytes) left in buffer to parse a 12 byte RTPFB/PSFB message.";
    1182           0 :         return false;
    1183             :     }
    1184             : 
    1185           0 :     _ptrRTCPData += 4; // Skip RTCP header
    1186             : 
    1187           0 :     uint32_t senderSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData);
    1188           0 :     _ptrRTCPData += 4;
    1189             : 
    1190           0 :     uint32_t mediaSSRC = ByteReader<uint32_t>::ReadBigEndian(_ptrRTCPData);
    1191           0 :     _ptrRTCPData += 4;
    1192             : 
    1193           0 :     if (header.packet_type == PT_RTPFB) {
    1194             :         // Transport layer feedback
    1195             : 
    1196           0 :         switch (header.count_or_format) {
    1197             :         case 1:
    1198             :         {
    1199             :             // NACK
    1200           0 :           _packetType = RTCPPacketTypes::kRtpfbNack;
    1201           0 :             _packet.NACK.SenderSSRC = senderSSRC;
    1202           0 :             _packet.NACK.MediaSSRC  = mediaSSRC;
    1203             : 
    1204           0 :             _state = ParseState::State_RTPFB_NACKItem;
    1205             : 
    1206           0 :             return true;
    1207             :         }
    1208             :         case 3:
    1209             :         {
    1210             :             // TMMBR
    1211           0 :           _packetType = RTCPPacketTypes::kRtpfbTmmbr;
    1212           0 :             _packet.TMMBR.SenderSSRC = senderSSRC;
    1213           0 :             _packet.TMMBR.MediaSSRC  = mediaSSRC;
    1214             : 
    1215           0 :             _state = ParseState::State_RTPFB_TMMBRItem;
    1216             : 
    1217           0 :             return true;
    1218             :         }
    1219             :         case 4:
    1220             :         {
    1221             :             // TMMBN
    1222           0 :           _packetType = RTCPPacketTypes::kRtpfbTmmbn;
    1223           0 :             _packet.TMMBN.SenderSSRC = senderSSRC;
    1224           0 :             _packet.TMMBN.MediaSSRC  = mediaSSRC;
    1225             : 
    1226           0 :             _state = ParseState::State_RTPFB_TMMBNItem;
    1227             : 
    1228           0 :             return true;
    1229             :         }
    1230             :         case 5:
    1231             :          {
    1232             :             // RTCP-SR-REQ Rapid Synchronisation of RTP Flows
    1233             :             // draft-perkins-avt-rapid-rtp-sync-03.txt
    1234             :             // trigger a new RTCP SR
    1235           0 :           _packetType = RTCPPacketTypes::kRtpfbSrReq;
    1236             : 
    1237             :             // Note: No state transition, SR REQ is empty!
    1238           0 :             return true;
    1239             :         }
    1240             :         case 15: {
    1241             :           rtcp_packet_ =
    1242           0 :               rtcp::TransportFeedback::ParseFrom(_ptrRTCPData - 12, length);
    1243             :           // Since we parse the whole packet here, keep the TopLevel state and
    1244             :           // just end the current block.
    1245           0 :           EndCurrentBlock();
    1246           0 :           if (rtcp_packet_.get()) {
    1247           0 :             _packetType = RTCPPacketTypes::kTransportFeedback;
    1248           0 :             return true;
    1249             :           }
    1250           0 :           break;
    1251             :         }
    1252             :         default:
    1253           0 :             break;
    1254             :         }
    1255             :         // Unsupported RTPFB message. Skip and move to next block.
    1256           0 :         ++num_skipped_blocks_;
    1257           0 :         return false;
    1258           0 :     } else if (header.packet_type == PT_PSFB) {
    1259             :         // Payload specific feedback
    1260           0 :         switch (header.count_or_format) {
    1261             :         case 1:
    1262             :             // PLI
    1263           0 :           _packetType = RTCPPacketTypes::kPsfbPli;
    1264           0 :             _packet.PLI.SenderSSRC = senderSSRC;
    1265           0 :             _packet.PLI.MediaSSRC  = mediaSSRC;
    1266             : 
    1267             :             // Note: No state transition, PLI FCI is empty!
    1268           0 :             return true;
    1269             :         case 2:
    1270             :             // SLI
    1271           0 :           _packetType = RTCPPacketTypes::kPsfbSli;
    1272           0 :             _packet.SLI.SenderSSRC = senderSSRC;
    1273           0 :             _packet.SLI.MediaSSRC  = mediaSSRC;
    1274             : 
    1275           0 :             _state = ParseState::State_PSFB_SLIItem;
    1276             : 
    1277           0 :             return true;
    1278             :         case 3:
    1279           0 :           _packetType = RTCPPacketTypes::kPsfbRpsi;
    1280           0 :             _packet.RPSI.SenderSSRC = senderSSRC;
    1281           0 :             _packet.RPSI.MediaSSRC  = mediaSSRC;
    1282             : 
    1283           0 :             _state = ParseState::State_PSFB_RPSIItem;
    1284           0 :             return true;
    1285             :         case 4:
    1286             :             // FIR
    1287           0 :           _packetType = RTCPPacketTypes::kPsfbFir;
    1288           0 :             _packet.FIR.SenderSSRC = senderSSRC;
    1289           0 :             _packet.FIR.MediaSSRC  = mediaSSRC;
    1290             : 
    1291           0 :             _state = ParseState::State_PSFB_FIRItem;
    1292           0 :             return true;
    1293             :         case 15:
    1294           0 :           _packetType = RTCPPacketTypes::kPsfbApp;
    1295           0 :             _packet.PSFBAPP.SenderSSRC = senderSSRC;
    1296           0 :             _packet.PSFBAPP.MediaSSRC  = mediaSSRC;
    1297             : 
    1298           0 :             _state = ParseState::State_PSFB_AppItem;
    1299           0 :             return true;
    1300             :         default:
    1301           0 :             break;
    1302             :         }
    1303             : 
    1304           0 :         return false;
    1305             :     }
    1306             :     else
    1307             :     {
    1308           0 :       RTC_NOTREACHED();
    1309           0 :         return false;
    1310             :     }
    1311             : }
    1312             : 
    1313           0 : bool RTCPUtility::RTCPParserV2::ParseRPSIItem() {
    1314             : 
    1315             :     // RFC 4585 6.3.3.  Reference Picture Selection Indication (RPSI).
    1316             :     //
    1317             :     //  0                   1                   2                   3
    1318             :     //  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
    1319             :     //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1320             :     //  |      PB       |0| Payload Type|    Native RPSI bit string     |
    1321             :     //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1322             :     //  |   defined per codec          ...                | Padding (0) |
    1323             :     //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1324             : 
    1325           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1326             : 
    1327           0 :     if (length < 4) {
    1328           0 :       _state = ParseState::State_TopLevel;
    1329             : 
    1330           0 :         EndCurrentBlock();
    1331           0 :         return false;
    1332             :     }
    1333           0 :     if (length > 2 + RTCP_RPSI_DATA_SIZE) {
    1334           0 :       _state = ParseState::State_TopLevel;
    1335             : 
    1336           0 :         EndCurrentBlock();
    1337           0 :         return false;
    1338             :     }
    1339             : 
    1340             : 
    1341           0 :     uint8_t padding_bits = *_ptrRTCPData++;
    1342           0 :     _packet.RPSI.PayloadType = *_ptrRTCPData++;
    1343             : 
    1344           0 :     if (padding_bits > static_cast<uint16_t>(length - 2) * 8) {
    1345           0 :       _state = ParseState::State_TopLevel;
    1346             : 
    1347           0 :       EndCurrentBlock();
    1348           0 :       return false;
    1349             :     }
    1350             : 
    1351           0 :     _packetType = RTCPPacketTypes::kPsfbRpsiItem;
    1352             : 
    1353           0 :     memcpy(_packet.RPSI.NativeBitString, _ptrRTCPData, length - 2);
    1354           0 :     _ptrRTCPData += length - 2;
    1355             : 
    1356           0 :     _packet.RPSI.NumberOfValidBits =
    1357           0 :         static_cast<uint16_t>(length - 2) * 8 - padding_bits;
    1358           0 :     return true;
    1359             : }
    1360             : 
    1361             : bool
    1362           0 : RTCPUtility::RTCPParserV2::ParseNACKItem()
    1363             : {
    1364             :     // RFC 4585 6.2.1. Generic NACK
    1365             : 
    1366           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1367             : 
    1368           0 :     if (length < 4)
    1369             :     {
    1370           0 :       _state = ParseState::State_TopLevel;
    1371             : 
    1372           0 :         EndCurrentBlock();
    1373           0 :         return false;
    1374             :     }
    1375             : 
    1376           0 :     _packetType = RTCPPacketTypes::kRtpfbNackItem;
    1377             : 
    1378           0 :     _packet.NACKItem.PacketID = *_ptrRTCPData++ << 8;
    1379           0 :     _packet.NACKItem.PacketID += *_ptrRTCPData++;
    1380             : 
    1381           0 :     _packet.NACKItem.BitMask = *_ptrRTCPData++ << 8;
    1382           0 :     _packet.NACKItem.BitMask += *_ptrRTCPData++;
    1383             : 
    1384           0 :     return true;
    1385             : }
    1386             : 
    1387             : bool
    1388           0 : RTCPUtility::RTCPParserV2::ParsePsfbAppItem()
    1389             : {
    1390           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1391             : 
    1392           0 :     if (length < 4)
    1393             :     {
    1394           0 :       _state = ParseState::State_TopLevel;
    1395             : 
    1396           0 :         EndCurrentBlock();
    1397           0 :         return false;
    1398             :     }
    1399           0 :     if(*_ptrRTCPData++ != 'R')
    1400             :     {
    1401           0 :       _state = ParseState::State_TopLevel;
    1402             : 
    1403           0 :         EndCurrentBlock();
    1404           0 :         return false;
    1405             :     }
    1406           0 :     if(*_ptrRTCPData++ != 'E')
    1407             :     {
    1408           0 :       _state = ParseState::State_TopLevel;
    1409             : 
    1410           0 :         EndCurrentBlock();
    1411           0 :         return false;
    1412             :     }
    1413           0 :     if(*_ptrRTCPData++ != 'M')
    1414             :     {
    1415           0 :       _state = ParseState::State_TopLevel;
    1416             : 
    1417           0 :         EndCurrentBlock();
    1418           0 :         return false;
    1419             :     }
    1420           0 :     if(*_ptrRTCPData++ != 'B')
    1421             :     {
    1422           0 :       _state = ParseState::State_TopLevel;
    1423             : 
    1424           0 :         EndCurrentBlock();
    1425           0 :         return false;
    1426             :     }
    1427           0 :     _packetType = RTCPPacketTypes::kPsfbRemb;
    1428           0 :     _state = ParseState::State_PSFB_REMBItem;
    1429           0 :     return true;
    1430             : }
    1431             : 
    1432             : bool
    1433           0 : RTCPUtility::RTCPParserV2::ParsePsfbREMBItem()
    1434             : {
    1435           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1436             : 
    1437           0 :     if (length < 4)
    1438             :     {
    1439           0 :       _state = ParseState::State_TopLevel;
    1440             : 
    1441           0 :         EndCurrentBlock();
    1442           0 :         return false;
    1443             :     }
    1444             : 
    1445           0 :     _packet.REMBItem.NumberOfSSRCs = *_ptrRTCPData++;
    1446           0 :     const uint8_t exp = (_ptrRTCPData[0] >> 2) & 0x3F;
    1447             : 
    1448           0 :     uint64_t mantissa = (_ptrRTCPData[0] & 0x03) << 16;
    1449           0 :     mantissa += (_ptrRTCPData[1] << 8);
    1450           0 :     mantissa += (_ptrRTCPData[2]);
    1451             : 
    1452           0 :     _ptrRTCPData += 3; // Fwd read data
    1453           0 :     uint64_t bitrate_bps = (mantissa << exp);
    1454           0 :     bool shift_overflow = exp > 0 && (mantissa >> (64 - exp)) != 0;
    1455           0 :     if (shift_overflow || bitrate_bps > kMaxBitrateBps) {
    1456           0 :       LOG(LS_ERROR) << "Unhandled remb bitrate value : " << mantissa
    1457           0 :                     << "*2^" << static_cast<int>(exp);
    1458           0 :       _state = ParseState::State_TopLevel;
    1459           0 :       EndCurrentBlock();
    1460           0 :       return false;
    1461             :     }
    1462           0 :     _packet.REMBItem.BitRate = bitrate_bps;
    1463             : 
    1464           0 :     const ptrdiff_t length_ssrcs = _ptrRTCPBlockEnd - _ptrRTCPData;
    1465           0 :     if (length_ssrcs < 4 * _packet.REMBItem.NumberOfSSRCs)
    1466             :     {
    1467           0 :       _state = ParseState::State_TopLevel;
    1468             : 
    1469           0 :         EndCurrentBlock();
    1470           0 :         return false;
    1471             :     }
    1472             : 
    1473           0 :     _packetType = RTCPPacketTypes::kPsfbRembItem;
    1474             : 
    1475           0 :     for (int i = 0; i < _packet.REMBItem.NumberOfSSRCs; i++)
    1476             :     {
    1477           0 :         _packet.REMBItem.SSRCs[i] = *_ptrRTCPData++ << 24;
    1478           0 :         _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++ << 16;
    1479           0 :         _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++ << 8;
    1480           0 :         _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++;
    1481             :     }
    1482           0 :     return true;
    1483             : }
    1484             : 
    1485             : bool
    1486           0 : RTCPUtility::RTCPParserV2::ParseTMMBRItem()
    1487             : {
    1488             :     // RFC 5104 4.2.1. Temporary Maximum Media Stream Bit Rate Request (TMMBR)
    1489             : 
    1490           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1491             : 
    1492           0 :     if (length < 8)
    1493             :     {
    1494           0 :       _state = ParseState::State_TopLevel;
    1495             : 
    1496           0 :         EndCurrentBlock();
    1497           0 :         return false;
    1498             :     }
    1499             : 
    1500           0 :     _packetType = RTCPPacketTypes::kRtpfbTmmbrItem;
    1501             : 
    1502           0 :     _packet.TMMBRItem.SSRC = *_ptrRTCPData++ << 24;
    1503           0 :     _packet.TMMBRItem.SSRC += *_ptrRTCPData++ << 16;
    1504           0 :     _packet.TMMBRItem.SSRC += *_ptrRTCPData++ << 8;
    1505           0 :     _packet.TMMBRItem.SSRC += *_ptrRTCPData++;
    1506             : 
    1507           0 :     uint8_t exp = (_ptrRTCPData[0] >> 2) & 0x3F;
    1508             : 
    1509           0 :     uint64_t mantissa = (_ptrRTCPData[0] & 0x03) << 15;
    1510           0 :     mantissa += (_ptrRTCPData[1] << 7);
    1511           0 :     mantissa += (_ptrRTCPData[2] >> 1) & 0x7F;
    1512             : 
    1513           0 :     uint32_t measuredOH = (_ptrRTCPData[2] & 0x01) << 8;
    1514           0 :     measuredOH += _ptrRTCPData[3];
    1515             : 
    1516           0 :     _ptrRTCPData += 4; // Fwd read data
    1517             : 
    1518           0 :     uint64_t bitrate_bps = (mantissa << exp);
    1519           0 :     bool shift_overflow = exp > 0 && (mantissa >> (64 - exp)) != 0;
    1520           0 :     if (shift_overflow || bitrate_bps > kMaxBitrateBps) {
    1521           0 :       LOG(LS_ERROR) << "Unhandled tmmbr bitrate value : " << mantissa
    1522           0 :                     << "*2^" << static_cast<int>(exp);
    1523           0 :       _state = ParseState::State_TopLevel;
    1524           0 :       EndCurrentBlock();
    1525           0 :       return false;
    1526             :     }
    1527             : 
    1528           0 :     _packet.TMMBRItem.MaxTotalMediaBitRate = bitrate_bps / 1000;
    1529           0 :     _packet.TMMBRItem.MeasuredOverhead     = measuredOH;
    1530             : 
    1531           0 :     return true;
    1532             : }
    1533             : 
    1534             : bool
    1535           0 : RTCPUtility::RTCPParserV2::ParseTMMBNItem()
    1536             : {
    1537             :     // RFC 5104 4.2.2. Temporary Maximum Media Stream Bit Rate Notification (TMMBN)
    1538             : 
    1539           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1540             : 
    1541           0 :     if (length < 8)
    1542             :     {
    1543           0 :       _state = ParseState::State_TopLevel;
    1544             : 
    1545           0 :         EndCurrentBlock();
    1546           0 :         return false;
    1547             :     }
    1548             : 
    1549           0 :     _packetType = RTCPPacketTypes::kRtpfbTmmbnItem;
    1550             : 
    1551           0 :     _packet.TMMBNItem.SSRC = *_ptrRTCPData++ << 24;
    1552           0 :     _packet.TMMBNItem.SSRC += *_ptrRTCPData++ << 16;
    1553           0 :     _packet.TMMBNItem.SSRC += *_ptrRTCPData++ << 8;
    1554           0 :     _packet.TMMBNItem.SSRC += *_ptrRTCPData++;
    1555             : 
    1556           0 :     uint8_t exp = (_ptrRTCPData[0] >> 2) & 0x3F;
    1557             : 
    1558           0 :     uint64_t mantissa = (_ptrRTCPData[0] & 0x03) << 15;
    1559           0 :     mantissa += (_ptrRTCPData[1] << 7);
    1560           0 :     mantissa += (_ptrRTCPData[2] >> 1) & 0x7F;
    1561             : 
    1562           0 :     uint32_t measuredOH = (_ptrRTCPData[2] & 0x01) << 8;
    1563           0 :     measuredOH += _ptrRTCPData[3];
    1564             : 
    1565           0 :     _ptrRTCPData += 4; // Fwd read data
    1566             : 
    1567           0 :     uint64_t bitrate_bps = (mantissa << exp);
    1568           0 :     bool shift_overflow = exp > 0 && (mantissa >> (64 - exp)) != 0;
    1569           0 :     if (shift_overflow || bitrate_bps > kMaxBitrateBps) {
    1570           0 :       LOG(LS_ERROR) << "Unhandled tmmbn bitrate value : " << mantissa
    1571           0 :                     << "*2^" << static_cast<int>(exp);
    1572           0 :       _state = ParseState::State_TopLevel;
    1573           0 :       EndCurrentBlock();
    1574           0 :       return false;
    1575             :     }
    1576             : 
    1577           0 :     _packet.TMMBNItem.MaxTotalMediaBitRate = bitrate_bps / 1000;
    1578           0 :     _packet.TMMBNItem.MeasuredOverhead     = measuredOH;
    1579             : 
    1580           0 :     return true;
    1581             : }
    1582             : 
    1583             : bool
    1584           0 : RTCPUtility::RTCPParserV2::ParseSLIItem()
    1585             : {
    1586             :     // RFC 5104 6.3.2.  Slice Loss Indication (SLI)
    1587             :     /*
    1588             :     0                   1                   2                   3
    1589             :     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
    1590             :     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1591             :     |            First        |        Number           | PictureID |
    1592             :     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1593             :     */
    1594             : 
    1595           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1596             : 
    1597           0 :     if (length < 4)
    1598             :     {
    1599           0 :       _state = ParseState::State_TopLevel;
    1600             : 
    1601           0 :         EndCurrentBlock();
    1602           0 :         return false;
    1603             :     }
    1604           0 :     _packetType = RTCPPacketTypes::kPsfbSliItem;
    1605             : 
    1606             :     uint32_t buffer;
    1607           0 :     buffer = *_ptrRTCPData++ << 24;
    1608           0 :     buffer += *_ptrRTCPData++ << 16;
    1609           0 :     buffer += *_ptrRTCPData++ << 8;
    1610           0 :     buffer += *_ptrRTCPData++;
    1611             : 
    1612           0 :     _packet.SLIItem.FirstMB = uint16_t((buffer>>19) & 0x1fff);
    1613           0 :     _packet.SLIItem.NumberOfMB = uint16_t((buffer>>6) & 0x1fff);
    1614           0 :     _packet.SLIItem.PictureId = uint8_t(buffer & 0x3f);
    1615             : 
    1616           0 :     return true;
    1617             : }
    1618             : 
    1619             : bool
    1620           0 : RTCPUtility::RTCPParserV2::ParseFIRItem()
    1621             : {
    1622             :     // RFC 5104 4.3.1. Full Intra Request (FIR)
    1623             : 
    1624           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1625             : 
    1626           0 :     if (length < 8)
    1627             :     {
    1628           0 :       _state = ParseState::State_TopLevel;
    1629             : 
    1630           0 :         EndCurrentBlock();
    1631           0 :         return false;
    1632             :     }
    1633             : 
    1634           0 :     _packetType = RTCPPacketTypes::kPsfbFirItem;
    1635             : 
    1636           0 :     _packet.FIRItem.SSRC = *_ptrRTCPData++ << 24;
    1637           0 :     _packet.FIRItem.SSRC += *_ptrRTCPData++ << 16;
    1638           0 :     _packet.FIRItem.SSRC += *_ptrRTCPData++ << 8;
    1639           0 :     _packet.FIRItem.SSRC += *_ptrRTCPData++;
    1640             : 
    1641           0 :     _packet.FIRItem.CommandSequenceNumber = *_ptrRTCPData++;
    1642           0 :     _ptrRTCPData += 3; // Skip "Reserved" bytes.
    1643           0 :     return true;
    1644             : }
    1645             : 
    1646           0 : bool RTCPUtility::RTCPParserV2::ParseAPP(const RtcpCommonHeader& header) {
    1647           0 :     ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1648             : 
    1649           0 :     if (length < 12) // 4 * 3, RFC 3550 6.7 APP: Application-Defined RTCP Packet
    1650             :     {
    1651           0 :         EndCurrentBlock();
    1652           0 :         return false;
    1653             :     }
    1654             : 
    1655           0 :     _ptrRTCPData += 4; // Skip RTCP header
    1656             : 
    1657           0 :     uint32_t senderSSRC = *_ptrRTCPData++ << 24;
    1658           0 :     senderSSRC += *_ptrRTCPData++ << 16;
    1659           0 :     senderSSRC += *_ptrRTCPData++ << 8;
    1660           0 :     senderSSRC += *_ptrRTCPData++;
    1661             : 
    1662           0 :     uint32_t name = *_ptrRTCPData++ << 24;
    1663           0 :     name += *_ptrRTCPData++ << 16;
    1664           0 :     name += *_ptrRTCPData++ << 8;
    1665           0 :     name += *_ptrRTCPData++;
    1666             : 
    1667           0 :     length  = _ptrRTCPBlockEnd - _ptrRTCPData;
    1668             : 
    1669           0 :     _packetType = RTCPPacketTypes::kApp;
    1670             : 
    1671           0 :     _packet.APP.SubType = header.count_or_format;
    1672           0 :     _packet.APP.Name = name;
    1673             : 
    1674           0 :     _state = ParseState::State_AppItem;
    1675           0 :     return true;
    1676             : }
    1677             : 
    1678             : bool
    1679           0 : RTCPUtility::RTCPParserV2::ParseAPPItem()
    1680             : {
    1681           0 :     const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
    1682           0 :     if (length < 4)
    1683             :     {
    1684           0 :       _state = ParseState::State_TopLevel;
    1685             : 
    1686           0 :         EndCurrentBlock();
    1687           0 :         return false;
    1688             :     }
    1689           0 :     _packetType = RTCPPacketTypes::kAppItem;
    1690             : 
    1691           0 :     if(length > kRtcpAppCode_DATA_SIZE)
    1692             :     {
    1693           0 :         memcpy(_packet.APP.Data, _ptrRTCPData, kRtcpAppCode_DATA_SIZE);
    1694           0 :         _packet.APP.Size = kRtcpAppCode_DATA_SIZE;
    1695           0 :         _ptrRTCPData += kRtcpAppCode_DATA_SIZE;
    1696             :     }else
    1697             :     {
    1698           0 :         memcpy(_packet.APP.Data, _ptrRTCPData, length);
    1699           0 :         _packet.APP.Size = (uint16_t)length;
    1700           0 :         _ptrRTCPData += length;
    1701             :     }
    1702           0 :     return true;
    1703             : }
    1704             : 
    1705           0 : size_t RTCPUtility::RTCPParserV2::NumSkippedBlocks() const {
    1706           0 :   return num_skipped_blocks_;
    1707             : }
    1708             : 
    1709           0 : RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData,
    1710           0 :                                                     size_t rtcpDataLength)
    1711             :     : _ptrBegin(rtcpData),
    1712           0 :       _ptrEnd(rtcpData + rtcpDataLength),
    1713           0 :       _ptrBlock(NULL) {
    1714           0 :   memset(&_header, 0, sizeof(_header));
    1715           0 : }
    1716             : 
    1717           0 : RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() {
    1718           0 : }
    1719             : 
    1720           0 : const RTCPUtility::RtcpCommonHeader* RTCPUtility::RTCPPacketIterator::Begin() {
    1721           0 :     _ptrBlock = _ptrBegin;
    1722             : 
    1723           0 :     return Iterate();
    1724             : }
    1725             : 
    1726             : const RTCPUtility::RtcpCommonHeader*
    1727           0 : RTCPUtility::RTCPPacketIterator::Iterate() {
    1728           0 :   if ((_ptrEnd <= _ptrBlock) ||
    1729           0 :       !RtcpParseCommonHeader(_ptrBlock, _ptrEnd - _ptrBlock, &_header)) {
    1730           0 :     _ptrBlock = nullptr;
    1731           0 :     return nullptr;
    1732             :   }
    1733           0 :   _ptrBlock += _header.BlockSize();
    1734             : 
    1735           0 :   if (_ptrBlock > _ptrEnd) {
    1736           0 :     _ptrBlock = nullptr;
    1737           0 :     return nullptr;
    1738             :   }
    1739             : 
    1740           0 :   return &_header;
    1741             : }
    1742             : 
    1743             : const RTCPUtility::RtcpCommonHeader*
    1744           0 : RTCPUtility::RTCPPacketIterator::Current() {
    1745           0 :     if (!_ptrBlock)
    1746             :     {
    1747           0 :         return NULL;
    1748             :     }
    1749             : 
    1750           0 :     return &_header;
    1751             : }
    1752             : }  // namespace webrtc

Generated by: LCOV version 1.13