2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
14 #include <math.h> // ceil
15 #include <string.h> // memcpy
19 namespace RTCPUtility {
21 NackStats::NackStats()
22 : max_sequence_number_(0),
24 unique_requests_(0) {}
26 NackStats::~NackStats() {}
28 void NackStats::ReportRequest(uint16_t sequence_number) {
30 webrtc::IsNewerSequenceNumber(sequence_number, max_sequence_number_)) {
31 max_sequence_number_ = sequence_number;
37 uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac) {
38 return (ntp_sec << 16) + (ntp_frac >> 16);
42 // RTCPParserV2 : currently read only
43 RTCPUtility::RTCPParserV2::RTCPParserV2(const uint8_t* rtcpData,
44 size_t rtcpDataLength,
45 bool rtcpReducedSizeEnable)
46 : _ptrRTCPDataBegin(rtcpData),
47 _RTCPReducedSizeEnable(rtcpReducedSizeEnable),
48 _ptrRTCPDataEnd(rtcpData + rtcpDataLength),
50 _ptrRTCPData(rtcpData),
51 _ptrRTCPBlockEnd(NULL),
52 _state(State_TopLevel),
54 _packetType(kRtcpNotValidCode) {
58 RTCPUtility::RTCPParserV2::~RTCPParserV2() {
62 RTCPUtility::RTCPParserV2::LengthLeft() const
64 return (_ptrRTCPDataEnd- _ptrRTCPData);
67 RTCPUtility::RTCPPacketTypes
68 RTCPUtility::RTCPParserV2::PacketType() const
73 const RTCPUtility::RTCPPacket&
74 RTCPUtility::RTCPParserV2::Packet() const
79 RTCPUtility::RTCPPacketTypes
80 RTCPUtility::RTCPParserV2::Begin()
82 _ptrRTCPData = _ptrRTCPDataBegin;
87 RTCPUtility::RTCPPacketTypes
88 RTCPUtility::RTCPParserV2::Iterate()
91 _packetType = kRtcpNotValidCode;
100 case State_ReportBlockItem:
101 IterateReportBlockItem();
103 case State_SDESChunk:
109 case State_ExtendedJitterItem:
110 IterateExtendedJitterItem();
112 case State_RTPFB_NACKItem:
115 case State_RTPFB_TMMBRItem:
118 case State_RTPFB_TMMBNItem:
121 case State_PSFB_SLIItem:
124 case State_PSFB_RPSIItem:
127 case State_PSFB_FIRItem:
130 case State_PSFB_AppItem:
131 IteratePsfbAppItem();
133 case State_PSFB_REMBItem:
134 IteratePsfbREMBItem();
139 case State_XR_DLLRItem:
146 assert(false); // Invalid state!
154 RTCPUtility::RTCPParserV2::IterateTopLevel()
158 RTCPCommonHeader header;
160 const bool success = RTCPParseCommonHeader(_ptrRTCPData,
168 _ptrRTCPBlockEnd = _ptrRTCPData + header.LengthInOctets;
169 if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd)
179 // number of Report blocks
180 _numberOfBlocks = header.IC;
186 // number of Report blocks
187 _numberOfBlocks = header.IC;
193 // number of SDES blocks
194 _numberOfBlocks = header.IC;
195 const bool ok = ParseSDES();
198 // Nothing supported found, continue to next block!
205 _numberOfBlocks = header.IC;
206 const bool ok = ParseBYE();
209 // Nothing supported found, continue to next block!
216 // number of Report blocks
217 _numberOfBlocks = header.IC;
221 case PT_RTPFB: // Fall through!
224 const bool ok = ParseFBCommon(header);
227 // Nothing supported found, continue to next block!
234 const bool ok = ParseAPP(header);
237 // Nothing supported found, continue to next block!
244 const bool ok = ParseXr();
247 // Nothing supported found, continue to next block!
253 // Not supported! Skip!
261 RTCPUtility::RTCPParserV2::IterateXrItem()
263 const bool success = ParseXrItem();
271 RTCPUtility::RTCPParserV2::IterateXrDlrrItem()
273 const bool success = ParseXrDlrrItem();
281 RTCPUtility::RTCPParserV2::IterateReportBlockItem()
283 const bool success = ParseReportBlockItem();
291 RTCPUtility::RTCPParserV2::IterateSDESChunk()
293 const bool success = ParseSDESChunk();
301 RTCPUtility::RTCPParserV2::IterateBYEItem()
303 const bool success = ParseBYEItem();
311 RTCPUtility::RTCPParserV2::IterateExtendedJitterItem()
313 const bool success = ParseIJItem();
321 RTCPUtility::RTCPParserV2::IterateNACKItem()
323 const bool success = ParseNACKItem();
331 RTCPUtility::RTCPParserV2::IterateTMMBRItem()
333 const bool success = ParseTMMBRItem();
341 RTCPUtility::RTCPParserV2::IterateTMMBNItem()
343 const bool success = ParseTMMBNItem();
351 RTCPUtility::RTCPParserV2::IterateSLIItem()
353 const bool success = ParseSLIItem();
361 RTCPUtility::RTCPParserV2::IterateRPSIItem()
363 const bool success = ParseRPSIItem();
371 RTCPUtility::RTCPParserV2::IterateFIRItem()
373 const bool success = ParseFIRItem();
381 RTCPUtility::RTCPParserV2::IteratePsfbAppItem()
383 const bool success = ParsePsfbAppItem();
391 RTCPUtility::RTCPParserV2::IteratePsfbREMBItem()
393 const bool success = ParsePsfbREMBItem();
401 RTCPUtility::RTCPParserV2::IterateAppItem()
403 const bool success = ParseAPPItem();
411 RTCPUtility::RTCPParserV2::Validate()
413 if (_ptrRTCPData == NULL)
418 RTCPCommonHeader header;
419 const bool success = RTCPParseCommonHeader(_ptrRTCPDataBegin,
425 return; // NOT VALID!
428 // * if (!reducedSize) : first packet must be RR or SR.
430 // * The padding bit (P) should be zero for the first packet of a
431 // compound RTCP packet because padding should only be applied,
432 // if it is needed, to the last packet. (NOT CHECKED!)
434 // * The length fields of the individual RTCP packets must add up
435 // to the overall length of the compound RTCP packet as
436 // received. This is a fairly strong check. (NOT CHECKED!)
438 if (!_RTCPReducedSizeEnable)
440 if ((header.PT != PT_SR) && (header.PT != PT_RR))
450 RTCPUtility::RTCPParserV2::IsValid() const
456 RTCPUtility::RTCPParserV2::EndCurrentBlock()
458 _ptrRTCPData = _ptrRTCPBlockEnd;
462 RTCPUtility::RTCPParseCommonHeader( const uint8_t* ptrDataBegin,
463 const uint8_t* ptrDataEnd,
464 RTCPCommonHeader& parsedHeader)
466 if (!ptrDataBegin || !ptrDataEnd)
472 // 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
473 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
474 // |V=2|P| IC | PT | length |
475 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
477 // Common header for all RTCP packets, 4 octets.
479 if ((ptrDataEnd - ptrDataBegin) < 4)
484 parsedHeader.V = ptrDataBegin[0] >> 6;
485 parsedHeader.P = ((ptrDataBegin[0] & 0x20) == 0) ? false : true;
486 parsedHeader.IC = ptrDataBegin[0] & 0x1f;
487 parsedHeader.PT = ptrDataBegin[1];
489 parsedHeader.LengthInOctets = (ptrDataBegin[2] << 8) + ptrDataBegin[3] + 1;
490 parsedHeader.LengthInOctets *= 4;
492 if(parsedHeader.LengthInOctets == 0)
496 // Check if RTP version field == 2
497 if (parsedHeader.V != 2)
506 RTCPUtility::RTCPParserV2::ParseRR()
508 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
516 _ptrRTCPData += 4; // Skip header
518 _packetType = kRtcpRrCode;
520 _packet.RR.SenderSSRC = *_ptrRTCPData++ << 24;
521 _packet.RR.SenderSSRC += *_ptrRTCPData++ << 16;
522 _packet.RR.SenderSSRC += *_ptrRTCPData++ << 8;
523 _packet.RR.SenderSSRC += *_ptrRTCPData++;
525 _packet.RR.NumberOfReportBlocks = _numberOfBlocks;
528 _state = State_ReportBlockItem;
534 RTCPUtility::RTCPParserV2::ParseSR()
536 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
544 _ptrRTCPData += 4; // Skip header
546 _packetType = kRtcpSrCode;
548 _packet.SR.SenderSSRC = *_ptrRTCPData++ << 24;
549 _packet.SR.SenderSSRC += *_ptrRTCPData++ << 16;
550 _packet.SR.SenderSSRC += *_ptrRTCPData++ << 8;
551 _packet.SR.SenderSSRC += *_ptrRTCPData++;
553 _packet.SR.NTPMostSignificant = *_ptrRTCPData++ << 24;
554 _packet.SR.NTPMostSignificant += *_ptrRTCPData++ << 16;
555 _packet.SR.NTPMostSignificant += *_ptrRTCPData++ << 8;
556 _packet.SR.NTPMostSignificant += *_ptrRTCPData++;
558 _packet.SR.NTPLeastSignificant = *_ptrRTCPData++ << 24;
559 _packet.SR.NTPLeastSignificant += *_ptrRTCPData++ << 16;
560 _packet.SR.NTPLeastSignificant += *_ptrRTCPData++ << 8;
561 _packet.SR.NTPLeastSignificant += *_ptrRTCPData++;
563 _packet.SR.RTPTimestamp = *_ptrRTCPData++ << 24;
564 _packet.SR.RTPTimestamp += *_ptrRTCPData++ << 16;
565 _packet.SR.RTPTimestamp += *_ptrRTCPData++ << 8;
566 _packet.SR.RTPTimestamp += *_ptrRTCPData++;
568 _packet.SR.SenderPacketCount = *_ptrRTCPData++ << 24;
569 _packet.SR.SenderPacketCount += *_ptrRTCPData++ << 16;
570 _packet.SR.SenderPacketCount += *_ptrRTCPData++ << 8;
571 _packet.SR.SenderPacketCount += *_ptrRTCPData++;
573 _packet.SR.SenderOctetCount = *_ptrRTCPData++ << 24;
574 _packet.SR.SenderOctetCount += *_ptrRTCPData++ << 16;
575 _packet.SR.SenderOctetCount += *_ptrRTCPData++ << 8;
576 _packet.SR.SenderOctetCount += *_ptrRTCPData++;
578 _packet.SR.NumberOfReportBlocks = _numberOfBlocks;
581 if(_numberOfBlocks != 0)
583 _state = State_ReportBlockItem;
586 // don't go to state report block item if 0 report blocks
587 _state = State_TopLevel;
594 RTCPUtility::RTCPParserV2::ParseReportBlockItem()
596 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
598 if (length < 24 || _numberOfBlocks <= 0)
600 _state = State_TopLevel;
605 _packet.ReportBlockItem.SSRC = *_ptrRTCPData++ << 24;
606 _packet.ReportBlockItem.SSRC += *_ptrRTCPData++ << 16;
607 _packet.ReportBlockItem.SSRC += *_ptrRTCPData++ << 8;
608 _packet.ReportBlockItem.SSRC += *_ptrRTCPData++;
610 _packet.ReportBlockItem.FractionLost = *_ptrRTCPData++;
612 _packet.ReportBlockItem.CumulativeNumOfPacketsLost = *_ptrRTCPData++ << 16;
613 _packet.ReportBlockItem.CumulativeNumOfPacketsLost += *_ptrRTCPData++ << 8;
614 _packet.ReportBlockItem.CumulativeNumOfPacketsLost += *_ptrRTCPData++;
616 _packet.ReportBlockItem.ExtendedHighestSequenceNumber = *_ptrRTCPData++ << 24;
617 _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++ << 16;
618 _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++ << 8;
619 _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++;
621 _packet.ReportBlockItem.Jitter = *_ptrRTCPData++ << 24;
622 _packet.ReportBlockItem.Jitter += *_ptrRTCPData++ << 16;
623 _packet.ReportBlockItem.Jitter += *_ptrRTCPData++ << 8;
624 _packet.ReportBlockItem.Jitter += *_ptrRTCPData++;
626 _packet.ReportBlockItem.LastSR = *_ptrRTCPData++ << 24;
627 _packet.ReportBlockItem.LastSR += *_ptrRTCPData++ << 16;
628 _packet.ReportBlockItem.LastSR += *_ptrRTCPData++ << 8;
629 _packet.ReportBlockItem.LastSR += *_ptrRTCPData++;
631 _packet.ReportBlockItem.DelayLastSR = *_ptrRTCPData++ << 24;
632 _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++ << 16;
633 _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++ << 8;
634 _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++;
637 _packetType = kRtcpReportBlockItemCode;
641 /* From RFC 5450: Transmission Time Offsets in RTP Streams.
643 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
644 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
645 hdr |V=2|P| RC | PT=IJ=195 | length |
646 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
647 | inter-arrival jitter |
648 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
652 | inter-arrival jitter |
653 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
657 RTCPUtility::RTCPParserV2::ParseIJ()
659 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
666 _ptrRTCPData += 4; // Skip header
668 _packetType = kRtcpExtendedIjCode;
671 _state = State_ExtendedJitterItem;
676 RTCPUtility::RTCPParserV2::ParseIJItem()
678 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
680 if (length < 4 || _numberOfBlocks <= 0)
682 _state = State_TopLevel;
687 _packet.ExtendedJitterReportItem.Jitter = *_ptrRTCPData++ << 24;
688 _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++ << 16;
689 _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++ << 8;
690 _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++;
693 _packetType = kRtcpExtendedIjItemCode;
698 RTCPUtility::RTCPParserV2::ParseSDES()
700 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
704 _state = State_TopLevel;
709 _ptrRTCPData += 4; // Skip header
711 _state = State_SDESChunk;
712 _packetType = kRtcpSdesCode;
717 RTCPUtility::RTCPParserV2::ParseSDESChunk()
719 if(_numberOfBlocks <= 0)
721 _state = State_TopLevel;
728 // Find CName item in a SDES chunk.
729 while (_ptrRTCPData < _ptrRTCPBlockEnd)
731 const ptrdiff_t dataLen = _ptrRTCPBlockEnd - _ptrRTCPData;
734 _state = State_TopLevel;
740 uint32_t SSRC = *_ptrRTCPData++ << 24;
741 SSRC += *_ptrRTCPData++ << 16;
742 SSRC += *_ptrRTCPData++ << 8;
743 SSRC += *_ptrRTCPData++;
745 const bool foundCname = ParseSDESItem();
748 _packet.CName.SenderSSRC = SSRC; // Add SSRC
752 _state = State_TopLevel;
759 RTCPUtility::RTCPParserV2::ParseSDESItem()
762 // Only the CNAME item is mandatory. RFC 3550 page 46
763 bool foundCName = false;
765 size_t itemOctetsRead = 0;
766 while (_ptrRTCPData < _ptrRTCPBlockEnd)
768 const uint8_t tag = *_ptrRTCPData++;
773 // End tag! 4 oct aligned
774 while ((itemOctetsRead++ % 4) != 0)
781 if (_ptrRTCPData < _ptrRTCPBlockEnd)
783 const uint8_t len = *_ptrRTCPData++;
791 if ((_ptrRTCPData + len) >= _ptrRTCPBlockEnd)
793 _state = State_TopLevel;
801 const uint8_t c = _ptrRTCPData[i];
802 if ((c < ' ') || (c > '{') || (c == '%') || (c == '\\'))
805 _state = State_TopLevel;
810 _packet.CName.CName[i] = c;
812 // Make sure we are null terminated.
813 _packet.CName.CName[i] = 0;
814 _packetType = kRtcpSdesChunkCode;
819 itemOctetsRead += len;
824 _state = State_TopLevel;
831 RTCPUtility::RTCPParserV2::ParseBYE()
833 _ptrRTCPData += 4; // Skip header
835 _state = State_BYEItem;
837 return ParseBYEItem();
841 RTCPUtility::RTCPParserV2::ParseBYEItem()
843 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
844 if (length < 4 || _numberOfBlocks == 0)
846 _state = State_TopLevel;
852 _packetType = kRtcpByeCode;
854 _packet.BYE.SenderSSRC = *_ptrRTCPData++ << 24;
855 _packet.BYE.SenderSSRC += *_ptrRTCPData++ << 16;
856 _packet.BYE.SenderSSRC += *_ptrRTCPData++ << 8;
857 _packet.BYE.SenderSSRC += *_ptrRTCPData++;
859 // we can have several CSRCs attached
862 if(length >= 4*_numberOfBlocks)
864 _ptrRTCPData += (_numberOfBlocks -1)*4;
872 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
873 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
874 |V=2|P|reserved | PT=XR=207 | length |
875 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
877 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
879 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
881 bool RTCPUtility::RTCPParserV2::ParseXr()
883 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
890 _ptrRTCPData += 4; // Skip header
892 _packet.XR.OriginatorSSRC = *_ptrRTCPData++ << 24;
893 _packet.XR.OriginatorSSRC += *_ptrRTCPData++ << 16;
894 _packet.XR.OriginatorSSRC += *_ptrRTCPData++ << 8;
895 _packet.XR.OriginatorSSRC += *_ptrRTCPData++;
897 _packetType = kRtcpXrHeaderCode;
898 _state = State_XRItem;
902 /* Extended report block format (RFC 3611).
904 block length: length of report block in 32-bits words minus one (including
907 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
908 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
909 | BT | type-specific | block length |
910 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
911 : type-specific block contents :
912 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
914 bool RTCPUtility::RTCPParserV2::ParseXrItem() {
915 const int kBlockHeaderLengthInBytes = 4;
916 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
917 if (length < kBlockHeaderLengthInBytes) {
918 _state = State_TopLevel;
923 uint8_t block_type = *_ptrRTCPData++;
924 _ptrRTCPData++; // Ignore reserved.
926 uint16_t block_length_in_4bytes = *_ptrRTCPData++ << 8;
927 block_length_in_4bytes += *_ptrRTCPData++;
929 switch (block_type) {
930 case kBtReceiverReferenceTime:
931 return ParseXrReceiverReferenceTimeItem(block_length_in_4bytes);
933 return ParseXrDlrr(block_length_in_4bytes);
935 return ParseXrVoipMetricItem(block_length_in_4bytes);
937 return ParseXrUnsupportedBlockType(block_length_in_4bytes);
941 /* Receiver Reference Time Report Block.
943 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
944 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
945 | BT=4 | reserved | block length = 2 |
946 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
947 | NTP timestamp, most significant word |
948 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
949 | NTP timestamp, least significant word |
950 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
952 bool RTCPUtility::RTCPParserV2::ParseXrReceiverReferenceTimeItem(
953 int block_length_4bytes) {
954 const int kBlockLengthIn4Bytes = 2;
955 const int kBlockLengthInBytes = kBlockLengthIn4Bytes * 4;
956 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
957 if (block_length_4bytes != kBlockLengthIn4Bytes ||
958 length < kBlockLengthInBytes) {
959 _state = State_TopLevel;
964 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant = *_ptrRTCPData++<<24;
965 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++<<16;
966 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++<<8;
967 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++;
969 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant = *_ptrRTCPData++<<24;
970 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++<<16;
971 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++<<8;
972 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++;
974 _packetType = kRtcpXrReceiverReferenceTimeCode;
975 _state = State_XRItem;
979 /* DLRR Report Block.
981 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
982 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
983 | BT=5 | reserved | block length |
984 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
985 | SSRC_1 (SSRC of first receiver) | sub-
986 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
988 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
989 | delay since last RR (DLRR) |
990 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
991 | SSRC_2 (SSRC of second receiver) | sub-
992 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
994 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
996 bool RTCPUtility::RTCPParserV2::ParseXrDlrr(int block_length_4bytes) {
997 const int kSubBlockLengthIn4Bytes = 3;
998 if (block_length_4bytes < 0 ||
999 (block_length_4bytes % kSubBlockLengthIn4Bytes) != 0) {
1000 _state = State_TopLevel;
1004 _packetType = kRtcpXrDlrrReportBlockCode;
1005 _state = State_XR_DLLRItem;
1006 _numberOfBlocks = block_length_4bytes / kSubBlockLengthIn4Bytes;
1010 bool RTCPUtility::RTCPParserV2::ParseXrDlrrItem() {
1011 if (_numberOfBlocks == 0) {
1012 _state = State_XRItem;
1015 const int kSubBlockLengthInBytes = 12;
1016 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1017 if (length < kSubBlockLengthInBytes) {
1018 _state = State_TopLevel;
1023 _packet.XRDLRRReportBlockItem.SSRC = *_ptrRTCPData++ << 24;
1024 _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++ << 16;
1025 _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++ << 8;
1026 _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++;
1028 _packet.XRDLRRReportBlockItem.LastRR = *_ptrRTCPData++ << 24;
1029 _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++ << 16;
1030 _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++ << 8;
1031 _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++;
1033 _packet.XRDLRRReportBlockItem.DelayLastRR = *_ptrRTCPData++ << 24;
1034 _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++ << 16;
1035 _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++ << 8;
1036 _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++;
1038 _packetType = kRtcpXrDlrrReportBlockItemCode;
1040 _state = State_XR_DLLRItem;
1043 /* VoIP Metrics Report Block.
1045 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
1046 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1047 | BT=7 | reserved | block length = 8 |
1048 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1050 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1051 | loss rate | discard rate | burst density | gap density |
1052 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1053 | burst duration | gap duration |
1054 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1055 | round trip delay | end system delay |
1056 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1057 | signal level | noise level | RERL | Gmin |
1058 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1059 | R factor | ext. R factor | MOS-LQ | MOS-CQ |
1060 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1061 | RX config | reserved | JB nominal |
1062 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1063 | JB maximum | JB abs max |
1064 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1067 bool RTCPUtility::RTCPParserV2::ParseXrVoipMetricItem(int block_length_4bytes) {
1068 const int kBlockLengthIn4Bytes = 8;
1069 const int kBlockLengthInBytes = kBlockLengthIn4Bytes * 4;
1070 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1071 if (block_length_4bytes != kBlockLengthIn4Bytes ||
1072 length < kBlockLengthInBytes) {
1073 _state = State_TopLevel;
1078 _packet.XRVOIPMetricItem.SSRC = *_ptrRTCPData++ << 24;
1079 _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++ << 16;
1080 _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++ << 8;
1081 _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++;
1083 _packet.XRVOIPMetricItem.lossRate = *_ptrRTCPData++;
1084 _packet.XRVOIPMetricItem.discardRate = *_ptrRTCPData++;
1085 _packet.XRVOIPMetricItem.burstDensity = *_ptrRTCPData++;
1086 _packet.XRVOIPMetricItem.gapDensity = *_ptrRTCPData++;
1088 _packet.XRVOIPMetricItem.burstDuration = *_ptrRTCPData++ << 8;
1089 _packet.XRVOIPMetricItem.burstDuration += *_ptrRTCPData++;
1091 _packet.XRVOIPMetricItem.gapDuration = *_ptrRTCPData++ << 8;
1092 _packet.XRVOIPMetricItem.gapDuration += *_ptrRTCPData++;
1094 _packet.XRVOIPMetricItem.roundTripDelay = *_ptrRTCPData++ << 8;
1095 _packet.XRVOIPMetricItem.roundTripDelay += *_ptrRTCPData++;
1097 _packet.XRVOIPMetricItem.endSystemDelay = *_ptrRTCPData++ << 8;
1098 _packet.XRVOIPMetricItem.endSystemDelay += *_ptrRTCPData++;
1100 _packet.XRVOIPMetricItem.signalLevel = *_ptrRTCPData++;
1101 _packet.XRVOIPMetricItem.noiseLevel = *_ptrRTCPData++;
1102 _packet.XRVOIPMetricItem.RERL = *_ptrRTCPData++;
1103 _packet.XRVOIPMetricItem.Gmin = *_ptrRTCPData++;
1104 _packet.XRVOIPMetricItem.Rfactor = *_ptrRTCPData++;
1105 _packet.XRVOIPMetricItem.extRfactor = *_ptrRTCPData++;
1106 _packet.XRVOIPMetricItem.MOSLQ = *_ptrRTCPData++;
1107 _packet.XRVOIPMetricItem.MOSCQ = *_ptrRTCPData++;
1108 _packet.XRVOIPMetricItem.RXconfig = *_ptrRTCPData++;
1109 _ptrRTCPData++; // skip reserved
1111 _packet.XRVOIPMetricItem.JBnominal = *_ptrRTCPData++ << 8;
1112 _packet.XRVOIPMetricItem.JBnominal += *_ptrRTCPData++;
1114 _packet.XRVOIPMetricItem.JBmax = *_ptrRTCPData++ << 8;
1115 _packet.XRVOIPMetricItem.JBmax += *_ptrRTCPData++;
1117 _packet.XRVOIPMetricItem.JBabsMax = *_ptrRTCPData++ << 8;
1118 _packet.XRVOIPMetricItem.JBabsMax += *_ptrRTCPData++;
1120 _packetType = kRtcpXrVoipMetricCode;
1121 _state = State_XRItem;
1125 bool RTCPUtility::RTCPParserV2::ParseXrUnsupportedBlockType(
1126 int block_length_4bytes) {
1127 const int32_t kBlockLengthInBytes = block_length_4bytes * 4;
1128 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1129 if (length < kBlockLengthInBytes) {
1130 _state = State_TopLevel;
1135 _ptrRTCPData += kBlockLengthInBytes;
1136 _state = State_XRItem;
1141 RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header)
1143 assert((header.PT == PT_RTPFB) || (header.PT == PT_PSFB)); // Parser logic check
1145 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1147 if (length < 12) // 4 * 3, RFC4585 section 6.1
1153 _ptrRTCPData += 4; // Skip RTCP header
1155 uint32_t senderSSRC = *_ptrRTCPData++ << 24;
1156 senderSSRC += *_ptrRTCPData++ << 16;
1157 senderSSRC += *_ptrRTCPData++ << 8;
1158 senderSSRC += *_ptrRTCPData++;
1160 uint32_t mediaSSRC = *_ptrRTCPData++ << 24;
1161 mediaSSRC += *_ptrRTCPData++ << 16;
1162 mediaSSRC += *_ptrRTCPData++ << 8;
1163 mediaSSRC += *_ptrRTCPData++;
1165 if (header.PT == PT_RTPFB)
1167 // Transport layer feedback
1174 _packetType = kRtcpRtpfbNackCode;
1175 _packet.NACK.SenderSSRC = senderSSRC;
1176 _packet.NACK.MediaSSRC = mediaSSRC;
1178 _state = State_RTPFB_NACKItem;
1184 // used to be ACK is this code point, which is removed
1185 // conficts with http://tools.ietf.org/html/draft-levin-avt-rtcp-burst-00
1191 _packetType = kRtcpRtpfbTmmbrCode;
1192 _packet.TMMBR.SenderSSRC = senderSSRC;
1193 _packet.TMMBR.MediaSSRC = mediaSSRC;
1195 _state = State_RTPFB_TMMBRItem;
1202 _packetType = kRtcpRtpfbTmmbnCode;
1203 _packet.TMMBN.SenderSSRC = senderSSRC;
1204 _packet.TMMBN.MediaSSRC = mediaSSRC;
1206 _state = State_RTPFB_TMMBNItem;
1212 // RTCP-SR-REQ Rapid Synchronisation of RTP Flows
1213 // draft-perkins-avt-rapid-rtp-sync-03.txt
1214 // trigger a new RTCP SR
1215 _packetType = kRtcpRtpfbSrReqCode;
1217 // Note: No state transition, SR REQ is empty!
1226 else if (header.PT == PT_PSFB)
1228 // Payload specific feedback
1233 _packetType = kRtcpPsfbPliCode;
1234 _packet.PLI.SenderSSRC = senderSSRC;
1235 _packet.PLI.MediaSSRC = mediaSSRC;
1237 // Note: No state transition, PLI FCI is empty!
1241 _packetType = kRtcpPsfbSliCode;
1242 _packet.SLI.SenderSSRC = senderSSRC;
1243 _packet.SLI.MediaSSRC = mediaSSRC;
1245 _state = State_PSFB_SLIItem;
1249 _packetType = kRtcpPsfbRpsiCode;
1250 _packet.RPSI.SenderSSRC = senderSSRC;
1251 _packet.RPSI.MediaSSRC = mediaSSRC;
1253 _state = State_PSFB_RPSIItem;
1257 _packetType = kRtcpPsfbFirCode;
1258 _packet.FIR.SenderSSRC = senderSSRC;
1259 _packet.FIR.MediaSSRC = mediaSSRC;
1261 _state = State_PSFB_FIRItem;
1264 _packetType = kRtcpPsfbAppCode;
1265 _packet.PSFBAPP.SenderSSRC = senderSSRC;
1266 _packet.PSFBAPP.MediaSSRC = mediaSSRC;
1268 _state = State_PSFB_AppItem;
1286 bool RTCPUtility::RTCPParserV2::ParseRPSIItem() {
1288 // RFC 4585 6.3.3. Reference Picture Selection Indication (RPSI).
1291 // 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
1292 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1293 // | PB |0| Payload Type| Native RPSI bit string |
1294 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1295 // | defined per codec ... | Padding (0) |
1296 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1298 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1301 _state = State_TopLevel;
1306 if (length > 2 + RTCP_RPSI_DATA_SIZE) {
1307 _state = State_TopLevel;
1313 _packetType = kRtcpPsfbRpsiCode;
1315 uint8_t padding_bits = *_ptrRTCPData++;
1316 _packet.RPSI.PayloadType = *_ptrRTCPData++;
1318 memcpy(_packet.RPSI.NativeBitString, _ptrRTCPData, length - 2);
1319 _ptrRTCPData += length - 2;
1321 _packet.RPSI.NumberOfValidBits =
1322 static_cast<uint16_t>(length - 2) * 8 - padding_bits;
1327 RTCPUtility::RTCPParserV2::ParseNACKItem()
1329 // RFC 4585 6.2.1. Generic NACK
1331 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1335 _state = State_TopLevel;
1341 _packetType = kRtcpRtpfbNackItemCode;
1343 _packet.NACKItem.PacketID = *_ptrRTCPData++ << 8;
1344 _packet.NACKItem.PacketID += *_ptrRTCPData++;
1346 _packet.NACKItem.BitMask = *_ptrRTCPData++ << 8;
1347 _packet.NACKItem.BitMask += *_ptrRTCPData++;
1353 RTCPUtility::RTCPParserV2::ParsePsfbAppItem()
1355 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1359 _state = State_TopLevel;
1364 if(*_ptrRTCPData++ != 'R')
1366 _state = State_TopLevel;
1371 if(*_ptrRTCPData++ != 'E')
1373 _state = State_TopLevel;
1378 if(*_ptrRTCPData++ != 'M')
1380 _state = State_TopLevel;
1385 if(*_ptrRTCPData++ != 'B')
1387 _state = State_TopLevel;
1392 _packetType = kRtcpPsfbRembCode;
1393 _state = State_PSFB_REMBItem;
1398 RTCPUtility::RTCPParserV2::ParsePsfbREMBItem()
1400 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1404 _state = State_TopLevel;
1410 _packet.REMBItem.NumberOfSSRCs = *_ptrRTCPData++;
1411 const uint8_t brExp = (_ptrRTCPData[0] >> 2) & 0x3F;
1413 uint32_t brMantissa = (_ptrRTCPData[0] & 0x03) << 16;
1414 brMantissa += (_ptrRTCPData[1] << 8);
1415 brMantissa += (_ptrRTCPData[2]);
1417 _ptrRTCPData += 3; // Fwd read data
1418 _packet.REMBItem.BitRate = (brMantissa << brExp);
1420 const ptrdiff_t length_ssrcs = _ptrRTCPBlockEnd - _ptrRTCPData;
1421 if (length_ssrcs < 4 * _packet.REMBItem.NumberOfSSRCs)
1423 _state = State_TopLevel;
1429 _packetType = kRtcpPsfbRembItemCode;
1431 for (int i = 0; i < _packet.REMBItem.NumberOfSSRCs; i++)
1433 _packet.REMBItem.SSRCs[i] = *_ptrRTCPData++ << 24;
1434 _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++ << 16;
1435 _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++ << 8;
1436 _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++;
1442 RTCPUtility::RTCPParserV2::ParseTMMBRItem()
1444 // RFC 5104 4.2.1. Temporary Maximum Media Stream Bit Rate Request (TMMBR)
1446 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1450 _state = State_TopLevel;
1456 _packetType = kRtcpRtpfbTmmbrItemCode;
1458 _packet.TMMBRItem.SSRC = *_ptrRTCPData++ << 24;
1459 _packet.TMMBRItem.SSRC += *_ptrRTCPData++ << 16;
1460 _packet.TMMBRItem.SSRC += *_ptrRTCPData++ << 8;
1461 _packet.TMMBRItem.SSRC += *_ptrRTCPData++;
1463 uint8_t mxtbrExp = (_ptrRTCPData[0] >> 2) & 0x3F;
1465 uint32_t mxtbrMantissa = (_ptrRTCPData[0] & 0x03) << 15;
1466 mxtbrMantissa += (_ptrRTCPData[1] << 7);
1467 mxtbrMantissa += (_ptrRTCPData[2] >> 1) & 0x7F;
1469 uint32_t measuredOH = (_ptrRTCPData[2] & 0x01) << 8;
1470 measuredOH += _ptrRTCPData[3];
1472 _ptrRTCPData += 4; // Fwd read data
1474 _packet.TMMBRItem.MaxTotalMediaBitRate = ((mxtbrMantissa << mxtbrExp) / 1000);
1475 _packet.TMMBRItem.MeasuredOverhead = measuredOH;
1481 RTCPUtility::RTCPParserV2::ParseTMMBNItem()
1483 // RFC 5104 4.2.2. Temporary Maximum Media Stream Bit Rate Notification (TMMBN)
1485 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1489 _state = State_TopLevel;
1495 _packetType = kRtcpRtpfbTmmbnItemCode;
1497 _packet.TMMBNItem.SSRC = *_ptrRTCPData++ << 24;
1498 _packet.TMMBNItem.SSRC += *_ptrRTCPData++ << 16;
1499 _packet.TMMBNItem.SSRC += *_ptrRTCPData++ << 8;
1500 _packet.TMMBNItem.SSRC += *_ptrRTCPData++;
1502 uint8_t mxtbrExp = (_ptrRTCPData[0] >> 2) & 0x3F;
1504 uint32_t mxtbrMantissa = (_ptrRTCPData[0] & 0x03) << 15;
1505 mxtbrMantissa += (_ptrRTCPData[1] << 7);
1506 mxtbrMantissa += (_ptrRTCPData[2] >> 1) & 0x7F;
1508 uint32_t measuredOH = (_ptrRTCPData[2] & 0x01) << 8;
1509 measuredOH += _ptrRTCPData[3];
1511 _ptrRTCPData += 4; // Fwd read data
1513 _packet.TMMBNItem.MaxTotalMediaBitRate = ((mxtbrMantissa << mxtbrExp) / 1000);
1514 _packet.TMMBNItem.MeasuredOverhead = measuredOH;
1520 RTCPUtility::RTCPParserV2::ParseSLIItem()
1522 // RFC 5104 6.3.2. Slice Loss Indication (SLI)
1525 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
1526 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1527 | First | Number | PictureID |
1528 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1531 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1535 _state = State_TopLevel;
1540 _packetType = kRtcpPsfbSliItemCode;
1543 buffer = *_ptrRTCPData++ << 24;
1544 buffer += *_ptrRTCPData++ << 16;
1545 buffer += *_ptrRTCPData++ << 8;
1546 buffer += *_ptrRTCPData++;
1548 _packet.SLIItem.FirstMB = uint16_t((buffer>>19) & 0x1fff);
1549 _packet.SLIItem.NumberOfMB = uint16_t((buffer>>6) & 0x1fff);
1550 _packet.SLIItem.PictureId = uint8_t(buffer & 0x3f);
1556 RTCPUtility::RTCPParserV2::ParseFIRItem()
1558 // RFC 5104 4.3.1. Full Intra Request (FIR)
1560 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1564 _state = State_TopLevel;
1570 _packetType = kRtcpPsfbFirItemCode;
1572 _packet.FIRItem.SSRC = *_ptrRTCPData++ << 24;
1573 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 16;
1574 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 8;
1575 _packet.FIRItem.SSRC += *_ptrRTCPData++;
1577 _packet.FIRItem.CommandSequenceNumber = *_ptrRTCPData++;
1578 _ptrRTCPData += 3; // Skip "Reserved" bytes.
1583 RTCPUtility::RTCPParserV2::ParseAPP( const RTCPCommonHeader& header)
1585 ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1587 if (length < 12) // 4 * 3, RFC 3550 6.7 APP: Application-Defined RTCP Packet
1593 _ptrRTCPData += 4; // Skip RTCP header
1595 uint32_t senderSSRC = *_ptrRTCPData++ << 24;
1596 senderSSRC += *_ptrRTCPData++ << 16;
1597 senderSSRC += *_ptrRTCPData++ << 8;
1598 senderSSRC += *_ptrRTCPData++;
1600 uint32_t name = *_ptrRTCPData++ << 24;
1601 name += *_ptrRTCPData++ << 16;
1602 name += *_ptrRTCPData++ << 8;
1603 name += *_ptrRTCPData++;
1605 length = _ptrRTCPBlockEnd - _ptrRTCPData;
1607 _packetType = kRtcpAppCode;
1609 _packet.APP.SubType = header.IC;
1610 _packet.APP.Name = name;
1612 _state = State_AppItem;
1617 RTCPUtility::RTCPParserV2::ParseAPPItem()
1619 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1622 _state = State_TopLevel;
1627 _packetType = kRtcpAppItemCode;
1629 if(length > kRtcpAppCode_DATA_SIZE)
1631 memcpy(_packet.APP.Data, _ptrRTCPData, kRtcpAppCode_DATA_SIZE);
1632 _packet.APP.Size = kRtcpAppCode_DATA_SIZE;
1633 _ptrRTCPData += kRtcpAppCode_DATA_SIZE;
1636 memcpy(_packet.APP.Data, _ptrRTCPData, length);
1637 _packet.APP.Size = (uint16_t)length;
1638 _ptrRTCPData += length;
1643 RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData,
1644 size_t rtcpDataLength)
1645 : _ptrBegin(rtcpData),
1646 _ptrEnd(rtcpData + rtcpDataLength),
1648 memset(&_header, 0, sizeof(_header));
1651 RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() {
1654 const RTCPUtility::RTCPCommonHeader*
1655 RTCPUtility::RTCPPacketIterator::Begin()
1657 _ptrBlock = _ptrBegin;
1662 const RTCPUtility::RTCPCommonHeader*
1663 RTCPUtility::RTCPPacketIterator::Iterate()
1665 const bool success = RTCPParseCommonHeader(_ptrBlock, _ptrEnd, _header);
1671 _ptrBlock += _header.LengthInOctets;
1673 if (_ptrBlock > _ptrEnd)
1682 const RTCPUtility::RTCPCommonHeader*
1683 RTCPUtility::RTCPPacketIterator::Current()
1692 } // namespace webrtc