@@ -69,7 +69,6 @@ PeerConnection::~PeerConnection() {
69
69
}
70
70
71
71
void PeerConnection::close () {
72
- negotiationNeeded = false ;
73
72
if (!closing.exchange (true )) {
74
73
PLOG_VERBOSE << " Closing PeerConnection" ;
75
74
if (auto transport = std::atomic_load (&mSctpTransport ))
@@ -802,25 +801,27 @@ void PeerConnection::iterateTracks(std::function<void(shared_ptr<Track> track)>
802
801
803
802
void PeerConnection::openTracks () {
804
803
#if RTC_ENABLE_MEDIA
805
- if (auto transport = std::atomic_load (&mDtlsTransport )) {
806
- auto srtpTransport = std::dynamic_pointer_cast<DtlsSrtpTransport>(transport);
807
-
808
- iterateTracks ([&](const shared_ptr<Track> &track) {
809
- if (!track->isOpen ()) {
810
- if (srtpTransport) {
811
- track->open (srtpTransport);
812
- } else {
813
- // A track was added during a latter renegotiation, whereas SRTP transport was
814
- // not initialized. This is an optimization to use the library with data
815
- // channels only. Set forceMediaTransport to true to initialize the transport
816
- // before dynamically adding tracks.
817
- auto errorMsg = " The connection has no media transport" ;
818
- PLOG_ERROR << errorMsg;
819
- track->triggerError (errorMsg);
820
- }
804
+ auto remote = remoteDescription ();
805
+ auto transport = std::atomic_load (&mDtlsTransport );
806
+ if (!remote || !transport)
807
+ return ;
808
+
809
+ auto srtpTransport = std::dynamic_pointer_cast<DtlsSrtpTransport>(transport);
810
+ iterateTracks ([&](const shared_ptr<Track> &track) {
811
+ if (remote->hasMid (track->mid ()) && !track->isOpen ()) {
812
+ if (srtpTransport) {
813
+ track->open (srtpTransport);
814
+ } else {
815
+ // A track was added during a latter renegotiation, whereas SRTP transport was
816
+ // not initialized. This is an optimization to use the library with data
817
+ // channels only. Set forceMediaTransport to true to initialize the transport
818
+ // before dynamically adding tracks.
819
+ auto errorMsg = " The connection has no media transport" ;
820
+ PLOG_ERROR << errorMsg;
821
+ track->triggerError (errorMsg);
821
822
}
822
- });
823
- }
823
+ }
824
+ });
824
825
#endif
825
826
}
826
827
@@ -1003,8 +1004,7 @@ void PeerConnection::processLocalDescription(Description description) {
1003
1004
}
1004
1005
}
1005
1006
1006
- // There might be no media at this point if the user created a Track, deleted it,
1007
- // then called setLocalDescription().
1007
+ // There might be no media at this point, for instance if the user deleted tracks
1008
1008
if (description.mediaCount () == 0 )
1009
1009
throw std::runtime_error (" No DataChannel or Track to negotiate" );
1010
1010
}
@@ -1132,6 +1132,27 @@ string PeerConnection::localBundleMid() const {
1132
1132
return mLocalDescription ? mLocalDescription ->bundleMid () : " 0" ;
1133
1133
}
1134
1134
1135
+ bool PeerConnection::negotiationNeeded () const {
1136
+ auto description = localDescription ();
1137
+
1138
+ {
1139
+ std::shared_lock lock (mDataChannelsMutex );
1140
+ if (!mDataChannels .empty () || !mUnassignedDataChannels .empty ())
1141
+ if ((!description || !description->hasApplication ()))
1142
+ return true ;
1143
+ }
1144
+
1145
+ {
1146
+ std::shared_lock lock (mTracksMutex );
1147
+ for (auto it = mTrackLines .begin (); it != mTrackLines .end (); ++it)
1148
+ if (auto track = it->lock ())
1149
+ if (!description || !description->hasMid (track->mid ()))
1150
+ return true ;
1151
+ }
1152
+
1153
+ return false ;
1154
+ }
1155
+
1135
1156
void PeerConnection::setMediaHandler (shared_ptr<MediaHandler> handler) {
1136
1157
std::unique_lock lock (mMediaHandlerMutex );
1137
1158
mMediaHandler = handler;
0 commit comments