Browse Source

Merged with paullouisageneau/libdatachannel

Staz M 4 years ago
parent
commit
4f89e479bc
5 changed files with 83 additions and 38 deletions
  1. 1 1
      examples/web/script.js
  2. 1 4
      include/rtc/description.hpp
  3. 2 1
      include/rtc/track.hpp
  4. 73 30
      src/peerconnection.cpp
  5. 6 2
      src/track.cpp

+ 1 - 1
examples/web/script.js

@@ -55,7 +55,7 @@ function openSignaling(url) {
     const ws = new WebSocket(url);
     ws.onopen = () => resolve(ws);
     ws.onerror = () => reject(new Error('WebSocket error'));
-    ws.onclosed = () => console.error('WebSocket disconnected');
+    ws.onclose = () => console.error('WebSocket disconnected');
     ws.onmessage = (e) => {
       if(typeof(e.data) != 'string') return;
       const message = JSON.parse(e.data);

+ 1 - 4
include/rtc/description.hpp

@@ -95,8 +95,7 @@ public:
 	struct Application : public Entry {
 	public:
 		Application(string mid = "data");
-		Application(const Application &other) = default;
-		Application(Application &&other) = default;
+		virtual ~Application() = default;
 
 		string description() const override;
 		Application reciprocate() const;
@@ -122,8 +121,6 @@ public:
 	public:
 		Media(const string &sdp);
 		Media(const string &mline, string mid, Direction dir = Direction::SendOnly);
-		Media(const Media &other) = default;
-		Media(Media &&other) = default;
 		virtual ~Media() = default;
 
 		string description() const override;

+ 2 - 1
include/rtc/track.hpp

@@ -42,7 +42,8 @@ public:
 
 	string mid() const;
 	Description::Media description() const;
-    void replaceSSRC(SSRC oldSSRC, SSRC ssrc, string cname);
+
+	void setDescription(Description::Media description);
 
 	void close(void) override;
 	bool send(message_variant data) override;

+ 73 - 30
src/peerconnection.cpp

@@ -369,21 +369,24 @@ void PeerConnection::onSignalingStateChange(std::function<void(SignalingState st
 }
 
 std::shared_ptr<Track> PeerConnection::addTrack(Description::Media description) {
-
-	if (auto it = mTracks.find(description.mid()); it != mTracks.end())
-		if (auto track = it->second.lock())
-			return track;
-
 #if !RTC_ENABLE_MEDIA
 	if (mTracks.empty()) {
 		PLOG_WARNING << "Tracks will be inative (not compiled with SRTP support)";
 	}
 #endif
-	auto track = std::make_shared<Track>(std::move(description));
-	mTracks.emplace(std::make_pair(track->mid(), track));
-    mTrackLines.emplace_back(track);
 
-	// Renegotiation is needed for the new track
+	std::shared_ptr<Track> track;
+	if (auto it = mTracks.find(description.mid()); it != mTracks.end())
+		if (track = it->second.lock(); track)
+			track->setDescription(std::move(description));
+
+	if (!track) {
+		track = std::make_shared<Track>(std::move(description));
+		mTracks.emplace(std::make_pair(track->mid(), track));
+		mTrackLines.emplace_back(track);
+	}
+
+	// Renegotiation is needed for the new or updated track
 	mNegotiationNeeded = true;
 
 	return track;
@@ -949,24 +952,65 @@ void PeerConnection::validateRemoteDescription(const Description &description) {
 }
 
 void PeerConnection::processLocalDescription(Description description) {
-	if (mSignalingState == SignalingState::HaveRemoteOffer) {
-        if (auto remote = remoteDescription()) {
-            // Reciprocate remote description
-            for (unsigned int i = 0; i < remote->mediaCount(); ++i)
-                std::visit( // reciprocate each media
-                        rtc::overloaded{
-                                [&](Description::Application *app) {
-                                    auto reciprocated = app->reciprocate();
-                                    reciprocated.hintSctpPort(DEFAULT_SCTP_PORT);
-                                    reciprocated.setMaxMessageSize(LOCAL_MAX_MESSAGE_SIZE);
-
-                                    PLOG_DEBUG << "Reciprocating application in local description, mid=\""
-                                               << reciprocated.mid() << "\"";
 
-                                    description.addMedia(std::move(reciprocated));
-                                },
-                                [&](Description::Media *media) {
-                                    auto reciprocated = media->reciprocate();
+	if (auto remote = remoteDescription()) {
+		// Reciprocate remote description
+		for (size_t i = 0; i < remote->mediaCount(); ++i)
+			std::visit( // reciprocate each media
+			    rtc::overloaded{
+			        [&](Description::Application *remoteApp) {
+				        std::shared_lock lock(mDataChannelsMutex);
+				        if (!mDataChannels.empty()) {
+					        // Prefer local description
+					        Description::Application app(remoteApp->mid());
+					        app.setSctpPort(DEFAULT_SCTP_PORT);
+					        app.setMaxMessageSize(LOCAL_MAX_MESSAGE_SIZE);
+
+					        PLOG_DEBUG << "Adding application to local description, mid=\""
+					                   << app.mid() << "\"";
+
+					        description.addMedia(std::move(app));
+					        return;
+				        }
+
+				        auto reciprocated = remoteApp->reciprocate();
+				        reciprocated.hintSctpPort(DEFAULT_SCTP_PORT);
+				        reciprocated.setMaxMessageSize(LOCAL_MAX_MESSAGE_SIZE);
+
+				        PLOG_DEBUG << "Reciprocating application in local description, mid=\""
+				                   << reciprocated.mid() << "\"";
+
+				        description.addMedia(std::move(reciprocated));
+			        },
+			        [&](Description::Media *remoteMedia) {
+				        std::shared_lock lock(mTracksMutex);
+				        if (auto it = mTracks.find(remoteMedia->mid()); it != mTracks.end()) {
+					        // Prefer local description
+					        if (auto track = it->second.lock()) {
+						        auto media = track->description();
+#if !RTC_ENABLE_MEDIA
+						        // No media support, mark as inactive
+						        media.setDirection(Description::Direction::Inactive);
+#endif
+						        PLOG_DEBUG
+						            << "Adding media to local description, mid=\"" << media.mid()
+						            << "\", active=" << std::boolalpha
+						            << (media.direction() != Description::Direction::Inactive);
+
+						        description.addMedia(std::move(media));
+					        } else {
+						        auto reciprocated = remoteMedia->reciprocate();
+						        reciprocated.setDirection(Description::Direction::Inactive);
+
+						        PLOG_DEBUG << "Adding inactive media to local description, mid=\""
+						                   << reciprocated.mid() << "\"";
+
+						        description.addMedia(std::move(reciprocated));
+					        }
+					        return;
+				        }
+
+				        auto reciprocated = remoteMedia->reciprocate();
 #if !RTC_ENABLE_MEDIA
                                     // No media support, mark as inactive
                                     reciprocated.setDirection(Description::Direction::Inactive);
@@ -983,7 +1027,6 @@ void PeerConnection::processLocalDescription(Description description) {
                         },
                         remote->media(i));
         }
-    }
 
 	if (description.type() == Description::Type::Offer) {
 		// This is an offer, add locally created data channels and tracks
@@ -1156,7 +1199,7 @@ bool PeerConnection::changeState(State state) {
 bool PeerConnection::changeGatheringState(GatheringState state) {
 	if (mGatheringState.exchange(state) == state)
 		return false;
-	
+
 	std::ostringstream s;
 	s << state;
 	PLOG_INFO << "Changed gathering state to " << s.str();
@@ -1165,9 +1208,9 @@ bool PeerConnection::changeGatheringState(GatheringState state) {
 }
 
 bool PeerConnection::changeSignalingState(SignalingState state) {
-	if (mSignalingState.exchange(state) == state) 
+	if (mSignalingState.exchange(state) == state)
 		return false;
-	
+
 	std::ostringstream s;
 	s << state;
 	PLOG_INFO << "Changed signaling state to " << s.str();

+ 6 - 2
src/track.cpp

@@ -32,8 +32,12 @@ string Track::mid() const { return mMediaDescription.mid(); }
 
 Description::Media Track::description() const { return mMediaDescription; }
 
-void Track::replaceSSRC(SSRC oldSSRC, SSRC ssrc, std::string cname) {
-    mMediaDescription.replaceSSRC(oldSSRC, ssrc, cname);
+
+void Track::setDescription(Description::Media description) {
+	if(description.mid() != mMediaDescription.mid())
+		throw std::logic_error("Media description mid does not match track mid");
+
+	mMediaDescription = std::move(description);
 }
 
 void Track::close() {