|
|
@@ -23,17 +23,18 @@ import * as GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';
|
|
23
|
23
|
import JitsiRemoteTrack from './JitsiRemoteTrack';
|
|
24
|
24
|
import RTC from './RTC';
|
|
25
|
25
|
import RTCUtils from './RTCUtils';
|
|
26
|
|
-import { SIM_LAYER_RIDS, TPCUtils } from './TPCUtils';
|
|
|
26
|
+import {
|
|
|
27
|
+ HD_BITRATE,
|
|
|
28
|
+ HD_SCALE_FACTOR,
|
|
|
29
|
+ SIM_LAYER_RIDS,
|
|
|
30
|
+ TPCUtils
|
|
|
31
|
+} from './TPCUtils';
|
|
27
|
32
|
|
|
28
|
33
|
// FIXME SDP tools should end up in some kind of util module
|
|
29
|
34
|
|
|
30
|
35
|
const logger = getLogger(__filename);
|
|
31
|
36
|
const DEGRADATION_PREFERENCE_CAMERA = 'maintain-framerate';
|
|
32
|
37
|
const DEGRADATION_PREFERENCE_DESKTOP = 'maintain-resolution';
|
|
33
|
|
-const DESKTOP_SHARE_RATE = 500000;
|
|
34
|
|
-const HD_BITRATE = 2500000;
|
|
35
|
|
-const LD_BITRATE = 200000;
|
|
36
|
|
-const SD_BITRATE = 700000;
|
|
37
|
38
|
|
|
38
|
39
|
/* eslint-disable max-params */
|
|
39
|
40
|
|
|
|
@@ -224,21 +225,7 @@ export default function TraceablePeerConnection(
|
|
224
|
225
|
|
|
225
|
226
|
this.peerconnection = new RTCUtils.RTCPeerConnectionType(pcConfig, safeConstraints);
|
|
226
|
227
|
|
|
227
|
|
- // The standard video bitrates are used in Unified plan when switching
|
|
228
|
|
- // between camera/desktop tracks on the same sender.
|
|
229
|
|
- const standardVideoBitrates = {
|
|
230
|
|
- low: LD_BITRATE,
|
|
231
|
|
- standard: SD_BITRATE,
|
|
232
|
|
- high: HD_BITRATE
|
|
233
|
|
- };
|
|
234
|
|
-
|
|
235
|
|
- // Check if the max. bitrates for video are specified through config.js videoQuality settings.
|
|
236
|
|
- // These bitrates will be applied on all browsers for camera sources in both simulcast and p2p mode.
|
|
237
|
|
- this.videoBitrates = this.options.videoQuality && this.options.videoQuality.maxBitratesVideo
|
|
238
|
|
- ? this.options.videoQuality.maxBitratesVideo
|
|
239
|
|
- : standardVideoBitrates;
|
|
240
|
|
-
|
|
241
|
|
- this.tpcUtils = new TPCUtils(this, this.videoBitrates);
|
|
|
228
|
+ this.tpcUtils = new TPCUtils(this);
|
|
242
|
229
|
this.updateLog = [];
|
|
243
|
230
|
this.stats = {};
|
|
244
|
231
|
this.statsinterval = null;
|
|
|
@@ -293,9 +280,10 @@ export default function TraceablePeerConnection(
|
|
293
|
280
|
this.rtxModifier = new RtxModifier();
|
|
294
|
281
|
|
|
295
|
282
|
/**
|
|
296
|
|
- * The height constraint applied on the video sender.
|
|
|
283
|
+ * The height constraint applied on the video sender. The default value is 2160 (4K) when layer suspension is
|
|
|
284
|
+ * explicitly disabled.
|
|
297
|
285
|
*/
|
|
298
|
|
- this.senderVideoMaxHeight = null;
|
|
|
286
|
+ this._senderVideoMaxHeight = 2160;
|
|
299
|
287
|
|
|
300
|
288
|
// override as desired
|
|
301
|
289
|
this.trace = (what, info) => {
|
|
|
@@ -724,7 +712,7 @@ TraceablePeerConnection.prototype.getRemoteSourceInfoByParticipant = function(id
|
|
724
|
712
|
TraceablePeerConnection.prototype.getTargetVideoBitrates = function() {
|
|
725
|
713
|
const currentCodec = this.getConfiguredVideoCodec();
|
|
726
|
714
|
|
|
727
|
|
- return this.videoBitrates[currentCodec.toUpperCase()] || this.videoBitrates;
|
|
|
715
|
+ return this.tpcUtils.videoBitrates[currentCodec.toUpperCase()] || this.tpcUtils.videoBitrates;
|
|
728
|
716
|
};
|
|
729
|
717
|
|
|
730
|
718
|
/**
|
|
|
@@ -1593,7 +1581,7 @@ TraceablePeerConnection.prototype._getSSRC = function(rtcId) {
|
|
1593
|
1581
|
* @private
|
|
1594
|
1582
|
* @returns {boolean} Returns true if 5 fps screensharing is in progress, false otherwise.
|
|
1595
|
1583
|
*/
|
|
1596
|
|
-TraceablePeerConnection.prototype._isSharingLowFpsScreen = function() {
|
|
|
1584
|
+TraceablePeerConnection.prototype.isSharingLowFpsScreen = function() {
|
|
1597
|
1585
|
return this._isSharingScreen() && this._capScreenshareBitrate;
|
|
1598
|
1586
|
};
|
|
1599
|
1587
|
|
|
|
@@ -1649,7 +1637,7 @@ TraceablePeerConnection.prototype._mungeCodecOrder = function(description) {
|
|
1649
|
1637
|
// as soon as the browser switches to VP9.
|
|
1650
|
1638
|
if (this.codecPreference.mimeType === CodecMimeType.VP9
|
|
1651
|
1639
|
&& this.getConfiguredVideoCodec() === CodecMimeType.VP9) {
|
|
1652
|
|
- const bitrates = this.videoBitrates.VP9 || this.videoBitrates;
|
|
|
1640
|
+ const bitrates = this.tpcUtils.videoBitrates.VP9 || this.tpcUtils.videoBitrates;
|
|
1653
|
1641
|
const hdBitrate = bitrates.high ? bitrates.high : HD_BITRATE;
|
|
1654
|
1642
|
const limit = Math.floor((this._isSharingScreen() ? HD_BITRATE : hdBitrate) / 1000);
|
|
1655
|
1643
|
|
|
|
@@ -2243,6 +2231,15 @@ TraceablePeerConnection.prototype._mungeOpus = function(description) {
|
|
2243
|
2231
|
});
|
|
2244
|
2232
|
};
|
|
2245
|
2233
|
|
|
|
2234
|
+/**
|
|
|
2235
|
+ * Configures the stream encodings depending on the video type and the bitrates configured.
|
|
|
2236
|
+ *
|
|
|
2237
|
+ * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
|
|
|
2238
|
+ */
|
|
|
2239
|
+TraceablePeerConnection.prototype.configureSenderVideoEncodings = function() {
|
|
|
2240
|
+ return this.setSenderVideoConstraints(this._senderVideoMaxHeight);
|
|
|
2241
|
+};
|
|
|
2242
|
+
|
|
2246
|
2243
|
TraceablePeerConnection.prototype.setLocalDescription = function(description) {
|
|
2247
|
2244
|
let localSdp = description;
|
|
2248
|
2245
|
|
|
|
@@ -2319,131 +2316,6 @@ TraceablePeerConnection.prototype.setAudioTransferActive = function(active) {
|
|
2319
|
2316
|
return changed;
|
|
2320
|
2317
|
};
|
|
2321
|
2318
|
|
|
2322
|
|
-/**
|
|
2323
|
|
- * Sets the degradation preference on the video sender. This setting determines if
|
|
2324
|
|
- * resolution or framerate will be preferred when bandwidth or cpu is constrained.
|
|
2325
|
|
- * Sets it to 'maintain-framerate' when a camera track is added to the pc, sets it
|
|
2326
|
|
- * to 'maintain-resolution' when a desktop track is being shared instead.
|
|
2327
|
|
- * @returns {Promise<void>}
|
|
2328
|
|
- */
|
|
2329
|
|
-TraceablePeerConnection.prototype.setSenderVideoDegradationPreference = function() {
|
|
2330
|
|
- if (!this.peerconnection.getSenders) {
|
|
2331
|
|
- logger.debug(`${this} Browser does not support RTCRtpSender`);
|
|
2332
|
|
-
|
|
2333
|
|
- return Promise.resolve();
|
|
2334
|
|
- }
|
|
2335
|
|
- const localVideoTrack = this.getLocalVideoTrack();
|
|
2336
|
|
- const videoSender = this.findSenderByKind(MediaType.VIDEO);
|
|
2337
|
|
-
|
|
2338
|
|
- if (!videoSender) {
|
|
2339
|
|
- return Promise.resolve();
|
|
2340
|
|
- }
|
|
2341
|
|
- const parameters = videoSender.getParameters();
|
|
2342
|
|
- const preference = this._isSharingLowFpsScreen()
|
|
2343
|
|
-
|
|
2344
|
|
- // Prefer resolution for low fps share.
|
|
2345
|
|
- ? DEGRADATION_PREFERENCE_DESKTOP
|
|
2346
|
|
-
|
|
2347
|
|
- // Prefer frame-rate for high fps share and camera.
|
|
2348
|
|
- : DEGRADATION_PREFERENCE_CAMERA;
|
|
2349
|
|
-
|
|
2350
|
|
- logger.info(`${this} Setting a degradation preference [preference=${preference},track=${localVideoTrack}`);
|
|
2351
|
|
- parameters.degradationPreference = preference;
|
|
2352
|
|
- this.tpcUtils.updateEncodingsResolution(parameters);
|
|
2353
|
|
-
|
|
2354
|
|
- return videoSender.setParameters(parameters);
|
|
2355
|
|
-};
|
|
2356
|
|
-
|
|
2357
|
|
-/**
|
|
2358
|
|
- * Sets the max bitrate on the RTCRtpSender so that the
|
|
2359
|
|
- * bitrate of the enocder doesn't exceed the configured value.
|
|
2360
|
|
- * This is needed for the desktop share until spec-complaint
|
|
2361
|
|
- * simulcast is implemented.
|
|
2362
|
|
- * @param {JitsiLocalTrack} localTrack - the local track whose
|
|
2363
|
|
- * max bitrate is to be configured.
|
|
2364
|
|
- * @returns {Promise<void>}
|
|
2365
|
|
- */
|
|
2366
|
|
-TraceablePeerConnection.prototype.setMaxBitRate = function() {
|
|
2367
|
|
- // For VP9, max bitrate is configured by setting b=AS value in SDP. Browsers do
|
|
2368
|
|
- // not yet support setting max bitrates for individual VP9 SVC layers.
|
|
2369
|
|
- if (this.getConfiguredVideoCodec() === CodecMimeType.VP9 || !window.RTCRtpSender) {
|
|
2370
|
|
- return Promise.resolve();
|
|
2371
|
|
- }
|
|
2372
|
|
- const localVideoTrack = this.getLocalVideoTrack();
|
|
2373
|
|
-
|
|
2374
|
|
- if (!localVideoTrack) {
|
|
2375
|
|
- return Promise.resolve();
|
|
2376
|
|
- }
|
|
2377
|
|
-
|
|
2378
|
|
- const videoType = localVideoTrack.getVideoType();
|
|
2379
|
|
-
|
|
2380
|
|
- // Apply the maxbitrates on the video track when one of the conditions is met.
|
|
2381
|
|
- // 1. Max. bitrates for video are specified through videoQuality settings in config.js
|
|
2382
|
|
- // 2. Track is a low fps desktop track.
|
|
2383
|
|
- // 3. The client is running in Unified plan mode (the same sender is re-used for different types
|
|
2384
|
|
- // of tracks so bitrates have to be configured whenever the local tracks are replaced).
|
|
2385
|
|
- if (!(this.options?.videoQuality?.maxBitratesVideo || this._isSharingLowFpsScreen() || this._usesUnifiedPlan)) {
|
|
2386
|
|
- return Promise.resolve();
|
|
2387
|
|
- }
|
|
2388
|
|
-
|
|
2389
|
|
- const presenterEnabled = localVideoTrack._originalStream
|
|
2390
|
|
- && localVideoTrack._originalStream.id !== localVideoTrack.getStreamId();
|
|
2391
|
|
- const videoSender = this.findSenderByKind(MediaType.VIDEO);
|
|
2392
|
|
-
|
|
2393
|
|
- if (!videoSender) {
|
|
2394
|
|
- return Promise.resolve();
|
|
2395
|
|
- }
|
|
2396
|
|
- const parameters = videoSender.getParameters();
|
|
2397
|
|
-
|
|
2398
|
|
- if (!parameters.encodings?.length) {
|
|
2399
|
|
- return Promise.resolve();
|
|
2400
|
|
- }
|
|
2401
|
|
-
|
|
2402
|
|
- if (this.isSimulcastOn()) {
|
|
2403
|
|
- for (const encoding in parameters.encodings) {
|
|
2404
|
|
- if (parameters.encodings.hasOwnProperty(encoding)) {
|
|
2405
|
|
- const bitrate = this._isSharingLowFpsScreen()
|
|
2406
|
|
-
|
|
2407
|
|
- // For low fps screensharing, set a max bitrate of 500 Kbps when presenter is not turned on.
|
|
2408
|
|
- // FIXME the top 'isSimulcastOn' condition is confusing for screensharing, because
|
|
2409
|
|
- // if capScreenshareBitrate option is enabled then simulcast is turned off for the stream.
|
|
2410
|
|
- ? presenterEnabled ? HD_BITRATE : DESKTOP_SHARE_RATE
|
|
2411
|
|
-
|
|
2412
|
|
- // For high fps screenshare, 'maxBitrate' setting must be cleared on Chrome, because if simulcast is
|
|
2413
|
|
- // enabled for screen and maxBitrates are set then Chrome will not send the desktop stream.
|
|
2414
|
|
- : videoType === VideoType.DESKTOP && browser.isChromiumBased()
|
|
2415
|
|
- ? undefined
|
|
2416
|
|
- : this.tpcUtils.localStreamEncodingsConfig[encoding].maxBitrate;
|
|
2417
|
|
-
|
|
2418
|
|
- logger.info(`${this} Setting a max bitrate of ${bitrate} bps on layer `
|
|
2419
|
|
- + `${this.tpcUtils.localStreamEncodingsConfig[encoding].rid}`);
|
|
2420
|
|
- parameters.encodings[encoding].maxBitrate = bitrate;
|
|
2421
|
|
- }
|
|
2422
|
|
- }
|
|
2423
|
|
- } else {
|
|
2424
|
|
- // Do not change the max bitrate for desktop tracks in non-simulcast mode.
|
|
2425
|
|
- let bitrate = this.getTargetVideoBitrates()?.high;
|
|
2426
|
|
-
|
|
2427
|
|
- if (videoType === VideoType.CAMERA) {
|
|
2428
|
|
- // Determine the bitrates based on the sender constraint applied for unicast tracks.
|
|
2429
|
|
- const scaleFactor = this.senderVideoMaxHeight
|
|
2430
|
|
- ? Math.floor(localVideoTrack.resolution / this.senderVideoMaxHeight)
|
|
2431
|
|
- : 1;
|
|
2432
|
|
- const encoding = this.tpcUtils.localStreamEncodingsConfig
|
|
2433
|
|
- .find(layer => layer.scaleResolutionDownBy === scaleFactor);
|
|
2434
|
|
-
|
|
2435
|
|
- if (encoding) {
|
|
2436
|
|
- logger.info(`${this} Setting max bitrate=${encoding.maxBitrate} bps on track=${localVideoTrack}`);
|
|
2437
|
|
- bitrate = encoding.maxBitrate;
|
|
2438
|
|
- }
|
|
2439
|
|
- }
|
|
2440
|
|
- parameters.encodings[0].maxBitrate = bitrate;
|
|
2441
|
|
- }
|
|
2442
|
|
- this.tpcUtils.updateEncodingsResolution(parameters);
|
|
2443
|
|
-
|
|
2444
|
|
- return videoSender.setParameters(parameters);
|
|
2445
|
|
-};
|
|
2446
|
|
-
|
|
2447
|
2319
|
TraceablePeerConnection.prototype.setRemoteDescription = function(description) {
|
|
2448
|
2320
|
this.trace('setRemoteDescription::preTransform', dumpSDP(description));
|
|
2449
|
2321
|
|
|
|
@@ -2519,16 +2391,14 @@ TraceablePeerConnection.prototype.setRemoteDescription = function(description) {
|
|
2519
|
2391
|
};
|
|
2520
|
2392
|
|
|
2521
|
2393
|
/**
|
|
2522
|
|
- * Changes the resolution of the video stream that is sent to the peer based on
|
|
2523
|
|
- * the user preferred value. If simulcast is enabled on the peerconection, all the
|
|
2524
|
|
- * simulcast encodings that have a resolution height lower or equal to the value
|
|
2525
|
|
- * provided will remain active. For the non-simulcast case, video constraint is
|
|
2526
|
|
- * applied on the track.
|
|
2527
|
|
- * @param {number} frameHeight - The user preferred max frame height.
|
|
2528
|
|
- * @returns {Promise} promise that will be resolved when the operation is
|
|
2529
|
|
- * successful and rejected otherwise.
|
|
|
2394
|
+ * Changes the resolution of the video stream that is sent to the peer based on the resolution requested by the peer
|
|
|
2395
|
+ * and user preference, sets the degradation preference on the sender based on the video type, configures the maximum
|
|
|
2396
|
+ * bitrates on the send stream.
|
|
|
2397
|
+ *
|
|
|
2398
|
+ * @param {number} frameHeight - The max frame height to be imposed on the outgoing video stream.
|
|
|
2399
|
+ * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
|
|
2530
|
2400
|
*/
|
|
2531
|
|
-TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeight = null) {
|
|
|
2401
|
+TraceablePeerConnection.prototype.setSenderVideoConstraints = function(frameHeight) {
|
|
2532
|
2402
|
if (frameHeight < 0) {
|
|
2533
|
2403
|
throw new Error(`Invalid frameHeight: ${frameHeight}`);
|
|
2534
|
2404
|
}
|
|
|
@@ -2538,20 +2408,7 @@ TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeigh
|
|
2538
|
2408
|
return Promise.resolve();
|
|
2539
|
2409
|
}
|
|
2540
|
2410
|
|
|
2541
|
|
- // Need to explicitly check for null as 0 is falsy, but a valid value
|
|
2542
|
|
- const newHeight = frameHeight === null ? this.senderVideoMaxHeight : frameHeight;
|
|
2543
|
|
-
|
|
2544
|
|
- this.senderVideoMaxHeight = newHeight;
|
|
2545
|
|
-
|
|
2546
|
|
- // If layer suspension is disabled and sender constraint is not configured for the conference,
|
|
2547
|
|
- // resolve here so that the encodings stay enabled. This can happen in custom apps built using
|
|
2548
|
|
- // lib-jitsi-meet.
|
|
2549
|
|
- if (newHeight === null) {
|
|
2550
|
|
- return Promise.resolve();
|
|
2551
|
|
- }
|
|
2552
|
|
-
|
|
2553
|
|
- logger.log(`${this} senderVideoMaxHeight: ${newHeight}`);
|
|
2554
|
|
-
|
|
|
2411
|
+ this._senderVideoMaxHeight = frameHeight;
|
|
2555
|
2412
|
const localVideoTrack = this.getLocalVideoTrack();
|
|
2556
|
2413
|
|
|
2557
|
2414
|
if (!localVideoTrack || localVideoTrack.isMuted()) {
|
|
|
@@ -2568,62 +2425,71 @@ TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeigh
|
|
2568
|
2425
|
return Promise.resolve();
|
|
2569
|
2426
|
}
|
|
2570
|
2427
|
|
|
2571
|
|
- if (this.isSimulcastOn()) {
|
|
2572
|
|
- // Determine the encodings that need to stay enabled based on the new frameHeight provided.
|
|
2573
|
|
- this.encodingsEnabledState = this.tpcUtils.getLocalStreamHeightConstraints(localVideoTrack.track)
|
|
2574
|
|
- .map(height => height <= newHeight);
|
|
2575
|
|
-
|
|
2576
|
|
- // Always keep the LD stream enabled, specifically when the LD stream's resolution is higher than of the
|
|
2577
|
|
- // requested resolution. This can happen when camera is captured at resolutions higher than 720p but the
|
|
2578
|
|
- // requested resolution is 180. Since getParameters doesn't give us information about the resolutions
|
|
2579
|
|
- // of the simulcast encodings, we have to rely on our initial config for the simulcast streams.
|
|
2580
|
|
- const ldStreamIndex = this.tpcUtils.localStreamEncodingsConfig
|
|
2581
|
|
- .findIndex(layer => layer.scaleResolutionDownBy === 4.0);
|
|
2582
|
|
-
|
|
2583
|
|
- if (newHeight > 0 && ldStreamIndex !== -1) {
|
|
2584
|
|
- this.encodingsEnabledState[ldStreamIndex] = true;
|
|
2585
|
|
- }
|
|
|
2428
|
+ // Set the degradation preference.
|
|
|
2429
|
+ const preference = this.isSharingLowFpsScreen()
|
|
|
2430
|
+ ? DEGRADATION_PREFERENCE_DESKTOP // Prefer resolution for low fps share.
|
|
|
2431
|
+ : DEGRADATION_PREFERENCE_CAMERA; // Prefer frame-rate for high fps share and camera.
|
|
2586
|
2432
|
|
|
2587
|
|
- // Disable the lower spatial layers for screensharing in Unified plan when low fps screensharing is in progress
|
|
2588
|
|
- // There is no way to enable or disable simulcast during the call since we are re-using the same sender.
|
|
2589
|
|
- // Safari is an exception here since it does not send the desktop stream at all if only the high resolution
|
|
2590
|
|
- // stream is enabled.
|
|
2591
|
|
- if (this._isSharingLowFpsScreen() && this._usesUnifiedPlan && !browser.isWebKitBased()) {
|
|
2592
|
|
- const highResolutionEncoding = browser.isFirefox() ? 0 : this.encodingsEnabledState.length - 1;
|
|
|
2433
|
+ parameters.degradationPreference = preference;
|
|
|
2434
|
+ logger.info(`${this} Setting degradation preference [preference=${preference},track=${localVideoTrack}`);
|
|
2593
|
2435
|
|
|
2594
|
|
- this.encodingsEnabledState = this.encodingsEnabledState
|
|
2595
|
|
- .map((encoding, idx) => idx === highResolutionEncoding);
|
|
2596
|
|
- }
|
|
|
2436
|
+ // Calculate the encodings active state based on the resolution requested by the bridge.
|
|
|
2437
|
+ this.encodingsEnabledState = this.tpcUtils.calculateEncodingsActiveState(localVideoTrack, frameHeight);
|
|
|
2438
|
+ const maxBitrates = this.tpcUtils.calculateEncodingsBitrates(localVideoTrack);
|
|
|
2439
|
+ const videoType = localVideoTrack.getVideoType();
|
|
2597
|
2440
|
|
|
|
2441
|
+ if (this.isSimulcastOn()) {
|
|
2598
|
2442
|
for (const encoding in parameters.encodings) {
|
|
2599
|
2443
|
if (parameters.encodings.hasOwnProperty(encoding)) {
|
|
2600
|
2444
|
parameters.encodings[encoding].active = this.encodingsEnabledState[encoding];
|
|
|
2445
|
+
|
|
|
2446
|
+ // Firefox doesn't follow the spec and lets application specify the degradation preference on the
|
|
|
2447
|
+ // encodings.
|
|
|
2448
|
+ browser.isFirefox() && (parameters.encodings[encoding].degradationPreference = preference);
|
|
|
2449
|
+
|
|
|
2450
|
+ // Max bitrates are configured on the encodings only for VP8.
|
|
|
2451
|
+ if (this.getConfiguredVideoCodec() === CodecMimeType.VP8
|
|
|
2452
|
+ && (this.options?.videoQuality?.maxBitratesVideo
|
|
|
2453
|
+ || this.isSharingLowFpsScreen()
|
|
|
2454
|
+ || this._usesUnifiedPlan)) {
|
|
|
2455
|
+ parameters.encodings[encoding].maxBitrate = maxBitrates[encoding];
|
|
|
2456
|
+ }
|
|
2601
|
2457
|
}
|
|
2602
|
2458
|
}
|
|
2603
|
2459
|
this.tpcUtils.updateEncodingsResolution(parameters);
|
|
2604
|
|
- } else if (newHeight > 0) {
|
|
|
2460
|
+
|
|
|
2461
|
+ // For p2p and cases and where simulcast is explicitly disabled.
|
|
|
2462
|
+ } else if (frameHeight > 0) {
|
|
2605
|
2463
|
// Do not scale down encodings for desktop tracks for non-simulcast case.
|
|
2606
|
|
- parameters.encodings[0].scaleResolutionDownBy
|
|
2607
|
|
- = localVideoTrack.videoType === VideoType.DESKTOP || localVideoTrack.resolution <= newHeight
|
|
2608
|
|
- ? 1
|
|
2609
|
|
- : Math.floor(localVideoTrack.resolution / newHeight);
|
|
|
2464
|
+ const scaleFactor = videoType === VideoType.DESKTOP || localVideoTrack.resolution <= frameHeight
|
|
|
2465
|
+ ? HD_SCALE_FACTOR
|
|
|
2466
|
+ : Math.floor(localVideoTrack.resolution / frameHeight);
|
|
|
2467
|
+
|
|
2610
|
2468
|
parameters.encodings[0].active = true;
|
|
|
2469
|
+ parameters.encodings[0].scaleResolutionDownBy = scaleFactor;
|
|
|
2470
|
+
|
|
|
2471
|
+ // Firefox doesn't follow the spec and lets application specify the degradation preference on the encodings.
|
|
|
2472
|
+ browser.isFirefox() && (parameters.encodings[0].degradationPreference = preference);
|
|
|
2473
|
+
|
|
|
2474
|
+ // Configure the bitrate.
|
|
|
2475
|
+ if (this.getConfiguredVideoCodec() === CodecMimeType.VP8 && this.options?.videoQuality?.maxBitratesVideo) {
|
|
|
2476
|
+ let bitrate = this.getTargetVideoBitrates()?.high;
|
|
|
2477
|
+
|
|
|
2478
|
+ if (videoType === VideoType.CAMERA) {
|
|
|
2479
|
+ bitrate = this.tpcUtils.localStreamEncodingsConfig
|
|
|
2480
|
+ .find(layer => layer.scaleResolutionDownBy === scaleFactor)?.maxBitrate ?? bitrate;
|
|
|
2481
|
+ }
|
|
|
2482
|
+ parameters.encodings[0].maxBitrate = bitrate;
|
|
|
2483
|
+ }
|
|
2611
|
2484
|
} else {
|
|
2612
|
|
- parameters.encodings[0].scaleResolutionDownBy = undefined;
|
|
2613
|
2485
|
parameters.encodings[0].active = false;
|
|
2614
|
2486
|
}
|
|
2615
|
2487
|
|
|
2616
|
|
- logger.info(`${this} setting max height=${newHeight},encodings=${JSON.stringify(parameters.encodings)}`);
|
|
|
2488
|
+ logger.info(`${this} setting max height=${frameHeight},encodings=${JSON.stringify(parameters.encodings)}`);
|
|
2617
|
2489
|
|
|
2618
|
2490
|
return videoSender.setParameters(parameters).then(() => {
|
|
2619
|
|
- localVideoTrack.maxEnabledResolution = newHeight;
|
|
|
2491
|
+ localVideoTrack.maxEnabledResolution = frameHeight;
|
|
2620
|
2492
|
this.eventEmitter.emit(RTCEvents.LOCAL_TRACK_MAX_ENABLED_RESOLUTION_CHANGED, localVideoTrack);
|
|
2621
|
|
-
|
|
2622
|
|
- // Max bitrate needs to be reconfigured on the sender in p2p/non-simulcast case if needed when
|
|
2623
|
|
- // the send resolution changes.
|
|
2624
|
|
- if (this.isP2P || !this.isSimulcastOn()) {
|
|
2625
|
|
- return this.setMaxBitRate();
|
|
2626
|
|
- }
|
|
2627
|
2493
|
});
|
|
2628
|
2494
|
};
|
|
2629
|
2495
|
|
|
|
@@ -2827,7 +2693,7 @@ TraceablePeerConnection.prototype._createOfferOrAnswer = function(
|
|
2827
|
2693
|
if (this.isSimulcastOn() && browser.usesSdpMungingForSimulcast()
|
|
2828
|
2694
|
&& (localVideoTrack?.getVideoType() === VideoType.CAMERA
|
|
2829
|
2695
|
|| this._usesUnifiedPlan
|
|
2830
|
|
- || !this._isSharingLowFpsScreen())) {
|
|
|
2696
|
+ || !this.isSharingLowFpsScreen())) {
|
|
2831
|
2697
|
// eslint-disable-next-line no-param-reassign
|
|
2832
|
2698
|
resultSdp = this.simulcast.mungeLocalDescription(resultSdp);
|
|
2833
|
2699
|
this.trace(
|
|
|
@@ -3029,7 +2895,7 @@ TraceablePeerConnection.prototype.generateNewStreamSSRCInfo = function(track) {
|
|
3029
|
2895
|
|
|
3030
|
2896
|
// Configure simulcast for camera tracks and desktop tracks that need simulcast.
|
|
3031
|
2897
|
if (this.isSimulcastOn()
|
|
3032
|
|
- && (track.getVideoType() === VideoType.CAMERA || !this._isSharingLowFpsScreen())) {
|
|
|
2898
|
+ && (track.getVideoType() === VideoType.CAMERA || !this.isSharingLowFpsScreen())) {
|
|
3033
|
2899
|
ssrcInfo = {
|
|
3034
|
2900
|
ssrcs: [],
|
|
3035
|
2901
|
groups: []
|