| /* | |
| * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_ | |
| #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_ | |
| #include <stddef.h> // size_t, ptrdiff_t | |
| #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" | |
| #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h" | |
| #include "webrtc/typedefs.h" | |
| namespace webrtc { | |
| namespace RTCPUtility { | |
| class NackStats { | |
| public: | |
| NackStats(); | |
| ~NackStats(); | |
| // Updates stats with requested sequence number. | |
| // This function should be called for each NACK request to calculate the | |
| // number of unique NACKed RTP packets. | |
| void ReportRequest(uint16_t sequence_number); | |
| // Gets the number of NACKed RTP packets. | |
| uint32_t requests() const { return requests_; } | |
| // Gets the number of unique NACKed RTP packets. | |
| uint32_t unique_requests() const { return unique_requests_; } | |
| private: | |
| uint16_t max_sequence_number_; | |
| uint32_t requests_; | |
| uint32_t unique_requests_; | |
| }; | |
| uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac); | |
| // CNAME | |
| struct RTCPCnameInformation { | |
| char name[RTCP_CNAME_SIZE]; | |
| }; | |
| struct RTCPPacketRR { | |
| uint32_t SenderSSRC; | |
| uint8_t NumberOfReportBlocks; | |
| }; | |
| struct RTCPPacketSR { | |
| uint32_t SenderSSRC; | |
| uint8_t NumberOfReportBlocks; | |
| // sender info | |
| uint32_t NTPMostSignificant; | |
| uint32_t NTPLeastSignificant; | |
| uint32_t RTPTimestamp; | |
| uint32_t SenderPacketCount; | |
| uint32_t SenderOctetCount; | |
| }; | |
| struct RTCPPacketReportBlockItem { | |
| // report block | |
| uint32_t SSRC; | |
| uint8_t FractionLost; | |
| uint32_t CumulativeNumOfPacketsLost; | |
| uint32_t ExtendedHighestSequenceNumber; | |
| uint32_t Jitter; | |
| uint32_t LastSR; | |
| uint32_t DelayLastSR; | |
| }; | |
| struct RTCPPacketSDESCName { | |
| // RFC3550 | |
| uint32_t SenderSSRC; | |
| char CName[RTCP_CNAME_SIZE]; | |
| }; | |
| struct RTCPPacketExtendedJitterReportItem { | |
| // RFC 5450 | |
| uint32_t Jitter; | |
| }; | |
| struct RTCPPacketBYE { | |
| uint32_t SenderSSRC; | |
| }; | |
| struct RTCPPacketXR { | |
| // RFC 3611 | |
| uint32_t OriginatorSSRC; | |
| }; | |
| struct RTCPPacketXRReceiverReferenceTimeItem { | |
| // RFC 3611 4.4 | |
| uint32_t NTPMostSignificant; | |
| uint32_t NTPLeastSignificant; | |
| }; | |
| struct RTCPPacketXRDLRRReportBlockItem { | |
| // RFC 3611 4.5 | |
| uint32_t SSRC; | |
| uint32_t LastRR; | |
| uint32_t DelayLastRR; | |
| }; | |
| struct RTCPPacketXRVOIPMetricItem { | |
| // RFC 3611 4.7 | |
| uint32_t SSRC; | |
| uint8_t lossRate; | |
| uint8_t discardRate; | |
| uint8_t burstDensity; | |
| uint8_t gapDensity; | |
| uint16_t burstDuration; | |
| uint16_t gapDuration; | |
| uint16_t roundTripDelay; | |
| uint16_t endSystemDelay; | |
| uint8_t signalLevel; | |
| uint8_t noiseLevel; | |
| uint8_t RERL; | |
| uint8_t Gmin; | |
| uint8_t Rfactor; | |
| uint8_t extRfactor; | |
| uint8_t MOSLQ; | |
| uint8_t MOSCQ; | |
| uint8_t RXconfig; | |
| uint16_t JBnominal; | |
| uint16_t JBmax; | |
| uint16_t JBabsMax; | |
| }; | |
| struct RTCPPacketRTPFBNACK { | |
| uint32_t SenderSSRC; | |
| uint32_t MediaSSRC; | |
| }; | |
| struct RTCPPacketRTPFBNACKItem { | |
| // RFC4585 | |
| uint16_t PacketID; | |
| uint16_t BitMask; | |
| }; | |
| struct RTCPPacketRTPFBTMMBR { | |
| uint32_t SenderSSRC; | |
| uint32_t MediaSSRC; // zero! | |
| }; | |
| struct RTCPPacketRTPFBTMMBRItem { | |
| // RFC5104 | |
| uint32_t SSRC; | |
| uint32_t MaxTotalMediaBitRate; // In Kbit/s | |
| uint32_t MeasuredOverhead; | |
| }; | |
| struct RTCPPacketRTPFBTMMBN { | |
| uint32_t SenderSSRC; | |
| uint32_t MediaSSRC; // zero! | |
| }; | |
| struct RTCPPacketRTPFBTMMBNItem { | |
| // RFC5104 | |
| uint32_t SSRC; // "Owner" | |
| uint32_t MaxTotalMediaBitRate; | |
| uint32_t MeasuredOverhead; | |
| }; | |
| struct RTCPPacketPSFBFIR { | |
| uint32_t SenderSSRC; | |
| uint32_t MediaSSRC; // zero! | |
| }; | |
| struct RTCPPacketPSFBFIRItem { | |
| // RFC5104 | |
| uint32_t SSRC; | |
| uint8_t CommandSequenceNumber; | |
| }; | |
| struct RTCPPacketPSFBPLI { | |
| // RFC4585 | |
| uint32_t SenderSSRC; | |
| uint32_t MediaSSRC; | |
| }; | |
| struct RTCPPacketPSFBSLI { | |
| // RFC4585 | |
| uint32_t SenderSSRC; | |
| uint32_t MediaSSRC; | |
| }; | |
| struct RTCPPacketPSFBSLIItem { | |
| // RFC4585 | |
| uint16_t FirstMB; | |
| uint16_t NumberOfMB; | |
| uint8_t PictureId; | |
| }; | |
| struct RTCPPacketPSFBRPSI { | |
| // RFC4585 | |
| uint32_t SenderSSRC; | |
| uint32_t MediaSSRC; | |
| uint8_t PayloadType; | |
| uint16_t NumberOfValidBits; | |
| uint8_t NativeBitString[RTCP_RPSI_DATA_SIZE]; | |
| }; | |
| struct RTCPPacketPSFBAPP { | |
| uint32_t SenderSSRC; | |
| uint32_t MediaSSRC; | |
| }; | |
| struct RTCPPacketPSFBREMBItem { | |
| uint32_t BitRate; | |
| uint8_t NumberOfSSRCs; | |
| uint32_t SSRCs[MAX_NUMBER_OF_REMB_FEEDBACK_SSRCS]; | |
| }; | |
| // generic name APP | |
| struct RTCPPacketAPP { | |
| uint8_t SubType; | |
| uint32_t Name; | |
| uint8_t Data[kRtcpAppCode_DATA_SIZE]; | |
| uint16_t Size; | |
| }; | |
| union RTCPPacket { | |
| RTCPPacketRR RR; | |
| RTCPPacketSR SR; | |
| RTCPPacketReportBlockItem ReportBlockItem; | |
| RTCPPacketSDESCName CName; | |
| RTCPPacketBYE BYE; | |
| RTCPPacketExtendedJitterReportItem ExtendedJitterReportItem; | |
| RTCPPacketRTPFBNACK NACK; | |
| RTCPPacketRTPFBNACKItem NACKItem; | |
| RTCPPacketPSFBPLI PLI; | |
| RTCPPacketPSFBSLI SLI; | |
| RTCPPacketPSFBSLIItem SLIItem; | |
| RTCPPacketPSFBRPSI RPSI; | |
| RTCPPacketPSFBAPP PSFBAPP; | |
| RTCPPacketPSFBREMBItem REMBItem; | |
| RTCPPacketRTPFBTMMBR TMMBR; | |
| RTCPPacketRTPFBTMMBRItem TMMBRItem; | |
| RTCPPacketRTPFBTMMBN TMMBN; | |
| RTCPPacketRTPFBTMMBNItem TMMBNItem; | |
| RTCPPacketPSFBFIR FIR; | |
| RTCPPacketPSFBFIRItem FIRItem; | |
| RTCPPacketXR XR; | |
| RTCPPacketXRReceiverReferenceTimeItem XRReceiverReferenceTimeItem; | |
| RTCPPacketXRDLRRReportBlockItem XRDLRRReportBlockItem; | |
| RTCPPacketXRVOIPMetricItem XRVOIPMetricItem; | |
| RTCPPacketAPP APP; | |
| }; | |
| enum class RTCPPacketTypes { | |
| kInvalid, | |
| // RFC3550 | |
| kRr, | |
| kSr, | |
| kReportBlockItem, | |
| kSdes, | |
| kSdesChunk, | |
| kBye, | |
| // RFC5450 | |
| kExtendedIj, | |
| kExtendedIjItem, | |
| // RFC4585 | |
| kRtpfbNack, | |
| kRtpfbNackItem, | |
| kPsfbPli, | |
| kPsfbRpsi, | |
| kPsfbSli, | |
| kPsfbSliItem, | |
| kPsfbApp, | |
| kPsfbRemb, | |
| kPsfbRembItem, | |
| // RFC5104 | |
| kRtpfbTmmbr, | |
| kRtpfbTmmbrItem, | |
| kRtpfbTmmbn, | |
| kRtpfbTmmbnItem, | |
| kPsfbFir, | |
| kPsfbFirItem, | |
| // draft-perkins-avt-rapid-rtp-sync | |
| kRtpfbSrReq, | |
| // RFC 3611 | |
| kXrHeader, | |
| kXrReceiverReferenceTime, | |
| kXrDlrrReportBlock, | |
| kXrDlrrReportBlockItem, | |
| kXrVoipMetric, | |
| kApp, | |
| kAppItem, | |
| }; | |
| struct RTCPRawPacket { | |
| const uint8_t* _ptrPacketBegin; | |
| const uint8_t* _ptrPacketEnd; | |
| }; | |
| struct RTCPModRawPacket { | |
| uint8_t* _ptrPacketBegin; | |
| uint8_t* _ptrPacketEnd; | |
| }; | |
| struct RTCPCommonHeader { | |
| uint8_t V; // Version | |
| bool P; // Padding | |
| uint8_t IC; // Item count/subtype | |
| uint8_t PT; // Packet Type | |
| uint16_t LengthInOctets; | |
| }; | |
| enum RTCPPT : uint8_t { | |
| PT_IJ = 195, | |
| PT_SR = 200, | |
| PT_RR = 201, | |
| PT_SDES = 202, | |
| PT_BYE = 203, | |
| PT_APP = 204, | |
| PT_RTPFB = 205, | |
| PT_PSFB = 206, | |
| PT_XR = 207 | |
| }; | |
| // Extended report blocks, RFC 3611. | |
| enum RtcpXrBlockType : uint8_t { | |
| kBtReceiverReferenceTime = 4, | |
| kBtDlrr = 5, | |
| kBtVoipMetric = 7 | |
| }; | |
| bool RTCPParseCommonHeader(const uint8_t* ptrDataBegin, | |
| const uint8_t* ptrDataEnd, | |
| RTCPCommonHeader& parsedHeader); | |
| class RTCPParserV2 { | |
| public: | |
| RTCPParserV2( | |
| const uint8_t* rtcpData, | |
| size_t rtcpDataLength, | |
| bool rtcpReducedSizeEnable); // Set to true, to allow non-compound RTCP! | |
| ~RTCPParserV2(); | |
| RTCPPacketTypes PacketType() const; | |
| const RTCPPacket& Packet() const; | |
| const RTCPRawPacket& RawPacket() const; | |
| ptrdiff_t LengthLeft() const; | |
| bool IsValid() const; | |
| RTCPPacketTypes Begin(); | |
| RTCPPacketTypes Iterate(); | |
| private: | |
| enum class ParseState { | |
| State_TopLevel, // Top level packet | |
| State_ReportBlockItem, // SR/RR report block | |
| State_SDESChunk, // SDES chunk | |
| State_BYEItem, // BYE item | |
| State_ExtendedJitterItem, // Extended jitter report item | |
| State_RTPFB_NACKItem, // NACK FCI item | |
| State_RTPFB_TMMBRItem, // TMMBR FCI item | |
| State_RTPFB_TMMBNItem, // TMMBN FCI item | |
| State_PSFB_SLIItem, // SLI FCI item | |
| State_PSFB_RPSIItem, // RPSI FCI item | |
| State_PSFB_FIRItem, // FIR FCI item | |
| State_PSFB_AppItem, // Application specific FCI item | |
| State_PSFB_REMBItem, // Application specific REMB item | |
| State_XRItem, | |
| State_XR_DLLRItem, | |
| State_AppItem | |
| }; | |
| private: | |
| void IterateTopLevel(); | |
| void IterateReportBlockItem(); | |
| void IterateSDESChunk(); | |
| void IterateBYEItem(); | |
| void IterateExtendedJitterItem(); | |
| void IterateNACKItem(); | |
| void IterateTMMBRItem(); | |
| void IterateTMMBNItem(); | |
| void IterateSLIItem(); | |
| void IterateRPSIItem(); | |
| void IterateFIRItem(); | |
| void IteratePsfbAppItem(); | |
| void IteratePsfbREMBItem(); | |
| void IterateAppItem(); | |
| void IterateXrItem(); | |
| void IterateXrDlrrItem(); | |
| void Validate(); | |
| void EndCurrentBlock(); | |
| bool ParseRR(); | |
| bool ParseSR(); | |
| bool ParseReportBlockItem(); | |
| bool ParseSDES(); | |
| bool ParseSDESChunk(); | |
| bool ParseSDESItem(); | |
| bool ParseBYE(); | |
| bool ParseBYEItem(); | |
| bool ParseIJ(); | |
| bool ParseIJItem(); | |
| bool ParseXr(); | |
| bool ParseXrItem(); | |
| bool ParseXrReceiverReferenceTimeItem(int block_length_4bytes); | |
| bool ParseXrDlrr(int block_length_4bytes); | |
| bool ParseXrDlrrItem(); | |
| bool ParseXrVoipMetricItem(int block_length_4bytes); | |
| bool ParseXrUnsupportedBlockType(int block_length_4bytes); | |
| bool ParseFBCommon(const RTCPCommonHeader& header); | |
| bool ParseNACKItem(); | |
| bool ParseTMMBRItem(); | |
| bool ParseTMMBNItem(); | |
| bool ParseSLIItem(); | |
| bool ParseRPSIItem(); | |
| bool ParseFIRItem(); | |
| bool ParsePsfbAppItem(); | |
| bool ParsePsfbREMBItem(); | |
| bool ParseAPP(const RTCPCommonHeader& header); | |
| bool ParseAPPItem(); | |
| private: | |
| const uint8_t* const _ptrRTCPDataBegin; | |
| const bool _RTCPReducedSizeEnable; | |
| const uint8_t* const _ptrRTCPDataEnd; | |
| bool _validPacket; | |
| const uint8_t* _ptrRTCPData; | |
| const uint8_t* _ptrRTCPBlockEnd; | |
| ParseState _state; | |
| uint8_t _numberOfBlocks; | |
| RTCPPacketTypes _packetType; | |
| RTCPPacket _packet; | |
| }; | |
| class RTCPPacketIterator { | |
| public: | |
| RTCPPacketIterator(uint8_t* rtcpData, size_t rtcpDataLength); | |
| ~RTCPPacketIterator(); | |
| const RTCPCommonHeader* Begin(); | |
| const RTCPCommonHeader* Iterate(); | |
| const RTCPCommonHeader* Current(); | |
| private: | |
| uint8_t* const _ptrBegin; | |
| uint8_t* const _ptrEnd; | |
| uint8_t* _ptrBlock; | |
| RTCPCommonHeader _header; | |
| }; | |
| } // RTCPUtility | |
| } // namespace webrtc | |
| #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_ |