|
@@ -1170,21 +1170,15 @@ export default class JingleSessionPC extends JingleSession {
|
1170
|
1170
|
addTracks.push(this.peerconnection.addTrack(track, this.isInitiator));
|
1171
|
1171
|
}
|
1172
|
1172
|
const newRemoteSdp = this._processNewJingleOfferIq(jingleOfferAnswerIq);
|
1173
|
|
- const oldLocalSdp = this.peerconnection.localDescription.sdp;
|
1174
|
|
-
|
1175
|
1173
|
const bridgeSession = $(jingleOfferAnswerIq).find('>bridge-session[xmlns="http://jitsi.org/protocol/focus"]');
|
1176
|
1174
|
const bridgeSessionId = bridgeSession.attr('id');
|
1177
|
1175
|
|
1178
|
1176
|
if (bridgeSessionId !== this._bridgeSessionId) {
|
1179
|
1177
|
this._bridgeSessionId = bridgeSessionId;
|
1180
|
1178
|
}
|
1181
|
|
- const remoteDescription = new RTCSessionDescription({
|
1182
|
|
- type: 'offer',
|
1183
|
|
- sdp: newRemoteSdp.raw
|
1184
|
|
- });
|
1185
|
1179
|
|
1186
|
1180
|
Promise.all(addTracks)
|
1187
|
|
- .then(() => this._responderRenegotiate(remoteDescription))
|
|
1181
|
+ .then(() => this._renegotiate(newRemoteSdp.raw))
|
1188
|
1182
|
.then(() => {
|
1189
|
1183
|
this.peerconnection.processLocalSdpForTransceiverInfo(tracks);
|
1190
|
1184
|
if (this.state === JingleSessionState.PENDING) {
|
|
@@ -1197,19 +1191,11 @@ export default class JingleSessionPC extends JingleSession {
|
1197
|
1191
|
// interested in receiving video content. Changing media direction in the remote SDP will mess
|
1198
|
1192
|
// up our SDP translation chain (simulcast, video mute, RTX etc.)
|
1199
|
1193
|
// #2 Sends the max frame height if it was set, before the session-initiate/accept
|
1200
|
|
- if (this.isP2P
|
1201
|
|
- && (!this._localVideoActive || this._sourceReceiverConstraints)) {
|
|
1194
|
+ if (this.isP2P && (!this._localVideoActive || this._sourceReceiverConstraints)) {
|
1202
|
1195
|
this.sendContentModify();
|
1203
|
1196
|
}
|
1204
|
1197
|
}
|
1205
|
1198
|
|
1206
|
|
- // Old local SDP will be available when we're setting answer for the first time, but not when offer
|
1207
|
|
- // and it's fine since we're generating an answer now it will contain all our SSRCs.
|
1208
|
|
- if (oldLocalSdp) {
|
1209
|
|
- const newLocalSdp = new SDP(this.peerconnection.localDescription.sdp);
|
1210
|
|
-
|
1211
|
|
- this.notifyMySSRCUpdate(new SDP(oldLocalSdp), newLocalSdp);
|
1212
|
|
- }
|
1213
|
1199
|
})
|
1214
|
1200
|
.then(() => {
|
1215
|
1201
|
logger.debug(`${this} setOfferAnswerCycle task done`);
|
|
@@ -1955,7 +1941,6 @@ export default class JingleSessionPC extends JingleSession {
|
1955
|
1941
|
|
1956
|
1942
|
logger.log(`${this} Processing ${logPrefix}`);
|
1957
|
1943
|
|
1958
|
|
- const oldLocalSdp = new SDP(this.peerconnection.localDescription.sdp);
|
1959
|
1944
|
const sdp = new SDP(this.peerconnection.remoteDescription.sdp);
|
1960
|
1945
|
const addOrRemoveSsrcInfo
|
1961
|
1946
|
= isAdd
|
|
@@ -1965,19 +1950,9 @@ export default class JingleSessionPC extends JingleSession {
|
1965
|
1950
|
= isAdd
|
1966
|
1951
|
? this._processRemoteAddSource(addOrRemoveSsrcInfo)
|
1967
|
1952
|
: this._processRemoteRemoveSource(addOrRemoveSsrcInfo);
|
1968
|
|
- const remoteDescription = new RTCSessionDescription({
|
1969
|
|
- type: 'offer',
|
1970
|
|
- sdp: newRemoteSdp.raw
|
1971
|
|
- });
|
1972
|
|
-
|
1973
|
|
- // Always initiate a sRD->cA->sLD cycle when a remote source is added or removed irrespective of whether
|
1974
|
|
- // the local endpoint is an initiator or responder. Fixes bugs on Chromium where decoders are not created
|
1975
|
|
- // when sLD->cO->sRD cycle is initiated for p2p cases when remote sources are received.
|
1976
|
|
- this._responderRenegotiate(remoteDescription).then(() => {
|
1977
|
|
- const newLocalSdp = new SDP(this.peerconnection.localDescription.sdp);
|
1978
|
1953
|
|
|
1954
|
+ this._renegotiate(newRemoteSdp.raw).then(() => {
|
1979
|
1955
|
logger.log(`${this} ${logPrefix} - OK`);
|
1980
|
|
- this.notifyMySSRCUpdate(oldLocalSdp, newLocalSdp);
|
1981
|
1956
|
finishedCallback();
|
1982
|
1957
|
}, error => {
|
1983
|
1958
|
logger.error(`${this} ${logPrefix} failed:`, error);
|
|
@@ -2117,13 +2092,13 @@ export default class JingleSessionPC extends JingleSession {
|
2117
|
2092
|
}
|
2118
|
2093
|
|
2119
|
2094
|
/**
|
2120
|
|
- * Do a new o/a flow using the existing remote description
|
2121
|
|
- * @param {string} [optionalRemoteSdp] optional, raw remote sdp
|
2122
|
|
- * to use. If not provided, the remote sdp from the
|
2123
|
|
- * peerconnection will be used
|
2124
|
|
- * @returns {Promise} promise which resolves when the
|
2125
|
|
- * o/a flow is complete with no arguments or
|
2126
|
|
- * rejects with an error {string}
|
|
2095
|
+ * Does a new offer/answer flow using the existing remote description (if not provided) and signals any new sources
|
|
2096
|
+ * to Jicofo or the remote peer.
|
|
2097
|
+ *
|
|
2098
|
+ * @param {string} [optionalRemoteSdp] optional, raw remote sdp to use. If not provided, the remote sdp from the
|
|
2099
|
+ * peerconnection will be used.
|
|
2100
|
+ * @returns {Promise} promise which resolves when the o/a flow is complete with no arguments or rejects with an
|
|
2101
|
+ * error {string}
|
2127
|
2102
|
*/
|
2128
|
2103
|
_renegotiate(optionalRemoteSdp) {
|
2129
|
2104
|
if (this.peerconnection.signalingState === 'closed') {
|
|
@@ -2134,8 +2109,7 @@ export default class JingleSessionPC extends JingleSession {
|
2134
|
2109
|
return Promise.reject(error);
|
2135
|
2110
|
}
|
2136
|
2111
|
|
2137
|
|
- const remoteSdp
|
2138
|
|
- = optionalRemoteSdp || this.peerconnection.remoteDescription.sdp;
|
|
2112
|
+ const remoteSdp = optionalRemoteSdp || this.peerconnection.remoteDescription.sdp;
|
2139
|
2113
|
|
2140
|
2114
|
if (!remoteSdp) {
|
2141
|
2115
|
const error = new Error(`Can not renegotiate without remote description, current state: ${this.state}`);
|
|
@@ -2146,65 +2120,30 @@ export default class JingleSessionPC extends JingleSession {
|
2146
|
2120
|
}
|
2147
|
2121
|
|
2148
|
2122
|
const remoteDescription = new RTCSessionDescription({
|
2149
|
|
- type: this.isInitiator ? 'answer' : 'offer',
|
|
2123
|
+ type: 'offer',
|
2150
|
2124
|
sdp: remoteSdp
|
2151
|
2125
|
});
|
2152
|
2126
|
|
2153
|
|
- const promise = this.isInitiator
|
2154
|
|
- ? this._initiatorRenegotiate(remoteDescription)
|
2155
|
|
- : this._responderRenegotiate(remoteDescription);
|
2156
|
|
- const oldLocalSDP = new SDP(this.peerconnection.localDescription.sdp);
|
2157
|
|
-
|
2158
|
|
- return promise.then(() => {
|
2159
|
|
- const newLocalSDP = new SDP(this.peerconnection.localDescription.sdp);
|
2160
|
|
-
|
2161
|
|
- // Send the source updates after every renegotiation cycle.
|
2162
|
|
- oldLocalSDP && this.notifyMySSRCUpdate(oldLocalSDP, newLocalSDP);
|
2163
|
|
- });
|
2164
|
|
- }
|
|
2127
|
+ const oldLocalSDP = this.peerconnection.localDescription.sdp;
|
2165
|
2128
|
|
2166
|
|
- /**
|
2167
|
|
- * Renegotiate cycle implementation for the responder case.
|
2168
|
|
- * @param {object} remoteDescription the SDP object as defined by the WebRTC
|
2169
|
|
- * which will be used as remote description in the cycle.
|
2170
|
|
- * @private
|
2171
|
|
- */
|
2172
|
|
- _responderRenegotiate(remoteDescription) {
|
2173
|
2129
|
logger.debug(`${this} Renegotiate: setting remote description`);
|
2174
|
2130
|
|
2175
|
2131
|
return this.peerconnection.setRemoteDescription(remoteDescription)
|
2176
|
2132
|
.then(() => {
|
2177
|
2133
|
logger.debug(`${this} Renegotiate: creating answer`);
|
2178
|
2134
|
|
2179
|
|
- return this.peerconnection.createAnswer(this.mediaConstraints)
|
2180
|
|
- .then(answer => {
|
2181
|
|
- logger.debug(`${this} Renegotiate: setting local description`);
|
2182
|
|
-
|
2183
|
|
- return this.peerconnection.setLocalDescription(answer);
|
2184
|
|
- });
|
2185
|
|
- });
|
2186
|
|
- }
|
2187
|
|
-
|
2188
|
|
- /**
|
2189
|
|
- * Renegotiate cycle implementation for the initiator's case.
|
2190
|
|
- * @param {object} remoteDescription the SDP object as defined by the WebRTC
|
2191
|
|
- * which will be used as remote description in the cycle.
|
2192
|
|
- * @private
|
2193
|
|
- */
|
2194
|
|
- _initiatorRenegotiate(remoteDescription) {
|
2195
|
|
- logger.debug(`${this} Renegotiate: creating offer`);
|
2196
|
|
-
|
2197
|
|
- return this.peerconnection.createOffer(this.mediaConstraints)
|
2198
|
|
- .then(offer => {
|
|
2135
|
+ return this.peerconnection.createAnswer(this.mediaConstraints);
|
|
2136
|
+ })
|
|
2137
|
+ .then(answer => {
|
2199
|
2138
|
logger.debug(`${this} Renegotiate: setting local description`);
|
2200
|
2139
|
|
2201
|
|
- return this.peerconnection.setLocalDescription(offer)
|
2202
|
|
- .then(() => {
|
2203
|
|
- logger.debug(`${this} Renegotiate: setting remote description`);
|
2204
|
|
-
|
2205
|
|
- // eslint-disable-next-line max-len
|
2206
|
|
- return this.peerconnection.setRemoteDescription(remoteDescription);
|
2207
|
|
- });
|
|
2140
|
+ return this.peerconnection.setLocalDescription(answer);
|
|
2141
|
+ })
|
|
2142
|
+ .then(() => {
|
|
2143
|
+ if (oldLocalSDP) {
|
|
2144
|
+ // Send the source updates after every renegotiation cycle.
|
|
2145
|
+ this.notifyMySSRCUpdate(new SDP(oldLocalSDP), new SDP(this.peerconnection.localDescription.sdp));
|
|
2146
|
+ }
|
2208
|
2147
|
});
|
2209
|
2148
|
}
|
2210
|
2149
|
|
|
@@ -2240,13 +2179,7 @@ export default class JingleSessionPC extends JingleSession {
|
2240
|
2179
|
}
|
2241
|
2180
|
}
|
2242
|
2181
|
|
2243
|
|
- const remoteDescription = new RTCSessionDescription({
|
2244
|
|
- type: 'offer',
|
2245
|
|
- sdp: remoteSdp.raw
|
2246
|
|
- });
|
2247
|
|
-
|
2248
|
|
- // Always initiate a responder renegotiate since the new m-line is added to remote SDP.
|
2249
|
|
- this._responderRenegotiate(remoteDescription)
|
|
2182
|
+ this._renegotiate(remoteSdp.raw)
|
2250
|
2183
|
.then(() => {
|
2251
|
2184
|
// Replace the tracks on the newly generated transceivers.
|
2252
|
2185
|
for (const track of localTracks) {
|
|
@@ -2318,8 +2251,6 @@ export default class JingleSessionPC extends JingleSession {
|
2318
|
2251
|
const workFunction = finishedCallback => {
|
2319
|
2252
|
logger.debug(`${this} replaceTrack worker started. oldTrack = ${oldTrack}, newTrack = ${newTrack}`);
|
2320
|
2253
|
|
2321
|
|
- const oldLocalSdp = this.peerconnection.localDescription.sdp;
|
2322
|
|
-
|
2323
|
2254
|
if (!this.usesUnifiedPlan) {
|
2324
|
2255
|
// NOTE the code below assumes that no more than 1 video track
|
2325
|
2256
|
// can be added to the peer connection.
|
|
@@ -2362,33 +2293,13 @@ export default class JingleSessionPC extends JingleSession {
|
2362
|
2293
|
logger.debug(`${this} TPC.replaceTrack finished. shouldRenegotiate = ${
|
2363
|
2294
|
shouldRenegotiate}, JingleSessionState = ${this.state}`);
|
2364
|
2295
|
|
2365
|
|
- if (shouldRenegotiate
|
2366
|
|
- && (oldTrack || newTrack)
|
2367
|
|
- && this.state === JingleSessionState.ACTIVE) {
|
2368
|
|
- const remoteSdp = this.peerconnection.remoteDescription.sdp;
|
2369
|
|
- const remoteDescription = new RTCSessionDescription({
|
2370
|
|
- type: 'offer',
|
2371
|
|
- sdp: remoteSdp
|
2372
|
|
- });
|
2373
|
|
-
|
2374
|
|
- // Always initiate a sRD->cA->sLD cycle since renegotiation fails in the following scenario.
|
2375
|
|
- // In a p2p call when channelLastN=0, the direction on the video tranceiver is set to
|
2376
|
|
- // 'inactive'. At this point, if the user unmutes, the track is replaced on the video sender.
|
2377
|
|
- // If a cO->sLD->sRD is triggered, the browser adds a third m-line which isn't expected and
|
2378
|
|
- // possibly is a bug. All renegotiations fail as a result. However, the browser does not add a
|
2379
|
|
- // third m-line in the answer it generates and renegotiation succeeds.
|
2380
|
|
- promise = this._responderRenegotiate(remoteDescription).then(() => {
|
2381
|
|
- const newLocalSDP = new SDP(this.peerconnection.localDescription.sdp);
|
2382
|
|
-
|
2383
|
|
- this.notifyMySSRCUpdate(new SDP(oldLocalSdp), newLocalSDP);
|
2384
|
|
- });
|
|
2296
|
+ if (shouldRenegotiate && (oldTrack || newTrack) && this.state === JingleSessionState.ACTIVE) {
|
|
2297
|
+ promise = this._renegotiate();
|
2385
|
2298
|
}
|
2386
|
2299
|
|
2387
|
2300
|
return promise.then(() => {
|
2388
|
2301
|
// Set the source name of the new track.
|
2389
|
|
- if (oldTrack
|
2390
|
|
- && newTrack
|
2391
|
|
- && oldTrack.isVideoTrack()) {
|
|
2302
|
+ if (oldTrack && newTrack && oldTrack.isVideoTrack()) {
|
2392
|
2303
|
newTrack.setSourceName(oldTrack.getSourceName());
|
2393
|
2304
|
}
|
2394
|
2305
|
});
|