Skip to content

Commit c2e51c8

Browse files
committed
Bug 1769802: Key JsepTransceiver by UUID instead of a simple integer index. r=mjf
The integer index we're replacing here is based on the order in which transceivers were added. If we clone the JSEP engine for an sRD that happens to result in the creation of a transceiver, and at the same time JS calls addTransceiver, we have a situation where the sRD transceiver is added first to the cloned JSEP engine, but the addTransceiver transceiver is added first to the old JSEP engine, resulting in them having the same index. So, let's just use a proper key for this stuff. Differential Revision: https://phabricator.services.mozilla.com/D150169
1 parent 118bbe6 commit c2e51c8

9 files changed

+293
-273
lines changed

dom/media/webrtc/jsapi/PeerConnectionImpl.cpp

+46-36
Original file line numberDiff line numberDiff line change
@@ -851,8 +851,7 @@ nsresult PeerConnectionImpl::GetDatachannelParameters(
851851
transportId->clear();
852852

853853
RefPtr<JsepTransceiver> datachannelTransceiver;
854-
for (const auto& [id, transceiver] : mJsepSession->GetTransceivers()) {
855-
(void)id; // Lame, but no better way to do this right now.
854+
for (const auto& transceiver : mJsepSession->GetTransceivers()) {
856855
if ((transceiver->GetMediaType() == SdpMediaSection::kApplication) &&
857856
transceiver->mSendTrack.GetNegotiatedDetails()) {
858857
datachannelTransceiver = transceiver;
@@ -958,18 +957,8 @@ already_AddRefed<RTCRtpTransceiver> PeerConnectionImpl::AddTransceiver(
958957
return nullptr;
959958
}
960959

961-
RefPtr<JsepTransceiver> jsepTransceiver = new JsepTransceiver(*type);
962-
963-
RefPtr<RTCRtpTransceiver> transceiver =
964-
CreateTransceiver(jsepTransceiver, aInit, aSendTrack, aRv);
965-
966-
if (aRv.Failed()) {
967-
// Would be nice if we could peek at the rv without stealing it, so we
968-
// could log...
969-
CSFLogError(LOGTAG, "%s: failed", __FUNCTION__);
970-
return nullptr;
971-
}
972-
960+
RefPtr<JsepTransceiver> jsepTransceiver =
961+
new JsepTransceiver(*type, *mUuidGen);
973962
jsepTransceiver->SetRtxIsAllowed(mRtxIsAllowed);
974963

975964
// Do this last, since it is not possible to roll back.
@@ -981,6 +970,18 @@ already_AddRefed<RTCRtpTransceiver> PeerConnectionImpl::AddTransceiver(
981970
return nullptr;
982971
}
983972

973+
RefPtr<RTCRtpTransceiver> transceiver = CreateTransceiver(
974+
jsepTransceiver->GetUuid(),
975+
jsepTransceiver->GetMediaType() == SdpMediaSection::kVideo, aInit,
976+
aSendTrack, aRv);
977+
978+
if (aRv.Failed()) {
979+
// Would be nice if we could peek at the rv without stealing it, so we
980+
// could log...
981+
CSFLogError(LOGTAG, "%s: failed", __FUNCTION__);
982+
return nullptr;
983+
}
984+
984985
mTransceivers.AppendElement(transceiver);
985986
return transceiver.forget();
986987
}
@@ -1073,17 +1074,16 @@ PeerConnectionImpl::CreateDataChannel(
10731074
CSFLogDebug(LOGTAG, "%s: making DOMDataChannel", __FUNCTION__);
10741075

10751076
RefPtr<JsepTransceiver> dcTransceiver;
1076-
for (auto& [id, transceiver] : mJsepSession->GetTransceivers()) {
1077-
(void)id; // Lame, but no better way to do this right now.
1077+
for (auto& transceiver : mJsepSession->GetTransceivers()) {
10781078
if (transceiver->GetMediaType() == SdpMediaSection::kApplication) {
10791079
dcTransceiver = transceiver;
10801080
break;
10811081
}
10821082
}
10831083

10841084
if (!dcTransceiver) {
1085-
dcTransceiver =
1086-
new JsepTransceiver(SdpMediaSection::MediaType::kApplication);
1085+
dcTransceiver = new JsepTransceiver(
1086+
SdpMediaSection::MediaType::kApplication, *mUuidGen);
10871087
mJsepSession->AddTransceiver(dcTransceiver);
10881088
}
10891089

@@ -1609,25 +1609,37 @@ PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP) {
16091609
mPCObserver->OnSetDescriptionError(*buildJSErrorData(result, errorString),
16101610
jrv);
16111611
} else {
1612-
for (const auto& [id, jsepTransceiver] : mJsepSession->GetTransceivers()) {
1612+
for (const auto& jsepTransceiver : mJsepSession->GetTransceivers()) {
16131613
if (jsepTransceiver->GetMediaType() ==
16141614
SdpMediaSection::MediaType::kApplication) {
16151615
continue;
16161616
}
16171617

1618-
if (originalTransceivers.count(id)) {
1619-
continue;
1618+
CSFLogDebug(LOGTAG, "%s: Looking for match", __FUNCTION__);
1619+
RefPtr<RTCRtpTransceiver> transceiver;
1620+
for (auto& temp : mTransceivers) {
1621+
if (temp->GetJsepTransceiverId() == jsepTransceiver->GetUuid()) {
1622+
CSFLogDebug(LOGTAG, "%s: Found match", __FUNCTION__);
1623+
transceiver = temp;
1624+
break;
1625+
}
16201626
}
16211627

1622-
dom::RTCRtpTransceiverInit init;
1623-
init.mDirection = RTCRtpTransceiverDirection::Recvonly;
1624-
RefPtr<RTCRtpTransceiver> transceiver =
1625-
CreateTransceiver(jsepTransceiver, init, nullptr, jrv);
1626-
if (jrv.Failed()) {
1627-
appendHistory();
1628-
return NS_ERROR_FAILURE;
1628+
if (!transceiver) {
1629+
CSFLogDebug(LOGTAG, "%s: No match, making new", __FUNCTION__);
1630+
dom::RTCRtpTransceiverInit init;
1631+
init.mDirection = RTCRtpTransceiverDirection::Recvonly;
1632+
IgnoredErrorResult rv;
1633+
transceiver = CreateTransceiver(
1634+
jsepTransceiver->GetUuid(),
1635+
jsepTransceiver->GetMediaType() == SdpMediaSection::kVideo, init,
1636+
nullptr, rv);
1637+
if (NS_WARN_IF(rv.Failed())) {
1638+
MOZ_ASSERT(false);
1639+
break;
1640+
}
1641+
mTransceivers.AppendElement(transceiver);
16291642
}
1630-
mTransceivers.AppendElement(transceiver);
16311643
}
16321644

16331645
if (wasRestartingIce) {
@@ -3213,8 +3225,7 @@ bool PeerConnectionImpl::ShouldForceProxy() const {
32133225
}
32143226

32153227
void PeerConnectionImpl::EnsureTransports(const JsepSession& aSession) {
3216-
for (const auto& [id, transceiver] : aSession.GetTransceivers()) {
3217-
(void)id; // Lame, but no better way to do this right now.
3228+
for (const auto& transceiver : aSession.GetTransceivers()) {
32183229
if (transceiver->HasOwnTransport()) {
32193230
mTransportHandler->EnsureProvisionalTransport(
32203231
transceiver->mTransport.mTransportId,
@@ -3264,8 +3275,7 @@ void PeerConnectionImpl::RemoveRTCDtlsTransportsExcept(
32643275
nsresult PeerConnectionImpl::UpdateTransports(const JsepSession& aSession,
32653276
const bool forceIceTcp) {
32663277
std::set<std::string> finalTransports;
3267-
for (const auto& [id, transceiver] : aSession.GetTransceivers()) {
3268-
(void)id; // Lame, but no better way to do this right now.
3278+
for (const auto& transceiver : aSession.GetTransceivers()) {
32693279
if (transceiver->HasOwnTransport()) {
32703280
finalTransports.insert(transceiver->mTransport.mTransportId);
32713281
UpdateTransport(*transceiver, forceIceTcp);
@@ -3636,7 +3646,7 @@ void PeerConnectionImpl::EnsureIceGathering(bool aDefaultRouteOnly,
36363646
}
36373647

36383648
already_AddRefed<dom::RTCRtpTransceiver> PeerConnectionImpl::CreateTransceiver(
3639-
JsepTransceiver* aJsepTransceiver, const RTCRtpTransceiverInit& aInit,
3649+
const std::string& aId, bool aIsVideo, const RTCRtpTransceiverInit& aInit,
36403650
dom::MediaStreamTrack* aSendTrack, ErrorResult& aRv) {
36413651
PeerConnectionCtx* ctx = PeerConnectionCtx::GetInstance();
36423652
if (!mCall) {
@@ -3649,8 +3659,8 @@ already_AddRefed<dom::RTCRtpTransceiver> PeerConnectionImpl::CreateTransceiver(
36493659
}
36503660

36513661
RefPtr<RTCRtpTransceiver> transceiver = new RTCRtpTransceiver(
3652-
mWindow, PrivacyNeeded(), this, mTransportHandler, aJsepTransceiver,
3653-
mSTSThread.get(), aSendTrack, mCall.get(), mIdGenerator);
3662+
mWindow, PrivacyNeeded(), this, mTransportHandler, mJsepSession.get(),
3663+
aId, aIsVideo, mSTSThread.get(), aSendTrack, mCall.get(), mIdGenerator);
36543664

36553665
transceiver->Init(aInit, aRv);
36563666
if (aRv.Failed()) {

dom/media/webrtc/jsapi/PeerConnectionImpl.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ class RemoteSourceStreamInfo;
126126
class PCUuidGenerator : public mozilla::JsepUuidGenerator {
127127
public:
128128
virtual bool Generate(std::string* idp) override;
129+
virtual mozilla::JsepUuidGenerator* Clone() const override {
130+
return new PCUuidGenerator(*this);
131+
}
129132

130133
private:
131134
nsCOMPtr<nsIUUIDGenerator> mGenerator;
@@ -725,7 +728,7 @@ class PeerConnectionImpl final
725728
nsresult UpdateMediaPipelines();
726729

727730
already_AddRefed<dom::RTCRtpTransceiver> CreateTransceiver(
728-
JsepTransceiver* aJsepTransceiver,
731+
const std::string& aId, bool aIsVideo,
729732
const dom::RTCRtpTransceiverInit& aInit,
730733
dom::MediaStreamTrack* aSendTrack, ErrorResult& aRv);
731734

dom/media/webrtc/jsapi/RTCRtpTransceiver.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,15 @@ NS_INTERFACE_MAP_END
156156

157157
RTCRtpTransceiver::RTCRtpTransceiver(
158158
nsPIDOMWindowInner* aWindow, bool aPrivacyNeeded, PeerConnectionImpl* aPc,
159-
MediaTransportHandler* aTransportHandler, JsepTransceiver* aJsepTransceiver,
159+
MediaTransportHandler* aTransportHandler, JsepSession* aJsepSession,
160+
const std::string& aTransceiverId, bool aIsVideo,
160161
nsISerialEventTarget* aStsThread, dom::MediaStreamTrack* aSendTrack,
161162
WebrtcCallWrapper* aCallWrapper, RTCStatsIdGenerator* aIdGenerator)
162163
: mWindow(aWindow),
163164
mPc(aPc),
164165
mTransportHandler(aTransportHandler),
165-
mJsepTransceiver(aJsepTransceiver),
166+
mTransceiverId(aTransceiverId),
167+
mJsepTransceiver(aJsepSession->GetTransceiver(mTransceiverId)),
166168
mStsThread(aStsThread),
167169
mCallWrapper(aCallWrapper),
168170
mSendTrack(aSendTrack),

dom/media/webrtc/jsapi/RTCRtpTransceiver.h

+11-11
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@
1212
#include "nsTArray.h"
1313
#include "mozilla/dom/MediaStreamTrack.h"
1414
#include "ErrorList.h"
15-
#include "jsep/JsepTransceiver.h"
15+
#include "jsep/JsepSession.h"
1616
#include "transport/transportlayer.h" // For TransportLayer::State
1717
#include "mozilla/dom/RTCRtpTransceiverBinding.h"
1818

1919
class nsIPrincipal;
2020

2121
namespace mozilla {
2222
class PeerIdentity;
23-
class JsepTransceiver;
2423
class MediaSessionConduit;
2524
class VideoSessionConduit;
2625
class AudioSessionConduit;
@@ -58,14 +57,12 @@ class RTCRtpTransceiver : public nsISupports,
5857
/**
5958
* |aSendTrack| might or might not be set.
6059
*/
61-
RTCRtpTransceiver(nsPIDOMWindowInner* aWindow, bool aPrivacyNeeded,
62-
PeerConnectionImpl* aPc,
63-
MediaTransportHandler* aTransportHandler,
64-
JsepTransceiver* aJsepTransceiver,
65-
nsISerialEventTarget* aStsThread,
66-
MediaStreamTrack* aSendTrack,
67-
WebrtcCallWrapper* aCallWrapper,
68-
RTCStatsIdGenerator* aIdGenerator);
60+
RTCRtpTransceiver(
61+
nsPIDOMWindowInner* aWindow, bool aPrivacyNeeded, PeerConnectionImpl* aPc,
62+
MediaTransportHandler* aTransportHandler, JsepSession* aJsepSession,
63+
const std::string& aTransceiverId, bool aIsVideo,
64+
nsISerialEventTarget* aStsThread, MediaStreamTrack* aSendTrack,
65+
WebrtcCallWrapper* aCallWrapper, RTCStatsIdGenerator* aIdGenerator);
6966

7067
void Init(const RTCRtpTransceiverInit& aInit, ErrorResult& aRv);
7168

@@ -145,6 +142,8 @@ class RTCRtpTransceiver : public nsISupports,
145142

146143
MediaSessionConduit* GetConduit() const { return mConduit; }
147144

145+
const std::string& GetJsepTransceiverId() const { return mTransceiverId; }
146+
148147
// nsISupports
149148
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
150149
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(RTCRtpTransceiver)
@@ -188,7 +187,8 @@ class RTCRtpTransceiver : public nsISupports,
188187
nsCOMPtr<nsPIDOMWindowInner> mWindow;
189188
RefPtr<PeerConnectionImpl> mPc;
190189
RefPtr<MediaTransportHandler> mTransportHandler;
191-
const RefPtr<JsepTransceiver> mJsepTransceiver;
190+
const std::string mTransceiverId;
191+
RefPtr<JsepTransceiver> mJsepTransceiver;
192192
nsCOMPtr<nsISerialEventTarget> mStsThread;
193193
// state for webrtc.org that is shared between all transceivers
194194
RefPtr<WebrtcCallWrapper> mCallWrapper;

dom/media/webrtc/jsep/JsepSession.h

+14-8
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ class JsepSession {
107107
template <class UnaryFunction>
108108
void ForEachCodec(UnaryFunction& function) {
109109
std::for_each(Codecs().begin(), Codecs().end(), function);
110-
for (auto& [id, transceiver] : GetTransceivers()) {
111-
(void)id; // Lame, but no better way to do this right now.
110+
for (auto& transceiver : GetTransceivers()) {
112111
transceiver->mSendTrack.ForEachCodec(function);
113112
transceiver->mRecvTrack.ForEachCodec(function);
114113
}
@@ -117,16 +116,24 @@ class JsepSession {
117116
template <class BinaryPredicate>
118117
void SortCodecs(BinaryPredicate& sorter) {
119118
std::stable_sort(Codecs().begin(), Codecs().end(), sorter);
120-
for (auto& [id, transceiver] : GetTransceivers()) {
121-
(void)id; // Lame, but no better way to do this right now.
119+
for (auto& transceiver : GetTransceivers()) {
122120
transceiver->mSendTrack.SortCodecs(sorter);
123121
transceiver->mRecvTrack.SortCodecs(sorter);
124122
}
125123
}
126124

127-
virtual const std::map<size_t, RefPtr<JsepTransceiver>>& GetTransceivers()
125+
// Returns transceivers in the order they were added.
126+
virtual const std::vector<RefPtr<JsepTransceiver>>& GetTransceivers()
128127
const = 0;
129-
virtual std::map<size_t, RefPtr<JsepTransceiver>>& GetTransceivers() = 0;
128+
virtual std::vector<RefPtr<JsepTransceiver>>& GetTransceivers() = 0;
129+
RefPtr<JsepTransceiver> GetTransceiver(const std::string& aId) const {
130+
for (const auto& transceiver : GetTransceivers()) {
131+
if (transceiver->GetUuid() == aId) {
132+
return transceiver;
133+
}
134+
}
135+
return nullptr;
136+
}
130137
virtual nsresult AddTransceiver(RefPtr<JsepTransceiver> transceiver) = 0;
131138

132139
class Result {
@@ -198,8 +205,7 @@ class JsepSession {
198205
memset(receiving, 0, sizeof(receiving));
199206
memset(sending, 0, sizeof(sending));
200207

201-
for (const auto& [id, transceiver] : GetTransceivers()) {
202-
(void)id; // Lame, but no better way to do this right now.
208+
for (const auto& transceiver : GetTransceivers()) {
203209
if (transceiver->mRecvTrack.GetActive() ||
204210
transceiver->GetMediaType() == SdpMediaSection::kApplication) {
205211
receiving[transceiver->mRecvTrack.GetMediaType()]++;

0 commit comments

Comments
 (0)