|
|
@@ -513,6 +513,21 @@ TraceablePeerConnection.prototype.getDesiredMediaDirection = function(mediaType,
|
|
513
|
513
|
return MediaDirection.INACTIVE;
|
|
514
|
514
|
};
|
|
515
|
515
|
|
|
|
516
|
+/**
|
|
|
517
|
+ * Returns the MID of the m-line associated with the local desktop track (if it exists).
|
|
|
518
|
+ *
|
|
|
519
|
+ * @returns {Number|null}
|
|
|
520
|
+ */
|
|
|
521
|
+TraceablePeerConnection.prototype._getDesktopTrackMid = function() {
|
|
|
522
|
+ const desktopTrack = this.getLocalVideoTracks().find(track => track.getVideoType() === VideoType.DESKTOP);
|
|
|
523
|
+
|
|
|
524
|
+ if (desktopTrack) {
|
|
|
525
|
+ return Number(this._localTrackTransceiverMids.get(desktopTrack.rtcId));
|
|
|
526
|
+ }
|
|
|
527
|
+
|
|
|
528
|
+ return null;
|
|
|
529
|
+};
|
|
|
530
|
+
|
|
516
|
531
|
/**
|
|
517
|
532
|
* Returns the list of RTCRtpReceivers created for the source of the given media type associated with
|
|
518
|
533
|
* the set of remote endpoints specified.
|
|
|
@@ -1639,28 +1654,26 @@ TraceablePeerConnection.prototype._mungeCodecOrder = function(description) {
|
|
1639
|
1654
|
}
|
|
1640
|
1655
|
|
|
1641
|
1656
|
const parsedSdp = transform.parse(description.sdp);
|
|
|
1657
|
+ const mLines = parsedSdp.media.filter(m => m.type === this.codecPreference.mediaType);
|
|
1642
|
1658
|
|
|
1643
|
|
- // Only the m-line that defines the source the browser will be sending should need to change.
|
|
1644
|
|
- // This is typically the first m-line with the matching media type.
|
|
1645
|
|
- const mLine = parsedSdp.media.find(m => m.type === this.codecPreference.mediaType);
|
|
1646
|
|
-
|
|
1647
|
|
- if (!mLine) {
|
|
|
1659
|
+ if (!mLines.length) {
|
|
1648
|
1660
|
return description;
|
|
1649
|
1661
|
}
|
|
1650
|
1662
|
|
|
1651
|
|
- if (this.codecPreference.enable) {
|
|
1652
|
|
- SDPUtil.preferCodec(mLine, this.codecPreference.mimeType);
|
|
1653
|
|
-
|
|
1654
|
|
- // Strip the high profile H264 codecs on mobile clients for p2p connection.
|
|
1655
|
|
- // High profile codecs give better quality at the expense of higher load which
|
|
1656
|
|
- // we do not want on mobile clients.
|
|
1657
|
|
- // Jicofo offers only the baseline code for the jvb connection.
|
|
1658
|
|
- // TODO - add check for mobile browsers once js-utils provides that check.
|
|
1659
|
|
- if (this.codecPreference.mimeType === CodecMimeType.H264 && browser.isReactNative() && this.isP2P) {
|
|
1660
|
|
- SDPUtil.stripCodec(mLine, this.codecPreference.mimeType, true /* high profile */);
|
|
|
1663
|
+ for (const mLine of mLines) {
|
|
|
1664
|
+ if (this.codecPreference.enable) {
|
|
|
1665
|
+ SDPUtil.preferCodec(mLine, this.codecPreference.mimeType);
|
|
|
1666
|
+
|
|
|
1667
|
+ // Strip the high profile H264 codecs on mobile clients for p2p connection. High profile codecs give better
|
|
|
1668
|
+ // quality at the expense of higher load which we do not want on mobile clients. Jicofo offers only the
|
|
|
1669
|
+ // baseline code for the jvb connection and therefore this is not needed for jvb connection.
|
|
|
1670
|
+ // TODO - add check for mobile browsers once js-utils provides that check.
|
|
|
1671
|
+ if (this.codecPreference.mimeType === CodecMimeType.H264 && browser.isReactNative() && this.isP2P) {
|
|
|
1672
|
+ SDPUtil.stripCodec(mLine, this.codecPreference.mimeType, true /* high profile */);
|
|
|
1673
|
+ }
|
|
|
1674
|
+ } else {
|
|
|
1675
|
+ SDPUtil.stripCodec(mLine, this.codecPreference.mimeType);
|
|
1661
|
1676
|
}
|
|
1662
|
|
- } else {
|
|
1663
|
|
- SDPUtil.stripCodec(mLine, this.codecPreference.mimeType);
|
|
1664
|
1677
|
}
|
|
1665
|
1678
|
|
|
1666
|
1679
|
return new RTCSessionDescription({
|
|
|
@@ -1989,15 +2002,17 @@ TraceablePeerConnection.prototype.processLocalSdpForTransceiverInfo = function(l
|
|
1989
|
2002
|
return;
|
|
1990
|
2003
|
}
|
|
1991
|
2004
|
|
|
1992
|
|
- for (const localTrack of localTracks) {
|
|
1993
|
|
- const mediaType = localTrack.getType();
|
|
|
2005
|
+ [ MediaType.AUDIO, MediaType.VIDEO ].forEach(mediaType => {
|
|
|
2006
|
+ const tracks = localTracks.filter(t => t.getType() === mediaType);
|
|
1994
|
2007
|
const parsedSdp = transform.parse(localSdp);
|
|
1995
|
|
- const mLine = parsedSdp.media.find(mline => mline.type === mediaType);
|
|
|
2008
|
+ const mLines = parsedSdp.media.filter(mline => mline.type === mediaType);
|
|
1996
|
2009
|
|
|
1997
|
|
- if (!this._localTrackTransceiverMids.has(localTrack.rtcId)) {
|
|
1998
|
|
- this._localTrackTransceiverMids.set(localTrack.rtcId, mLine.mid.toString());
|
|
1999
|
|
- }
|
|
2000
|
|
- }
|
|
|
2010
|
+ tracks.forEach((track, idx) => {
|
|
|
2011
|
+ if (!this._localTrackTransceiverMids.has(track.rtcId)) {
|
|
|
2012
|
+ this._localTrackTransceiverMids.set(track.rtcId, mLines[idx].mid.toString());
|
|
|
2013
|
+ }
|
|
|
2014
|
+ });
|
|
|
2015
|
+ });
|
|
2001
|
2016
|
};
|
|
2002
|
2017
|
|
|
2003
|
2018
|
/**
|
|
|
@@ -2083,7 +2098,7 @@ TraceablePeerConnection.prototype.replaceTrack = function(oldTrack, newTrack) {
|
|
2083
|
2098
|
? Promise.resolve()
|
|
2084
|
2099
|
: this.tpcUtils.setEncodings(newTrack);
|
|
2085
|
2100
|
|
|
2086
|
|
- return configureEncodingsPromise.then(() => false);
|
|
|
2101
|
+ return configureEncodingsPromise.then(() => this.isP2P);
|
|
2087
|
2102
|
});
|
|
2088
|
2103
|
}
|
|
2089
|
2104
|
|
|
|
@@ -2240,15 +2255,31 @@ TraceablePeerConnection.prototype._adjustRemoteMediaDirection = function(remoteD
|
|
2240
|
2255
|
const transformer = new SdpTransformWrap(remoteDescription.sdp);
|
|
2241
|
2256
|
|
|
2242
|
2257
|
[ MediaType.AUDIO, MediaType.VIDEO ].forEach(mediaType => {
|
|
2243
|
|
- const media = transformer.selectMedia(mediaType)?.[0];
|
|
2244
|
|
- const hasLocalSource = this.hasAnyTracksOfType(mediaType);
|
|
2245
|
|
- const hasRemoteSource = this.getRemoteTracks(null, mediaType).length > 0;
|
|
2246
|
|
-
|
|
2247
|
|
- media.direction = hasLocalSource && hasRemoteSource
|
|
2248
|
|
- ? MediaDirection.SENDRECV
|
|
2249
|
|
- : hasLocalSource
|
|
2250
|
|
- ? MediaDirection.RECVONLY
|
|
2251
|
|
- : hasRemoteSource ? MediaDirection.SENDONLY : MediaDirection.INACTIVE;
|
|
|
2258
|
+ const media = transformer.selectMedia(mediaType);
|
|
|
2259
|
+ const localSources = this.getLocalTracks(mediaType).length;
|
|
|
2260
|
+ const remoteSources = this.getRemoteTracks(null, mediaType).length;
|
|
|
2261
|
+
|
|
|
2262
|
+ media.forEach((mLine, idx) => {
|
|
|
2263
|
+ if (localSources && localSources === remoteSources) {
|
|
|
2264
|
+ mLine.direction = MediaDirection.SENDRECV;
|
|
|
2265
|
+ } else if (!localSources && !remoteSources) {
|
|
|
2266
|
+ mLine.direction = MediaDirection.INACTIVE;
|
|
|
2267
|
+ } else if (!localSources) {
|
|
|
2268
|
+ mLine.direction = MediaDirection.SENDONLY;
|
|
|
2269
|
+ } else if (!remoteSources) {
|
|
|
2270
|
+ mLine.direction = MediaDirection.RECVONLY;
|
|
|
2271
|
+
|
|
|
2272
|
+ // When there are 2 local sources and 1 remote source, the first m-line should be set to 'sendrecv' while
|
|
|
2273
|
+ // the second one needs to be set to 'recvonly'.
|
|
|
2274
|
+ } else if (localSources > remoteSources) {
|
|
|
2275
|
+ mLine.direction = idx ? MediaDirection.RECVONLY : MediaDirection.SENDRECV;
|
|
|
2276
|
+
|
|
|
2277
|
+ // When there are 2 remote sources and 1 local source, the first m-line should be set to 'sendrecv' while
|
|
|
2278
|
+ // the second one needs to be set to 'sendonly'.
|
|
|
2279
|
+ } else {
|
|
|
2280
|
+ mLine.direction = idx ? MediaDirection.SENDONLY : MediaDirection.SENDRECV;
|
|
|
2281
|
+ }
|
|
|
2282
|
+ });
|
|
2252
|
2283
|
});
|
|
2253
|
2284
|
|
|
2254
|
2285
|
return new RTCSessionDescription({
|
|
|
@@ -2398,34 +2429,13 @@ TraceablePeerConnection.prototype._setVp9MaxBitrates = function(description, isL
|
|
2398
|
2429
|
? parsedSdp.media.filter(m => m.type === MediaType.VIDEO && m.direction !== direction)
|
|
2399
|
2430
|
: [ parsedSdp.media.find(m => m.type === MediaType.VIDEO) ];
|
|
2400
|
2431
|
|
|
2401
|
|
- // Find the mid associated with the desktop track so that bitrates can be configured accordingly on the
|
|
2402
|
|
- // corresponding m-line.
|
|
2403
|
|
- const getDesktopTrackMid = () => {
|
|
2404
|
|
- const desktopTrack = this.getLocalVideoTracks().find(track => track.getVideoType() === VideoType.DESKTOP);
|
|
2405
|
|
- let mid;
|
|
2406
|
|
-
|
|
2407
|
|
- if (desktopTrack) {
|
|
2408
|
|
- const trackIndex = Number(desktopTrack.getSourceName()?.split('-')[1].substring(1));
|
|
2409
|
|
-
|
|
2410
|
|
- if (typeof trackIndex === 'number') {
|
|
2411
|
|
- const transceiver = this.peerconnection.getTransceivers()
|
|
2412
|
|
- .filter(t => t.receiver.track.kind === MediaType.VIDEO
|
|
2413
|
|
- && t.direction !== MediaDirection.RECVONLY)[trackIndex];
|
|
2414
|
|
-
|
|
2415
|
|
- mid = transceiver?.mid;
|
|
2416
|
|
- }
|
|
2417
|
|
- }
|
|
2418
|
|
-
|
|
2419
|
|
- return Number(mid);
|
|
2420
|
|
- };
|
|
2421
|
|
-
|
|
2422
|
2432
|
for (const mLine of mLines) {
|
|
2423
|
2433
|
if (this.codecPreference.mimeType === CodecMimeType.VP9) {
|
|
2424
|
2434
|
const bitrates = this.tpcUtils.videoBitrates.VP9 || this.tpcUtils.videoBitrates;
|
|
2425
|
2435
|
const hdBitrate = bitrates.high ? bitrates.high : HD_BITRATE;
|
|
2426
|
2436
|
const mid = mLine.mid;
|
|
2427
|
2437
|
const isSharingScreen = FeatureFlags.isMultiStreamSupportEnabled()
|
|
2428
|
|
- ? mid === getDesktopTrackMid()
|
|
|
2438
|
+ ? mid === this._getDesktopTrackMid()
|
|
2429
|
2439
|
: this._isSharingScreen();
|
|
2430
|
2440
|
const limit = Math.floor((isSharingScreen ? HD_BITRATE : hdBitrate) / 1000);
|
|
2431
|
2441
|
|
|
|
@@ -2635,7 +2645,12 @@ TraceablePeerConnection.prototype.setSenderVideoConstraints = function(frameHeig
|
|
2635
|
2645
|
}
|
|
2636
|
2646
|
|
|
2637
|
2647
|
if (FeatureFlags.isSourceNameSignalingEnabled()) {
|
|
2638
|
|
- this._senderMaxHeights.set(localVideoTrack.getSourceName(), frameHeight);
|
|
|
2648
|
+ const sourceName = localVideoTrack.getSourceName();
|
|
|
2649
|
+
|
|
|
2650
|
+ if (this._senderMaxHeights.get(sourceName) === frameHeight) {
|
|
|
2651
|
+ return Promise.resolve();
|
|
|
2652
|
+ }
|
|
|
2653
|
+ this._senderMaxHeights.set(sourceName, frameHeight);
|
|
2639
|
2654
|
} else {
|
|
2640
|
2655
|
this._senderVideoMaxHeight = frameHeight;
|
|
2641
|
2656
|
}
|