Browse Source

This commit removes the processing of strings in the forwarding of media to tracks

Staz M 4 years ago
parent
commit
30ca8fb9c3
4 changed files with 129 additions and 75 deletions
  1. 1 0
      include/rtc/description.hpp
  2. 3 1
      include/rtc/peerconnection.hpp
  3. 4 5
      src/description.cpp
  4. 121 69
      src/peerconnection.cpp

+ 1 - 0
include/rtc/description.hpp

@@ -169,6 +169,7 @@ public:
 		Media::RTPMap &getFormat(const string &fmt);
 
 		std::map<int, RTPMap> mRtpMap;
+		std::vector<uint32_t> mSsrcs;
 
 	public:
         void addRTPMap(const RTPMap& map);

+ 3 - 1
include/rtc/peerconnection.hpp

@@ -135,6 +135,7 @@ private:
 	void forwardMedia(message_ptr message);
 	void forwardBufferedAmount(uint16_t stream, size_t amount);
     std::optional<std::string> getMidFromSSRC(SSRC ssrc);
+    std::optional<uint32_t> getMLineFromSSRC(SSRC ssrc);
 
 	std::shared_ptr<DataChannel> emplaceDataChannel(Description::Role role, string label,
 	                                                string protocol, Reliability reliability);
@@ -181,7 +182,8 @@ private:
 	std::vector<std::weak_ptr<Track>> mTrackLines;                              // by SDP order
 	std::shared_mutex mDataChannelsMutex, mTracksMutex;
 
-	std::unordered_map<unsigned int, string> mMidFromSssrc; // cache
+	std::unordered_map<uint32_t, string> mMidFromSssrc; // cache
+    std::unordered_map<uint32_t , unsigned int> mMLineFromSssrc; // cache
 
 	std::atomic<State> mState;
 	std::atomic<GatheringState> mGatheringState;

+ 4 - 5
src/description.cpp

@@ -517,10 +517,7 @@ void Description::Media::addSSRC(uint32_t ssrc) {
 }
 
 bool Description::Media::hasSSRC(uint32_t ssrc) {
-    for (auto &val : mAttributes) {
-        if (val.find("ssrc:" + std::to_string(ssrc)) != std::string ::npos)
-            return true;
-    }
+    return std::find(mSsrcs.begin(), mSsrcs.end(), ssrc) != mSsrcs.end();
     return false;
 }
 
@@ -782,7 +779,9 @@ void Description::Media::parseSdpLine(string_view line) {
 				it->second.fmtps.emplace_back(value.substr(p + 1));
 			}
 		} else if (key == "rtcp-mux") {
-			// always added
+            // always added
+        }else if (key == "ssrc") {
+		    mSsrcs.emplace_back(std::stoul((std::string)value));
 		} else {
 			Entry::parseSdpLine(line);
 		}

+ 121 - 69
src/peerconnection.cpp

@@ -670,7 +670,8 @@ void PeerConnection::forwardMedia(message_ptr message) {
 
 	// Browsers like to compound their packets with a random SSRC.
 	// we have to do this monstrosity to distribute the report blocks
-    std::optional<string> mid;
+//    std::optional<string> mid;
+    std::optional<unsigned int> mediaLine;
     if (message->type == Message::Control) {
         unsigned int offset = 0;
         std::vector<SSRC> ssrcsFound;
@@ -683,59 +684,59 @@ void PeerConnection::forwardMedia(message_ptr message) {
                 break;
             } else {
                 if (header->payloadType() == 205 || header->payloadType() == 206) {
-                     auto rtcpfb = (RTCP_FB_HEADER*) header;
-                     auto ssrc = rtcpfb->getPacketSenderSSRC();
-                    mid = getMidFromSSRC(ssrc);
-                    if (mid.has_value() && std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) == ssrcsFound.end()) {
-                        hasFound = true;
-                        std::shared_lock lock(mTracksMutex); // read-only
-                        if (auto it = mTracks.find(*mid); it != mTracks.end()) {
-                            if (auto track = it->second.lock()) {
+                    auto rtcpfb = (RTCP_FB_HEADER *) header;
+                    auto ssrc = rtcpfb->getPacketSenderSSRC();
+                    if (std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) != ssrcsFound.end()) {
+                        mediaLine = getMLineFromSSRC(ssrc);
+                        if (mediaLine.has_value()) {
+                            hasFound = true;
+                            std::shared_lock lock(mTracksMutex); // read-only
+                            if (auto track = mTrackLines[*mediaLine].lock()) {
                                 track->incoming(message);
                             }
+                            ssrcsFound.emplace_back(ssrc);
                         }
-                        ssrcsFound.emplace_back(ssrc);
                     }
 
                     ssrc = rtcpfb->getMediaSourceSSRC();
-                    mid = getMidFromSSRC(ssrc);
-                    if (mid.has_value() && std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) == ssrcsFound.end()) {
-                        hasFound = true;
-                        std::shared_lock lock(mTracksMutex); // read-only
-                        if (auto it = mTracks.find(*mid); it != mTracks.end()) {
-                            if (auto track = it->second.lock()) {
+                    if (std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) != ssrcsFound.end()) {
+                        mediaLine = getMLineFromSSRC(ssrc);
+                        if (mediaLine.has_value()) {
+                            hasFound = true;
+                            std::shared_lock lock(mTracksMutex); // read-only
+                            if (auto track = mTrackLines[*mediaLine].lock()) {
                                 track->incoming(message);
                             }
+                            ssrcsFound.emplace_back(ssrc);
                         }
-                        ssrcsFound.emplace_back(ssrc);
                     }
                 }else if (header->payloadType() == 200 || header->payloadType() == 201) {
                     auto rtcpsr = (RTCP_SR*) header;
                     auto ssrc = rtcpsr->senderSSRC();
-                    mid = getMidFromSSRC(ssrc);
-                    if (mid.has_value() && std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) == ssrcsFound.end()) {
-                        hasFound = true;
-                        std::shared_lock lock(mTracksMutex); // read-only
-                        if (auto it = mTracks.find(*mid); it != mTracks.end()) {
-                            if (auto track = it->second.lock()) {
+                    if (std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) != ssrcsFound.end()) {
+                        mediaLine = getMLineFromSSRC(ssrc);
+                        if (mediaLine.has_value()) {
+                            hasFound = true;
+                            std::shared_lock lock(mTracksMutex); // read-only
+                            if (auto track = mTrackLines[*mediaLine].lock()) {
                                 track->incoming(message);
                             }
+                            ssrcsFound.emplace_back(ssrc);
                         }
-                        ssrcsFound.emplace_back(ssrc);
                     }
                     for (int i = 0; i < rtcpsr->header.reportCount(); i++) {
                         auto block = rtcpsr->getReportBlock(i);
                         ssrc = block->getSSRC();
-                        mid = getMidFromSSRC(ssrc);
-                        if (mid.has_value() && std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) == ssrcsFound.end()) {
-                            hasFound = true;
-                            std::shared_lock lock(mTracksMutex); // read-only
-                            if (auto it = mTracks.find(*mid); it != mTracks.end()) {
-                                if (auto track = it->second.lock()) {
+                        if (std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) != ssrcsFound.end()) {
+                            mediaLine = getMLineFromSSRC(ssrc);
+                            if (mediaLine.has_value()) {
+                                hasFound = true;
+                                std::shared_lock lock(mTracksMutex); // read-only
+                                if (auto track = mTrackLines[*mediaLine].lock()) {
                                     track->incoming(message);
                                 }
+                                ssrcsFound.emplace_back(ssrc);
                             }
-                            ssrcsFound.emplace_back(ssrc);
                         }
                     }
                 }else {
@@ -751,9 +752,9 @@ void PeerConnection::forwardMedia(message_ptr message) {
     }
 
     unsigned int ssrc = message->stream;
-    mid = getMidFromSSRC(ssrc);
+    mediaLine = getMLineFromSSRC(ssrc);
 
-	if (!mid) {
+	if (!mediaLine) {
 	    /* TODO
 	     *   So the problem is that when stop sending streams, we stop getting report blocks for those streams
 	     *   Therefore when we get compound RTCP packets, they are empty, and we can't forward them.
@@ -765,50 +766,101 @@ void PeerConnection::forwardMedia(message_ptr message) {
 	}
 
 	std::shared_lock lock(mTracksMutex); // read-only
-	if (auto it = mTracks.find(*mid); it != mTracks.end())
-		if (auto track = it->second.lock())
-			track->incoming(message);
+    if (auto track = mTrackLines[*mediaLine].lock()) {
+        track->incoming(message);
+    }
+}
+
+std::optional<unsigned int> PeerConnection::getMLineFromSSRC(SSRC ssrc) {
+    if (auto it = mMLineFromSssrc.find(ssrc); it != mMLineFromSssrc.end()) {
+        return it->second;
+    }else {
+        {
+            std::lock_guard lock(mRemoteDescriptionMutex);
+            if (!mRemoteDescription)
+                return nullopt;
+            for (unsigned int i = 0; i < mRemoteDescription->mediaCount(); ++i) {
+                if (auto found = std::visit(
+                        rtc::overloaded{[&](Description::Application *) -> bool {
+                            return false;
+                        },
+                                        [&](Description::Media *media) -> bool {
+                                            return media->hasSSRC(ssrc);
+                                        }},
+                        mRemoteDescription->media(i))) {
+
+                    mMLineFromSssrc.emplace(ssrc, i);
+                    return i;
+                }
+            }
+        }
+        {
+            std::lock_guard lock(mLocalDescriptionMutex);
+            if (!mLocalDescription)
+                return nullopt;
+            for (unsigned int i = 0; i < mLocalDescription->mediaCount(); ++i) {
+                if (auto found = std::visit(
+                        rtc::overloaded{[&](Description::Application *) -> bool {
+                            return false;
+                        },
+                                        [&](Description::Media *media) -> bool {
+                                            return media->hasSSRC(ssrc);
+                                        }},
+                        mLocalDescription->media(i))) {
+
+                    mMLineFromSssrc.emplace(ssrc, i);
+                    return i;
+                }
+            }
+        }
+    }
+    return std::nullopt;
 }
 
 std::optional<std::string> PeerConnection::getMidFromSSRC(SSRC ssrc) {
     if (auto it = mMidFromSssrc.find(ssrc); it != mMidFromSssrc.end()) {
         return it->second;
     } else {
-        std::lock_guard lock(mLocalDescriptionMutex);
-        if (!mLocalDescription)
-            return nullopt;
-
-        for (unsigned int i = 0; i < mRemoteDescription->mediaCount(); ++i) {
-            if (auto found = std::visit(
-                    rtc::overloaded{[&](Description::Application *) -> std::optional<string> {
-                        return std::nullopt;
-                    },
-                                    [&](Description::Media *media) -> std::optional<string> {
-                                        return media->hasSSRC(ssrc)
-                                               ? std::make_optional(media->mid())
-                                               : nullopt;
-                                    }},
-                    mRemoteDescription->media(i))) {
-
-                mMidFromSssrc.emplace(ssrc, *found);
-                return *found;
+        {
+            std::lock_guard lock(mRemoteDescriptionMutex);
+            if (!mRemoteDescription)
+                return nullopt;
+            for (unsigned int i = 0; i < mRemoteDescription->mediaCount(); ++i) {
+                if (auto found = std::visit(
+                        rtc::overloaded{[&](Description::Application *) -> std::optional<string> {
+                            return std::nullopt;
+                        },
+                                        [&](Description::Media *media) -> std::optional<string> {
+                                            return media->hasSSRC(ssrc)
+                                                   ? std::make_optional(media->mid())
+                                                   : nullopt;
+                                        }},
+                        mRemoteDescription->media(i))) {
+
+                    mMidFromSssrc.emplace(ssrc, *found);
+                    return *found;
+                }
             }
         }
-
-        for (unsigned int i = 0; i < mLocalDescription->mediaCount(); ++i) {
-            if (auto found = std::visit(
-                    rtc::overloaded{[&](Description::Application *) -> std::optional<string> {
-                        return std::nullopt;
-                    },
-                                    [&](Description::Media *media) -> std::optional<string> {
-                                        return media->hasSSRC(ssrc)
-                                               ? std::make_optional(media->mid())
-                                               : nullopt;
-                                    }},
-                    mLocalDescription->media(i))) {
-
-                mMidFromSssrc.emplace(ssrc, *found);
-                return *found;
+        {
+            std::lock_guard lock(mLocalDescriptionMutex);
+            if (!mLocalDescription)
+                return nullopt;
+            for (unsigned int i = 0; i < mLocalDescription->mediaCount(); ++i) {
+                if (auto found = std::visit(
+                        rtc::overloaded{[&](Description::Application *) -> std::optional<string> {
+                            return std::nullopt;
+                        },
+                                        [&](Description::Media *media) -> std::optional<string> {
+                                            return media->hasSSRC(ssrc)
+                                                   ? std::make_optional(media->mid())
+                                                   : nullopt;
+                                        }},
+                        mLocalDescription->media(i))) {
+
+                    mMidFromSssrc.emplace(ssrc, *found);
+                    return *found;
+                }
             }
         }
     }