Browse Source

Optimize Lookup in PeerConnection::forwardMedia()

SE2Dev 3 years ago
parent
commit
91eff1b915
2 changed files with 53 additions and 12 deletions
  1. 48 10
      src/impl/peerconnection.cpp
  2. 5 2
      src/impl/peerconnection.hpp

+ 48 - 10
src/impl/peerconnection.cpp

@@ -517,12 +517,11 @@ void PeerConnection::forwardMedia(message_ptr message) {
 		}
 
 		if (!ssrcs.empty()) {
+			std::shared_lock lock(mTracksMutex); // read-only
 			for (uint32_t ssrc : ssrcs) {
-				if (auto mid = getMidFromSsrc(ssrc)) {
-					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 it = mTracksBySsrc.find(ssrc); it != mTracksBySsrc.end()) {
+					if (auto track = it->second.lock())
+						track->incoming(message);
 				}
 			}
 			return;
@@ -530,11 +529,11 @@ void PeerConnection::forwardMedia(message_ptr message) {
 	}
 
 	uint32_t ssrc = uint32_t(message->stream);
-	if (auto mid = getMidFromSsrc(ssrc)) {
-		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);
+
+	std::shared_lock lock(mTracksMutex); // read-only
+	if (auto it = mTracksBySsrc.find(ssrc); it != mTracksBySsrc.end()) {
+		if (auto track = it->second.lock())
+			track->incoming(message);
 	} else {
 		/*
 		 * TODO: So the problem is that when stop sending streams, we stop getting report blocks for
@@ -993,6 +992,8 @@ void PeerConnection::processLocalDescription(Description description) {
 	if (description.mediaCount() == 0)
 		throw std::logic_error("Local description has no media line");
 
+	updateTrackSsrcCache(description);
+
 	{
 		// Set as local description
 		std::lock_guard lock(mLocalDescriptionMutex);
@@ -1037,6 +1038,8 @@ void PeerConnection::processLocalCandidate(Candidate candidate) {
 }
 
 void PeerConnection::processRemoteDescription(Description description) {
+	updateTrackSsrcCache(description);
+
 	{
 		// Set as remote description
 		std::lock_guard lock(mRemoteDescriptionMutex);
@@ -1218,4 +1221,39 @@ void PeerConnection::resetCallbacks() {
 	gatheringStateChangeCallback = nullptr;
 }
 
+void PeerConnection::updateTrackSsrcCache(const Description &description) {
+	std::unique_lock lock(mTracksMutex); // for safely writing to mTracksBySsrc
+
+	// Setup SSRC -> Track mapping
+	for (unsigned int i = 0; i < description.mediaCount(); ++i)
+		std::visit( // ssrc -> track mapping
+		    rtc::overloaded{
+		        [&](Description::Application const *) { return; },
+		        [&](Description::Media const *media) {
+			        const auto ssrcs = media->getSSRCs();
+
+			        // Note: We don't want to lock (or do any other lookups), if we
+			        // already know there's no SSRCs to loop over.
+			        if (ssrcs.size() <= 0) {
+				        return;
+			        }
+
+			        std::shared_ptr<Track> track{nullptr};
+			        if (auto it = mTracks.find(media->mid()); it != mTracks.end())
+				        if (auto track_for_mid = it->second.lock())
+					        track = track_for_mid;
+
+			        if (!track) {
+				        // Unable to find track for MID
+				        return;
+			        }
+
+			        for (auto ssrc : ssrcs) {
+				        mTracksBySsrc.emplace(ssrc, track);
+			        }
+		        },
+		    },
+		    description.media(i));
+}
+
 } // namespace rtc::impl

+ 5 - 2
src/impl/peerconnection.hpp

@@ -126,6 +126,8 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
 	synchronized_callback<shared_ptr<rtc::Track>> trackCallback;
 
 private:
+	void updateTrackSsrcCache(const Description &description);
+
 	const init_token mInitToken = Init::Instance().token();
 	const future_certificate_ptr mCertificate;
 
@@ -142,8 +144,9 @@ private:
 	std::vector<weak_ptr<DataChannel>> mUnassignedDataChannels;
 	std::shared_mutex mDataChannelsMutex;
 
-	std::unordered_map<string, weak_ptr<Track>> mTracks; // by mid
-	std::vector<weak_ptr<Track>> mTrackLines;            // by SDP order
+	std::unordered_map<string, weak_ptr<Track>> mTracks;         // by mid
+	std::unordered_map<uint32_t, weak_ptr<Track>> mTracksBySsrc; // by SSRC
+	std::vector<weak_ptr<Track>> mTrackLines;                    // by SDP order
 	std::shared_mutex mTracksMutex;
 
 	Queue<shared_ptr<DataChannel>> mPendingDataChannels;