Browse Source

Merge pull request #228 from paullouisageneau/update-tracks

Allow updating local track description
Paul-Louis Ageneau 4 years ago
parent
commit
12579825a9
4 changed files with 69 additions and 18 deletions
  1. 1 4
      include/rtc/description.hpp
  2. 2 0
      include/rtc/track.hpp
  3. 59 14
      src/peerconnection.cpp
  4. 7 0
      src/track.cpp

+ 1 - 4
include/rtc/description.hpp

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

+ 2 - 0
include/rtc/track.hpp

@@ -43,6 +43,8 @@ public:
 	string mid() const;
 	string mid() const;
 	Description::Media description() const;
 	Description::Media description() const;
 
 
+	void setDescription(Description::Media description);
+
 	void close(void) override;
 	void close(void) override;
 	bool send(message_variant data) override;
 	bool send(message_variant data) override;
 	bool send(const byte *data, size_t size);
 	bool send(const byte *data, size_t size);

+ 59 - 14
src/peerconnection.cpp

@@ -368,19 +368,23 @@ void PeerConnection::onSignalingStateChange(std::function<void(SignalingState st
 }
 }
 
 
 std::shared_ptr<Track> PeerConnection::addTrack(Description::Media description) {
 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 !RTC_ENABLE_MEDIA
 	if (mTracks.empty()) {
 	if (mTracks.empty()) {
 		PLOG_WARNING << "Tracks will be inative (not compiled with SRTP support)";
 		PLOG_WARNING << "Tracks will be inative (not compiled with SRTP support)";
 	}
 	}
 #endif
 #endif
-	auto track = std::make_shared<Track>(std::move(description));
-	mTracks.emplace(std::make_pair(track->mid(), 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));
+	}
+
+	// Renegotiation is needed for the new or updated track
 	mNegotiationNeeded = true;
 	mNegotiationNeeded = true;
 
 
 	return track;
 	return track;
@@ -852,8 +856,22 @@ void PeerConnection::processLocalDescription(Description description) {
 		for (int i = 0; i < remote->mediaCount(); ++i)
 		for (int i = 0; i < remote->mediaCount(); ++i)
 			std::visit( // reciprocate each media
 			std::visit( // reciprocate each media
 			    rtc::overloaded{
 			    rtc::overloaded{
-			        [&](Description::Application *app) {
-				        auto reciprocated = app->reciprocate();
+			        [&](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.hintSctpPort(DEFAULT_SCTP_PORT);
 				        reciprocated.setMaxMessageSize(LOCAL_MAX_MESSAGE_SIZE);
 				        reciprocated.setMaxMessageSize(LOCAL_MAX_MESSAGE_SIZE);
 
 
@@ -862,8 +880,35 @@ void PeerConnection::processLocalDescription(Description description) {
 
 
 				        description.addMedia(std::move(reciprocated));
 				        description.addMedia(std::move(reciprocated));
 			        },
 			        },
-			        [&](Description::Media *media) {
-				        auto reciprocated = media->reciprocate();
+			        [&](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
 #if !RTC_ENABLE_MEDIA
 				        // No media support, mark as inactive
 				        // No media support, mark as inactive
 				        reciprocated.setDirection(Description::Direction::Inactive);
 				        reciprocated.setDirection(Description::Direction::Inactive);
@@ -1051,7 +1096,7 @@ bool PeerConnection::changeState(State state) {
 bool PeerConnection::changeGatheringState(GatheringState state) {
 bool PeerConnection::changeGatheringState(GatheringState state) {
 	if (mGatheringState.exchange(state) == state)
 	if (mGatheringState.exchange(state) == state)
 		return false;
 		return false;
-	
+
 	std::ostringstream s;
 	std::ostringstream s;
 	s << state;
 	s << state;
 	PLOG_INFO << "Changed gathering state to " << s.str();
 	PLOG_INFO << "Changed gathering state to " << s.str();
@@ -1060,9 +1105,9 @@ bool PeerConnection::changeGatheringState(GatheringState state) {
 }
 }
 
 
 bool PeerConnection::changeSignalingState(SignalingState state) {
 bool PeerConnection::changeSignalingState(SignalingState state) {
-	if (mSignalingState.exchange(state) == state) 
+	if (mSignalingState.exchange(state) == state)
 		return false;
 		return false;
-	
+
 	std::ostringstream s;
 	std::ostringstream s;
 	s << state;
 	s << state;
 	PLOG_INFO << "Changed signaling state to " << s.str();
 	PLOG_INFO << "Changed signaling state to " << s.str();

+ 7 - 0
src/track.cpp

@@ -32,6 +32,13 @@ string Track::mid() const { return mMediaDescription.mid(); }
 
 
 Description::Media Track::description() const { return mMediaDescription; }
 Description::Media Track::description() const { return mMediaDescription; }
 
 
+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() {
 void Track::close() {
 	mIsClosed = true;
 	mIsClosed = true;
 	resetCallbacks();
 	resetCallbacks();