Browse Source

Removed unreliable bit fields in RTP structures

Paul-Louis Ageneau 4 years ago
parent
commit
66e9b9dd8b
1 changed files with 103 additions and 105 deletions
  1. 103 105
      include/rtc/rtp.hpp

+ 103 - 105
include/rtc/rtp.hpp

@@ -45,19 +45,22 @@
 
 namespace rtc {
 
+using std::size_t;
+
 typedef uint32_t SSRC;
 
 #pragma pack(push, 1)
 
 struct RTCP_ReportBlock {
-private:
 	SSRC ssrc;
-	uint32_t fractionLostAndPacketsLost; // fraction lost is 8-bit, packets lost is 24-bit
-	uint16_t seqNoCycles;
-	uint16_t highestSeqNo;
-	uint32_t arrivalJitter;
-	uint32_t lastReport;
-	uint32_t delaySinceLastReport;
+
+private:
+	uint32_t _fractionLostAndPacketsLost; // fraction lost is 8-bit, packets lost is 24-bit
+	uint16_t _seqNoCycles;
+	uint16_t _highestSeqNo;
+	uint32_t _jitter;
+	uint32_t _lastReport;
+	uint32_t _delaySinceLastReport;
 
 public:
 	void print() {
@@ -65,8 +68,8 @@ public:
 		    // TODO Implement these reports
 		    //			  " fractionLost: " << fractionLost <<
 		    //			  " packetsLost: " << packetsLost <<
-		    " highestSeqNo:" << getHighestSeqNo() << " seqNoCycles:" << getSeqCycleCount()
-		          << " jitter:" << getJitter() << " lastSR:" << getNTPOfSR()
+		    " highestSeqNo:" << highestSeqNo() << " seqNoCycles:" << seqNoCycles()
+		          << " jitter:" << jitter() << " lastSR:" << getNTPOfSR()
 		          << " lastSRDelay:" << getDelaySinceSR();
 	}
 
@@ -93,7 +96,7 @@ public:
 	void inline setPacketsLost([[maybe_unused]] unsigned int packetsLost,
 	                           [[maybe_unused]] unsigned int totalPackets) {
 		// TODO Implement loss percentages.
-		this->fractionLostAndPacketsLost = 0;
+		_fractionLostAndPacketsLost = 0;
 	}
 	unsigned int inline getLossPercentage() const {
 		// TODO Implement loss percentages.
@@ -104,82 +107,79 @@ public:
 		return 0;
 	}
 
+	uint16_t inline seqNoCycles() const { return ntohs(_seqNoCycles); }
+	uint16_t inline highestSeqNo() const { return ntohs(_highestSeqNo); }
+	uint32_t inline jitter() const { return ntohl(_jitter); }
+
 	void inline setSeqNo(uint16_t highestSeqNo, uint16_t seqNoCycles) {
-		this->highestSeqNo = htons(highestSeqNo);
-		this->seqNoCycles = htons(seqNoCycles);
+		_highestSeqNo = htons(highestSeqNo);
+		_seqNoCycles = htons(seqNoCycles);
 	}
 
-	uint16_t inline getHighestSeqNo() const { return ntohs(this->highestSeqNo); }
-	uint16_t inline getSeqCycleCount() const { return ntohs(this->seqNoCycles); }
+	void inline setJitter(uint32_t jitter) { _jitter = htonl(jitter); }
 
-	uint32_t inline getJitter() const { return ntohl(arrivalJitter); }
-	void inline setJitter(uint32_t jitter) { this->arrivalJitter = htonl(jitter); }
+	void inline setNTPOfSR(uint32_t ntp) { _lastReport = htonl(ntp >> 16u); }
+	inline uint32_t getNTPOfSR() const { return ntohl(_lastReport) << 16u; }
 
-	void inline setNTPOfSR(uint32_t ntp) { lastReport = htonl(ntp >> 16u); }
-	inline uint32_t getNTPOfSR() const { return ntohl(lastReport) << 16u; }
 	inline void setDelaySinceSR(uint32_t sr) {
 		// The delay, expressed in units of 1/65536 seconds
-		delaySinceLastReport = htonl(sr);
+		_delaySinceLastReport = htonl(sr);
 	}
-	inline uint32_t getDelaySinceSR() const { return ntohl(delaySinceLastReport); }
+	inline uint32_t getDelaySinceSR() const { return ntohl(_delaySinceLastReport); }
 };
 
 struct RTCP_HEADER {
 private:
-	uint8_t version : 2;
-	uint8_t padding : 1;
-	uint8_t reportCount : 5;
-	uint8_t payloadType;
-	uint16_t length;
+	uint8_t _first;
+	uint8_t _payloadType;
+	uint16_t _length;
 
 public:
-	void prepareHeader(uint8_t payloadType, unsigned int reportCount, uint16_t length) {
-		version = 2;
-		padding = false;
-		this->payloadType = payloadType;
-		this->reportCount = reportCount;
+	inline uint8_t version() const { return _first >> 6; }
+	inline bool padding() const { return (_first >> 5) & 0x01; }
+	inline uint8_t reportCount() const { return _first & 0x0F; }
+	inline uint8_t payloadType() const { return _payloadType; }
+	inline uint16_t length() const { return ntohs(_length); }
+
+	inline void setPayloadType(uint8_t type) { _payloadType = type; }
+	inline void setReportCount(uint8_t count) { _first = (_first & 0xF0) | (count & 0x0F); }
+	inline void setLength(uint16_t length) { _length = htons(length); }
+
+	void prepareHeader(uint8_t payloadType, uint8_t reportCount, uint16_t length) {
+		_first = 0x02 << 6; // version 2, no padding
+		setReportCount(reportCount);
+		setPayloadType(payloadType);
 		setLength(length);
 	}
 
-	inline uint8_t getPayloadType() const { return payloadType; }
-	inline void setPayloadType(uint8_t payloadType) { this->payloadType = payloadType; }
-
-	inline uint8_t getReportCount() const { return reportCount; }
-	inline void setReportCount(uint8_t reportCount) { this->reportCount = reportCount; }
-
-	inline uint16_t getLength() const { return ntohs(length); }
-	inline void setLength(uint16_t length) { this->length = htons(length); }
-
 	void print() {
-		std::cout << "version:" << (uint16_t)version << " padding:" << (padding ? "T" : "F")
-		          << " reportCount: " << (uint16_t)getReportCount()
-		          << " payloadType:" << (uint16_t)getPayloadType() << " length: " << getLength();
+		std::cout << "version:" << unsigned(version()) << " padding:" << (padding() ? "T" : "F")
+		          << " reportCount: " << unsigned(reportCount())
+		          << " payloadType:" << unsigned(payloadType()) << " length: " << length();
 	}
 };
 
 struct RTCP_SR {
-private:
 	RTCP_HEADER header;
-
 	SSRC senderSSRC;
 
-	uint64_t ntpTimestamp;
-	uint32_t rtpTimestamp;
-
-	uint32_t packetCount;
-	uint32_t octetCount;
+private:
+	uint64_t _ntpTimestamp;
+	uint32_t _rtpTimestamp;
+	uint32_t _packetCount;
+	uint32_t _octetCount;
 
-	RTCP_ReportBlock reportBlocks;
+	RTCP_ReportBlock _reportBlocks;
 
 public:
 	void print() {
 		std::cout << "SR ";
 		header.print();
-		std::cout << " SSRC:" << ntohl(senderSSRC) << " NTP TS: " << ntohll(ntpTimestamp)
-		          << " RTP TS: " << ntohl(rtpTimestamp) << " packetCount: " << ntohl(packetCount)
-		          << " octetCount: " << ntohl(octetCount) << std::endl;
+		std::cout << " SSRC:" << ntohl(senderSSRC) << " NTP TS: " << ntpTimestamp()
+		          << " RTP TS: " << rtpTimestamp() << " packetCount: " << packetCount()
+		          << " octetCount: " << octetCount() << std::endl;
 
-		for (int i = 0; i < header.getReportCount(); i++) {
+		for (unsigned i = 0; i < unsigned(header.reportCount()); i++) {
 			getReportBlock(i)->print();
 			std::cout << std::endl;
 		}
@@ -187,30 +187,33 @@ public:
 
 	inline void preparePacket(SSRC senderSSRC, uint8_t reportCount) {
 		unsigned int length =
-		    ((offsetof(RTCP_SR, reportBlocks) + reportCount * sizeof(RTCP_ReportBlock)) / 4) - 1;
-		header.prepareHeader(200, reportCount, length);
-		this->senderSSRC = senderSSRC;
+		    ((sizeof(header) + 24 + reportCount * sizeof(RTCP_ReportBlock)) / 4) - 1;
+		header.prepareHeader(200, reportCount, uint16_t(length));
+		this->senderSSRC = htonl(senderSSRC);
 	}
 
-	RTCP_ReportBlock *getReportBlock(int num) { return &reportBlocks + num; }
+	RTCP_ReportBlock *getReportBlock(int num) { return &_reportBlocks + num; }
 
-	[[nodiscard]] unsigned int getSize() const {
+	[[nodiscard]] size_t getSize() const {
 		// "length" in packet is one less than the number of 32 bit words in the packet.
-		return sizeof(uint32_t) * (1 + header.getLength());
+		return sizeof(uint32_t) * (1 + size_t(header.length()));
 	}
 
-	inline uint32_t getRTPTS() const { return ntohl(rtpTimestamp); }
-	inline uint32_t getNTPTS() const { return ntohll(ntpTimestamp); }
+	inline uint32_t ntpTimestamp() const { return ntohll(_ntpTimestamp); }
+	inline uint32_t rtpTimestamp() const { return ntohl(_rtpTimestamp); }
+	inline uint32_t packetCount() const { return ntohl(_packetCount); }
+	inline uint32_t octetCount() const { return ntohl(_octetCount); }
 
-	inline void setRTPTS(uint32_t ts) { this->rtpTimestamp = htonl(ts); }
-	inline void setNTPTS(uint32_t ts) { this->ntpTimestamp = htonll(ts); }
+	inline void setNtpTimestamp(uint32_t ts) { _ntpTimestamp = htonll(ts); }
+	inline void setRtpTimestamp(uint32_t ts) { _rtpTimestamp = htonl(ts); }
 };
 
 struct RTCP_RR {
-private:
 	RTCP_HEADER header;
 	SSRC senderSSRC;
-	RTCP_ReportBlock reportBlocks;
+
+private:
+	RTCP_ReportBlock _reportBlocks;
 
 public:
 	void print() {
@@ -218,56 +221,51 @@ public:
 		header.print();
 		std::cout << " SSRC:" << ntohl(senderSSRC) << std::endl;
 
-		for (int i = 0; i < header.getReportCount(); i++) {
+		for (unsigned i = 0; i < unsigned(header.reportCount()); i++) {
 			getReportBlock(i)->print();
 			std::cout << std::endl;
 		}
 	}
-	RTCP_ReportBlock *getReportBlock(int num) { return &reportBlocks + num; }
-
-	inline RTCP_HEADER &getHeader() { return header; }
+	RTCP_ReportBlock *getReportBlock(int num) { return &_reportBlocks + num; }
 
 	inline SSRC getSenderSSRC() const { return ntohl(senderSSRC); }
+	inline void setSenderSSRC(SSRC ssrc) { this->senderSSRC = htonl(ssrc); }
 
-	inline void setSenderSSRC(SSRC ssrc) { this->senderSSRC = ssrc; }
-
-	[[nodiscard]] inline unsigned int getSize() const {
+	[[nodiscard]] inline size_t getSize() const {
 		// "length" in packet is one less than the number of 32 bit words in the packet.
-		return sizeof(uint32_t) * (1 + header.getLength());
+		return sizeof(uint32_t) * (1 + size_t(header.length()));
 	}
 
 	inline void preparePacket(SSRC senderSSRC, uint8_t reportCount) {
-		//		  version = 2;
-		//		  padding = false;
-		//		  this->reportCount = reportCount;
-		//		  payloadType = 201;
-		//		  // "length" in packet is one less than the number of 32 bit words in the packet.
-		unsigned int length =
-		    ((offsetof(RTCP_RR, reportBlocks) + reportCount * sizeof(RTCP_ReportBlock)) / 4) - 1;
-		header.prepareHeader(201, reportCount, length);
+		// "length" in packet is one less than the number of 32 bit words in the packet.
+		size_t length = (sizeWithReportBlocks(reportCount) / 4) - 1;
+		header.prepareHeader(201, reportCount, uint16_t(length));
 		this->senderSSRC = htonl(senderSSRC);
 	}
 
-	static unsigned inline int sizeWithReportBlocks(int reportCount) {
-		return offsetof(RTCP_RR, reportBlocks) + reportCount * sizeof(RTCP_ReportBlock);
+	inline static size_t sizeWithReportBlocks(uint8_t reportCount) {
+		return sizeof(header) + 4 + size_t(reportCount) * sizeof(RTCP_ReportBlock);
 	}
 };
 
 struct RTP
 {
-	uint8_t version : 2;
-	uint8_t padding : 1;
-	uint8_t extension : 1;
-	uint8_t csrcCount : 4;
-	uint8_t markerBit : 1;
-	uint8_t payloadType : 7;
-	uint16_t seqNumber;
-	uint32_t timestamp;
+private:
+	uint8_t _first;
+	uint8_t _payloadType;
+	uint16_t _seqNumber;
+	uint32_t _timestamp;
+
+public:
 	SSRC ssrc;
 	SSRC csrc[16];
 
-	inline uint32_t getSeqNo() const { return ntohs(seqNumber); }
-	inline uint32_t getTS() const { return ntohl(timestamp); }
+	inline uint8_t version() const { return _first >> 6; }
+	inline bool padding() const { return (_first >> 5) & 0x01; }
+	inline uint8_t csrcCount() const { return _first & 0x0F; }
+	inline uint8_t payloadType() const { return _payloadType; }
+	inline uint16_t seqNumber() const { return ntohs(_seqNumber); }
+	inline uint32_t timestamp() const { return ntohl(_timestamp); }
 };
 
 struct RTCP_REMB {
@@ -284,9 +282,9 @@ struct RTCP_REMB {
 
 	SSRC ssrc[1];
 
-	[[nodiscard]] unsigned int getSize() const {
+	[[nodiscard]] size_t getSize() const {
 		// "length" in packet is one less than the number of 32 bit words in the packet.
-		return sizeof(uint32_t) * (1 + header.getLength());
+		return sizeof(uint32_t) * (1 + size_t(header.length()));
 	}
 
 	void preparePacket(SSRC senderSSRC, unsigned int numSSRC, unsigned int bitrate) {
@@ -363,25 +361,25 @@ public:
 			RTP *rtp = (RTP *)ptr->data();
 
 			// https://tools.ietf.org/html/rfc3550#appendix-A.1
-			if (rtp->version != 2) {
+			if (rtp->version() != 2) {
 				PLOG_WARNING << "RTP packet is not version 2";
 
 				return std::nullopt;
 			}
-			if (rtp->payloadType == 201 || rtp->payloadType == 200) {
+			if (rtp->payloadType() == 201 || rtp->payloadType() == 200) {
 				PLOG_WARNING << "RTP packet has a payload type indicating RR/SR";
 
 				return std::nullopt;
 			}
 
 			// TODO Implement the padding bit
-			if (rtp->padding) {
+			if (rtp->padding()) {
 				PLOG_WARNING << "Padding processing not implemented";
 			}
 
 			ssrc = ntohl(rtp->ssrc);
 
-			uint32_t seqNo = rtp->getSeqNo();
+			uint32_t seqNo = rtp->seqNumber();
 			// uint32_t rtpTS = rtp->getTS();
 
 			if (greatestSeqNo < seqNo)
@@ -392,17 +390,17 @@ public:
 
 		assert(ptr->type == rtc::Message::Type::Control);
 		auto rr = (RTCP_RR *)ptr->data();
-		if (rr->getHeader().getPayloadType() == 201) {
+		if (rr->header.payloadType() == 201) {
 			// RR
 			ssrc = rr->getSenderSSRC();
 			rr->print();
 			std::cout << std::endl;
-		} else if (rr->getHeader().getPayloadType() == 200) {
+		} else if (rr->header.payloadType() == 200) {
 			// SR
 			ssrc = rr->getSenderSSRC();
 			auto sr = (RTCP_SR *)ptr->data();
-			syncRTPTS = sr->getRTPTS();
-			syncNTPTS = sr->getNTPTS();
+			syncRTPTS = sr->rtpTimestamp();
+			syncNTPTS = sr->ntpTimestamp();
 			sr->print();
 			std::cout << std::endl;
 
@@ -435,7 +433,7 @@ private:
 	}
 
 	void pushRR(unsigned int lastSR_delay) {
-		//		  std::cout << "size " << RTCP_RR::sizeWithReportBlocks(1) << std::endl;
+		// std::cout << "size " << RTCP_RR::sizeWithReportBlocks(1) << std::endl;
 		auto msg = rtc::make_message(RTCP_RR::sizeWithReportBlocks(1), rtc::Message::Type::Control);
 		auto rr = (RTCP_RR *)msg->data();
 		rr->preparePacket(ssrc, 1);