Paul-Louis Ageneau преди 1 година
родител
ревизия
9e0072a178
променени са 5 файла, в които са добавени 86 реда и са изтрити 14 реда
  1. 3 2
      include/rtc/rtp.hpp
  2. 1 1
      src/description.cpp
  3. 37 0
      src/impl/track.cpp
  4. 2 0
      src/impl/track.hpp
  5. 43 11
      src/rtp.cpp

+ 3 - 2
include/rtc/rtp.hpp

@@ -38,8 +38,9 @@ struct RTC_CPP_EXPORT RtpExtensionHeader {
 	void setHeaderLength(uint16_t headerLength);
 	void setHeaderLength(uint16_t headerLength);
 
 
 	void clearBody();
 	void clearBody();
-	void writeCurrentVideoOrientation(size_t offset, uint8_t id, uint8_t value);
-	void writeOneByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
+	size_t writeCurrentVideoOrientation(size_t offset, uint8_t id, uint8_t value);
+	size_t writeOneByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
+	size_t readOneByteHeader(size_t offset, uint8_t *id, const byte **value, size_t *size) const;
 };
 };
 
 
 struct RTC_CPP_EXPORT RtpHeader {
 struct RTC_CPP_EXPORT RtpHeader {

+ 1 - 1
src/description.cpp

@@ -595,7 +595,7 @@ int Description::Entry::nextExtId() const {
 	// RFC 8285: In the signaling section, the range 1-256 is referred to as the valid range, with
 	// RFC 8285: In the signaling section, the range 1-256 is referred to as the valid range, with
 	// the values 1-255 referring to extension elements and the value 256 referring to the 4-bit
 	// the values 1-255 referring to extension elements and the value 256 referring to the 4-bit
 	// appbits field.
 	// appbits field.
-	for (int i = 1; i < 255; ++i)
+	for (int i = 1; i <= 255; ++i)
 		if (mExtMaps.find(i) == mExtMaps.end())
 		if (mExtMaps.find(i) == mExtMaps.end())
 			return i;
 			return i;
 
 

+ 37 - 0
src/impl/track.cpp

@@ -238,4 +238,41 @@ shared_ptr<MediaHandler> Track::getMediaHandler() {
 	return mMediaHandler;
 	return mMediaHandler;
 }
 }
 
 
+
+void Track::tagWithMid(message_ptr message) {
+	// TODO: lock
+	if(IsRtcp(*message)) {
+
+	} else {
+		if(!mSdesMidExtId)
+			return;
+
+		if(message->size() < sizeof(RtpHeader)) {
+			const string mid =mMediaDescription.mid();
+			const size_t sdesMidExtLength = 1 + mid.size();
+
+			auto *header = reinterpret_cast<RtpHeader*>(message->data());
+			if(header->extension()) {
+				auto *extHeader = header->getExtensionHeader();
+				if(extHeader->profileSpecificId() != 0xbede) // TODO: check in RtpHeader
+					return;
+
+				size_t extHeaderLength = extHeader->headerLength(); // TODO: actually used length
+				size_t newExtHeaderLength = (extHeaderLength + sdesMidExtLength + 3) / 4;
+				message->insert(message->begin() + header->getSize(), newExtHeaderLength - extHeaderLength, byte(0));
+				extHeader->setHeaderLength(static_cast<uint16_t>(newExtHeaderLength));
+				extHeader->writeOneByteHeader(extHeaderLength, *mSdesMidExtId, reinterpret_cast<const std::byte *>(mid.c_str()), mid.size());
+			} else {
+				size_t extHeaderLength = (sdesMidExtLength + 3) / 4;
+				message->insert(message->begin() + header->getSize(), sizeof(RtpExtensionHeader) + extHeaderLength, byte(0));
+				header->setExtension(true);
+				auto *extHeader = header->getExtensionHeader();
+				extHeader->setProfileSpecificId(0xbede);
+				extHeader->setHeaderLength(static_cast<uint16_t>(extHeaderLength));
+				extHeader->writeOneByteHeader(0, *mSdesMidExtId, reinterpret_cast<const std::byte *>(mid.c_str()), mid.size());
+			}
+		}
+	}
+}
+
 } // namespace rtc::impl
 } // namespace rtc::impl

+ 2 - 0
src/impl/track.hpp

@@ -59,8 +59,10 @@ public:
 
 
 private:
 private:
 	const weak_ptr<PeerConnection> mPeerConnection;
 	const weak_ptr<PeerConnection> mPeerConnection;
+
 #if RTC_ENABLE_MEDIA
 #if RTC_ENABLE_MEDIA
 	weak_ptr<DtlsSrtpTransport> mDtlsSrtpTransport;
 	weak_ptr<DtlsSrtpTransport> mDtlsSrtpTransport;
+	void tagWithMid(message_ptr message);
 #endif
 #endif
 
 
 	Description::Media mMediaDescription;
 	Description::Media mMediaDescription;

+ 43 - 11
src/rtp.cpp

@@ -130,22 +130,52 @@ void RtpExtensionHeader::setHeaderLength(uint16_t headerLength) {
 
 
 void RtpExtensionHeader::clearBody() { std::memset(getBody(), 0, getSize()); }
 void RtpExtensionHeader::clearBody() { std::memset(getBody(), 0, getSize()); }
 
 
-void RtpExtensionHeader::writeOneByteHeader(size_t offset, uint8_t id, const byte *value,
-                                            size_t size) {
+size_t RtpExtensionHeader::writeOneByteHeader(size_t offset, uint8_t id, const byte *value,
+                                              size_t size) {
 	if ((id == 0) || (id > 14) || (size == 0) || (size > 16) || ((offset + 1 + size) > getSize()))
 	if ((id == 0) || (id > 14) || (size == 0) || (size > 16) || ((offset + 1 + size) > getSize()))
-		return;
-	auto buf = getBody() + offset;
+		return offset;
+
+	auto *buf = getBody() + offset;
 	buf[0] = id << 4;
 	buf[0] = id << 4;
-	if (size != 1) {
-		buf[0] |= (uint8_t(size) - 1);
-	}
+	buf[0] |= (uint8_t(size) - 1);
 	std::memcpy(buf + 1, value, size);
 	std::memcpy(buf + 1, value, size);
+
+	return offset + 1 + size;
 }
 }
 
 
-void RtpExtensionHeader::writeCurrentVideoOrientation(size_t offset, const uint8_t id,
-                                                      uint8_t value) {
+size_t RtpExtensionHeader::writeCurrentVideoOrientation(size_t offset, const uint8_t id,
+                                                        uint8_t value) {
 	auto v = std::byte{value};
 	auto v = std::byte{value};
-	writeOneByteHeader(offset, id, &v, 1);
+	return writeOneByteHeader(offset, id, &v, 1);
+}
+
+size_t RtpExtensionHeader::readOneByteHeader(size_t offset, uint8_t *id, const byte **value,
+                                             size_t *size) const {
+	do {
+		if (offset + 1 > getSize()) {
+			if (id)
+				*id = 0;
+			if (value)
+				*value = 0;
+			if (size)
+				*size = 0;
+			return offset;
+		}
+	} while (*(getBody() + offset) == 0); // padding
+
+	const auto *buf = getBody() + offset;
+	size_t s = buf[0] & 0x0F + 1;
+
+	if (offset + 1 + s > getSize())
+		throw std::invalid_argument("RTP one-byte extension overflows extension header");
+
+	if (id)
+		*id = buf[0] >> 4;
+	if (value)
+		*value = reinterpret_cast<const byte *>(buf + 1);
+	if (size)
+		*size = s;
+	return offset + 1 + s;
 }
 }
 
 
 SSRC RtcpReportBlock::getSSRC() const { return ntohl(_ssrc); }
 SSRC RtcpReportBlock::getSSRC() const { return ntohl(_ssrc); }
@@ -188,7 +218,9 @@ uint16_t RtcpReportBlock::seqNoCycles() const { return ntohs(_seqNoCycles); }
 
 
 uint16_t RtcpReportBlock::highestSeqNo() const { return ntohs(_highestSeqNo); }
 uint16_t RtcpReportBlock::highestSeqNo() const { return ntohs(_highestSeqNo); }
 
 
-uint32_t RtcpReportBlock::extendedHighestSeqNo() const { return (seqNoCycles() <<  16) | highestSeqNo(); }
+uint32_t RtcpReportBlock::extendedHighestSeqNo() const {
+	return (seqNoCycles() << 16) | highestSeqNo();
+}
 
 
 uint32_t RtcpReportBlock::jitter() const { return ntohl(_jitter); }
 uint32_t RtcpReportBlock::jitter() const { return ntohl(_jitter); }