blob: 629de4e99ec83d1691d9c195943ba2ffaa9b718d [file] [log] [blame]
/*
* 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 <memory>
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h"
#include "webrtc/typedefs.h"
namespace webrtc {
namespace rtcp {
class RtcpPacket;
}
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,
kPsfbRpsiItem,
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,
// draft-holmer-rmcat-transport-wide-cc-extensions
kTransportFeedback,
};
struct RTCPRawPacket {
const uint8_t* _ptrPacketBegin;
const uint8_t* _ptrPacketEnd;
};
struct RTCPModRawPacket {
uint8_t* _ptrPacketBegin;
uint8_t* _ptrPacketEnd;
};
struct RtcpCommonHeader {
static const uint8_t kHeaderSizeBytes = 4;
RtcpCommonHeader()
: version(2),
count_or_format(0),
packet_type(0),
payload_size_bytes(0),
padding_bytes(0) {}
uint32_t BlockSize() const {
return kHeaderSizeBytes + payload_size_bytes + padding_bytes;
}
uint8_t version;
uint8_t count_or_format;
uint8_t packet_type;
uint32_t payload_size_bytes;
uint8_t padding_bytes;
};
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* buffer,
size_t size_bytes,
RtcpCommonHeader* parsed_header);
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;
rtcp::RtcpPacket* ReleaseRtcpPacket();
const RTCPRawPacket& RawPacket() const;
ptrdiff_t LengthLeft() const;
bool IsValid() const;
size_t NumSkippedBlocks() 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;
size_t num_skipped_blocks_;
RTCPPacketTypes _packetType;
RTCPPacket _packet;
std::unique_ptr<webrtc::rtcp::RtcpPacket> rtcp_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;
};
} // namespace RTCPUtility
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_UTILITY_H_