Browse Source

Merge pull request #918 from Sean-Der/simulcast

Add Simulcast support to RtpPacketizer
Paul-Louis Ageneau 2 years ago
parent
commit
709a663394
2 changed files with 63 additions and 11 deletions
  1. 10 1
      include/rtc/rtppacketizationconfig.hpp
  2. 53 10
      src/rtppacketizer.cpp

+ 10 - 1
include/rtc/rtppacketizationconfig.hpp

@@ -18,7 +18,7 @@ namespace rtc {
 // RTP configuration used in packetization process
 class RTC_CPP_EXPORT RtpPacketizationConfig {
 public:
-	const SSRC ssrc;
+	SSRC ssrc;
 	const std::string cname;
 	const uint8_t payloadType;
 	const uint32_t clockRate;
@@ -53,6 +53,15 @@ public:
 	///   3 - 270 degrees
 	uint8_t videoOrientation = 0;
 
+
+	// MID Extension Header
+	uint8_t midId = 0;
+	optional<std::string> mid;
+
+	// RID Extension Header
+	uint8_t ridId = 0;
+	optional<std::string> rid;
+
 	/// Construct RTP configuration used in packetization process
 	/// @param ssrc SSRC of source
 	/// @param cname CNAME of source

+ 53 - 10
src/rtppacketizer.cpp

@@ -10,6 +10,7 @@
 
 #include "rtppacketizer.hpp"
 
+#include <cmath>
 #include <cstring>
 
 namespace rtc {
@@ -17,15 +18,30 @@ namespace rtc {
 RtpPacketizer::RtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig) : rtpConfig(rtpConfig) {}
 
 binary_ptr RtpPacketizer::packetize(shared_ptr<binary> payload, bool setMark) {
-	int rtpExtHeaderSize = 0;
-	const bool setVideoRotation =
-		(rtpConfig->videoOrientationId != 0) &&
-		(rtpConfig->videoOrientationId < 15) &&  // needs fixing if longer extension headers are supported
-		setMark &&
-		(rtpConfig->videoOrientation != 0);
+	size_t rtpExtHeaderSize = 0;
+
+	const bool setVideoRotation = (rtpConfig->videoOrientationId != 0) &&
+	                              (rtpConfig->videoOrientationId <
+	                               15) && // needs fixing if longer extension headers are supported
+	                              setMark &&
+	                              (rtpConfig->videoOrientation != 0);
+
 	if (setVideoRotation) {
-		rtpExtHeaderSize = rtpExtHeaderCvoSize;
+		rtpExtHeaderSize += 2;
 	}
+
+	if (rtpConfig->mid.has_value()) {
+		rtpExtHeaderSize += (1 + rtpConfig->mid->length());
+	}
+
+	if (rtpConfig->rid.has_value()) {
+		rtpExtHeaderSize += (1 + rtpConfig->rid->length());
+	}
+
+	if (rtpExtHeaderSize != 0) {
+		rtpExtHeaderSize += 4;
+	}
+
 	auto msg = std::make_shared<binary>(rtpHeaderSize + rtpExtHeaderSize + payload->size());
 	auto *rtp = (RtpHeader *)msg->data();
 	rtp->setPayloadType(rtpConfig->payloadType);
@@ -33,19 +49,46 @@ binary_ptr RtpPacketizer::packetize(shared_ptr<binary> payload, bool setMark) {
 	rtp->setSeqNumber(rtpConfig->sequenceNumber++);
 	rtp->setTimestamp(rtpConfig->timestamp);
 	rtp->setSsrc(rtpConfig->ssrc);
+
 	if (setMark) {
 		rtp->setMarker(true);
 	}
+
 	if (rtpExtHeaderSize) {
 		rtp->setExtension(true);
 
 		auto extHeader = rtp->getExtensionHeader();
 		extHeader->setProfileSpecificId(0xbede);
-		extHeader->setHeaderLength(1);
+
+		auto headerLength = static_cast<uint16_t>(rtpExtHeaderSize - 4);
+		headerLength = static_cast<uint16_t>((headerLength + 3) / 4);
+
+		extHeader->setHeaderLength(headerLength);
 		extHeader->clearBody();
-		extHeader->writeCurrentVideoOrientation(0,
-			rtpConfig->videoOrientationId, rtpConfig->videoOrientation);
+
+		size_t offset = 0;
+		if (setVideoRotation) {
+			extHeader->writeCurrentVideoOrientation(offset, rtpConfig->videoOrientationId,
+			                                        rtpConfig->videoOrientation);
+			offset += 2;
+		}
+
+		if (rtpConfig->mid.has_value()) {
+			extHeader->writeOneByteHeader(
+			    offset, rtpConfig->midId,
+			    reinterpret_cast<const std::byte *>(rtpConfig->mid->c_str()),
+			    rtpConfig->mid->length());
+			offset += (1 + rtpConfig->mid->length());
+		}
+
+		if (rtpConfig->rid.has_value()) {
+			extHeader->writeOneByteHeader(
+			    offset, rtpConfig->ridId,
+			    reinterpret_cast<const std::byte *>(rtpConfig->rid->c_str()),
+			    rtpConfig->rid->length());
+		}
 	}
+
 	rtp->preparePacket();
 	std::memcpy(msg->data() + rtpHeaderSize + rtpExtHeaderSize, payload->data(), payload->size());
 	return msg;