Skip to content

Commit c3535fb

Browse files
WIP
1 parent 437a758 commit c3535fb

File tree

3 files changed

+54
-35
lines changed

3 files changed

+54
-35
lines changed

src/impl/peerconnection.cpp

+42-21
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ PeerConnection::~PeerConnection() {
6969
}
7070

7171
void PeerConnection::close() {
72-
negotiationNeeded = false;
7372
if (!closing.exchange(true)) {
7473
PLOG_VERBOSE << "Closing PeerConnection";
7574
if (auto transport = std::atomic_load(&mSctpTransport))
@@ -802,25 +801,27 @@ void PeerConnection::iterateTracks(std::function<void(shared_ptr<Track> track)>
802801

803802
void PeerConnection::openTracks() {
804803
#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);
821822
}
822-
});
823-
}
823+
}
824+
});
824825
#endif
825826
}
826827

@@ -1003,8 +1004,7 @@ void PeerConnection::processLocalDescription(Description description) {
10031004
}
10041005
}
10051006

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
10081008
if (description.mediaCount() == 0)
10091009
throw std::runtime_error("No DataChannel or Track to negotiate");
10101010
}
@@ -1132,6 +1132,27 @@ string PeerConnection::localBundleMid() const {
11321132
return mLocalDescription ? mLocalDescription->bundleMid() : "0";
11331133
}
11341134

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+
11351156
void PeerConnection::setMediaHandler(shared_ptr<MediaHandler> handler) {
11361157
std::unique_lock lock(mMediaHandlerMutex);
11371158
mMediaHandler = handler;

src/impl/peerconnection.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
8080
void processRemoteCandidate(Candidate candidate);
8181
string localBundleMid() const;
8282

83+
bool negotiationNeeded() const;
84+
8385
void setMediaHandler(shared_ptr<MediaHandler> handler);
8486
shared_ptr<MediaHandler> getMediaHandler();
8587

@@ -113,7 +115,6 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
113115
std::atomic<IceState> iceState = IceState::New;
114116
std::atomic<GatheringState> gatheringState = GatheringState::New;
115117
std::atomic<SignalingState> signalingState = SignalingState::Stable;
116-
std::atomic<bool> negotiationNeeded = false;
117118
std::atomic<bool> closing = false;
118119
std::mutex signalingMutex;
119120

@@ -148,12 +149,12 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
148149

149150
std::unordered_map<uint16_t, weak_ptr<DataChannel>> mDataChannels; // by stream ID
150151
std::vector<weak_ptr<DataChannel>> mUnassignedDataChannels;
151-
std::shared_mutex mDataChannelsMutex;
152+
mutable std::shared_mutex mDataChannelsMutex;
152153

153154
std::unordered_map<string, weak_ptr<Track>> mTracks; // by mid
154155
std::unordered_map<uint32_t, weak_ptr<Track>> mTracksBySsrc; // by SSRC
155156
std::vector<weak_ptr<Track>> mTrackLines; // by SDP order
156-
std::shared_mutex mTracksMutex;
157+
mutable std::shared_mutex mTracksMutex;
157158

158159
Queue<shared_ptr<DataChannel>> mPendingDataChannels;
159160
Queue<shared_ptr<Track>> mPendingTracks;

src/peerconnection.cpp

+8-11
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ void PeerConnection::setLocalDescription(Description::Type type) {
9999
}
100100

101101
// Only a local offer resets the negotiation needed flag
102-
if (type == Description::Type::Offer && !impl()->negotiationNeeded.exchange(false)) {
102+
if (type == Description::Type::Offer && !impl()->negotiationNeeded()) {
103103
PLOG_DEBUG << "No negotiation needed";
104104
return;
105105
}
@@ -146,9 +146,11 @@ void PeerConnection::setLocalDescription(Description::Type type) {
146146
impl()->changeSignalingState(newSignalingState);
147147
signalingLock.unlock();
148148

149-
if (impl()->gatheringState == GatheringState::New) {
149+
if (impl()->gatheringState == GatheringState::New)
150150
iceTransport->gatherLocalCandidates(impl()->localBundleMid());
151-
}
151+
152+
if(newSignalingState == SignalingState::Stable && impl()->negotiationNeeded())
153+
setLocalDescription(Description::Type::Offer);
152154
}
153155

154156
void PeerConnection::setRemoteDescription(Description description) {
@@ -241,6 +243,9 @@ void PeerConnection::setRemoteDescription(Description description) {
241243

242244
for (const auto &candidate : remoteCandidates)
243245
addRemoteCandidate(candidate);
246+
247+
if(newSignalingState == SignalingState::Stable && impl()->negotiationNeeded())
248+
setLocalDescription();
244249
}
245250

246251
void PeerConnection::addRemoteCandidate(Candidate candidate) {
@@ -271,11 +276,6 @@ shared_ptr<DataChannel> PeerConnection::createDataChannel(string label, DataChan
271276
auto channelImpl = impl()->emplaceDataChannel(std::move(label), std::move(init));
272277
auto channel = std::make_shared<DataChannel>(channelImpl);
273278

274-
// Renegotiation is needed iff the current local description does not have application
275-
auto local = impl()->localDescription();
276-
if (!local || !local->hasApplication())
277-
impl()->negotiationNeeded = true;
278-
279279
if (!impl()->config.disableAutoNegotiation)
280280
setLocalDescription();
281281

@@ -292,9 +292,6 @@ std::shared_ptr<Track> PeerConnection::addTrack(Description::Media description)
292292
auto trackImpl = impl()->emplaceTrack(std::move(description));
293293
auto track = std::make_shared<Track>(trackImpl);
294294

295-
// Renegotiation is needed for the new or updated track
296-
impl()->negotiationNeeded = true;
297-
298295
return track;
299296
}
300297

0 commit comments

Comments
 (0)