Browse Source

Keep m-line order in description

Paul-Louis Ageneau 5 years ago
parent
commit
cd28340de3
2 changed files with 33 additions and 27 deletions
  1. 1 1
      include/rtc/description.hpp
  2. 32 26
      src/description.cpp

+ 1 - 1
include/rtc/description.hpp

@@ -87,7 +87,7 @@ private:
 		string mid;
 		std::vector<string> attributes;
 	};
-	std::map<string, Media> mMedia; // by mid
+	std::map<int, Media> mMedia; // by m-line index
 
 	// Candidates
 	std::vector<Candidate> mCandidates;

+ 32 - 26
src/description.cpp

@@ -63,6 +63,7 @@ Description::Description(const string &sdp, Type type, Role role)
 	std::istringstream ss(sdp);
 	std::optional<Media> currentMedia;
 
+	int mlineIndex = 0;
 	bool finished;
 	do {
 		string line;
@@ -76,7 +77,9 @@ Description::Description(const string &sdp, Type type, Role role)
 					if (currentMedia->type == "application")
 						mData.mid = currentMedia->mid;
 					else
-						mMedia.emplace(currentMedia->mid, std::move(*currentMedia));
+						mMedia.emplace(mlineIndex, std::move(*currentMedia));
+
+					++mlineIndex;
 
 				} else if (line.find(" ICE/SDP") != string::npos) {
 					PLOG_WARNING << "SDP \"m=\" line has no corresponding mid, ignoring";
@@ -190,10 +193,7 @@ bool Description::hasMedia() const { return !mMedia.empty(); }
 
 void Description::addMedia(const Description &source) {
 	for (auto p : source.mMedia)
-		if (p.first != mData.mid)
-			mMedia.emplace(std::move(p));
-		else
-			PLOG_WARNING << "Media mid \"" << p.first << "\" is the same as data mid, ignoring";
+		mMedia.emplace(p);
 }
 
 Description::operator string() const { return generateSdp("\r\n"); }
@@ -214,9 +214,12 @@ string Description::generateSdp(const string &eol) const {
 	// see Negotiating Media Multiplexing Using the Session Description Protocol
 	// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-54
 	sdp << "a=group:BUNDLE";
-	for (const auto &m : mMedia)
-		sdp << " " << m.first; // mid
-	sdp << " " << mData.mid << eol;
+	for (int i = 0; i < mMedia.size() + 1; ++i)
+		if (auto it = mMedia.find(i); it != mMedia.end())
+			sdp << ' ' << it->second.mid;
+		else
+			sdp << ' ' << mData.mid;
+	sdp << eol;
 
 	sdp << "a=msid-semantic: WMS" << eol;
 
@@ -224,35 +227,38 @@ string Description::generateSdp(const string &eol) const {
 	if (!mMedia.empty()) {
 		// Lip-sync
 		sdp << "a=group:LS";
-		for (const auto &m : mMedia)
-			sdp << " " << m.first; // mid
+		for (const auto &p : mMedia)
+			sdp << " " << p.second.mid;
 		sdp << eol;
+	}
 
-		// Descriptions and attributes
-		for (const auto &m : mMedia) {
-			const auto &media = m.second;
+	// Descriptions and attributes
+	for (int i = 0; i < mMedia.size() + 1; ++i) {
+		if (auto it = mMedia.find(i); it != mMedia.end()) {
+			// Non-data media
+			const auto &media = it->second;
 			sdp << "m=" << media.type << ' ' << 0 << ' ' << media.description << eol;
 			sdp << "c=IN IP4 0.0.0.0" << eol;
 			sdp << "a=bundle-only" << eol;
 			sdp << "a=mid:" << media.mid << eol;
 			for (const auto &attr : media.attributes)
 				sdp << "a=" << attr << eol;
+
+		} else {
+			// Data
+			const string description = "UDP/DTLS/SCTP webrtc-datachannel";
+			sdp << "m=application" << ' ' << (!mMedia.empty() ? 0 : 9) << ' ' << description << eol;
+			sdp << "c=IN IP4 0.0.0.0" << eol;
+			if (!mMedia.empty())
+				sdp << "a=bundle-only" << eol;
+			sdp << "a=mid:" << mData.mid << eol;
+			if (mData.sctpPort)
+				sdp << "a=sctp-port:" << *mData.sctpPort << eol;
+			if (mData.maxMessageSize)
+				sdp << "a=max-message-size:" << *mData.maxMessageSize << eol;
 		}
 	}
 
-	// Data
-	const string dataDescription = "UDP/DTLS/SCTP webrtc-datachannel";
-	sdp << "m=application" << ' ' << (!mMedia.empty() ? 0 : 9) << ' ' << dataDescription << eol;
-	sdp << "c=IN IP4 0.0.0.0" << eol;
-	if (!mMedia.empty())
-		sdp << "a=bundle-only" << eol;
-	sdp << "a=mid:" << mData.mid << eol;
-	if (mData.sctpPort)
-		sdp << "a=sctp-port:" << *mData.sctpPort << eol;
-	if (mData.maxMessageSize)
-		sdp << "a=max-message-size:" << *mData.maxMessageSize << eol;
-
-
 	// Common
 	if (!mEnded)
 		sdp << "a=ice-options:trickle" << eol;