Browse Source

Add Simulcast sender support

Sean DuBois 2 years ago
parent
commit
f39a85a39f
4 changed files with 50 additions and 5 deletions
  1. 3 0
      include/rtc/description.hpp
  2. 1 0
      include/rtc/rtp.hpp
  3. 35 2
      src/description.cpp
  4. 11 3
      src/rtp.cpp

+ 3 - 0
include/rtc/description.hpp

@@ -91,6 +91,7 @@ public:
 		std::vector<string> attributes() const;
 		void addAttribute(string attr);
 		void removeAttribute(const string &attr);
+		void addRid(string rid);
 
 		struct RTC_CPP_EXPORT ExtMap {
 			static int parseId(string_view description);
@@ -119,6 +120,7 @@ public:
 
 	protected:
 		Entry(const string &mline, string mid, Direction dir = Direction::Unknown);
+
 		virtual string generateSdpLines(string_view eol) const;
 
 		std::vector<string> mAttributes;
@@ -128,6 +130,7 @@ public:
 		string mType;
 		string mDescription;
 		string mMid;
+		std::vector<string> mRids;
 		Direction mDirection;
 		bool mIsRemoved;
 	};

+ 1 - 0
include/rtc/rtp.hpp

@@ -39,6 +39,7 @@ struct RTC_CPP_EXPORT RtpExtensionHeader {
 
 	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);
 };
 
 struct RTC_CPP_EXPORT RtpHeader {

+ 35 - 2
src/description.cpp

@@ -532,6 +532,10 @@ void Description::addAttribute(string attr) {
 		mAttributes.emplace_back(std::move(attr));
 }
 
+void Description::Entry::addRid(string rid) {
+	mRids.emplace_back(rid);
+}
+
 void Description::removeAttribute(const string &attr) {
 	mAttributes.erase(
 	    std::remove_if(mAttributes.begin(), mAttributes.end(),
@@ -597,8 +601,34 @@ string Description::Entry::generateSdpLines(string_view eol) const {
 	if (mDirection != Direction::Unknown)
 		sdp << "a=" << mDirection << eol;
 
-	for (const auto &attr : mAttributes)
+	for (const auto &attr : mAttributes) {
+		if (mRids.size() != 0 && match_prefix(attr, "ssrc:")) {
+			continue;
+		}
+
 		sdp << "a=" << attr << eol;
+	}
+
+	for (const auto &rid : mRids) {
+		sdp << "a=rid:" << rid << " send" << eol;
+	}
+
+	if (mRids.size() != 0) {
+		sdp << "a=simulcast:send ";
+
+		bool first = true;
+		for (const auto &rid : mRids) {
+			if (first) {
+				first = false;
+			} else {
+				sdp << ";";
+			}
+
+			sdp << rid;
+		}
+
+		sdp << eol;
+	}
 
 	return sdp.str();
 }
@@ -695,9 +725,12 @@ void Description::Media::addSSRC(uint32_t ssrc, optional<string> name, optional<
 		mAttributes.emplace_back("ssrc:" + std::to_string(ssrc));
 	}
 
-	if (msid)
+	if (msid) {
 		mAttributes.emplace_back("ssrc:" + std::to_string(ssrc) + " msid:" + *msid + " " +
 		                         trackId.value_or(*msid));
+		mAttributes.emplace_back("msid:" + *msid + " " +
+				trackId.value_or(*msid));
+	}
 
 	mSsrcs.emplace_back(ssrc);
 }

+ 11 - 3
src/rtp.cpp

@@ -130,12 +130,20 @@ void RtpExtensionHeader::setHeaderLength(uint16_t headerLength) {
 
 void RtpExtensionHeader::clearBody() { std::memset(getBody(), 0, getSize()); }
 
-void RtpExtensionHeader::writeCurrentVideoOrientation(size_t offset, uint8_t id, uint8_t value) {
-	if ((id == 0) || (id > 14) || ((offset + 2) > getSize()))
+void 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()))
 		return;
 	auto buf = getBody() + offset;
 	buf[0] = id << 4;
-	buf[1] = value;
+	if (size != 1) {
+		buf[0] |= (uint8_t(size) - 1);
+	}
+	std::memcpy(buf + 1, value, size);
+}
+
+void RtpExtensionHeader::writeCurrentVideoOrientation(size_t offset, const uint8_t id, uint8_t value) {
+	auto v = std::byte{value};
+	writeOneByteHeader(offset, id, &v, 1);
 }
 
 SSRC RtcpReportBlock::getSSRC() const { return ntohl(_ssrc); }