|
@@ -3,6 +3,7 @@
|
3
|
3
|
import async from 'async';
|
4
|
4
|
import { getLogger } from 'jitsi-meet-logger';
|
5
|
5
|
import { $iq, Strophe } from 'strophe.js';
|
|
6
|
+import { integerHash } from '../util/StringUtils';
|
6
|
7
|
|
7
|
8
|
import JingleSession from './JingleSession';
|
8
|
9
|
import * as JingleSessionState from './JingleSessionState';
|
|
@@ -59,8 +60,8 @@ export default class JingleSessionPC extends JingleSession {
|
59
|
60
|
* Creates new <tt>JingleSessionPC</tt>
|
60
|
61
|
* @param {string} sid the Jingle Session ID - random string which
|
61
|
62
|
* identifies the session
|
62
|
|
- * @param {string} me our JID
|
63
|
|
- * @param {string} peerjid remote peer JID
|
|
63
|
+ * @param {string} localJid our JID
|
|
64
|
+ * @param {string} remoteJid remote peer JID
|
64
|
65
|
* @param {Strophe.Connection} connection Strophe XMPP connection instance
|
65
|
66
|
* used to send packets.
|
66
|
67
|
* @param mediaConstraints the media constraints object passed to
|
|
@@ -71,7 +72,7 @@ export default class JingleSessionPC extends JingleSession {
|
71
|
72
|
* meant to be used in a direct, peer to peer connection or <tt>false</tt>
|
72
|
73
|
* if it's a JVB connection.
|
73
|
74
|
* @param {boolean} isInitiator indicates whether or not we are the side
|
74
|
|
- * which sends the 'session-intiate'.
|
|
75
|
+ * which sends the 'session-initiate'.
|
75
|
76
|
* @param {object} options a set of config options
|
76
|
77
|
* @param {boolean} options.webrtcIceUdpDisable <tt>true</tt> to block UDP
|
77
|
78
|
* candidates.
|
|
@@ -86,15 +87,16 @@ export default class JingleSessionPC extends JingleSession {
|
86
|
87
|
*/
|
87
|
88
|
constructor(
|
88
|
89
|
sid,
|
89
|
|
- me,
|
90
|
|
- peerjid,
|
|
90
|
+ localJid,
|
|
91
|
+ remoteJid,
|
91
|
92
|
connection,
|
92
|
93
|
mediaConstraints,
|
93
|
94
|
iceConfig,
|
94
|
95
|
isP2P,
|
95
|
96
|
isInitiator,
|
96
|
97
|
options) {
|
97
|
|
- super(sid, me, peerjid, connection, mediaConstraints, iceConfig);
|
|
98
|
+ super(
|
|
99
|
+ sid, localJid, remoteJid, connection, mediaConstraints, iceConfig);
|
98
|
100
|
|
99
|
101
|
/**
|
100
|
102
|
* Stores result of {@link window.performance.now()} at the time when
|
|
@@ -240,40 +242,40 @@ export default class JingleSessionPC extends JingleSession {
|
240
|
242
|
// Set to true if the connection was ever stable
|
241
|
243
|
this.wasstable = false;
|
242
|
244
|
|
243
|
|
- // Create new peer connection instance
|
|
245
|
+ const pcOptions = { disableRtx: this.room.options.disableRtx };
|
|
246
|
+
|
244
|
247
|
if (this.isP2P) {
|
245
|
|
- this.peerconnection = this.rtc.createPeerConnection(
|
246
|
|
- this.signalingLayer,
|
247
|
|
- this.iceConfig,
|
248
|
|
- this.isP2P,
|
249
|
|
- {
|
250
|
|
- // simulcast needs to be disabled for P2P (121) calls
|
251
|
|
- disableSimulcast: true,
|
252
|
|
- disableRtx: this.room.options.disableRtx,
|
253
|
|
- disableH264: this.room.options.p2p
|
254
|
|
- && this.room.options.p2p.disableH264,
|
255
|
|
- preferH264: this.room.options.p2p
|
256
|
|
- && this.room.options.p2p.preferH264
|
257
|
|
- });
|
|
248
|
+ // simulcast needs to be disabled for P2P (121) calls
|
|
249
|
+ pcOptions.disableSimulcast = true;
|
|
250
|
+ pcOptions.disableH264
|
|
251
|
+ = this.room.options.p2p && this.room.options.p2p.disableH264;
|
|
252
|
+ pcOptions.preferH264
|
|
253
|
+ = this.room.options.p2p && this.room.options.p2p.preferH264;
|
|
254
|
+
|
|
255
|
+ const abtestSuspendVideo = this._abtestSuspendVideoEnabled();
|
|
256
|
+
|
|
257
|
+ if (typeof abtestSuspendVideo !== 'undefined') {
|
|
258
|
+ pcOptions.abtestSuspendVideo = abtestSuspendVideo;
|
|
259
|
+ }
|
258
|
260
|
} else {
|
259
|
|
- this.peerconnection = this.rtc.createPeerConnection(
|
260
|
|
- this.signalingLayer,
|
261
|
|
- this.iceConfig,
|
262
|
|
- this.isP2P,
|
263
|
|
- {
|
264
|
|
- // H264 does not support simulcast, so it needs to be
|
265
|
|
- // disabled.
|
266
|
|
- disableSimulcast: this.room.options.disableSimulcast
|
267
|
|
- || (this.room.options.preferH264
|
268
|
|
- && !this.room.options.disableH264),
|
269
|
|
- disableRtx: this.room.options.disableRtx,
|
270
|
|
- disableH264: this.room.options.disableH264,
|
271
|
|
- preferH264: this.room.options.preferH264,
|
272
|
|
- enableFirefoxSimulcast: this.room.options.testing
|
273
|
|
- && this.room.options.testing.enableFirefoxSimulcast
|
274
|
|
- });
|
|
261
|
+ // H264 does not support simulcast, so it needs to be disabled.
|
|
262
|
+ pcOptions.disableSimulcast
|
|
263
|
+ = this.room.options.disableSimulcast
|
|
264
|
+ || (this.room.options.preferH264
|
|
265
|
+ && !this.room.options.disableH264);
|
|
266
|
+ pcOptions.preferH264 = this.room.options.preferH264;
|
|
267
|
+ pcOptions.enableFirefoxSimulcast
|
|
268
|
+ = this.room.options.testing
|
|
269
|
+ && this.room.options.testing.enableFirefoxSimulcast;
|
275
|
270
|
}
|
276
|
271
|
|
|
272
|
+ this.peerconnection
|
|
273
|
+ = this.rtc.createPeerConnection(
|
|
274
|
+ this.signalingLayer,
|
|
275
|
+ this.iceConfig,
|
|
276
|
+ this.isP2P,
|
|
277
|
+ pcOptions);
|
|
278
|
+
|
277
|
279
|
this.peerconnection.onicecandidate = ev => {
|
278
|
280
|
if (!ev) {
|
279
|
281
|
// There was an incomplete check for ev before which left
|
|
@@ -509,7 +511,7 @@ export default class JingleSessionPC extends JingleSession {
|
509
|
511
|
}
|
510
|
512
|
|
511
|
513
|
logger.log('sendIceCandidates', candidates);
|
512
|
|
- const cand = $iq({ to: this.peerjid,
|
|
514
|
+ const cand = $iq({ to: this.remoteJid,
|
513
|
515
|
type: 'set' })
|
514
|
516
|
.c('jingle', { xmlns: 'urn:xmpp:jingle:1',
|
515
|
517
|
action: 'transport-info',
|
|
@@ -657,7 +659,7 @@ export default class JingleSessionPC extends JingleSession {
|
657
|
659
|
if (this.isP2P) {
|
658
|
660
|
// In P2P all SSRCs are owner by the remote peer
|
659
|
661
|
this.signalingLayer.setSSRCOwner(
|
660
|
|
- ssrc, Strophe.getResourceFromJid(this.peerjid));
|
|
662
|
+ ssrc, Strophe.getResourceFromJid(this.remoteJid));
|
661
|
663
|
} else {
|
662
|
664
|
$(ssrcElement)
|
663
|
665
|
.find('>ssrc-info[xmlns="http://jitsi.org/jitmeet"]')
|
|
@@ -794,7 +796,7 @@ export default class JingleSessionPC extends JingleSession {
|
794
|
796
|
*/
|
795
|
797
|
sendSessionInitiate(offerSdp) {
|
796
|
798
|
let init = $iq({
|
797
|
|
- to: this.peerjid,
|
|
799
|
+ to: this.remoteJid,
|
798
|
800
|
type: 'set'
|
799
|
801
|
}).c('jingle', {
|
800
|
802
|
xmlns: 'urn:xmpp:jingle:1',
|
|
@@ -967,7 +969,7 @@ export default class JingleSessionPC extends JingleSession {
|
967
|
969
|
// NOTE: since we're just reading from it, we don't need to be within
|
968
|
970
|
// the modification queue to access the local description
|
969
|
971
|
const localSDP = new SDP(this.peerconnection.localDescription.sdp);
|
970
|
|
- let accept = $iq({ to: this.peerjid,
|
|
972
|
+ let accept = $iq({ to: this.remoteJid,
|
971
|
973
|
type: 'set' })
|
972
|
974
|
.c('jingle', { xmlns: 'urn:xmpp:jingle:1',
|
973
|
975
|
action: 'session-accept',
|
|
@@ -1039,7 +1041,7 @@ export default class JingleSessionPC extends JingleSession {
|
1039
|
1041
|
|
1040
|
1042
|
const sessionModify
|
1041
|
1043
|
= $iq({
|
1042
|
|
- to: this.peerjid,
|
|
1044
|
+ to: this.remoteJid,
|
1043
|
1045
|
type: 'set'
|
1044
|
1046
|
})
|
1045
|
1047
|
.c('jingle', {
|
|
@@ -1074,7 +1076,7 @@ export default class JingleSessionPC extends JingleSession {
|
1074
|
1076
|
* @private
|
1075
|
1077
|
*/
|
1076
|
1078
|
sendTransportAccept(localSDP, success, failure) {
|
1077
|
|
- let transportAccept = $iq({ to: this.peerjid,
|
|
1079
|
+ let transportAccept = $iq({ to: this.remoteJid,
|
1078
|
1080
|
type: 'set' })
|
1079
|
1081
|
.c('jingle', {
|
1080
|
1082
|
xmlns: 'urn:xmpp:jingle:1',
|
|
@@ -1123,7 +1125,7 @@ export default class JingleSessionPC extends JingleSession {
|
1123
|
1125
|
sendTransportReject(success, failure) {
|
1124
|
1126
|
// Send 'transport-reject', so that the focus will
|
1125
|
1127
|
// know that we've failed
|
1126
|
|
- let transportReject = $iq({ to: this.peerjid,
|
|
1128
|
+ let transportReject = $iq({ to: this.remoteJid,
|
1127
|
1129
|
type: 'set' })
|
1128
|
1130
|
.c('jingle', {
|
1129
|
1131
|
xmlns: 'urn:xmpp:jingle:1',
|
|
@@ -1152,7 +1154,7 @@ export default class JingleSessionPC extends JingleSession {
|
1152
|
1154
|
if (!options || Boolean(options.sendSessionTerminate)) {
|
1153
|
1155
|
let sessionTerminate
|
1154
|
1156
|
= $iq({
|
1155
|
|
- to: this.peerjid,
|
|
1157
|
+ to: this.remoteJid,
|
1156
|
1158
|
type: 'set'
|
1157
|
1159
|
})
|
1158
|
1160
|
.c('jingle', {
|
|
@@ -2025,7 +2027,7 @@ export default class JingleSessionPC extends JingleSession {
|
2025
|
2027
|
|
2026
|
2028
|
// send source-remove IQ.
|
2027
|
2029
|
let sdpDiffer = new SDPDiffer(newSDP, oldSDP);
|
2028
|
|
- const remove = $iq({ to: this.peerjid,
|
|
2030
|
+ const remove = $iq({ to: this.remoteJid,
|
2029
|
2031
|
type: 'set' })
|
2030
|
2032
|
.c('jingle', {
|
2031
|
2033
|
xmlns: 'urn:xmpp:jingle:1',
|
|
@@ -2047,7 +2049,7 @@ export default class JingleSessionPC extends JingleSession {
|
2047
|
2049
|
|
2048
|
2050
|
// send source-add IQ.
|
2049
|
2051
|
sdpDiffer = new SDPDiffer(oldSDP, newSDP);
|
2050
|
|
- const add = $iq({ to: this.peerjid,
|
|
2052
|
+ const add = $iq({ to: this.remoteJid,
|
2051
|
2053
|
type: 'set' })
|
2052
|
2054
|
.c('jingle', {
|
2053
|
2055
|
xmlns: 'urn:xmpp:jingle:1',
|
|
@@ -2181,4 +2183,23 @@ export default class JingleSessionPC extends JingleSession {
|
2181
|
2183
|
return `JingleSessionPC[p2p=${this.isP2P},`
|
2182
|
2184
|
+ `initiator=${this.isInitiator},sid=${this.sid}]`;
|
2183
|
2185
|
}
|
|
2186
|
+
|
|
2187
|
+ /**
|
|
2188
|
+ * If the A/B test for suspend video is disabled according to the room's
|
|
2189
|
+ * configuration, returns undefined. Otherwise returns a boolean which
|
|
2190
|
+ * indicates whether the suspend video option should be enabled or disabled.
|
|
2191
|
+ */
|
|
2192
|
+ _abtestSuspendVideoEnabled() {
|
|
2193
|
+ if (!this.room.options.abTesting
|
|
2194
|
+ || !this.room.options.abTesting.enableSuspendVideoTest) {
|
|
2195
|
+ return;
|
|
2196
|
+ }
|
|
2197
|
+
|
|
2198
|
+ // We want the two participants in a P2P call to agree on the value of
|
|
2199
|
+ // the "suspend" option. We use the JID of the initiator, because it is
|
|
2200
|
+ // both randomly selected and agreed upon by both participants.
|
|
2201
|
+ const jid = this._getInitiatorJid();
|
|
2202
|
+
|
|
2203
|
+ return integerHash(jid) % 2 === 0;
|
|
2204
|
+ }
|
2184
|
2205
|
}
|