|
@@ -6,10 +6,6 @@ import transform from 'sdp-transform';
|
6
|
6
|
|
7
|
7
|
import * as GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';
|
8
|
8
|
import JitsiRemoteTrack from './JitsiRemoteTrack';
|
9
|
|
-import {
|
10
|
|
- TRACK_ADDED,
|
11
|
|
- TRACK_MUTE_CHANGED
|
12
|
|
-} from '../../JitsiConferenceEvents';
|
13
|
9
|
import * as MediaType from '../../service/RTC/MediaType';
|
14
|
10
|
import * as VideoType from '../../service/RTC/VideoType';
|
15
|
11
|
import LocalSdpMunger from './LocalSdpMunger';
|
|
@@ -30,7 +26,8 @@ import * as SignalingEvents from '../../service/RTC/SignalingEvents';
|
30
|
26
|
const logger = getLogger(__filename);
|
31
|
27
|
const MAX_BITRATE = 2500000;
|
32
|
28
|
const DESKSTOP_SHARE_RATE = 500000;
|
33
|
|
-
|
|
29
|
+const DEGRADATION_PREFERENCE_CAMERA = 'maintain-framerate';
|
|
30
|
+const DEGRADATION_PREFERENCE_DESKTOP = 'maintain-resolution';
|
34
|
31
|
/* eslint-disable max-params */
|
35
|
32
|
|
36
|
33
|
/**
|
|
@@ -250,6 +247,11 @@ export default function TraceablePeerConnection(
|
250
|
247
|
this.eventEmitter = rtc.eventEmitter;
|
251
|
248
|
this.rtxModifier = new RtxModifier();
|
252
|
249
|
|
|
250
|
+ /**
|
|
251
|
+ * The height constraint applied on the video sender.
|
|
252
|
+ */
|
|
253
|
+ this.senderVideoMaxHeight = null;
|
|
254
|
+
|
253
|
255
|
// override as desired
|
254
|
256
|
this.trace = (what, info) => {
|
255
|
257
|
logger.debug(what, info);
|
|
@@ -340,29 +342,6 @@ export default function TraceablePeerConnection(
|
340
|
342
|
}, 1000);
|
341
|
343
|
}
|
342
|
344
|
|
343
|
|
- // Set sender video constraints when a new local video track is added
|
344
|
|
- // to the conference or when it is unmuted.
|
345
|
|
- this.senderVideoMaxHeight = null;
|
346
|
|
- const maybeSetSenderVideoConstraints = track => {
|
347
|
|
- if (track.isLocal()
|
348
|
|
- && !track.isMuted()
|
349
|
|
- && track.isVideoTrack()
|
350
|
|
- && track.videoType === VideoType.CAMERA
|
351
|
|
- && this.senderVideoMaxHeight) {
|
352
|
|
- this.setSenderVideoConstraint(this.senderVideoMaxHeight)
|
353
|
|
- .catch(err => {
|
354
|
|
- logger.error(`Settings sender video constraints failed: ${err}`);
|
355
|
|
- });
|
356
|
|
- }
|
357
|
|
- };
|
358
|
|
-
|
359
|
|
- this.rtc.conference.on(
|
360
|
|
- TRACK_ADDED,
|
361
|
|
- maybeSetSenderVideoConstraints);
|
362
|
|
- this.rtc.conference.on(
|
363
|
|
- TRACK_MUTE_CHANGED,
|
364
|
|
- maybeSetSenderVideoConstraints);
|
365
|
|
-
|
366
|
345
|
logger.info(`Create new ${this}`);
|
367
|
346
|
}
|
368
|
347
|
|
|
@@ -1916,6 +1895,43 @@ TraceablePeerConnection.prototype.setAudioTransferActive = function(active) {
|
1916
|
1895
|
return changed;
|
1917
|
1896
|
};
|
1918
|
1897
|
|
|
1898
|
+/**
|
|
1899
|
+ * Sets the degradation preference on the video sender. This setting determines if
|
|
1900
|
+ * resolution or framerate will be preferred when bandwidth or cpu is constrained.
|
|
1901
|
+ * Sets it to 'maintain-framerate' when a camera track is added to the pc, sets it
|
|
1902
|
+ * to 'maintain-resolution' when a desktop track is being shared instead.
|
|
1903
|
+ * @returns {void}
|
|
1904
|
+ */
|
|
1905
|
+TraceablePeerConnection.prototype.setSenderVideoDegradationPreference = function() {
|
|
1906
|
+ if (!this.peerconnection.getSenders) {
|
|
1907
|
+ logger.debug('Browser does not support RTCRtpSender');
|
|
1908
|
+
|
|
1909
|
+ return;
|
|
1910
|
+ }
|
|
1911
|
+ const localVideoTrack = Array.from(this.localTracks.values()).find(t => t.isVideoTrack());
|
|
1912
|
+ const videoSender = this.findSenderByKind(MediaType.VIDEO);
|
|
1913
|
+
|
|
1914
|
+ if (!videoSender) {
|
|
1915
|
+ return;
|
|
1916
|
+ }
|
|
1917
|
+ const parameters = videoSender.getParameters();
|
|
1918
|
+
|
|
1919
|
+ if (!parameters.encodings || !parameters.encodings.length) {
|
|
1920
|
+ return;
|
|
1921
|
+ }
|
|
1922
|
+ for (const encoding in parameters.encodings) {
|
|
1923
|
+ if (parameters.encodings.hasOwnProperty(encoding)) {
|
|
1924
|
+ const preference = localVideoTrack.videoType === VideoType.CAMERA
|
|
1925
|
+ ? DEGRADATION_PREFERENCE_CAMERA
|
|
1926
|
+ : DEGRADATION_PREFERENCE_DESKTOP;
|
|
1927
|
+
|
|
1928
|
+ logger.info(`Setting video sender degradation preference on ${this} to ${preference}`);
|
|
1929
|
+ parameters.encodings[encoding].degradationPreference = preference;
|
|
1930
|
+ }
|
|
1931
|
+ }
|
|
1932
|
+ videoSender.setParameters(parameters);
|
|
1933
|
+};
|
|
1934
|
+
|
1919
|
1935
|
/**
|
1920
|
1936
|
* Sets the max bitrate on the RTCRtpSender so that the
|
1921
|
1937
|
* bitrate of the enocder doesn't exceed the configured value.
|
|
@@ -1925,16 +1941,13 @@ TraceablePeerConnection.prototype.setAudioTransferActive = function(active) {
|
1925
|
1941
|
* max bitrate is to be configured.
|
1926
|
1942
|
*/
|
1927
|
1943
|
TraceablePeerConnection.prototype.setMaxBitRate = function(localTrack) {
|
1928
|
|
- const mediaType = localTrack.type;
|
1929
|
1944
|
const trackId = localTrack.track.id;
|
1930
|
1945
|
const videoType = localTrack.videoType;
|
1931
|
1946
|
|
1932
|
1947
|
// No need to set max bitrates on the streams in the following cases.
|
1933
|
|
- // 1. When an audio track has been replaced.
|
1934
|
|
- // 2. When a 'camera' track is replaced in plan-b mode, since its a new sender.
|
1935
|
|
- // 3. When the config.js option for capping the SS bitrate is not enabled.
|
1936
|
|
- if ((mediaType === MediaType.AUDIO)
|
1937
|
|
- || (browser.usesPlanB() && !this.options.capScreenshareBitrate)
|
|
1948
|
+ // 1. When a 'camera' track is replaced in plan-b mode, since its a new sender.
|
|
1949
|
+ // 2. When the config.js option for capping the SS bitrate is not enabled.
|
|
1950
|
+ if ((browser.usesPlanB() && !this.options.capScreenshareBitrate)
|
1938
|
1951
|
|| (browser.usesPlanB() && videoType === VideoType.CAMERA)) {
|
1939
|
1952
|
return;
|
1940
|
1953
|
}
|
|
@@ -2066,8 +2079,13 @@ TraceablePeerConnection.prototype.setRemoteDescription = function(description) {
|
2066
|
2079
|
* @returns {Promise} promise that will be resolved when the operation is
|
2067
|
2080
|
* successful and rejected otherwise.
|
2068
|
2081
|
*/
|
2069
|
|
-TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeight) {
|
2070
|
|
- this.senderVideoMaxHeight = frameHeight;
|
|
2082
|
+TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeight = null) {
|
|
2083
|
+ const newHeight = frameHeight || this.senderVideoMaxHeight;
|
|
2084
|
+
|
|
2085
|
+ this.senderVideoMaxHeight = newHeight;
|
|
2086
|
+ if (!newHeight) {
|
|
2087
|
+ return Promise.resolve();
|
|
2088
|
+ }
|
2071
|
2089
|
const localVideoTrack = Array.from(this.localTracks.values()).find(t => t.isVideoTrack());
|
2072
|
2090
|
|
2073
|
2091
|
if (!localVideoTrack || localVideoTrack.isMuted() || localVideoTrack.videoType !== VideoType.CAMERA) {
|
|
@@ -2093,7 +2111,7 @@ TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeigh
|
2093
|
2111
|
// Determine the encodings that need to stay enabled based on the
|
2094
|
2112
|
// new frameHeight provided.
|
2095
|
2113
|
const encodingsEnabledState = this.tpcUtils.simulcastStreamConstraints
|
2096
|
|
- .map(constraint => constraint.height <= frameHeight);
|
|
2114
|
+ .map(constraint => constraint.height <= newHeight);
|
2097
|
2115
|
const videoSender = this.findSenderByKind(MediaType.VIDEO);
|
2098
|
2116
|
|
2099
|
2117
|
if (!videoSender) {
|
|
@@ -2104,7 +2122,7 @@ TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeigh
|
2104
|
2122
|
if (!parameters || !parameters.encodings || !parameters.encodings.length) {
|
2105
|
2123
|
return Promise.reject(new Error('RTCRtpSendParameters not found for local video track'));
|
2106
|
2124
|
}
|
2107
|
|
- logger.debug(`Setting max height of ${frameHeight} on local video`);
|
|
2125
|
+ logger.debug(`Setting max height of ${newHeight} on local video`);
|
2108
|
2126
|
for (const encoding in parameters.encodings) {
|
2109
|
2127
|
if (parameters.encodings.hasOwnProperty(encoding)) {
|
2110
|
2128
|
parameters.encodings[encoding].active = encodingsEnabledState[encoding];
|
|
@@ -2118,13 +2136,13 @@ TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeigh
|
2118
|
2136
|
// Apply the height constraint on the local camera track
|
2119
|
2137
|
const aspectRatio = (track.getSettings().width / track.getSettings().height).toPrecision(4);
|
2120
|
2138
|
|
2121
|
|
- logger.debug(`Setting max height of ${frameHeight} on local video`);
|
|
2139
|
+ logger.debug(`Setting max height of ${newHeight} on local video`);
|
2122
|
2140
|
|
2123
|
2141
|
return track.applyConstraints(
|
2124
|
2142
|
{
|
2125
|
2143
|
aspectRatio,
|
2126
|
2144
|
height: {
|
2127
|
|
- ideal: frameHeight
|
|
2145
|
+ ideal: newHeight
|
2128
|
2146
|
}
|
2129
|
2147
|
});
|
2130
|
2148
|
};
|