forked from mirrors/gecko-dev
Bug 1829667: Make JsepTransceiver non-refcounted. r=mjf,webidl,mccr8
Involves substantial refactoring to make most access by-value (or through functional-style in-place modifications) for safety. Differential Revision: https://phabricator.services.mozilla.com/D176423
This commit is contained in:
parent
e533a4c3dd
commit
c7504aeccf
15 changed files with 1207 additions and 1207 deletions
|
|
@ -1391,11 +1391,14 @@ export class RTCPeerConnection {
|
||||||
transceiver.setDirectionInternal("sendonly");
|
transceiver.setDirectionInternal("sendonly");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
transceiver = this._addTransceiverNoEvents(track, {
|
transceiver = this._addTransceiverNoEvents(
|
||||||
|
track,
|
||||||
|
{
|
||||||
streams,
|
streams,
|
||||||
direction: "sendrecv",
|
direction: "sendrecv",
|
||||||
});
|
},
|
||||||
transceiver.setAddTrackMagic();
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateNegotiationNeeded();
|
this.updateNegotiationNeeded();
|
||||||
|
|
@ -1431,7 +1434,7 @@ export class RTCPeerConnection {
|
||||||
this.updateNegotiationNeeded();
|
this.updateNegotiationNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
_addTransceiverNoEvents(sendTrackOrKind, init) {
|
_addTransceiverNoEvents(sendTrackOrKind, init, addTrackMagic) {
|
||||||
let sendTrack = null;
|
let sendTrack = null;
|
||||||
let kind;
|
let kind;
|
||||||
if (typeof sendTrackOrKind == "string") {
|
if (typeof sendTrackOrKind == "string") {
|
||||||
|
|
@ -1449,7 +1452,7 @@ export class RTCPeerConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return this._pc.addTransceiver(init, kind, sendTrack);
|
return this._pc.addTransceiver(init, kind, sendTrack, addTrackMagic);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Exceptions thrown by c++ code do not propagate. In most cases, that's
|
// Exceptions thrown by c++ code do not propagate. In most cases, that's
|
||||||
// fine because we're using Promises, which can be copied. But this is
|
// fine because we're using Promises, which can be copied. But this is
|
||||||
|
|
|
||||||
|
|
@ -877,17 +877,14 @@ nsresult PeerConnectionImpl::GetDatachannelParameters(
|
||||||
*mmsset = false;
|
*mmsset = false;
|
||||||
transportId->clear();
|
transportId->clear();
|
||||||
|
|
||||||
RefPtr<JsepTransceiver> datachannelTransceiver;
|
Maybe<const JsepTransceiver> datachannelTransceiver =
|
||||||
for (const auto& transceiver : mJsepSession->GetTransceivers()) {
|
mJsepSession->FindTransceiver([](const JsepTransceiver& aTransceiver) {
|
||||||
if ((transceiver->GetMediaType() == SdpMediaSection::kApplication) &&
|
return aTransceiver.GetMediaType() == SdpMediaSection::kApplication;
|
||||||
transceiver->mSendTrack.GetNegotiatedDetails()) {
|
});
|
||||||
datachannelTransceiver = transceiver;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!datachannelTransceiver ||
|
if (!datachannelTransceiver ||
|
||||||
!datachannelTransceiver->mTransport.mComponents) {
|
!datachannelTransceiver->mTransport.mComponents ||
|
||||||
|
!datachannelTransceiver->mSendTrack.GetNegotiatedDetails()) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -942,7 +939,7 @@ nsresult PeerConnectionImpl::GetDatachannelParameters(
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult PeerConnectionImpl::AddRtpTransceiverToJsepSession(
|
nsresult PeerConnectionImpl::AddRtpTransceiverToJsepSession(
|
||||||
RefPtr<JsepTransceiver>& transceiver) {
|
JsepTransceiver& transceiver) {
|
||||||
nsresult res = ConfigureJsepSessionCodecs();
|
nsresult res = ConfigureJsepSessionCodecs();
|
||||||
if (NS_FAILED(res)) {
|
if (NS_FAILED(res)) {
|
||||||
CSFLogError(LOGTAG, "Failed to configure codecs");
|
CSFLogError(LOGTAG, "Failed to configure codecs");
|
||||||
|
|
@ -965,7 +962,7 @@ static Maybe<SdpMediaSection::MediaType> ToSdpMediaType(
|
||||||
|
|
||||||
already_AddRefed<RTCRtpTransceiver> PeerConnectionImpl::AddTransceiver(
|
already_AddRefed<RTCRtpTransceiver> PeerConnectionImpl::AddTransceiver(
|
||||||
const dom::RTCRtpTransceiverInit& aInit, const nsAString& aKind,
|
const dom::RTCRtpTransceiverInit& aInit, const nsAString& aKind,
|
||||||
dom::MediaStreamTrack* aSendTrack, ErrorResult& aRv) {
|
dom::MediaStreamTrack* aSendTrack, bool aAddTrackMagic, ErrorResult& aRv) {
|
||||||
// Copy, because we might need to modify
|
// Copy, because we might need to modify
|
||||||
RTCRtpTransceiverInit init(aInit);
|
RTCRtpTransceiverInit init(aInit);
|
||||||
|
|
||||||
|
|
@ -976,9 +973,8 @@ already_AddRefed<RTCRtpTransceiver> PeerConnectionImpl::AddTransceiver(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<JsepTransceiver> jsepTransceiver =
|
JsepTransceiver jsepTransceiver(*type, *mUuidGen);
|
||||||
new JsepTransceiver(*type, *mUuidGen);
|
jsepTransceiver.SetRtxIsAllowed(mRtxIsAllowed);
|
||||||
jsepTransceiver->SetRtxIsAllowed(mRtxIsAllowed);
|
|
||||||
|
|
||||||
// Do this last, since it is not possible to roll back.
|
// Do this last, since it is not possible to roll back.
|
||||||
nsresult rv = AddRtpTransceiverToJsepSession(jsepTransceiver);
|
nsresult rv = AddRtpTransceiverToJsepSession(jsepTransceiver);
|
||||||
|
|
@ -1074,9 +1070,9 @@ already_AddRefed<RTCRtpTransceiver> PeerConnectionImpl::AddTransceiver(
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<RTCRtpTransceiver> transceiver = CreateTransceiver(
|
RefPtr<RTCRtpTransceiver> transceiver = CreateTransceiver(
|
||||||
jsepTransceiver->GetUuid(),
|
jsepTransceiver.GetUuid(),
|
||||||
jsepTransceiver->GetMediaType() == SdpMediaSection::kVideo, init,
|
jsepTransceiver.GetMediaType() == SdpMediaSection::kVideo, init,
|
||||||
aSendTrack, aRv);
|
aSendTrack, aAddTrackMagic, aRv);
|
||||||
|
|
||||||
if (aRv.Failed()) {
|
if (aRv.Failed()) {
|
||||||
// Would be nice if we could peek at the rv without stealing it, so we
|
// Would be nice if we could peek at the rv without stealing it, so we
|
||||||
|
|
@ -1177,21 +1173,18 @@ PeerConnectionImpl::CreateDataChannel(
|
||||||
|
|
||||||
CSFLogDebug(LOGTAG, "%s: making DOMDataChannel", __FUNCTION__);
|
CSFLogDebug(LOGTAG, "%s: making DOMDataChannel", __FUNCTION__);
|
||||||
|
|
||||||
RefPtr<JsepTransceiver> dcTransceiver;
|
Maybe<JsepTransceiver> dcTransceiver =
|
||||||
for (auto& transceiver : mJsepSession->GetTransceivers()) {
|
mJsepSession->FindTransceiver([](const JsepTransceiver& aTransceiver) {
|
||||||
if (transceiver->GetMediaType() == SdpMediaSection::kApplication) {
|
return aTransceiver.GetMediaType() == SdpMediaSection::kApplication;
|
||||||
dcTransceiver = transceiver;
|
});
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dcTransceiver) {
|
|
||||||
dcTransceiver = new JsepTransceiver(
|
|
||||||
SdpMediaSection::MediaType::kApplication, *mUuidGen);
|
|
||||||
mJsepSession->AddTransceiver(dcTransceiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (dcTransceiver) {
|
||||||
dcTransceiver->RestartDatachannelTransceiver();
|
dcTransceiver->RestartDatachannelTransceiver();
|
||||||
|
mJsepSession->SetTransceiver(*dcTransceiver);
|
||||||
|
} else {
|
||||||
|
mJsepSession->AddTransceiver(
|
||||||
|
JsepTransceiver(SdpMediaSection::MediaType::kApplication, *mUuidGen));
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<nsDOMDataChannel> retval;
|
RefPtr<nsDOMDataChannel> retval;
|
||||||
rv = NS_NewDOMDataChannel(dataChannel.forget(), mWindow,
|
rv = NS_NewDOMDataChannel(dataChannel.forget(), mWindow,
|
||||||
|
|
@ -1364,22 +1357,24 @@ void PeerConnectionImpl::RunNextOperation(ErrorResult& aError) {
|
||||||
|
|
||||||
void PeerConnectionImpl::SyncToJsep() {
|
void PeerConnectionImpl::SyncToJsep() {
|
||||||
for (const auto& transceiver : mTransceivers) {
|
for (const auto& transceiver : mTransceivers) {
|
||||||
transceiver->SyncToJsep();
|
transceiver->SyncToJsep(*mJsepSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerConnectionImpl::SyncFromJsep() {
|
void PeerConnectionImpl::SyncFromJsep() {
|
||||||
CSFLogDebug(LOGTAG, "%s", __FUNCTION__);
|
CSFLogDebug(LOGTAG, "%s", __FUNCTION__);
|
||||||
for (const auto& jsepTransceiver : mJsepSession->GetTransceivers()) {
|
mJsepSession->ForEachTransceiver(
|
||||||
if (jsepTransceiver->GetMediaType() ==
|
[this, self = RefPtr<PeerConnectionImpl>(this)](
|
||||||
|
const JsepTransceiver& jsepTransceiver) {
|
||||||
|
if (jsepTransceiver.GetMediaType() ==
|
||||||
SdpMediaSection::MediaType::kApplication) {
|
SdpMediaSection::MediaType::kApplication) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSFLogDebug(LOGTAG, "%s: Looking for match", __FUNCTION__);
|
CSFLogDebug(LOGTAG, "%s: Looking for match", __FUNCTION__);
|
||||||
RefPtr<RTCRtpTransceiver> transceiver;
|
RefPtr<RTCRtpTransceiver> transceiver;
|
||||||
for (auto& temp : mTransceivers) {
|
for (auto& temp : mTransceivers) {
|
||||||
if (temp->GetJsepTransceiverId() == jsepTransceiver->GetUuid()) {
|
if (temp->GetJsepTransceiverId() == jsepTransceiver.GetUuid()) {
|
||||||
CSFLogDebug(LOGTAG, "%s: Found match", __FUNCTION__);
|
CSFLogDebug(LOGTAG, "%s: Found match", __FUNCTION__);
|
||||||
transceiver = temp;
|
transceiver = temp;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1392,9 +1387,9 @@ void PeerConnectionImpl::SyncFromJsep() {
|
||||||
init.mDirection = RTCRtpTransceiverDirection::Recvonly;
|
init.mDirection = RTCRtpTransceiverDirection::Recvonly;
|
||||||
IgnoredErrorResult rv;
|
IgnoredErrorResult rv;
|
||||||
transceiver = CreateTransceiver(
|
transceiver = CreateTransceiver(
|
||||||
jsepTransceiver->GetUuid(),
|
jsepTransceiver.GetUuid(),
|
||||||
jsepTransceiver->GetMediaType() == SdpMediaSection::kVideo, init,
|
jsepTransceiver.GetMediaType() == SdpMediaSection::kVideo, init,
|
||||||
nullptr, rv);
|
nullptr, false, rv);
|
||||||
if (NS_WARN_IF(rv.Failed())) {
|
if (NS_WARN_IF(rv.Failed())) {
|
||||||
MOZ_ASSERT(false);
|
MOZ_ASSERT(false);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1403,8 +1398,8 @@ void PeerConnectionImpl::SyncFromJsep() {
|
||||||
}
|
}
|
||||||
|
|
||||||
CSFLogDebug(LOGTAG, "%s: Syncing transceiver", __FUNCTION__);
|
CSFLogDebug(LOGTAG, "%s: Syncing transceiver", __FUNCTION__);
|
||||||
transceiver->SyncFromJsep();
|
transceiver->SyncFromJsep(*mJsepSession);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<dom::Promise> PeerConnectionImpl::MakePromise(
|
already_AddRefed<dom::Promise> PeerConnectionImpl::MakePromise(
|
||||||
|
|
@ -1592,9 +1587,6 @@ PeerConnectionImpl::CreateOffer(const JsepOfferOptions& aOptions) {
|
||||||
*buildJSErrorData(result, errorString), rv);
|
*buildJSErrorData(result, errorString), rv);
|
||||||
} else {
|
} else {
|
||||||
mJsepSession = std::move(uncommittedJsepSession);
|
mJsepSession = std::move(uncommittedJsepSession);
|
||||||
for (auto& transceiver : mTransceivers) {
|
|
||||||
transceiver->SetJsepSession(mJsepSession.get());
|
|
||||||
}
|
|
||||||
mPCObserver->OnCreateOfferSuccess(ObString(offer.c_str()), rv);
|
mPCObserver->OnCreateOfferSuccess(ObString(offer.c_str()), rv);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
@ -1631,9 +1623,6 @@ PeerConnectionImpl::CreateAnswer() {
|
||||||
*buildJSErrorData(result, errorString), rv);
|
*buildJSErrorData(result, errorString), rv);
|
||||||
} else {
|
} else {
|
||||||
mJsepSession = std::move(uncommittedJsepSession);
|
mJsepSession = std::move(uncommittedJsepSession);
|
||||||
for (auto& transceiver : mTransceivers) {
|
|
||||||
transceiver->SetJsepSession(mJsepSession.get());
|
|
||||||
}
|
|
||||||
mPCObserver->OnCreateAnswerSuccess(ObString(answer.c_str()), rv);
|
mPCObserver->OnCreateAnswerSuccess(ObString(answer.c_str()), rv);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
@ -3012,9 +3001,6 @@ void PeerConnectionImpl::DoSetDescriptionSuccessPostProcessing(
|
||||||
}
|
}
|
||||||
|
|
||||||
mJsepSession = std::move(mUncommittedJsepSession);
|
mJsepSession = std::move(mUncommittedJsepSession);
|
||||||
for (auto& transceiver : mTransceivers) {
|
|
||||||
transceiver->SetJsepSession(mJsepSession.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto newSignalingState = GetSignalingState();
|
auto newSignalingState = GetSignalingState();
|
||||||
SyncFromJsep();
|
SyncFromJsep();
|
||||||
|
|
@ -3981,30 +3967,33 @@ bool PeerConnectionImpl::ShouldForceProxy() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerConnectionImpl::EnsureTransports(const JsepSession& aSession) {
|
void PeerConnectionImpl::EnsureTransports(const JsepSession& aSession) {
|
||||||
for (const auto& transceiver : aSession.GetTransceivers()) {
|
mJsepSession->ForEachTransceiver([this,
|
||||||
if (transceiver->HasOwnTransport()) {
|
self = RefPtr<PeerConnectionImpl>(this)](
|
||||||
|
const JsepTransceiver& transceiver) {
|
||||||
|
if (transceiver.HasOwnTransport()) {
|
||||||
mTransportHandler->EnsureProvisionalTransport(
|
mTransportHandler->EnsureProvisionalTransport(
|
||||||
transceiver->mTransport.mTransportId,
|
transceiver.mTransport.mTransportId,
|
||||||
transceiver->mTransport.mLocalUfrag,
|
transceiver.mTransport.mLocalUfrag, transceiver.mTransport.mLocalPwd,
|
||||||
transceiver->mTransport.mLocalPwd,
|
transceiver.mTransport.mComponents);
|
||||||
transceiver->mTransport.mComponents);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
GatherIfReady();
|
GatherIfReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerConnectionImpl::UpdateRTCDtlsTransports(bool aMarkAsStable) {
|
void PeerConnectionImpl::UpdateRTCDtlsTransports(bool aMarkAsStable) {
|
||||||
for (const auto& jsepTransceiver : mJsepSession->GetTransceivers()) {
|
mJsepSession->ForEachTransceiver(
|
||||||
std::string transportId = jsepTransceiver->mTransport.mTransportId;
|
[this, self = RefPtr<PeerConnectionImpl>(this)](
|
||||||
|
const JsepTransceiver& jsepTransceiver) {
|
||||||
|
std::string transportId = jsepTransceiver.mTransport.mTransportId;
|
||||||
if (transportId.empty()) {
|
if (transportId.empty()) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
if (!mTransportIdToRTCDtlsTransport.count(transportId)) {
|
if (!mTransportIdToRTCDtlsTransport.count(transportId)) {
|
||||||
mTransportIdToRTCDtlsTransport.emplace(
|
mTransportIdToRTCDtlsTransport.emplace(
|
||||||
transportId, new RTCDtlsTransport(GetParentObject()));
|
transportId, new RTCDtlsTransport(GetParentObject()));
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
for (auto& transceiver : mTransceivers) {
|
for (auto& transceiver : mTransceivers) {
|
||||||
std::string transportId = transceiver->GetTransportId();
|
std::string transportId = transceiver->GetTransportId();
|
||||||
|
|
@ -4042,17 +4031,19 @@ nsresult PeerConnectionImpl::UpdateTransports(const JsepSession& aSession,
|
||||||
const bool forceIceTcp) {
|
const bool forceIceTcp) {
|
||||||
std::set<std::string> finalTransports;
|
std::set<std::string> finalTransports;
|
||||||
Maybe<std::string> sctpTransport;
|
Maybe<std::string> sctpTransport;
|
||||||
for (const auto& transceiver : aSession.GetTransceivers()) {
|
mJsepSession->ForEachTransceiver(
|
||||||
if (transceiver->GetMediaType() == SdpMediaSection::kApplication &&
|
[&, this, self = RefPtr<PeerConnectionImpl>(this)](
|
||||||
transceiver->HasTransport()) {
|
const JsepTransceiver& transceiver) {
|
||||||
sctpTransport = Some(transceiver->mTransport.mTransportId);
|
if (transceiver.GetMediaType() == SdpMediaSection::kApplication &&
|
||||||
|
transceiver.HasTransport()) {
|
||||||
|
sctpTransport = Some(transceiver.mTransport.mTransportId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transceiver->HasOwnTransport()) {
|
if (transceiver.HasOwnTransport()) {
|
||||||
finalTransports.insert(transceiver->mTransport.mTransportId);
|
finalTransports.insert(transceiver.mTransport.mTransportId);
|
||||||
UpdateTransport(*transceiver, forceIceTcp);
|
UpdateTransport(transceiver, forceIceTcp);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// clean up the unused RTCDtlsTransports
|
// clean up the unused RTCDtlsTransports
|
||||||
RemoveRTCDtlsTransportsExcept(finalTransports);
|
RemoveRTCDtlsTransportsExcept(finalTransports);
|
||||||
|
|
@ -4447,7 +4438,7 @@ void PeerConnectionImpl::EnsureIceGathering(bool aDefaultRouteOnly,
|
||||||
|
|
||||||
already_AddRefed<dom::RTCRtpTransceiver> PeerConnectionImpl::CreateTransceiver(
|
already_AddRefed<dom::RTCRtpTransceiver> PeerConnectionImpl::CreateTransceiver(
|
||||||
const std::string& aId, bool aIsVideo, const RTCRtpTransceiverInit& aInit,
|
const std::string& aId, bool aIsVideo, const RTCRtpTransceiverInit& aInit,
|
||||||
dom::MediaStreamTrack* aSendTrack, ErrorResult& aRv) {
|
dom::MediaStreamTrack* aSendTrack, bool aAddTrackMagic, ErrorResult& aRv) {
|
||||||
PeerConnectionCtx* ctx = PeerConnectionCtx::GetInstance();
|
PeerConnectionCtx* ctx = PeerConnectionCtx::GetInstance();
|
||||||
if (!mCall) {
|
if (!mCall) {
|
||||||
mCall = WebrtcCallWrapper::Create(
|
mCall = WebrtcCallWrapper::Create(
|
||||||
|
|
@ -4458,6 +4449,12 @@ already_AddRefed<dom::RTCRtpTransceiver> PeerConnectionImpl::CreateTransceiver(
|
||||||
ctx->GetSharedWebrtcState());
|
ctx->GetSharedWebrtcState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aAddTrackMagic) {
|
||||||
|
mJsepSession->ApplyToTransceiver(aId, [](JsepTransceiver& aTransceiver) {
|
||||||
|
aTransceiver.SetAddTrackMagic();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<RTCRtpTransceiver> transceiver = new RTCRtpTransceiver(
|
RefPtr<RTCRtpTransceiver> transceiver = new RTCRtpTransceiver(
|
||||||
mWindow, PrivacyRequested(), this, mTransportHandler, mJsepSession.get(),
|
mWindow, PrivacyRequested(), this, mTransportHandler, mJsepSession.get(),
|
||||||
aId, aIsVideo, mSTSThread.get(), aSendTrack, mCall.get(), mIdGenerator);
|
aId, aIsVideo, mSTSThread.get(), aSendTrack, mCall.get(), mIdGenerator);
|
||||||
|
|
@ -4467,8 +4464,6 @@ already_AddRefed<dom::RTCRtpTransceiver> PeerConnectionImpl::CreateTransceiver(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
transceiver->SyncToJsep();
|
|
||||||
|
|
||||||
if (aSendTrack) {
|
if (aSendTrack) {
|
||||||
// implement checking for peerIdentity (where failure == black/silence)
|
// implement checking for peerIdentity (where failure == black/silence)
|
||||||
Document* doc = mWindow->GetExtantDoc();
|
Document* doc = mWindow->GetExtantDoc();
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ class PeerConnectionImpl final
|
||||||
|
|
||||||
already_AddRefed<dom::RTCRtpTransceiver> AddTransceiver(
|
already_AddRefed<dom::RTCRtpTransceiver> AddTransceiver(
|
||||||
const dom::RTCRtpTransceiverInit& aInit, const nsAString& aKind,
|
const dom::RTCRtpTransceiverInit& aInit, const nsAString& aKind,
|
||||||
dom::MediaStreamTrack* aSendTrack, ErrorResult& aRv);
|
dom::MediaStreamTrack* aSendTrack, bool aAddTrackMagic, ErrorResult& aRv);
|
||||||
|
|
||||||
bool CheckNegotiationNeeded();
|
bool CheckNegotiationNeeded();
|
||||||
bool CreatedSender(const dom::RTCRtpSender& aSender) const;
|
bool CreatedSender(const dom::RTCRtpSender& aSender) const;
|
||||||
|
|
@ -614,7 +614,7 @@ class PeerConnectionImpl final
|
||||||
std::string* transportId,
|
std::string* transportId,
|
||||||
bool* client) const;
|
bool* client) const;
|
||||||
|
|
||||||
nsresult AddRtpTransceiverToJsepSession(RefPtr<JsepTransceiver>& transceiver);
|
nsresult AddRtpTransceiverToJsepSession(JsepTransceiver& transceiver);
|
||||||
|
|
||||||
void RecordIceRestartStatistics(JsepSdpType type);
|
void RecordIceRestartStatistics(JsepSdpType type);
|
||||||
|
|
||||||
|
|
@ -825,7 +825,7 @@ class PeerConnectionImpl final
|
||||||
already_AddRefed<dom::RTCRtpTransceiver> CreateTransceiver(
|
already_AddRefed<dom::RTCRtpTransceiver> CreateTransceiver(
|
||||||
const std::string& aId, bool aIsVideo,
|
const std::string& aId, bool aIsVideo,
|
||||||
const dom::RTCRtpTransceiverInit& aInit,
|
const dom::RTCRtpTransceiverInit& aInit,
|
||||||
dom::MediaStreamTrack* aSendTrack, ErrorResult& aRv);
|
dom::MediaStreamTrack* aSendTrack, bool aAddTrackMagic, ErrorResult& aRv);
|
||||||
|
|
||||||
std::string GetTransportIdMatchingSendTrack(
|
std::string GetTransportIdMatchingSendTrack(
|
||||||
const dom::MediaStreamTrack& aTrack) const;
|
const dom::MediaStreamTrack& aTrack) const;
|
||||||
|
|
|
||||||
|
|
@ -892,12 +892,12 @@ std::string RTCRtpReceiver::GetMid() const {
|
||||||
|
|
||||||
JsepTransceiver& RTCRtpReceiver::GetJsepTransceiver() {
|
JsepTransceiver& RTCRtpReceiver::GetJsepTransceiver() {
|
||||||
MOZ_ASSERT(mTransceiver);
|
MOZ_ASSERT(mTransceiver);
|
||||||
return *mTransceiver->GetJsepTransceiver();
|
return mTransceiver->GetJsepTransceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
const JsepTransceiver& RTCRtpReceiver::GetJsepTransceiver() const {
|
const JsepTransceiver& RTCRtpReceiver::GetJsepTransceiver() const {
|
||||||
MOZ_ASSERT(mTransceiver);
|
MOZ_ASSERT(mTransceiver);
|
||||||
return *mTransceiver->GetJsepTransceiver();
|
return mTransceiver->GetJsepTransceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozilla::dom
|
} // namespace mozilla::dom
|
||||||
|
|
|
||||||
|
|
@ -74,10 +74,6 @@ RTCRtpSender::RTCRtpSender(nsPIDOMWindowInner* aWindow, PeerConnectionImpl* aPc,
|
||||||
|
|
||||||
if (aConduit->type() == MediaSessionConduit::AUDIO) {
|
if (aConduit->type() == MediaSessionConduit::AUDIO) {
|
||||||
mDtmf = new RTCDTMFSender(aWindow, mTransceiver);
|
mDtmf = new RTCDTMFSender(aWindow, mTransceiver);
|
||||||
GetJsepTransceiver().mSendTrack.SetMaxEncodings(1);
|
|
||||||
} else {
|
|
||||||
GetJsepTransceiver().mSendTrack.SetMaxEncodings(
|
|
||||||
webrtc::kMaxSimulcastStreams);
|
|
||||||
}
|
}
|
||||||
mPipeline->SetTrack(mSenderTrack);
|
mPipeline->SetTrack(mSenderTrack);
|
||||||
|
|
||||||
|
|
@ -91,7 +87,7 @@ RTCRtpSender::RTCRtpSender(nsPIDOMWindowInner* aWindow, PeerConnectionImpl* aPc,
|
||||||
if (aEncodings.Length()) {
|
if (aEncodings.Length()) {
|
||||||
// This sender was created by addTransceiver with sendEncodings.
|
// This sender was created by addTransceiver with sendEncodings.
|
||||||
mParameters.mEncodings = aEncodings;
|
mParameters.mEncodings = aEncodings;
|
||||||
SetJsepRids(mParameters);
|
mSimulcastEnvelopeSet = true;
|
||||||
mozilla::glean::rtcrtpsender::used_sendencodings.AddToNumerator(1);
|
mozilla::glean::rtcrtpsender::used_sendencodings.AddToNumerator(1);
|
||||||
} else {
|
} else {
|
||||||
// This sender was created by addTrack, sRD(offer), or addTransceiver
|
// This sender was created by addTrack, sRD(offer), or addTransceiver
|
||||||
|
|
@ -724,7 +720,7 @@ already_AddRefed<Promise> RTCRtpSender::SetParameters(
|
||||||
MaybeUpdateConduit();
|
MaybeUpdateConduit();
|
||||||
|
|
||||||
if (compatModeAllowedRidChange) {
|
if (compatModeAllowedRidChange) {
|
||||||
SetJsepRids(paramsCopy);
|
mSimulcastEnvelopeSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the media stack is successfully configured with parameters,
|
// If the media stack is successfully configured with parameters,
|
||||||
|
|
@ -841,22 +837,6 @@ void RTCRtpSender::CheckAndRectifyEncodings(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTCRtpSender::SetJsepRids(const RTCRtpSendParameters& aParameters) {
|
|
||||||
MOZ_ASSERT(aParameters.mEncodings.Length());
|
|
||||||
|
|
||||||
std::vector<std::string> rids;
|
|
||||||
for (const auto& encoding : aParameters.mEncodings) {
|
|
||||||
if (encoding.mRid.WasPassed()) {
|
|
||||||
rids.push_back(NS_ConvertUTF16toUTF8(encoding.mRid.Value()).get());
|
|
||||||
} else {
|
|
||||||
rids.push_back("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GetJsepTransceiver().mSendTrack.SetRids(rids);
|
|
||||||
mSimulcastEnvelopeSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RTCRtpSender::GetParameters(RTCRtpSendParameters& aParameters) {
|
void RTCRtpSender::GetParameters(RTCRtpSendParameters& aParameters) {
|
||||||
MOZ_ASSERT(mParameters.mEncodings.Length());
|
MOZ_ASSERT(mParameters.mEncodings.Length());
|
||||||
// If sender.[[LastReturnedParameters]] is not null, return
|
// If sender.[[LastReturnedParameters]] is not null, return
|
||||||
|
|
@ -1206,10 +1186,10 @@ void RTCRtpSender::SetTrack(const RefPtr<MediaStreamTrack>& aTrack) {
|
||||||
mSenderTrack = aTrack;
|
mSenderTrack = aTrack;
|
||||||
SeamlessTrackSwitch(aTrack);
|
SeamlessTrackSwitch(aTrack);
|
||||||
if (aTrack) {
|
if (aTrack) {
|
||||||
// RFC says:
|
// RFC says (in the section on remote rollback):
|
||||||
// However, an RtpTransceiver MUST NOT be removed if a track was attached
|
// However, an RtpTransceiver MUST NOT be removed if a track was attached
|
||||||
// to the RtpTransceiver via the addTrack method.
|
// to the RtpTransceiver via the addTrack method.
|
||||||
GetJsepTransceiver().SetOnlyExistsBecauseOfSetRemote(false);
|
mAddTrackCalled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1314,6 +1294,29 @@ void RTCRtpSender::SyncToJsep(JsepTransceiver& aJsepTransceiver) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
aJsepTransceiver.mSendTrack.UpdateStreamIds(streamIds);
|
aJsepTransceiver.mSendTrack.UpdateStreamIds(streamIds);
|
||||||
|
|
||||||
|
if (mSimulcastEnvelopeSet) {
|
||||||
|
std::vector<std::string> rids;
|
||||||
|
for (const auto& encoding : mParameters.mEncodings) {
|
||||||
|
if (encoding.mRid.WasPassed()) {
|
||||||
|
rids.push_back(NS_ConvertUTF16toUTF8(encoding.mRid.Value()).get());
|
||||||
|
} else {
|
||||||
|
rids.push_back("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aJsepTransceiver.mSendTrack.SetRids(rids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTransceiver->IsVideo()) {
|
||||||
|
aJsepTransceiver.mSendTrack.SetMaxEncodings(webrtc::kMaxSimulcastStreams);
|
||||||
|
} else {
|
||||||
|
aJsepTransceiver.mSendTrack.SetMaxEncodings(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mAddTrackCalled) {
|
||||||
|
aJsepTransceiver.SetOnlyExistsBecauseOfSetRemote(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<RTCRtpSender::VideoConfig> RTCRtpSender::GetNewVideoConfig() {
|
Maybe<RTCRtpSender::VideoConfig> RTCRtpSender::GetNewVideoConfig() {
|
||||||
|
|
@ -1579,7 +1582,7 @@ RefPtr<MediaPipelineTransmit> RTCRtpSender::GetPipeline() const {
|
||||||
std::string RTCRtpSender::GetMid() const { return mTransceiver->GetMidAscii(); }
|
std::string RTCRtpSender::GetMid() const { return mTransceiver->GetMidAscii(); }
|
||||||
|
|
||||||
JsepTransceiver& RTCRtpSender::GetJsepTransceiver() {
|
JsepTransceiver& RTCRtpSender::GetJsepTransceiver() {
|
||||||
return *mTransceiver->GetJsepTransceiver();
|
return mTransceiver->GetJsepTransceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTCRtpSender::UpdateDtmfSender() {
|
void RTCRtpSender::UpdateDtmfSender() {
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,6 @@ class RTCRtpSender : public nsISupports,
|
||||||
|
|
||||||
std::string GetMid() const;
|
std::string GetMid() const;
|
||||||
JsepTransceiver& GetJsepTransceiver();
|
JsepTransceiver& GetJsepTransceiver();
|
||||||
void SetJsepRids(const RTCRtpSendParameters& aParameters);
|
|
||||||
static void ApplyJsEncodingToConduitEncoding(
|
static void ApplyJsEncodingToConduitEncoding(
|
||||||
const RTCRtpEncodingParameters& aJsEncoding,
|
const RTCRtpEncodingParameters& aJsEncoding,
|
||||||
VideoCodecConfig::Encoding* aConduitEncoding);
|
VideoCodecConfig::Encoding* aConduitEncoding);
|
||||||
|
|
@ -157,6 +156,7 @@ class RTCRtpSender : public nsISupports,
|
||||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||||
RefPtr<PeerConnectionImpl> mPc;
|
RefPtr<PeerConnectionImpl> mPc;
|
||||||
RefPtr<dom::MediaStreamTrack> mSenderTrack;
|
RefPtr<dom::MediaStreamTrack> mSenderTrack;
|
||||||
|
bool mAddTrackCalled = false;
|
||||||
RTCRtpSendParameters mParameters;
|
RTCRtpSendParameters mParameters;
|
||||||
Maybe<RTCRtpSendParameters> mPendingParameters;
|
Maybe<RTCRtpSendParameters> mPendingParameters;
|
||||||
uint32_t mNumSetParametersCalls = 0;
|
uint32_t mNumSetParametersCalls = 0;
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ RTCRtpTransceiver::RTCRtpTransceiver(
|
||||||
mPc(aPc),
|
mPc(aPc),
|
||||||
mTransportHandler(aTransportHandler),
|
mTransportHandler(aTransportHandler),
|
||||||
mTransceiverId(aTransceiverId),
|
mTransceiverId(aTransceiverId),
|
||||||
mJsepTransceiver(aJsepSession->GetTransceiver(mTransceiverId)),
|
mJsepTransceiver(*aJsepSession->GetTransceiver(mTransceiverId)),
|
||||||
mStsThread(aStsThread),
|
mStsThread(aStsThread),
|
||||||
mCallWrapper(aCallWrapper),
|
mCallWrapper(aCallWrapper),
|
||||||
mSendTrack(aSendTrack),
|
mSendTrack(aSendTrack),
|
||||||
|
|
@ -449,7 +449,7 @@ bool RTCRtpTransceiver::ConduitHasPluginID(uint64_t aPluginID) {
|
||||||
return mConduit && mConduit->HasCodecPluginID(aPluginID);
|
return mConduit && mConduit->HasCodecPluginID(aPluginID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTCRtpTransceiver::SyncFromJsep() {
|
void RTCRtpTransceiver::SyncFromJsep(const JsepSession& aSession) {
|
||||||
MOZ_MTLOG(ML_DEBUG, mPc->GetHandle()
|
MOZ_MTLOG(ML_DEBUG, mPc->GetHandle()
|
||||||
<< "[" << mMid.Ref() << "]: " << __FUNCTION__
|
<< "[" << mMid.Ref() << "]: " << __FUNCTION__
|
||||||
<< " Syncing from JSEP transceiver");
|
<< " Syncing from JSEP transceiver");
|
||||||
|
|
@ -459,35 +459,35 @@ void RTCRtpTransceiver::SyncFromJsep() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto jsepTransceiver = GetJsepTransceiver();
|
mJsepTransceiver = *aSession.GetTransceiver(mTransceiverId);
|
||||||
|
|
||||||
// Transceivers can stop due to JSEP negotiation, so we need to check that
|
// Transceivers can stop due to JSEP negotiation, so we need to check that
|
||||||
if (jsepTransceiver->IsStopped()) {
|
if (mJsepTransceiver.IsStopped()) {
|
||||||
StopImpl();
|
StopImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
mReceiver->SyncFromJsep(*jsepTransceiver);
|
mReceiver->SyncFromJsep(mJsepTransceiver);
|
||||||
mSender->SyncFromJsep(*jsepTransceiver);
|
mSender->SyncFromJsep(mJsepTransceiver);
|
||||||
|
|
||||||
// mid from JSEP
|
// mid from JSEP
|
||||||
if (jsepTransceiver->IsAssociated()) {
|
if (mJsepTransceiver.IsAssociated()) {
|
||||||
mMid = jsepTransceiver->GetMid();
|
mMid = mJsepTransceiver.GetMid();
|
||||||
} else {
|
} else {
|
||||||
mMid = std::string();
|
mMid = std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// currentDirection from JSEP, but not if "this transceiver has never been
|
// currentDirection from JSEP, but not if "this transceiver has never been
|
||||||
// represented in an offer/answer exchange"
|
// represented in an offer/answer exchange"
|
||||||
if (jsepTransceiver->HasLevel() && jsepTransceiver->IsNegotiated()) {
|
if (mJsepTransceiver.HasLevel() && mJsepTransceiver.IsNegotiated()) {
|
||||||
if (jsepTransceiver->mRecvTrack.GetActive()) {
|
if (mJsepTransceiver.mRecvTrack.GetActive()) {
|
||||||
if (jsepTransceiver->mSendTrack.GetActive()) {
|
if (mJsepTransceiver.mSendTrack.GetActive()) {
|
||||||
mCurrentDirection.SetValue(dom::RTCRtpTransceiverDirection::Sendrecv);
|
mCurrentDirection.SetValue(dom::RTCRtpTransceiverDirection::Sendrecv);
|
||||||
mHasBeenUsedToSend = true;
|
mHasBeenUsedToSend = true;
|
||||||
} else {
|
} else {
|
||||||
mCurrentDirection.SetValue(dom::RTCRtpTransceiverDirection::Recvonly);
|
mCurrentDirection.SetValue(dom::RTCRtpTransceiverDirection::Recvonly);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (jsepTransceiver->mSendTrack.GetActive()) {
|
if (mJsepTransceiver.mSendTrack.GetActive()) {
|
||||||
mCurrentDirection.SetValue(dom::RTCRtpTransceiverDirection::Sendonly);
|
mCurrentDirection.SetValue(dom::RTCRtpTransceiverDirection::Sendonly);
|
||||||
mHasBeenUsedToSend = true;
|
mHasBeenUsedToSend = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -496,28 +496,25 @@ void RTCRtpTransceiver::SyncFromJsep() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mShouldRemove = jsepTransceiver->IsRemoved();
|
mShouldRemove = mJsepTransceiver.IsRemoved();
|
||||||
mHasTransport = jsepTransceiver->HasLevel() && !jsepTransceiver->IsStopped();
|
mHasTransport = mJsepTransceiver.HasLevel() && !mJsepTransceiver.IsStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTCRtpTransceiver::SyncToJsep() const {
|
void RTCRtpTransceiver::SyncToJsep(JsepSession& aSession) const {
|
||||||
MOZ_MTLOG(ML_DEBUG, mPc->GetHandle()
|
MOZ_MTLOG(ML_DEBUG, mPc->GetHandle()
|
||||||
<< "[" << mMid.Ref() << "]: " << __FUNCTION__
|
<< "[" << mMid.Ref() << "]: " << __FUNCTION__
|
||||||
<< " Syncing to JSEP transceiver");
|
<< " Syncing to JSEP transceiver");
|
||||||
|
|
||||||
auto jsepTransceiver = GetJsepTransceiver();
|
aSession.ApplyToTransceiver(
|
||||||
mReceiver->SyncToJsep(*jsepTransceiver);
|
mTransceiverId, [this, self = RefPtr<const RTCRtpTransceiver>(this)](
|
||||||
mSender->SyncToJsep(*jsepTransceiver);
|
JsepTransceiver& aTransceiver) {
|
||||||
jsepTransceiver->mJsDirection = ToSdpDirection(mDirection);
|
mReceiver->SyncToJsep(aTransceiver);
|
||||||
|
mSender->SyncToJsep(aTransceiver);
|
||||||
|
aTransceiver.mJsDirection = ToSdpDirection(mDirection);
|
||||||
if (mStopped) {
|
if (mStopped) {
|
||||||
jsepTransceiver->Stop();
|
aTransceiver.Stop();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
// TODO: Unify with SyncFromJsep
|
|
||||||
void RTCRtpTransceiver::SetJsepSession(JsepSession* aJsepSession) {
|
|
||||||
mJsepTransceiver = aJsepSession->GetTransceiver(mTransceiverId);
|
|
||||||
MOZ_RELEASE_ASSERT(mJsepTransceiver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTCRtpTransceiver::GetKind(nsAString& aKind) const {
|
void RTCRtpTransceiver::GetKind(nsAString& aKind) const {
|
||||||
|
|
@ -565,12 +562,6 @@ void RTCRtpTransceiver::SetDirectionInternal(
|
||||||
mDirection = aDirection;
|
mDirection = aDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTCRtpTransceiver::SetAddTrackMagic() {
|
|
||||||
// We do this immediately, without waiting for a SyncToJsep, because this is
|
|
||||||
// set at transceiver creation time.
|
|
||||||
GetJsepTransceiver()->SetAddTrackMagic();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RTCRtpTransceiver::ShouldRemove() const { return mShouldRemove; }
|
bool RTCRtpTransceiver::ShouldRemove() const { return mShouldRemove; }
|
||||||
|
|
||||||
bool RTCRtpTransceiver::CanSendDTMF() const {
|
bool RTCRtpTransceiver::CanSendDTMF() const {
|
||||||
|
|
@ -589,8 +580,8 @@ bool RTCRtpTransceiver::CanSendDTMF() const {
|
||||||
|
|
||||||
// Ok, it looks like the connection is up and sending. Did we negotiate
|
// Ok, it looks like the connection is up and sending. Did we negotiate
|
||||||
// telephone-event?
|
// telephone-event?
|
||||||
JsepTrackNegotiatedDetails* details =
|
const JsepTrackNegotiatedDetails* details =
|
||||||
GetJsepTransceiver()->mSendTrack.GetNegotiatedDetails();
|
mJsepTransceiver.mSendTrack.GetNegotiatedDetails();
|
||||||
if (NS_WARN_IF(!details || !details->GetEncodingCount())) {
|
if (NS_WARN_IF(!details || !details->GetEncodingCount())) {
|
||||||
// What?
|
// What?
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -648,12 +639,11 @@ static void JsepCodecDescToAudioCodecConfig(
|
||||||
// TODO: This and the next function probably should move to JsepTransceiver
|
// TODO: This and the next function probably should move to JsepTransceiver
|
||||||
Maybe<const std::vector<UniquePtr<JsepCodecDescription>>&>
|
Maybe<const std::vector<UniquePtr<JsepCodecDescription>>&>
|
||||||
RTCRtpTransceiver::GetNegotiatedSendCodecs() const {
|
RTCRtpTransceiver::GetNegotiatedSendCodecs() const {
|
||||||
auto jsepTransceiver = GetJsepTransceiver();
|
if (!mJsepTransceiver.mSendTrack.GetActive()) {
|
||||||
if (!jsepTransceiver->mSendTrack.GetActive()) {
|
|
||||||
return Nothing();
|
return Nothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* details = jsepTransceiver->mSendTrack.GetNegotiatedDetails();
|
const auto* details = mJsepTransceiver.mSendTrack.GetNegotiatedDetails();
|
||||||
if (!details) {
|
if (!details) {
|
||||||
return Nothing();
|
return Nothing();
|
||||||
}
|
}
|
||||||
|
|
@ -667,12 +657,11 @@ RTCRtpTransceiver::GetNegotiatedSendCodecs() const {
|
||||||
|
|
||||||
Maybe<const std::vector<UniquePtr<JsepCodecDescription>>&>
|
Maybe<const std::vector<UniquePtr<JsepCodecDescription>>&>
|
||||||
RTCRtpTransceiver::GetNegotiatedRecvCodecs() const {
|
RTCRtpTransceiver::GetNegotiatedRecvCodecs() const {
|
||||||
auto jsepTransceiver = GetJsepTransceiver();
|
if (!mJsepTransceiver.mRecvTrack.GetActive()) {
|
||||||
if (!jsepTransceiver->mRecvTrack.GetActive()) {
|
|
||||||
return Nothing();
|
return Nothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* details = jsepTransceiver->mRecvTrack.GetNegotiatedDetails();
|
const auto* details = mJsepTransceiver.mRecvTrack.GetNegotiatedDetails();
|
||||||
if (!details) {
|
if (!details) {
|
||||||
return Nothing();
|
return Nothing();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,25 +102,21 @@ class RTCRtpTransceiver : public nsISupports, public nsWrapperCache {
|
||||||
void Stop(ErrorResult& aRv);
|
void Stop(ErrorResult& aRv);
|
||||||
void SetDirectionInternal(RTCRtpTransceiverDirection aDirection);
|
void SetDirectionInternal(RTCRtpTransceiverDirection aDirection);
|
||||||
bool HasBeenUsedToSend() const { return mHasBeenUsedToSend; }
|
bool HasBeenUsedToSend() const { return mHasBeenUsedToSend; }
|
||||||
void SetAddTrackMagic();
|
|
||||||
|
|
||||||
bool CanSendDTMF() const;
|
bool CanSendDTMF() const;
|
||||||
bool Stopped() const { return mStopped; }
|
bool Stopped() const { return mStopped; }
|
||||||
void SyncToJsep() const;
|
void SyncToJsep(JsepSession& aSession) const;
|
||||||
void SyncFromJsep();
|
void SyncFromJsep(const JsepSession& aSession);
|
||||||
void SetJsepSession(JsepSession* aJsepSession);
|
|
||||||
std::string GetMidAscii() const;
|
std::string GetMidAscii() const;
|
||||||
|
|
||||||
void SetDtlsTransport(RTCDtlsTransport* aDtlsTransport, bool aStable);
|
void SetDtlsTransport(RTCDtlsTransport* aDtlsTransport, bool aStable);
|
||||||
void RollbackToStableDtlsTransport();
|
void RollbackToStableDtlsTransport();
|
||||||
|
|
||||||
std::string GetTransportId() const {
|
std::string GetTransportId() const {
|
||||||
return mJsepTransceiver->mTransport.mTransportId;
|
return mJsepTransceiver.mTransport.mTransportId;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<JsepTransceiver> GetJsepTransceiver() const {
|
JsepTransceiver& GetJsepTransceiver() { return mJsepTransceiver; }
|
||||||
return mJsepTransceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsVideo() const;
|
bool IsVideo() const;
|
||||||
|
|
||||||
|
|
@ -193,7 +189,8 @@ class RTCRtpTransceiver : public nsISupports, public nsWrapperCache {
|
||||||
RefPtr<PeerConnectionImpl> mPc;
|
RefPtr<PeerConnectionImpl> mPc;
|
||||||
RefPtr<MediaTransportHandler> mTransportHandler;
|
RefPtr<MediaTransportHandler> mTransportHandler;
|
||||||
const std::string mTransceiverId;
|
const std::string mTransceiverId;
|
||||||
RefPtr<JsepTransceiver> mJsepTransceiver;
|
// Copy of latest from the JSEP engine.
|
||||||
|
JsepTransceiver mJsepTransceiver;
|
||||||
nsCOMPtr<nsISerialEventTarget> mStsThread;
|
nsCOMPtr<nsISerialEventTarget> mStsThread;
|
||||||
// state for webrtc.org that is shared between all transceivers
|
// state for webrtc.org that is shared between all transceivers
|
||||||
RefPtr<WebrtcCallWrapper> mCallWrapper;
|
RefPtr<WebrtcCallWrapper> mCallWrapper;
|
||||||
|
|
|
||||||
|
|
@ -113,8 +113,8 @@ class JsepSession {
|
||||||
void ForEachCodec(UnaryFunction& function) {
|
void ForEachCodec(UnaryFunction& function) {
|
||||||
std::for_each(Codecs().begin(), Codecs().end(), function);
|
std::for_each(Codecs().begin(), Codecs().end(), function);
|
||||||
for (auto& transceiver : GetTransceivers()) {
|
for (auto& transceiver : GetTransceivers()) {
|
||||||
transceiver->mSendTrack.ForEachCodec(function);
|
transceiver.mSendTrack.ForEachCodec(function);
|
||||||
transceiver->mRecvTrack.ForEachCodec(function);
|
transceiver.mRecvTrack.ForEachCodec(function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,24 +122,63 @@ class JsepSession {
|
||||||
void SortCodecs(BinaryPredicate& sorter) {
|
void SortCodecs(BinaryPredicate& sorter) {
|
||||||
std::stable_sort(Codecs().begin(), Codecs().end(), sorter);
|
std::stable_sort(Codecs().begin(), Codecs().end(), sorter);
|
||||||
for (auto& transceiver : GetTransceivers()) {
|
for (auto& transceiver : GetTransceivers()) {
|
||||||
transceiver->mSendTrack.SortCodecs(sorter);
|
transceiver.mSendTrack.SortCodecs(sorter);
|
||||||
transceiver->mRecvTrack.SortCodecs(sorter);
|
transceiver.mRecvTrack.SortCodecs(sorter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns transceivers in the order they were added.
|
// Would be nice to have this return a Maybe containing the return of
|
||||||
virtual const std::vector<RefPtr<JsepTransceiver>>& GetTransceivers()
|
// |aFunction|, but Maybe cannot contain a void.
|
||||||
const = 0;
|
template <typename UnaryFunction>
|
||||||
virtual std::vector<RefPtr<JsepTransceiver>>& GetTransceivers() = 0;
|
bool ApplyToTransceiver(const std::string& aId, UnaryFunction&& aFunction) {
|
||||||
RefPtr<JsepTransceiver> GetTransceiver(const std::string& aId) const {
|
for (auto& transceiver : GetTransceivers()) {
|
||||||
|
if (transceiver.GetUuid() == aId) {
|
||||||
|
std::forward<UnaryFunction>(aFunction)(transceiver);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename UnaryFunction>
|
||||||
|
void ForEachTransceiver(UnaryFunction&& aFunction) {
|
||||||
|
for (auto& transceiver : GetTransceivers()) {
|
||||||
|
std::forward<UnaryFunction>(aFunction)(transceiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename UnaryFunction>
|
||||||
|
void ForEachTransceiver(UnaryFunction&& aFunction) const {
|
||||||
for (const auto& transceiver : GetTransceivers()) {
|
for (const auto& transceiver : GetTransceivers()) {
|
||||||
if (transceiver->GetUuid() == aId) {
|
std::forward<UnaryFunction>(aFunction)(transceiver);
|
||||||
return transceiver;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
|
||||||
|
Maybe<const JsepTransceiver> GetTransceiver(const std::string& aId) const {
|
||||||
|
for (const auto& transceiver : GetTransceivers()) {
|
||||||
|
if (transceiver.GetUuid() == aId) {
|
||||||
|
return Some(transceiver);
|
||||||
}
|
}
|
||||||
virtual void AddTransceiver(RefPtr<JsepTransceiver> transceiver) = 0;
|
}
|
||||||
|
return Nothing();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename MatchFunction>
|
||||||
|
Maybe<const JsepTransceiver> FindTransceiver(MatchFunction&& aFunc) const {
|
||||||
|
for (const auto& transceiver : GetTransceivers()) {
|
||||||
|
if (std::forward<MatchFunction>(aFunc)(transceiver)) {
|
||||||
|
return Some(transceiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Nothing();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetTransceiver(const JsepTransceiver& aNew) {
|
||||||
|
return ApplyToTransceiver(aNew.GetUuid(),
|
||||||
|
[aNew](JsepTransceiver& aOld) { aOld = aNew; });
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddTransceiver(const JsepTransceiver& transceiver) = 0;
|
||||||
|
|
||||||
class Result {
|
class Result {
|
||||||
public:
|
public:
|
||||||
|
|
@ -211,14 +250,14 @@ class JsepSession {
|
||||||
memset(sending, 0, sizeof(sending));
|
memset(sending, 0, sizeof(sending));
|
||||||
|
|
||||||
for (const auto& transceiver : GetTransceivers()) {
|
for (const auto& transceiver : GetTransceivers()) {
|
||||||
if (transceiver->mRecvTrack.GetActive() ||
|
if (transceiver.mRecvTrack.GetActive() ||
|
||||||
transceiver->GetMediaType() == SdpMediaSection::kApplication) {
|
transceiver.GetMediaType() == SdpMediaSection::kApplication) {
|
||||||
receiving[transceiver->mRecvTrack.GetMediaType()]++;
|
receiving[transceiver.mRecvTrack.GetMediaType()]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transceiver->mSendTrack.GetActive() ||
|
if (transceiver.mSendTrack.GetActive() ||
|
||||||
transceiver->GetMediaType() == SdpMediaSection::kApplication) {
|
transceiver.GetMediaType() == SdpMediaSection::kApplication) {
|
||||||
sending[transceiver->mSendTrack.GetMediaType()]++;
|
sending[transceiver.mSendTrack.GetMediaType()]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -230,6 +269,11 @@ class JsepSession {
|
||||||
void SetRtxIsAllowed(bool aRtxIsAllowed) { mRtxIsAllowed = aRtxIsAllowed; }
|
void SetRtxIsAllowed(bool aRtxIsAllowed) { mRtxIsAllowed = aRtxIsAllowed; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
friend class JsepSessionTest;
|
||||||
|
// Returns transceivers in the order they were added.
|
||||||
|
virtual std::vector<JsepTransceiver>& GetTransceivers() = 0;
|
||||||
|
virtual const std::vector<JsepTransceiver>& GetTransceivers() const = 0;
|
||||||
|
|
||||||
const std::string mName;
|
const std::string mName;
|
||||||
JsepSignalingState mState;
|
JsepSignalingState mState;
|
||||||
uint32_t mNegotiations;
|
uint32_t mNegotiations;
|
||||||
|
|
|
||||||
|
|
@ -91,14 +91,6 @@ JsepSessionImpl::JsepSessionImpl(const JsepSessionImpl& aOrig)
|
||||||
: nullptr),
|
: nullptr),
|
||||||
mSdpHelper(&mLastError),
|
mSdpHelper(&mLastError),
|
||||||
mParser(new HybridSdpParser()) {
|
mParser(new HybridSdpParser()) {
|
||||||
for (const auto& transceiver : aOrig.mTransceivers) {
|
|
||||||
// Deep copy
|
|
||||||
mTransceivers.push_back(new JsepTransceiver(*transceiver));
|
|
||||||
}
|
|
||||||
for (const auto& transceiver : aOrig.mOldTransceivers) {
|
|
||||||
// Deep copy
|
|
||||||
mOldTransceivers.push_back(new JsepTransceiver(*transceiver));
|
|
||||||
}
|
|
||||||
for (const auto& codec : aOrig.mSupportedCodecs) {
|
for (const auto& codec : aOrig.mSupportedCodecs) {
|
||||||
mSupportedCodecs.emplace_back(codec->Clone());
|
mSupportedCodecs.emplace_back(codec->Clone());
|
||||||
}
|
}
|
||||||
|
|
@ -145,20 +137,20 @@ JsepSessionImpl::GetLocalIceCredentials() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsepSessionImpl::AddTransceiver(RefPtr<JsepTransceiver> aTransceiver) {
|
void JsepSessionImpl::AddTransceiver(const JsepTransceiver& aTransceiver) {
|
||||||
mLastError.clear();
|
mLastError.clear();
|
||||||
MOZ_MTLOG(ML_DEBUG, "[" << mName << "]: Adding transceiver "
|
MOZ_MTLOG(ML_DEBUG,
|
||||||
<< aTransceiver->GetUuid());
|
"[" << mName << "]: Adding transceiver " << aTransceiver.GetUuid());
|
||||||
InitTransceiver(*aTransceiver);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (aTransceiver->GetMediaType() == SdpMediaSection::kApplication) {
|
if (aTransceiver.GetMediaType() == SdpMediaSection::kApplication) {
|
||||||
// Make sure we don't add more than one DataChannel transceiver
|
// Make sure we don't add more than one DataChannel transceiver
|
||||||
for (const auto& transceiver : mTransceivers) {
|
for (const auto& transceiver : mTransceivers) {
|
||||||
MOZ_ASSERT(transceiver->GetMediaType() != SdpMediaSection::kApplication);
|
MOZ_ASSERT(transceiver.GetMediaType() != SdpMediaSection::kApplication);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
mTransceivers.push_back(aTransceiver);
|
mTransceivers.push_back(aTransceiver);
|
||||||
|
InitTransceiver(mTransceivers.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsepSessionImpl::InitTransceiver(JsepTransceiver& aTransceiver) {
|
void JsepSessionImpl::InitTransceiver(JsepTransceiver& aTransceiver) {
|
||||||
|
|
@ -409,9 +401,11 @@ JsepSession::Result JsepSessionImpl::CreateOffer(
|
||||||
NS_ENSURE_SUCCESS(rv, dom::PCError::OperationError);
|
NS_ENSURE_SUCCESS(rv, dom::PCError::OperationError);
|
||||||
|
|
||||||
for (size_t level = 0;
|
for (size_t level = 0;
|
||||||
JsepTransceiver* transceiver = GetTransceiverForLocal(level); ++level) {
|
Maybe<JsepTransceiver> transceiver = GetTransceiverForLocal(level);
|
||||||
|
++level) {
|
||||||
rv = CreateOfferMsection(options, *transceiver, sdp.get());
|
rv = CreateOfferMsection(options, *transceiver, sdp.get());
|
||||||
NS_ENSURE_SUCCESS(rv, dom::PCError::OperationError);
|
NS_ENSURE_SUCCESS(rv, dom::PCError::OperationError);
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupBundle(sdp.get());
|
SetupBundle(sdp.get());
|
||||||
|
|
@ -568,7 +562,7 @@ JsepSession::Result JsepSessionImpl::CreateAnswer(
|
||||||
|
|
||||||
for (size_t i = 0; i < offer.GetMediaSectionCount(); ++i) {
|
for (size_t i = 0; i < offer.GetMediaSectionCount(); ++i) {
|
||||||
// The transceivers are already in place, due to setRemote
|
// The transceivers are already in place, due to setRemote
|
||||||
JsepTransceiver* transceiver(GetTransceiverForLevel(i));
|
Maybe<JsepTransceiver> transceiver(GetTransceiverForLevel(i));
|
||||||
if (!transceiver) {
|
if (!transceiver) {
|
||||||
JSEP_SET_ERROR("No transceiver for level " << i);
|
JSEP_SET_ERROR("No transceiver for level " << i);
|
||||||
MOZ_ASSERT(false);
|
MOZ_ASSERT(false);
|
||||||
|
|
@ -577,6 +571,7 @@ JsepSession::Result JsepSessionImpl::CreateAnswer(
|
||||||
rv = CreateAnswerMsection(options, *transceiver, offer.GetMediaSection(i),
|
rv = CreateAnswerMsection(options, *transceiver, offer.GetMediaSection(i),
|
||||||
sdp.get());
|
sdp.get());
|
||||||
NS_ENSURE_SUCCESS(rv, dom::PCError::OperationError);
|
NS_ENSURE_SUCCESS(rv, dom::PCError::OperationError);
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that each bundle-group starts with a mid that has a transport, in
|
// Ensure that each bundle-group starts with a mid that has a transport, in
|
||||||
|
|
@ -814,10 +809,7 @@ JsepSession::Result JsepSessionImpl::SetLocalDescription(
|
||||||
|
|
||||||
if (type == kJsepSdpOffer) {
|
if (type == kJsepSdpOffer) {
|
||||||
// Save in case we need to rollback
|
// Save in case we need to rollback
|
||||||
mOldTransceivers.clear();
|
mOldTransceivers = mTransceivers;
|
||||||
for (const auto& transceiver : mTransceivers) {
|
|
||||||
mOldTransceivers.push_back(new JsepTransceiver(*transceiver));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SdpHelper::BundledMids bundledMids;
|
SdpHelper::BundledMids bundledMids;
|
||||||
|
|
@ -832,7 +824,7 @@ JsepSession::Result JsepSessionImpl::SetLocalDescription(
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < parsed->GetMediaSectionCount(); ++i) {
|
for (size_t i = 0; i < parsed->GetMediaSectionCount(); ++i) {
|
||||||
JsepTransceiver* transceiver(GetTransceiverForLevel(i));
|
Maybe<JsepTransceiver> transceiver(GetTransceiverForLevel(i));
|
||||||
if (!transceiver) {
|
if (!transceiver) {
|
||||||
MOZ_ASSERT(false);
|
MOZ_ASSERT(false);
|
||||||
JSEP_SET_ERROR("No transceiver for level " << i);
|
JSEP_SET_ERROR("No transceiver for level " << i);
|
||||||
|
|
@ -845,6 +837,7 @@ JsepSession::Result JsepSessionImpl::SetLocalDescription(
|
||||||
|
|
||||||
if (mSdpHelper.MsectionIsDisabled(msection)) {
|
if (mSdpHelper.MsectionIsDisabled(msection)) {
|
||||||
transceiver->mTransport.Close();
|
transceiver->mTransport.Close();
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -860,7 +853,7 @@ JsepSession::Result JsepSessionImpl::SetLocalDescription(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasOwnTransport) {
|
if (hasOwnTransport) {
|
||||||
EnsureHasOwnTransport(parsed->GetMediaSection(i), transceiver);
|
EnsureHasOwnTransport(parsed->GetMediaSection(i), *transceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == kJsepSdpOffer) {
|
if (type == kJsepSdpOffer) {
|
||||||
|
|
@ -876,6 +869,7 @@ JsepSession::Result JsepSessionImpl::SetLocalDescription(
|
||||||
transceiver->SetBundleLevel(it->second->GetLevel());
|
transceiver->SetBundleLevel(it->second->GetLevel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyBundleTransports();
|
CopyBundleTransports();
|
||||||
|
|
@ -1024,15 +1018,14 @@ JsepSession::Result JsepSessionImpl::SetRemoteDescription(
|
||||||
iceOptions = parsed->GetAttributeList().GetIceOptions().mValues;
|
iceOptions = parsed->GetAttributeList().GetIceOptions().mValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save in case we need to rollback.
|
|
||||||
if (type == kJsepSdpOffer) {
|
if (type == kJsepSdpOffer) {
|
||||||
mOldTransceivers.clear();
|
// Save in case we need to rollback.
|
||||||
for (const auto& transceiver : mTransceivers) {
|
mOldTransceivers = mTransceivers;
|
||||||
mOldTransceivers.push_back(new JsepTransceiver(*transceiver));
|
for (auto& transceiver : mTransceivers) {
|
||||||
if (!transceiver->IsNegotiated()) {
|
if (!transceiver.IsNegotiated()) {
|
||||||
// We chose a level for this transceiver, but never negotiated it.
|
// We chose a level for this transceiver, but never negotiated it.
|
||||||
// Discard this state.
|
// Discard this state.
|
||||||
transceiver->ClearLevel();
|
transceiver.ClearLevel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1085,18 +1078,19 @@ nsresult JsepSessionImpl::HandleNegotiatedSession(
|
||||||
|
|
||||||
// First, set the bundle level on the transceivers
|
// First, set the bundle level on the transceivers
|
||||||
for (auto& [mid, transportOwner] : bundledMids) {
|
for (auto& [mid, transportOwner] : bundledMids) {
|
||||||
JsepTransceiver* bundledTransceiver = GetTransceiverForMid(mid);
|
Maybe<JsepTransceiver> bundledTransceiver = GetTransceiverForMid(mid);
|
||||||
if (!bundledTransceiver) {
|
if (!bundledTransceiver) {
|
||||||
JSEP_SET_ERROR("No transceiver for bundled mid " << mid);
|
JSEP_SET_ERROR("No transceiver for bundled mid " << mid);
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
bundledTransceiver->SetBundleLevel(transportOwner->GetLevel());
|
bundledTransceiver->SetBundleLevel(transportOwner->GetLevel());
|
||||||
|
SetTransceiver(*bundledTransceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now walk through the m-sections, perform negotiation, and update the
|
// Now walk through the m-sections, perform negotiation, and update the
|
||||||
// transceivers.
|
// transceivers.
|
||||||
for (size_t i = 0; i < local->GetMediaSectionCount(); ++i) {
|
for (size_t i = 0; i < local->GetMediaSectionCount(); ++i) {
|
||||||
JsepTransceiver* transceiver(GetTransceiverForLevel(i));
|
Maybe<JsepTransceiver> transceiver(GetTransceiverForLevel(i));
|
||||||
if (!transceiver) {
|
if (!transceiver) {
|
||||||
MOZ_ASSERT(false);
|
MOZ_ASSERT(false);
|
||||||
JSEP_SET_ERROR("No transceiver for level " << i);
|
JSEP_SET_ERROR("No transceiver for level " << i);
|
||||||
|
|
@ -1112,20 +1106,22 @@ nsresult JsepSessionImpl::HandleNegotiatedSession(
|
||||||
transceiver->mSendTrack.SetActive(false);
|
transceiver->mSendTrack.SetActive(false);
|
||||||
transceiver->mRecvTrack.SetActive(false);
|
transceiver->mRecvTrack.SetActive(false);
|
||||||
transceiver->SetCanRecycle();
|
transceiver->SetCanRecycle();
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
// Do not clear mLevel yet! That will happen on the next negotiation.
|
// Do not clear mLevel yet! That will happen on the next negotiation.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = MakeNegotiatedTransceiver(remote->GetMediaSection(i),
|
rv = MakeNegotiatedTransceiver(remote->GetMediaSection(i),
|
||||||
local->GetMediaSection(i), transceiver);
|
local->GetMediaSection(i), *transceiver);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyBundleTransports();
|
CopyBundleTransports();
|
||||||
|
|
||||||
std::vector<JsepTrack*> remoteTracks;
|
std::vector<JsepTrack*> remoteTracks;
|
||||||
for (const auto& transceiver : mTransceivers) {
|
for (auto& transceiver : mTransceivers) {
|
||||||
remoteTracks.push_back(&transceiver->mRecvTrack);
|
remoteTracks.push_back(&transceiver.mRecvTrack);
|
||||||
}
|
}
|
||||||
JsepTrack::SetUniquePayloadTypes(remoteTracks);
|
JsepTrack::SetUniquePayloadTypes(remoteTracks);
|
||||||
|
|
||||||
|
|
@ -1139,14 +1135,14 @@ nsresult JsepSessionImpl::HandleNegotiatedSession(
|
||||||
|
|
||||||
nsresult JsepSessionImpl::MakeNegotiatedTransceiver(
|
nsresult JsepSessionImpl::MakeNegotiatedTransceiver(
|
||||||
const SdpMediaSection& remote, const SdpMediaSection& local,
|
const SdpMediaSection& remote, const SdpMediaSection& local,
|
||||||
JsepTransceiver* transceiver) {
|
JsepTransceiver& transceiver) {
|
||||||
const SdpMediaSection& answer = *mIsPendingOfferer ? remote : local;
|
const SdpMediaSection& answer = *mIsPendingOfferer ? remote : local;
|
||||||
|
|
||||||
bool sending = false;
|
bool sending = false;
|
||||||
bool receiving = false;
|
bool receiving = false;
|
||||||
|
|
||||||
// JS could stop the transceiver after the answer was created.
|
// JS could stop the transceiver after the answer was created.
|
||||||
if (!transceiver->IsStopped()) {
|
if (!transceiver.IsStopped()) {
|
||||||
if (*mIsPendingOfferer) {
|
if (*mIsPendingOfferer) {
|
||||||
receiving = answer.IsSending();
|
receiving = answer.IsSending();
|
||||||
sending = answer.IsReceiving();
|
sending = answer.IsReceiving();
|
||||||
|
|
@ -1161,23 +1157,23 @@ nsresult JsepSessionImpl::MakeNegotiatedTransceiver(
|
||||||
<< local.GetMediaType() << " sending=" << sending
|
<< local.GetMediaType() << " sending=" << sending
|
||||||
<< " receiving=" << receiving);
|
<< " receiving=" << receiving);
|
||||||
|
|
||||||
transceiver->SetNegotiated();
|
transceiver.SetNegotiated();
|
||||||
|
|
||||||
// Ensure that this is finalized in case we need to copy it below
|
// Ensure that this is finalized in case we need to copy it below
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
FinalizeTransport(remote.GetAttributeList(), answer.GetAttributeList(),
|
FinalizeTransport(remote.GetAttributeList(), answer.GetAttributeList(),
|
||||||
&transceiver->mTransport);
|
&transceiver.mTransport);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
transceiver->mSendTrack.SetActive(sending);
|
transceiver.mSendTrack.SetActive(sending);
|
||||||
rv = transceiver->mSendTrack.Negotiate(answer, remote, local);
|
rv = transceiver.mSendTrack.Negotiate(answer, remote, local);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
JSEP_SET_ERROR("Answer had no codecs in common with offer in m-section "
|
JSEP_SET_ERROR("Answer had no codecs in common with offer in m-section "
|
||||||
<< local.GetLevel());
|
<< local.GetLevel());
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsepTrack& recvTrack = transceiver->mRecvTrack;
|
JsepTrack& recvTrack = transceiver.mRecvTrack;
|
||||||
recvTrack.SetActive(receiving);
|
recvTrack.SetActive(receiving);
|
||||||
rv = recvTrack.Negotiate(answer, remote, local);
|
rv = recvTrack.Negotiate(answer, remote, local);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
|
@ -1186,7 +1182,7 @@ nsresult JsepSessionImpl::MakeNegotiatedTransceiver(
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transceiver->HasBundleLevel() && recvTrack.GetSsrcs().empty() &&
|
if (transceiver.HasBundleLevel() && recvTrack.GetSsrcs().empty() &&
|
||||||
recvTrack.GetMediaType() != SdpMediaSection::kApplication) {
|
recvTrack.GetMediaType() != SdpMediaSection::kApplication) {
|
||||||
// TODO(bug 1105005): Once we have urn:ietf:params:rtp-hdrext:sdes:mid
|
// TODO(bug 1105005): Once we have urn:ietf:params:rtp-hdrext:sdes:mid
|
||||||
// support, we should only fire this warning if that extension was not
|
// support, we should only fire this warning if that extension was not
|
||||||
|
|
@ -1197,7 +1193,7 @@ nsresult JsepSessionImpl::MakeNegotiatedTransceiver(
|
||||||
"dropped.");
|
"dropped.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transceiver->mTransport.mComponents == 2) {
|
if (transceiver.mTransport.mComponents == 2) {
|
||||||
// RTCP MUX or not.
|
// RTCP MUX or not.
|
||||||
// TODO(bug 1095743): verify that the PTs are consistent with mux.
|
// TODO(bug 1095743): verify that the PTs are consistent with mux.
|
||||||
MOZ_MTLOG(ML_DEBUG, "[" << mName << "]: RTCP-MUX is off");
|
MOZ_MTLOG(ML_DEBUG, "[" << mName << "]: RTCP-MUX is off");
|
||||||
|
|
@ -1234,10 +1230,10 @@ nsresult JsepSessionImpl::MakeNegotiatedTransceiver(
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsepSessionImpl::EnsureHasOwnTransport(const SdpMediaSection& msection,
|
void JsepSessionImpl::EnsureHasOwnTransport(const SdpMediaSection& msection,
|
||||||
JsepTransceiver* transceiver) {
|
JsepTransceiver& transceiver) {
|
||||||
JsepTransport& transport = transceiver->mTransport;
|
JsepTransport& transport = transceiver.mTransport;
|
||||||
|
|
||||||
if (!transceiver->HasOwnTransport()) {
|
if (!transceiver.HasOwnTransport()) {
|
||||||
// Transceiver didn't own this transport last time, it won't now either
|
// Transceiver didn't own this transport last time, it won't now either
|
||||||
transport.Close();
|
transport.Close();
|
||||||
}
|
}
|
||||||
|
|
@ -1245,7 +1241,7 @@ void JsepSessionImpl::EnsureHasOwnTransport(const SdpMediaSection& msection,
|
||||||
transport.mLocalUfrag = msection.GetAttributeList().GetIceUfrag();
|
transport.mLocalUfrag = msection.GetAttributeList().GetIceUfrag();
|
||||||
transport.mLocalPwd = msection.GetAttributeList().GetIcePwd();
|
transport.mLocalPwd = msection.GetAttributeList().GetIcePwd();
|
||||||
|
|
||||||
transceiver->ClearBundleLevel();
|
transceiver.ClearBundleLevel();
|
||||||
|
|
||||||
if (!transport.mComponents) {
|
if (!transport.mComponents) {
|
||||||
if (mSdpHelper.HasRtcp(msection.GetProtocol())) {
|
if (mSdpHelper.HasRtcp(msection.GetProtocol())) {
|
||||||
|
|
@ -1266,34 +1262,34 @@ void JsepSessionImpl::EnsureHasOwnTransport(const SdpMediaSection& msection,
|
||||||
|
|
||||||
void JsepSessionImpl::CopyBundleTransports() {
|
void JsepSessionImpl::CopyBundleTransports() {
|
||||||
for (auto& transceiver : mTransceivers) {
|
for (auto& transceiver : mTransceivers) {
|
||||||
if (transceiver->HasBundleLevel()) {
|
if (transceiver.HasBundleLevel()) {
|
||||||
MOZ_MTLOG(ML_DEBUG,
|
MOZ_MTLOG(ML_DEBUG,
|
||||||
"[" << mName << "] Transceiver " << transceiver->GetLevel()
|
"[" << mName << "] Transceiver " << transceiver.GetLevel()
|
||||||
<< " is in a bundle; transceiver "
|
<< " is in a bundle; transceiver "
|
||||||
<< transceiver->BundleLevel() << " owns the transport.");
|
<< transceiver.BundleLevel() << " owns the transport.");
|
||||||
const JsepTransceiver* transportOwner =
|
Maybe<const JsepTransceiver> transportOwner =
|
||||||
GetTransceiverForLevel(transceiver->BundleLevel());
|
GetTransceiverForLevel(transceiver.BundleLevel());
|
||||||
MOZ_ASSERT(transportOwner);
|
MOZ_ASSERT(transportOwner);
|
||||||
if (transportOwner) {
|
if (transportOwner) {
|
||||||
transceiver->mTransport = transportOwner->mTransport;
|
transceiver.mTransport = transportOwner->mTransport;
|
||||||
}
|
}
|
||||||
} else if (transceiver->HasLevel()) {
|
} else if (transceiver.HasLevel()) {
|
||||||
MOZ_MTLOG(ML_DEBUG, "[" << mName << "] Transceiver "
|
MOZ_MTLOG(ML_DEBUG, "[" << mName << "] Transceiver "
|
||||||
<< transceiver->GetLevel()
|
<< transceiver.GetLevel()
|
||||||
<< " is not necessarily in a bundle.");
|
<< " is not necessarily in a bundle.");
|
||||||
}
|
}
|
||||||
if (transceiver->HasLevel()) {
|
if (transceiver.HasLevel()) {
|
||||||
MOZ_MTLOG(ML_DEBUG,
|
MOZ_MTLOG(ML_DEBUG,
|
||||||
"[" << mName << "] Transceiver " << transceiver->GetLevel()
|
"[" << mName << "] Transceiver " << transceiver.GetLevel()
|
||||||
<< " transport-id: " << transceiver->mTransport.mTransportId
|
<< " transport-id: " << transceiver.mTransport.mTransportId
|
||||||
<< " components: " << transceiver->mTransport.mComponents);
|
<< " components: " << transceiver.mTransport.mComponents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult JsepSessionImpl::FinalizeTransport(const SdpAttributeList& remote,
|
nsresult JsepSessionImpl::FinalizeTransport(const SdpAttributeList& remote,
|
||||||
const SdpAttributeList& answer,
|
const SdpAttributeList& answer,
|
||||||
JsepTransport* transport) {
|
JsepTransport* transport) const {
|
||||||
if (!transport->mComponents) {
|
if (!transport->mComponents) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -1382,7 +1378,7 @@ nsresult JsepSessionImpl::CopyPreviousTransportParams(
|
||||||
// If newLocal is an offer, this will be the number of components we used
|
// If newLocal is an offer, this will be the number of components we used
|
||||||
// last time, and if it is an answer, this will be the number of
|
// last time, and if it is an answer, this will be the number of
|
||||||
// components we've decided we're using now.
|
// components we've decided we're using now.
|
||||||
JsepTransceiver* transceiver(GetTransceiverForLevel(i));
|
Maybe<const JsepTransceiver> transceiver(GetTransceiverForLevel(i));
|
||||||
if (!transceiver) {
|
if (!transceiver) {
|
||||||
MOZ_ASSERT(false);
|
MOZ_ASSERT(false);
|
||||||
JSEP_SET_ERROR("No transceiver for level " << i);
|
JSEP_SET_ERROR("No transceiver for level " << i);
|
||||||
|
|
@ -1545,43 +1541,39 @@ nsresult JsepSessionImpl::SetRemoteDescriptionAnswer(JsepSdpType type,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsepTransceiver* JsepSessionImpl::GetTransceiverForLevel(size_t level) const {
|
Maybe<JsepTransceiver> JsepSessionImpl::GetTransceiverForLevel(
|
||||||
for (const auto& transceiver : mTransceivers) {
|
size_t level) const {
|
||||||
if (transceiver->HasLevel() && (transceiver->GetLevel() == level)) {
|
return FindTransceiver([level](const JsepTransceiver& transceiver) {
|
||||||
return transceiver.get();
|
return transceiver.HasLevel() && (transceiver.GetLevel() == level);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
Maybe<JsepTransceiver> JsepSessionImpl::GetTransceiverForMid(
|
||||||
}
|
|
||||||
|
|
||||||
JsepTransceiver* JsepSessionImpl::GetTransceiverForMid(
|
|
||||||
const std::string& mid) const {
|
const std::string& mid) const {
|
||||||
for (const auto& transceiver : mTransceivers) {
|
return FindTransceiver([mid](const JsepTransceiver& transceiver) {
|
||||||
if (transceiver->IsAssociated() && (transceiver->GetMid() == mid)) {
|
return transceiver.IsAssociated() && (transceiver.GetMid() == mid);
|
||||||
return transceiver.get();
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
Maybe<JsepTransceiver> JsepSessionImpl::GetTransceiverForLocal(size_t level) {
|
||||||
}
|
if (Maybe<JsepTransceiver> transceiver = GetTransceiverForLevel(level)) {
|
||||||
|
|
||||||
JsepTransceiver* JsepSessionImpl::GetTransceiverForLocal(size_t level) {
|
|
||||||
if (JsepTransceiver* transceiver = GetTransceiverForLevel(level)) {
|
|
||||||
if (transceiver->CanRecycle() &&
|
if (transceiver->CanRecycle() &&
|
||||||
transceiver->GetMediaType() != SdpMediaSection::kApplication) {
|
transceiver->GetMediaType() != SdpMediaSection::kApplication) {
|
||||||
// Attempt to recycle. If this fails, the old transceiver stays put.
|
// Attempt to recycle. If this fails, the old transceiver stays put.
|
||||||
transceiver->Disassociate();
|
transceiver->Disassociate();
|
||||||
JsepTransceiver* newTransceiver =
|
Maybe<JsepTransceiver> newTransceiver =
|
||||||
FindUnassociatedTransceiver(transceiver->GetMediaType(), false);
|
FindUnassociatedTransceiver(transceiver->GetMediaType(), false);
|
||||||
if (newTransceiver) {
|
if (newTransceiver) {
|
||||||
newTransceiver->SetLevel(level);
|
newTransceiver->SetLevel(level);
|
||||||
transceiver->ClearLevel();
|
transceiver->ClearLevel();
|
||||||
transceiver->mSendTrack.ClearRids();
|
transceiver->mSendTrack.ClearRids();
|
||||||
|
SetTransceiver(*newTransceiver);
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
return newTransceiver;
|
return newTransceiver;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
return transceiver;
|
return transceiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1589,66 +1581,67 @@ JsepTransceiver* JsepSessionImpl::GetTransceiverForLocal(size_t level) {
|
||||||
|
|
||||||
// Look for an RTP transceiver
|
// Look for an RTP transceiver
|
||||||
for (auto& transceiver : mTransceivers) {
|
for (auto& transceiver : mTransceivers) {
|
||||||
if (transceiver->GetMediaType() != SdpMediaSection::kApplication &&
|
if (transceiver.GetMediaType() != SdpMediaSection::kApplication &&
|
||||||
!transceiver->IsStopped() && !transceiver->HasLevel()) {
|
!transceiver.IsStopped() && !transceiver.HasLevel()) {
|
||||||
transceiver->SetLevel(level);
|
transceiver.SetLevel(level);
|
||||||
return transceiver.get();
|
return Some(transceiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ok, look for a datachannel
|
// Ok, look for a datachannel
|
||||||
for (auto& transceiver : mTransceivers) {
|
for (auto& transceiver : mTransceivers) {
|
||||||
if (!transceiver->IsStopped() && !transceiver->HasLevel()) {
|
if (!transceiver.IsStopped() && !transceiver.HasLevel()) {
|
||||||
transceiver->SetLevel(level);
|
transceiver.SetLevel(level);
|
||||||
return transceiver.get();
|
return Some(transceiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return Nothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsepTransceiver* JsepSessionImpl::GetTransceiverForRemote(
|
Maybe<JsepTransceiver> JsepSessionImpl::GetTransceiverForRemote(
|
||||||
const SdpMediaSection& msection) {
|
const SdpMediaSection& msection) {
|
||||||
size_t level = msection.GetLevel();
|
size_t level = msection.GetLevel();
|
||||||
if (JsepTransceiver* transceiver = GetTransceiverForLevel(level)) {
|
Maybe<JsepTransceiver> transceiver = GetTransceiverForLevel(level);
|
||||||
|
if (transceiver) {
|
||||||
if (!transceiver->CanRecycle()) {
|
if (!transceiver->CanRecycle()) {
|
||||||
return transceiver;
|
return transceiver;
|
||||||
}
|
}
|
||||||
transceiver->Disassociate();
|
transceiver->Disassociate();
|
||||||
transceiver->ClearLevel();
|
transceiver->ClearLevel();
|
||||||
transceiver->mSendTrack.ClearRids();
|
transceiver->mSendTrack.ClearRids();
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No transceiver for |level|
|
// No transceiver for |level|
|
||||||
|
transceiver = FindUnassociatedTransceiver(msection.GetMediaType(), true);
|
||||||
JsepTransceiver* transceiver =
|
|
||||||
FindUnassociatedTransceiver(msection.GetMediaType(), true /*magic!*/);
|
|
||||||
if (transceiver) {
|
if (transceiver) {
|
||||||
transceiver->SetLevel(level);
|
transceiver->SetLevel(level);
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
return transceiver;
|
return transceiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a new transceiver
|
// Make a new transceiver
|
||||||
RefPtr<JsepTransceiver> newTransceiver(new JsepTransceiver(
|
JsepTransceiver newTransceiver(msection.GetMediaType(), *mUuidGen,
|
||||||
msection.GetMediaType(), *mUuidGen, SdpDirectionAttribute::kRecvonly));
|
SdpDirectionAttribute::kRecvonly);
|
||||||
newTransceiver->SetLevel(level);
|
newTransceiver.SetLevel(level);
|
||||||
newTransceiver->SetOnlyExistsBecauseOfSetRemote(true);
|
newTransceiver.SetOnlyExistsBecauseOfSetRemote(true);
|
||||||
AddTransceiver(newTransceiver);
|
AddTransceiver(newTransceiver);
|
||||||
return newTransceiver.get();
|
return Some(mTransceivers.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
JsepTransceiver* JsepSessionImpl::GetTransceiverWithTransport(
|
Maybe<JsepTransceiver> JsepSessionImpl::GetTransceiverWithTransport(
|
||||||
const std::string& transportId) const {
|
const std::string& transportId) const {
|
||||||
for (const auto& transceiver : mTransceivers) {
|
for (const auto& transceiver : mTransceivers) {
|
||||||
if (transceiver->HasOwnTransport() &&
|
if (transceiver.HasOwnTransport() &&
|
||||||
(transceiver->mTransport.mTransportId == transportId)) {
|
(transceiver.mTransport.mTransportId == transportId)) {
|
||||||
MOZ_ASSERT(transceiver->HasLevel(),
|
MOZ_ASSERT(transceiver.HasLevel(),
|
||||||
"Transceiver has a transport, but no level!");
|
"Transceiver has a transport, but no level!");
|
||||||
return transceiver.get();
|
return Some(transceiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return Nothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult JsepSessionImpl::UpdateTransceiversFromRemoteDescription(
|
nsresult JsepSessionImpl::UpdateTransceiversFromRemoteDescription(
|
||||||
|
|
@ -1657,7 +1650,7 @@ nsresult JsepSessionImpl::UpdateTransceiversFromRemoteDescription(
|
||||||
for (size_t i = 0; i < remote.GetMediaSectionCount(); ++i) {
|
for (size_t i = 0; i < remote.GetMediaSectionCount(); ++i) {
|
||||||
const SdpMediaSection& msection = remote.GetMediaSection(i);
|
const SdpMediaSection& msection = remote.GetMediaSection(i);
|
||||||
|
|
||||||
JsepTransceiver* transceiver(GetTransceiverForRemote(msection));
|
Maybe<JsepTransceiver> transceiver(GetTransceiverForRemote(msection));
|
||||||
if (!transceiver) {
|
if (!transceiver) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
@ -1677,10 +1670,12 @@ nsresult JsepSessionImpl::UpdateTransceiversFromRemoteDescription(
|
||||||
transceiver->Disassociate();
|
transceiver->Disassociate();
|
||||||
// This cannot be rolled back.
|
// This cannot be rolled back.
|
||||||
transceiver->Stop();
|
transceiver->Stop();
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msection.GetMediaType() == SdpMediaSection::MediaType::kApplication) {
|
if (msection.GetMediaType() == SdpMediaSection::MediaType::kApplication) {
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1696,43 +1691,43 @@ nsresult JsepSessionImpl::UpdateTransceiversFromRemoteDescription(
|
||||||
// msection is not sending. If the msection is sending, and there are no
|
// msection is not sending. If the msection is sending, and there are no
|
||||||
// a=msid, the previously set default will stay.
|
// a=msid, the previously set default will stay.
|
||||||
transceiver->mRecvTrack.RecvTrackSetRemote(remote, msection);
|
transceiver->mRecvTrack.RecvTrackSetRemote(remote, msection);
|
||||||
|
SetTransceiver(*transceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsepTransceiver* JsepSessionImpl::FindUnassociatedTransceiver(
|
Maybe<JsepTransceiver> JsepSessionImpl::FindUnassociatedTransceiver(
|
||||||
SdpMediaSection::MediaType type, bool magic) {
|
SdpMediaSection::MediaType type, bool magic) {
|
||||||
// Look through transceivers that are not mapped to an m-section
|
// Look through transceivers that are not mapped to an m-section
|
||||||
for (auto& transceiver : mTransceivers) {
|
for (auto& transceiver : mTransceivers) {
|
||||||
if (type == SdpMediaSection::kApplication &&
|
if (type == SdpMediaSection::kApplication &&
|
||||||
type == transceiver->GetMediaType()) {
|
type == transceiver.GetMediaType()) {
|
||||||
transceiver->RestartDatachannelTransceiver();
|
transceiver.RestartDatachannelTransceiver();
|
||||||
return transceiver.get();
|
return Some(transceiver);
|
||||||
}
|
}
|
||||||
if (!transceiver->IsStopped() && !transceiver->HasLevel() &&
|
if (!transceiver.IsStopped() && !transceiver.HasLevel() &&
|
||||||
(!magic || transceiver->HasAddTrackMagic()) &&
|
(!magic || transceiver.HasAddTrackMagic()) &&
|
||||||
(transceiver->GetMediaType() == type)) {
|
(transceiver.GetMediaType() == type)) {
|
||||||
return transceiver.get();
|
return Some(transceiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return Nothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsepSessionImpl::RollbackLocalOffer() {
|
void JsepSessionImpl::RollbackLocalOffer() {
|
||||||
for (size_t i = 0; i < mTransceivers.size(); ++i) {
|
for (size_t i = 0; i < mTransceivers.size(); ++i) {
|
||||||
auto transceiver = mTransceivers[i];
|
auto& transceiver = mTransceivers[i];
|
||||||
if (mOldTransceivers.size() > i) {
|
if (mOldTransceivers.size() > i) {
|
||||||
transceiver->Rollback(*mOldTransceivers[i], false);
|
transceiver.Rollback(mOldTransceivers[i], false);
|
||||||
mOldTransceivers[i] = transceiver;
|
mOldTransceivers[i] = transceiver;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<JsepTransceiver> temp(
|
JsepTransceiver temp(transceiver.GetMediaType(), *mUuidGen);
|
||||||
new JsepTransceiver(transceiver->GetMediaType(), *mUuidGen));
|
InitTransceiver(temp);
|
||||||
InitTransceiver(*temp);
|
transceiver.Rollback(temp, false);
|
||||||
transceiver->Rollback(*temp, false);
|
|
||||||
mOldTransceivers.push_back(transceiver);
|
mOldTransceivers.push_back(transceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1741,10 +1736,10 @@ void JsepSessionImpl::RollbackLocalOffer() {
|
||||||
|
|
||||||
void JsepSessionImpl::RollbackRemoteOffer() {
|
void JsepSessionImpl::RollbackRemoteOffer() {
|
||||||
for (size_t i = 0; i < mTransceivers.size(); ++i) {
|
for (size_t i = 0; i < mTransceivers.size(); ++i) {
|
||||||
auto transceiver = mTransceivers[i];
|
auto& transceiver = mTransceivers[i];
|
||||||
if (mOldTransceivers.size() > i) {
|
if (mOldTransceivers.size() > i) {
|
||||||
// Some stuff cannot be rolled back. Save this information.
|
// Some stuff cannot be rolled back. Save this information.
|
||||||
transceiver->Rollback(*mOldTransceivers[i], true);
|
transceiver.Rollback(mOldTransceivers[i], true);
|
||||||
mOldTransceivers[i] = transceiver;
|
mOldTransceivers[i] = transceiver;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1752,14 +1747,13 @@ void JsepSessionImpl::RollbackRemoteOffer() {
|
||||||
// New transceiver!
|
// New transceiver!
|
||||||
// We rollback even for transceivers we will remove, just to ensure we end
|
// We rollback even for transceivers we will remove, just to ensure we end
|
||||||
// up at the starting state.
|
// up at the starting state.
|
||||||
RefPtr<JsepTransceiver> temp(
|
JsepTransceiver temp(transceiver.GetMediaType(), *mUuidGen);
|
||||||
new JsepTransceiver(transceiver->GetMediaType(), *mUuidGen));
|
InitTransceiver(temp);
|
||||||
InitTransceiver(*temp);
|
transceiver.Rollback(temp, true);
|
||||||
transceiver->Rollback(*temp, true);
|
|
||||||
|
|
||||||
if (transceiver->OnlyExistsBecauseOfSetRemote()) {
|
if (transceiver.OnlyExistsBecauseOfSetRemote()) {
|
||||||
transceiver->Stop();
|
transceiver.Stop();
|
||||||
transceiver->SetRemoved();
|
transceiver.SetRemoved();
|
||||||
}
|
}
|
||||||
mOldTransceivers.push_back(transceiver);
|
mOldTransceivers.push_back(transceiver);
|
||||||
}
|
}
|
||||||
|
|
@ -2197,7 +2191,7 @@ JsepSession::Result JsepSessionImpl::AddRemoteIceCandidate(
|
||||||
return Result();
|
return Result();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsepTransceiver* transceiver = nullptr;
|
Maybe<JsepTransceiver> transceiver;
|
||||||
if (!mid.empty()) {
|
if (!mid.empty()) {
|
||||||
transceiver = GetTransceiverForMid(mid);
|
transceiver = GetTransceiverForMid(mid);
|
||||||
} else if (level.isSome()) {
|
} else if (level.isSome()) {
|
||||||
|
|
@ -2249,7 +2243,8 @@ nsresult JsepSessionImpl::AddLocalIceCandidate(const std::string& candidate,
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsepTransceiver* transceiver = GetTransceiverWithTransport(transportId);
|
Maybe<const JsepTransceiver> transceiver =
|
||||||
|
GetTransceiverWithTransport(transportId);
|
||||||
if (!transceiver || !transceiver->IsAssociated()) {
|
if (!transceiver || !transceiver->IsAssociated()) {
|
||||||
// mainly here to make some testing less complicated, but also just in case
|
// mainly here to make some testing less complicated, but also just in case
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
@ -2292,20 +2287,20 @@ nsresult JsepSessionImpl::UpdateDefaultCandidate(
|
||||||
for (const auto& transceiver : mTransceivers) {
|
for (const auto& transceiver : mTransceivers) {
|
||||||
// We set the default address for bundled m-sections, but not candidate
|
// We set the default address for bundled m-sections, but not candidate
|
||||||
// attributes. Ugh.
|
// attributes. Ugh.
|
||||||
if (transceiver->mTransport.mTransportId == transportId) {
|
if (transceiver.mTransport.mTransportId == transportId) {
|
||||||
MOZ_ASSERT(transceiver->HasLevel(),
|
MOZ_ASSERT(transceiver.HasLevel(),
|
||||||
"Transceiver has a transport, but no level! "
|
"Transceiver has a transport, but no level! "
|
||||||
"This should never happen.");
|
"This should never happen.");
|
||||||
std::string defaultRtcpCandidateAddrCopy(defaultRtcpCandidateAddr);
|
std::string defaultRtcpCandidateAddrCopy(defaultRtcpCandidateAddr);
|
||||||
if (mState == kJsepStateStable) {
|
if (mState == kJsepStateStable) {
|
||||||
if (transceiver->mTransport.mComponents == 1) {
|
if (transceiver.mTransport.mComponents == 1) {
|
||||||
// We know we're doing rtcp-mux by now. Don't create an rtcp attr.
|
// We know we're doing rtcp-mux by now. Don't create an rtcp attr.
|
||||||
defaultRtcpCandidateAddrCopy = "";
|
defaultRtcpCandidateAddrCopy = "";
|
||||||
defaultRtcpCandidatePort = 0;
|
defaultRtcpCandidatePort = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t level = transceiver->GetLevel();
|
size_t level = transceiver.GetLevel();
|
||||||
if (level >= sdp->GetMediaSectionCount()) {
|
if (level >= sdp->GetMediaSectionCount()) {
|
||||||
MOZ_ASSERT(false, "Transceiver's level is too large!");
|
MOZ_ASSERT(false, "Transceiver's level is too large!");
|
||||||
JSEP_SET_ERROR("Transceiver's level is too large!");
|
JSEP_SET_ERROR("Transceiver's level is too large!");
|
||||||
|
|
@ -2404,8 +2399,8 @@ bool JsepSessionImpl::CheckNegotiationNeeded() const {
|
||||||
MOZ_ASSERT(mState == kJsepStateStable);
|
MOZ_ASSERT(mState == kJsepStateStable);
|
||||||
|
|
||||||
for (const auto& transceiver : mTransceivers) {
|
for (const auto& transceiver : mTransceivers) {
|
||||||
if (transceiver->IsStopped()) {
|
if (transceiver.IsStopped()) {
|
||||||
if (transceiver->IsAssociated()) {
|
if (transceiver.IsAssociated()) {
|
||||||
MOZ_MTLOG(ML_DEBUG, "[" << mName
|
MOZ_MTLOG(ML_DEBUG, "[" << mName
|
||||||
<< "]: Negotiation needed because of "
|
<< "]: Negotiation needed because of "
|
||||||
"stopped transceiver that still has a mid.");
|
"stopped transceiver that still has a mid.");
|
||||||
|
|
@ -2414,7 +2409,7 @@ bool JsepSessionImpl::CheckNegotiationNeeded() const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!transceiver->IsAssociated()) {
|
if (!transceiver.IsAssociated()) {
|
||||||
MOZ_MTLOG(ML_DEBUG, "[" << mName
|
MOZ_MTLOG(ML_DEBUG, "[" << mName
|
||||||
<< "]: Negotiation needed because of "
|
<< "]: Negotiation needed because of "
|
||||||
"unassociated (but not stopped) transceiver.");
|
"unassociated (but not stopped) transceiver.");
|
||||||
|
|
@ -2428,16 +2423,16 @@ bool JsepSessionImpl::CheckNegotiationNeeded() const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!transceiver->HasLevel()) {
|
if (!transceiver.HasLevel()) {
|
||||||
MOZ_CRASH("Associated transceivers should always have a level.");
|
MOZ_CRASH("Associated transceivers should always have a level.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transceiver->GetMediaType() == SdpMediaSection::kApplication) {
|
if (transceiver.GetMediaType() == SdpMediaSection::kApplication) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t level = transceiver->GetLevel();
|
size_t level = transceiver.GetLevel();
|
||||||
if (NS_WARN_IF(mCurrentLocalDescription->GetMediaSectionCount() <= level) ||
|
if (NS_WARN_IF(mCurrentLocalDescription->GetMediaSectionCount() <= level) ||
|
||||||
NS_WARN_IF(mCurrentRemoteDescription->GetMediaSectionCount() <=
|
NS_WARN_IF(mCurrentRemoteDescription->GetMediaSectionCount() <=
|
||||||
level)) {
|
level)) {
|
||||||
|
|
@ -2450,7 +2445,7 @@ bool JsepSessionImpl::CheckNegotiationNeeded() const {
|
||||||
const SdpMediaSection& remote =
|
const SdpMediaSection& remote =
|
||||||
mCurrentRemoteDescription->GetMediaSection(level);
|
mCurrentRemoteDescription->GetMediaSection(level);
|
||||||
|
|
||||||
if (transceiver->mJsDirection & sdp::kSend) {
|
if (transceiver.mJsDirection & sdp::kSend) {
|
||||||
std::vector<std::string> sdpMsids;
|
std::vector<std::string> sdpMsids;
|
||||||
if (local.GetAttributeList().HasAttribute(SdpAttribute::kMsidAttribute)) {
|
if (local.GetAttributeList().HasAttribute(SdpAttribute::kMsidAttribute)) {
|
||||||
for (const auto& msidAttr : local.GetAttributeList().GetMsid().mMsids) {
|
for (const auto& msidAttr : local.GetAttributeList().GetMsid().mMsids) {
|
||||||
|
|
@ -2462,7 +2457,7 @@ bool JsepSessionImpl::CheckNegotiationNeeded() const {
|
||||||
std::sort(sdpMsids.begin(), sdpMsids.end());
|
std::sort(sdpMsids.begin(), sdpMsids.end());
|
||||||
|
|
||||||
std::vector<std::string> jsepMsids;
|
std::vector<std::string> jsepMsids;
|
||||||
for (const auto& jsepMsid : transceiver->mSendTrack.GetStreamIds()) {
|
for (const auto& jsepMsid : transceiver.mSendTrack.GetStreamIds()) {
|
||||||
jsepMsids.push_back(jsepMsid);
|
jsepMsids.push_back(jsepMsid);
|
||||||
}
|
}
|
||||||
std::sort(jsepMsids.begin(), jsepMsids.end());
|
std::sort(jsepMsids.begin(), jsepMsids.end());
|
||||||
|
|
@ -2489,8 +2484,8 @@ bool JsepSessionImpl::CheckNegotiationNeeded() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsCurrentOfferer.isSome() && *mIsCurrentOfferer) {
|
if (mIsCurrentOfferer.isSome() && *mIsCurrentOfferer) {
|
||||||
if ((local.GetDirection() != transceiver->mJsDirection) &&
|
if ((local.GetDirection() != transceiver.mJsDirection) &&
|
||||||
reverse(remote.GetDirection()) != transceiver->mJsDirection) {
|
reverse(remote.GetDirection()) != transceiver.mJsDirection) {
|
||||||
MOZ_MTLOG(ML_DEBUG, "[" << mName
|
MOZ_MTLOG(ML_DEBUG, "[" << mName
|
||||||
<< "]: Negotiation needed because "
|
<< "]: Negotiation needed because "
|
||||||
"the direction on our offer, and the remote "
|
"the direction on our offer, and the remote "
|
||||||
|
|
@ -2499,7 +2494,7 @@ bool JsepSessionImpl::CheckNegotiationNeeded() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (local.GetDirection() !=
|
} else if (local.GetDirection() !=
|
||||||
(transceiver->mJsDirection & reverse(remote.GetDirection()))) {
|
(transceiver.mJsDirection & reverse(remote.GetDirection()))) {
|
||||||
MOZ_MTLOG(
|
MOZ_MTLOG(
|
||||||
ML_DEBUG,
|
ML_DEBUG,
|
||||||
"[" << mName
|
"[" << mName
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,11 @@ class JsepSessionCopyableStuff {
|
||||||
std::vector<std::pair<size_t, std::string>> mLastSdpParsingErrors;
|
std::vector<std::pair<size_t, std::string>> mLastSdpParsingErrors;
|
||||||
bool mEncodeTrackId = true;
|
bool mEncodeTrackId = true;
|
||||||
SsrcGenerator mSsrcGenerator;
|
SsrcGenerator mSsrcGenerator;
|
||||||
|
// !!!NOT INDEXED BY LEVEL!!! The level mapping is done with
|
||||||
|
// JsepTransceiver::mLevel. The keys are UUIDs.
|
||||||
|
std::vector<JsepTransceiver> mTransceivers;
|
||||||
|
// So we can rollback. Not as simple as just going back to the old, though...
|
||||||
|
std::vector<JsepTransceiver> mOldTransceivers;
|
||||||
};
|
};
|
||||||
|
|
||||||
class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
|
class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
|
||||||
|
|
@ -167,16 +172,7 @@ class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
|
||||||
virtual std::set<std::pair<std::string, std::string>> GetLocalIceCredentials()
|
virtual std::set<std::pair<std::string, std::string>> GetLocalIceCredentials()
|
||||||
const override;
|
const override;
|
||||||
|
|
||||||
virtual const std::vector<RefPtr<JsepTransceiver>>& GetTransceivers()
|
virtual void AddTransceiver(const JsepTransceiver& transceiver) override;
|
||||||
const override {
|
|
||||||
return mTransceivers;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::vector<RefPtr<JsepTransceiver>>& GetTransceivers() override {
|
|
||||||
return mTransceivers;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void AddTransceiver(RefPtr<JsepTransceiver> transceiver) override;
|
|
||||||
|
|
||||||
virtual bool CheckNegotiationNeeded() const override;
|
virtual bool CheckNegotiationNeeded() const override;
|
||||||
|
|
||||||
|
|
@ -185,6 +181,15 @@ class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
|
||||||
override;
|
override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class JsepSessionTest;
|
||||||
|
virtual const std::vector<JsepTransceiver>& GetTransceivers() const override {
|
||||||
|
return mTransceivers;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::vector<JsepTransceiver>& GetTransceivers() override {
|
||||||
|
return mTransceivers;
|
||||||
|
}
|
||||||
|
|
||||||
// Non-const so it can set mLastError
|
// Non-const so it can set mLastError
|
||||||
nsresult CreateGenericSDP(UniquePtr<Sdp>* sdp);
|
nsresult CreateGenericSDP(UniquePtr<Sdp>* sdp);
|
||||||
void AddExtmap(SdpMediaSection* msection);
|
void AddExtmap(SdpMediaSection* msection);
|
||||||
|
|
@ -208,16 +213,17 @@ class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
|
||||||
nsresult ValidateOffer(const Sdp& offer);
|
nsresult ValidateOffer(const Sdp& offer);
|
||||||
nsresult ValidateAnswer(const Sdp& offer, const Sdp& answer);
|
nsresult ValidateAnswer(const Sdp& offer, const Sdp& answer);
|
||||||
nsresult UpdateTransceiversFromRemoteDescription(const Sdp& remote);
|
nsresult UpdateTransceiversFromRemoteDescription(const Sdp& remote);
|
||||||
JsepTransceiver* GetTransceiverForLevel(size_t level) const;
|
Maybe<JsepTransceiver> GetTransceiverForLevel(size_t level) const;
|
||||||
JsepTransceiver* GetTransceiverForMid(const std::string& mid) const;
|
Maybe<JsepTransceiver> GetTransceiverForMid(const std::string& mid) const;
|
||||||
JsepTransceiver* GetTransceiverForLocal(size_t level);
|
Maybe<JsepTransceiver> GetTransceiverForLocal(size_t level);
|
||||||
JsepTransceiver* GetTransceiverForRemote(const SdpMediaSection& msection);
|
Maybe<JsepTransceiver> GetTransceiverForRemote(
|
||||||
JsepTransceiver* GetTransceiverWithTransport(
|
const SdpMediaSection& msection);
|
||||||
|
Maybe<JsepTransceiver> GetTransceiverWithTransport(
|
||||||
const std::string& transportId) const;
|
const std::string& transportId) const;
|
||||||
// The w3c and IETF specs have a lot of "magical" behavior that happens when
|
// The w3c and IETF specs have a lot of "magical" behavior that happens when
|
||||||
// addTrack is used. This was a deliberate design choice. Sadface.
|
// addTrack is used. This was a deliberate design choice. Sadface.
|
||||||
JsepTransceiver* FindUnassociatedTransceiver(SdpMediaSection::MediaType type,
|
Maybe<JsepTransceiver> FindUnassociatedTransceiver(
|
||||||
bool magic);
|
SdpMediaSection::MediaType type, bool magic);
|
||||||
// Called for rollback of local description
|
// Called for rollback of local description
|
||||||
void RollbackLocalOffer();
|
void RollbackLocalOffer();
|
||||||
// Called for rollback of remote description
|
// Called for rollback of remote description
|
||||||
|
|
@ -241,14 +247,14 @@ class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
|
||||||
SdpSetupAttribute::Role* rolep);
|
SdpSetupAttribute::Role* rolep);
|
||||||
nsresult MakeNegotiatedTransceiver(const SdpMediaSection& remote,
|
nsresult MakeNegotiatedTransceiver(const SdpMediaSection& remote,
|
||||||
const SdpMediaSection& local,
|
const SdpMediaSection& local,
|
||||||
JsepTransceiver* transceiverOut);
|
JsepTransceiver& transceiverOut);
|
||||||
void EnsureHasOwnTransport(const SdpMediaSection& msection,
|
void EnsureHasOwnTransport(const SdpMediaSection& msection,
|
||||||
JsepTransceiver* transceiver);
|
JsepTransceiver& transceiver);
|
||||||
void CopyBundleTransports();
|
void CopyBundleTransports();
|
||||||
|
|
||||||
nsresult FinalizeTransport(const SdpAttributeList& remote,
|
nsresult FinalizeTransport(const SdpAttributeList& remote,
|
||||||
const SdpAttributeList& answer,
|
const SdpAttributeList& answer,
|
||||||
JsepTransport* transport);
|
JsepTransport* transport) const;
|
||||||
|
|
||||||
nsresult GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids);
|
nsresult GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids);
|
||||||
|
|
||||||
|
|
@ -263,12 +269,6 @@ class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
|
||||||
|
|
||||||
void InitTransceiver(JsepTransceiver& aTransceiver);
|
void InitTransceiver(JsepTransceiver& aTransceiver);
|
||||||
|
|
||||||
// !!!NOT INDEXED BY LEVEL!!! The level mapping is done with
|
|
||||||
// JsepTransceiver::mLevel. The keys are UUIDs.
|
|
||||||
std::vector<RefPtr<JsepTransceiver>> mTransceivers;
|
|
||||||
// So we can rollback. Not as simple as just going back to the old, though...
|
|
||||||
std::vector<RefPtr<JsepTransceiver>> mOldTransceivers;
|
|
||||||
|
|
||||||
UniquePtr<JsepUuidGenerator> mUuidGen;
|
UniquePtr<JsepUuidGenerator> mUuidGen;
|
||||||
UniquePtr<Sdp> mGeneratedOffer; // Created but not set.
|
UniquePtr<Sdp> mGeneratedOffer; // Created but not set.
|
||||||
UniquePtr<Sdp> mGeneratedAnswer; // Created but not set.
|
UniquePtr<Sdp> mGeneratedAnswer; // Created but not set.
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@
|
||||||
#include "jsep/JsepTransport.h"
|
#include "jsep/JsepTransport.h"
|
||||||
#include "jsep/JsepTrack.h"
|
#include "jsep/JsepTrack.h"
|
||||||
|
|
||||||
#include <mozilla/OwningNonNull.h>
|
|
||||||
#include "nsISupportsImpl.h"
|
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
@ -27,9 +25,6 @@ class JsepUuidGenerator {
|
||||||
};
|
};
|
||||||
|
|
||||||
class JsepTransceiver {
|
class JsepTransceiver {
|
||||||
private:
|
|
||||||
~JsepTransceiver(){};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit JsepTransceiver(SdpMediaSection::MediaType type,
|
explicit JsepTransceiver(SdpMediaSection::MediaType type,
|
||||||
JsepUuidGenerator& aUuidGen,
|
JsepUuidGenerator& aUuidGen,
|
||||||
|
|
@ -51,24 +46,12 @@ class JsepTransceiver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't use default copy c'tor because of the refcount members. Ugh.
|
JsepTransceiver(const JsepTransceiver& orig) = default;
|
||||||
JsepTransceiver(const JsepTransceiver& orig)
|
JsepTransceiver(JsepTransceiver&& orig) = default;
|
||||||
: mJsDirection(orig.mJsDirection),
|
JsepTransceiver& operator=(const JsepTransceiver& aRhs) = default;
|
||||||
mSendTrack(orig.mSendTrack),
|
JsepTransceiver& operator=(JsepTransceiver&& aRhs) = default;
|
||||||
mRecvTrack(orig.mRecvTrack),
|
|
||||||
mTransport(orig.mTransport),
|
|
||||||
mUuid(orig.mUuid),
|
|
||||||
mMid(orig.mMid),
|
|
||||||
mLevel(orig.mLevel),
|
|
||||||
mBundleLevel(orig.mBundleLevel),
|
|
||||||
mAddTrackMagic(orig.mAddTrackMagic),
|
|
||||||
mOnlyExistsBecauseOfSetRemote(orig.mOnlyExistsBecauseOfSetRemote),
|
|
||||||
mStopped(orig.mStopped),
|
|
||||||
mRemoved(orig.mRemoved),
|
|
||||||
mNegotiated(orig.mNegotiated),
|
|
||||||
mCanRecycle(orig.mCanRecycle) {}
|
|
||||||
|
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(JsepTransceiver);
|
~JsepTransceiver() = default;
|
||||||
|
|
||||||
void Rollback(JsepTransceiver& oldTransceiver, bool aRemote) {
|
void Rollback(JsepTransceiver& oldTransceiver, bool aRemote) {
|
||||||
MOZ_ASSERT(oldTransceiver.GetMediaType() == GetMediaType());
|
MOZ_ASSERT(oldTransceiver.GetMediaType() == GetMediaType());
|
||||||
|
|
@ -130,6 +113,7 @@ class JsepTransceiver {
|
||||||
void RestartDatachannelTransceiver() {
|
void RestartDatachannelTransceiver() {
|
||||||
MOZ_RELEASE_ASSERT(GetMediaType() == SdpMediaSection::kApplication);
|
MOZ_RELEASE_ASSERT(GetMediaType() == SdpMediaSection::kApplication);
|
||||||
mStopped = false;
|
mStopped = false;
|
||||||
|
mCanRecycle = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRemoved() { mRemoved = true; }
|
void SetRemoved() { mRemoved = true; }
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@ interface PeerConnectionImpl {
|
||||||
[Throws]
|
[Throws]
|
||||||
RTCRtpTransceiver addTransceiver(RTCRtpTransceiverInit init,
|
RTCRtpTransceiver addTransceiver(RTCRtpTransceiverInit init,
|
||||||
DOMString kind,
|
DOMString kind,
|
||||||
MediaStreamTrack? sendTrack);
|
MediaStreamTrack? sendTrack,
|
||||||
|
boolean addTrackMagic);
|
||||||
sequence<RTCRtpTransceiver> getTransceivers();
|
sequence<RTCRtpTransceiver> getTransceivers();
|
||||||
|
|
||||||
[Throws]
|
[Throws]
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,6 @@ interface RTCRtpTransceiver {
|
||||||
// TODO: bug 1396922
|
// TODO: bug 1396922
|
||||||
// undefined setCodecPreferences(sequence<RTCRtpCodecCapability> codecs);
|
// undefined setCodecPreferences(sequence<RTCRtpCodecCapability> codecs);
|
||||||
|
|
||||||
[ChromeOnly]
|
|
||||||
undefined setAddTrackMagic();
|
|
||||||
[ChromeOnly]
|
[ChromeOnly]
|
||||||
undefined setDirectionInternal(RTCRtpTransceiverDirection direction);
|
undefined setDirectionInternal(RTCRtpTransceiverDirection direction);
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue