瀏覽代碼

feat(multi-stream-support) Configure the senders based on SenderVideoConstraintsV2.

The encodings for local video tracks are confiugured based on the SenderVideoConstraintsV2 constraints received from the bridge. The constraints are sourceName based. Also ignore enableLayerSuspension flag since it has been deprecated and layer suspension has been enabled by default. Also having it off makes screensharing on Chrome in unified plan not work as expected.
dev1
Jaya Allamsetty 3 年之前
父節點
當前提交
b749b0e4e7

+ 8
- 0
JitsiConference.js 查看文件

882
     return this.rtc ? this.rtc.getLocalVideoTrack() : null;
882
     return this.rtc ? this.rtc.getLocalVideoTrack() : null;
883
 };
883
 };
884
 
884
 
885
+/**
886
+ * Returns all the local video tracks.
887
+ * @returns {Array<JitsiLocalTrack>}
888
+ */
889
+JitsiConference.prototype.getLocalVideoTracks = function() {
890
+    return this.rtc ? this.rtc.getLocalVideoTracks() : null;
891
+};
892
+
885
 /**
893
 /**
886
  * Obtains the performance statistics.
894
  * Obtains the performance statistics.
887
  * @returns {Object|null}
895
  * @returns {Object|null}

+ 20
- 0
modules/RTC/BridgeChannel.js 查看文件

2
 
2
 
3
 import RTCEvents from '../../service/RTC/RTCEvents';
3
 import RTCEvents from '../../service/RTC/RTCEvents';
4
 import { createBridgeChannelClosedEvent } from '../../service/statistics/AnalyticsEvents';
4
 import { createBridgeChannelClosedEvent } from '../../service/statistics/AnalyticsEvents';
5
+import FeatureFlags from '../flags/FeatureFlags';
5
 import Statistics from '../statistics/statistics';
6
 import Statistics from '../statistics/statistics';
6
 import GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';
7
 import GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';
7
 
8
 
375
                 }
376
                 }
376
                 break;
377
                 break;
377
             }
378
             }
379
+            case 'SenderVideoConstraintsV2': {
380
+                if (FeatureFlags.isSourceNameSignalingEnabled()) {
381
+                    const { sourceName, idealHeight } = obj;
382
+
383
+                    if (typeof sourceName === 'string' && typeof idealHeight === 'number') {
384
+                        // eslint-disable-next-line object-property-newline
385
+                        logger.info(`SenderVideoConstraintsV2: ${JSON.stringify({ sourceName, idealHeight })}`);
386
+                        emitter.emit(
387
+                            RTCEvents.SENDER_VIDEO_CONSTRAINTS_CHANGED, {
388
+                                sourceName,
389
+                                idealHeight
390
+                            }
391
+                        );
392
+                    } else {
393
+                        logger.error(`Invalid SenderVideoConstraintsV2: ${JSON.stringify(obj)}`);
394
+                    }
395
+                }
396
+                break;
397
+            }
378
             case 'ServerHello': {
398
             case 'ServerHello': {
379
                 logger.info(`Received ServerHello, version=${obj.version}.`);
399
                 logger.info(`Received ServerHello, version=${obj.version}.`);
380
                 break;
400
                 break;

+ 8
- 0
modules/RTC/RTC.js 查看文件

561
         return localVideo.length ? localVideo[0] : undefined;
561
         return localVideo.length ? localVideo[0] : undefined;
562
     }
562
     }
563
 
563
 
564
+    /**
565
+     * Returns all the local video tracks.
566
+     * @returns {Array<JitsiLocalTrack>}
567
+     */
568
+    getLocalVideoTracks() {
569
+        return this.getLocalTracks(MediaType.VIDEO);
570
+    }
571
+
564
     /**
572
     /**
565
      * Get local audio track.
573
      * Get local audio track.
566
      * @returns {JitsiLocalTrack|undefined}
574
      * @returns {JitsiLocalTrack|undefined}

+ 38
- 6
modules/RTC/TraceablePeerConnection.js 查看文件

297
      */
297
      */
298
     this._senderVideoMaxHeight = 2160;
298
     this._senderVideoMaxHeight = 2160;
299
 
299
 
300
+    /**
301
+     * The height constraints to be applied on the sender per local video source (source name as the key).
302
+     * @type {Map<string, number>}
303
+     */
304
+    this._senderMaxHeights = new Map();
305
+
300
     // override as desired
306
     // override as desired
301
     this.trace = (what, info) => {
307
     this.trace = (what, info) => {
302
         logger.debug(what, info);
308
         logger.debug(what, info);
2249
 /**
2255
 /**
2250
  * Configures the stream encodings depending on the video type and the bitrates configured.
2256
  * Configures the stream encodings depending on the video type and the bitrates configured.
2251
  *
2257
  *
2258
+ * @param {JitsiLocalTrack} - The local track for which the sender encodings have to configured.
2252
  * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
2259
  * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
2253
  */
2260
  */
2254
-TraceablePeerConnection.prototype.configureSenderVideoEncodings = function() {
2255
-    return this.setSenderVideoConstraints(this._senderVideoMaxHeight);
2261
+TraceablePeerConnection.prototype.configureSenderVideoEncodings = function(localVideoTrack = null) {
2262
+    if (FeatureFlags.isSourceNameSignalingEnabled()) {
2263
+        if (localVideoTrack) {
2264
+            return this.setSenderVideoConstraints(
2265
+                this._senderMaxHeights.get(localVideoTrack.getSourceName()),
2266
+                localVideoTrack);
2267
+        }
2268
+        const promises = [];
2269
+
2270
+        for (const track of this.getLocalVideoTracks()) {
2271
+            promises.push(this.setSenderVideoConstraints(this._senderMaxHeights.get(track.getSourceName()), track));
2272
+        }
2273
+
2274
+        return Promise.allSettled(promises);
2275
+    }
2276
+
2277
+    let localTrack = localVideoTrack;
2278
+
2279
+    if (!localTrack) {
2280
+        localTrack = this.getLocalVideoTracks()[0];
2281
+    }
2282
+
2283
+    return this.setSenderVideoConstraints(this._senderVideoMaxHeight, localTrack);
2256
 };
2284
 };
2257
 
2285
 
2258
 TraceablePeerConnection.prototype.setLocalDescription = function(description) {
2286
 TraceablePeerConnection.prototype.setLocalDescription = function(description) {
2395
  * bitrates on the send stream.
2423
  * bitrates on the send stream.
2396
  *
2424
  *
2397
  * @param {number} frameHeight - The max frame height to be imposed on the outgoing video stream.
2425
  * @param {number} frameHeight - The max frame height to be imposed on the outgoing video stream.
2426
+ * @param {JitsiLocalTrack} - The local track for which the sender constraints have to be applied.
2398
  * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
2427
  * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
2399
  */
2428
  */
2400
-TraceablePeerConnection.prototype.setSenderVideoConstraints = function(frameHeight) {
2429
+TraceablePeerConnection.prototype.setSenderVideoConstraints = function(frameHeight, localVideoTrack) {
2401
     if (frameHeight < 0) {
2430
     if (frameHeight < 0) {
2402
         throw new Error(`Invalid frameHeight: ${frameHeight}`);
2431
         throw new Error(`Invalid frameHeight: ${frameHeight}`);
2403
     }
2432
     }
2407
         return Promise.resolve();
2436
         return Promise.resolve();
2408
     }
2437
     }
2409
 
2438
 
2410
-    this._senderVideoMaxHeight = frameHeight;
2411
-    const localVideoTrack = this.getLocalVideoTracks()[0];
2439
+    if (FeatureFlags.isSourceNameSignalingEnabled()) {
2440
+        this._senderMaxHeights.set(localVideoTrack.getSourceName(), frameHeight);
2441
+    } else {
2442
+        this._senderVideoMaxHeight = frameHeight;
2443
+    }
2412
 
2444
 
2413
     if (!localVideoTrack || localVideoTrack.isMuted()) {
2445
     if (!localVideoTrack || localVideoTrack.isMuted()) {
2414
         return Promise.resolve();
2446
         return Promise.resolve();
2415
     }
2447
     }
2416
-    const videoSender = this.findSenderByKind(MediaType.VIDEO);
2448
+    const videoSender = this.findSenderForTrack(localVideoTrack.getTrack());
2417
 
2449
 
2418
     if (!videoSender) {
2450
     if (!videoSender) {
2419
         return Promise.resolve();
2451
         return Promise.resolve();

+ 53
- 25
modules/qualitycontrol/SendVideoController.js 查看文件

1
 import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
1
 import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
2
 import RTCEvents from '../../service/RTC/RTCEvents';
2
 import RTCEvents from '../../service/RTC/RTCEvents';
3
+import FeatureFlags from '../flags/FeatureFlags';
3
 import MediaSessionEvents from '../xmpp/MediaSessionEvents';
4
 import MediaSessionEvents from '../xmpp/MediaSessionEvents';
4
 
5
 
5
 /**
6
 /**
18
      * @param {RTC} rtc - the rtc instance that is responsible for sending the messages on the bridge channel.
19
      * @param {RTC} rtc - the rtc instance that is responsible for sending the messages on the bridge channel.
19
      */
20
      */
20
     constructor(conference, rtc) {
21
     constructor(conference, rtc) {
21
-        this.conference = conference;
22
-        this.layerSuspensionEnabled = conference.options?.config?.enableLayerSuspension ?? true;
23
-        this.rtc = rtc;
24
-        this.conference.on(
22
+        this._conference = conference;
23
+        this._rtc = rtc;
24
+
25
+        /**
26
+         * Source name based sender constraints.
27
+         * @type {Map<string, number>};
28
+         */
29
+
30
+        this._sourceSenderConstraints = new Map();
31
+        this._conference.on(
25
             JitsiConferenceEvents._MEDIA_SESSION_STARTED,
32
             JitsiConferenceEvents._MEDIA_SESSION_STARTED,
26
             session => this._onMediaSessionStarted(session));
33
             session => this._onMediaSessionStarted(session));
27
-        this.conference.on(
34
+        this._conference.on(
28
             JitsiConferenceEvents._MEDIA_SESSION_ACTIVE_CHANGED,
35
             JitsiConferenceEvents._MEDIA_SESSION_ACTIVE_CHANGED,
29
             () => this._propagateSendMaxFrameHeight());
36
             () => this._propagateSendMaxFrameHeight());
30
-        this.rtc.on(
37
+        this._rtc.on(
31
             RTCEvents.SENDER_VIDEO_CONSTRAINTS_CHANGED,
38
             RTCEvents.SENDER_VIDEO_CONSTRAINTS_CHANGED,
32
-            videoConstraints => {
33
-                // Propagate the sender constraint only if it has changed.
34
-                if (this._senderVideoConstraints?.idealHeight !== videoConstraints.idealHeight) {
35
-                    this._senderVideoConstraints = videoConstraints;
36
-                    this._propagateSendMaxFrameHeight();
37
-                }
38
-            });
39
+            videoConstraints => this._onSenderConstraintsReceived(videoConstraints));
39
     }
40
     }
40
 
41
 
41
     /**
42
     /**
50
         mediaSession.addListener(
51
         mediaSession.addListener(
51
             MediaSessionEvents.REMOTE_VIDEO_CONSTRAINTS_CHANGED,
52
             MediaSessionEvents.REMOTE_VIDEO_CONSTRAINTS_CHANGED,
52
             session => {
53
             session => {
53
-                if (session === this.conference.getActiveMediaSession()) {
54
+                if (session === this._conference.getActiveMediaSession()) {
54
                     this._propagateSendMaxFrameHeight();
55
                     this._propagateSendMaxFrameHeight();
55
                 }
56
                 }
56
             });
57
             });
57
     }
58
     }
58
 
59
 
60
+    /**
61
+     * Propagates the video constraints if they have changed.
62
+     *
63
+     * @param {Object} videoConstraints - The sender video constraints received from the bridge.
64
+     */
65
+    _onSenderConstraintsReceived(videoConstraints) {
66
+        if (FeatureFlags.isSourceNameSignalingEnabled()) {
67
+            const { idealHeight, sourceName } = videoConstraints;
68
+            const localVideoTracks = this._conference.getLocalVideoTracks() ?? [];
69
+
70
+            for (const track of localVideoTracks) {
71
+                // Propagate the sender constraint only if it has changed.
72
+                if (track.getSourceName() === sourceName
73
+                    && (!this._sourceSenderConstraints.has(sourceName)
74
+                    || this._sourceSenderConstraints.get(sourceName) !== idealHeight)) {
75
+                    this._sourceSenderConstraints.set(sourceName, idealHeight);
76
+                    this._propagateSendMaxFrameHeight(sourceName);
77
+                }
78
+            }
79
+        } else if (this._senderVideoConstraints?.idealHeight !== videoConstraints.idealHeight) {
80
+            this._senderVideoConstraints = videoConstraints;
81
+            this._propagateSendMaxFrameHeight();
82
+        }
83
+    }
84
+
59
     /**
85
     /**
60
      * Figures out the send video constraint as specified by {@link selectSendMaxFrameHeight} and sets it on all media
86
      * Figures out the send video constraint as specified by {@link selectSendMaxFrameHeight} and sets it on all media
61
      * sessions for the reasons mentioned in this class description.
87
      * sessions for the reasons mentioned in this class description.
62
      *
88
      *
89
+     * @param {string} sourceName - The source for which sender constraints have changed.
63
      * @returns {Promise<void[]>}
90
      * @returns {Promise<void[]>}
64
      * @private
91
      * @private
65
      */
92
      */
66
-    _propagateSendMaxFrameHeight() {
67
-        const sendMaxFrameHeight = this.selectSendMaxFrameHeight();
93
+    _propagateSendMaxFrameHeight(sourceName = null) {
94
+        const sendMaxFrameHeight = this.selectSendMaxFrameHeight(sourceName);
68
         const promises = [];
95
         const promises = [];
69
 
96
 
70
         if (sendMaxFrameHeight >= 0) {
97
         if (sendMaxFrameHeight >= 0) {
71
-            for (const session of this.conference.getMediaSessions()) {
72
-                promises.push(session.setSenderVideoConstraint(sendMaxFrameHeight));
98
+            for (const session of this._conference.getMediaSessions()) {
99
+                promises.push(session.setSenderVideoConstraint(sendMaxFrameHeight, sourceName));
73
             }
100
             }
74
         }
101
         }
75
 
102
 
80
      * Selects the lowest common value for the local video send constraint by looking at local user's preference and
107
      * Selects the lowest common value for the local video send constraint by looking at local user's preference and
81
      * the active media session's receive preference set by the remote party.
108
      * the active media session's receive preference set by the remote party.
82
      *
109
      *
110
+     * @param {string} sourceName - The source for which sender constraints have changed.
83
      * @returns {number|undefined}
111
      * @returns {number|undefined}
84
      */
112
      */
85
-    selectSendMaxFrameHeight() {
86
-        const activeMediaSession = this.conference.getActiveMediaSession();
113
+    selectSendMaxFrameHeight(sourceName = null) {
114
+        const activeMediaSession = this._conference.getActiveMediaSession();
87
         const remoteRecvMaxFrameHeight = activeMediaSession
115
         const remoteRecvMaxFrameHeight = activeMediaSession
88
             ? activeMediaSession.isP2P
116
             ? activeMediaSession.isP2P
89
                 ? activeMediaSession.getRemoteRecvMaxFrameHeight()
117
                 ? activeMediaSession.getRemoteRecvMaxFrameHeight()
90
-                : this.layerSuspensionEnabled ? this._senderVideoConstraints?.idealHeight : undefined
118
+                : sourceName ? this._sourceSenderConstraints.get(sourceName) : this._senderVideoConstraints?.idealHeight
91
             : undefined;
119
             : undefined;
92
 
120
 
93
-        if (this.preferredSendMaxFrameHeight >= 0 && remoteRecvMaxFrameHeight >= 0) {
94
-            return Math.min(this.preferredSendMaxFrameHeight, remoteRecvMaxFrameHeight);
121
+        if (this._preferredSendMaxFrameHeight >= 0 && remoteRecvMaxFrameHeight >= 0) {
122
+            return Math.min(this._preferredSendMaxFrameHeight, remoteRecvMaxFrameHeight);
95
         } else if (remoteRecvMaxFrameHeight >= 0) {
123
         } else if (remoteRecvMaxFrameHeight >= 0) {
96
             return remoteRecvMaxFrameHeight;
124
             return remoteRecvMaxFrameHeight;
97
         }
125
         }
98
 
126
 
99
-        return this.preferredSendMaxFrameHeight;
127
+        return this._preferredSendMaxFrameHeight;
100
     }
128
     }
101
 
129
 
102
     /**
130
     /**
106
      * @returns {Promise<void[]>} - resolved when the operation is complete.
134
      * @returns {Promise<void[]>} - resolved when the operation is complete.
107
      */
135
      */
108
     setPreferredSendMaxFrameHeight(maxFrameHeight) {
136
     setPreferredSendMaxFrameHeight(maxFrameHeight) {
109
-        this.preferredSendMaxFrameHeight = maxFrameHeight;
137
+        this._preferredSendMaxFrameHeight = maxFrameHeight;
110
 
138
 
111
         return this._propagateSendMaxFrameHeight();
139
         return this._propagateSendMaxFrameHeight();
112
     }
140
     }

+ 6
- 0
modules/qualitycontrol/SendVideoController.spec.js 查看文件

1
 import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
1
 import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
2
 import RTCEvents from '../../service/RTC/RTCEvents';
2
 import RTCEvents from '../../service/RTC/RTCEvents';
3
+import FeatureFlags from '../flags/FeatureFlags';
3
 import Listenable from '../util/Listenable';
4
 import Listenable from '../util/Listenable';
4
 import MediaSessionEvents from '../xmpp/MediaSessionEvents';
5
 import MediaSessionEvents from '../xmpp/MediaSessionEvents';
5
 
6
 
78
         return this.activeMediaSession;
79
         return this.activeMediaSession;
79
     }
80
     }
80
 
81
 
82
+    getLocalVideoTracks() {
83
+        return [];
84
+    }
85
+
81
     getMediaSessions() {
86
     getMediaSessions() {
82
         return this.mediaSessions;
87
         return this.mediaSessions;
83
     }
88
     }
108
     beforeEach(() => {
113
     beforeEach(() => {
109
         conference = new MockConference();
114
         conference = new MockConference();
110
         rtc = new MockRTC();
115
         rtc = new MockRTC();
116
+        FeatureFlags.init({ sourceNameSignaling: false });
111
         sendVideoController = new SendVideoController(conference, rtc);
117
         sendVideoController = new SendVideoController(conference, rtc);
112
         jvbConnection = new MockJingleSessionPC(rtc, false /* isP2P */);
118
         jvbConnection = new MockJingleSessionPC(rtc, false /* isP2P */);
113
         p2pConnection = new MockJingleSessionPC(rtc, true /* isP2P */);
119
         p2pConnection = new MockJingleSessionPC(rtc, true /* isP2P */);

+ 9
- 8
modules/xmpp/JingleSessionPC.js 查看文件

1506
     /**
1506
     /**
1507
      * Sets the resolution constraint on the local camera track.
1507
      * Sets the resolution constraint on the local camera track.
1508
      * @param {number} maxFrameHeight - The user preferred max frame height.
1508
      * @param {number} maxFrameHeight - The user preferred max frame height.
1509
+     * @param {string} sourceName - The source name of the track.
1509
      * @returns {Promise} promise that will be resolved when the operation is
1510
      * @returns {Promise} promise that will be resolved when the operation is
1510
      * successful and rejected otherwise.
1511
      * successful and rejected otherwise.
1511
      */
1512
      */
1512
-    setSenderVideoConstraint(maxFrameHeight) {
1513
+    setSenderVideoConstraint(maxFrameHeight, sourceName = null) {
1513
         if (this._assertNotEnded()) {
1514
         if (this._assertNotEnded()) {
1514
-            logger.info(`${this} setSenderVideoConstraint: ${maxFrameHeight}`);
1515
+            logger.info(`${this} setSenderVideoConstraint: ${maxFrameHeight}, sourceName: ${sourceName}`);
1515
 
1516
 
1516
             // RN doesn't support RTCRtpSenders yet, aggresive layer suspension on RN is implemented
1517
             // RN doesn't support RTCRtpSenders yet, aggresive layer suspension on RN is implemented
1517
             // by changing the media direction in the SDP. This is applicable to jvb sessions only.
1518
             // by changing the media direction in the SDP. This is applicable to jvb sessions only.
1521
                 return this.setMediaTransferActive(true, videoActive);
1522
                 return this.setMediaTransferActive(true, videoActive);
1522
             }
1523
             }
1523
 
1524
 
1524
-            const promise = typeof maxFrameHeight === 'undefined'
1525
-                ? this.peerconnection.configureSenderVideoEncodings()
1526
-                : this.peerconnection.setSenderVideoConstraints(maxFrameHeight);
1525
+            const jitsiLocalTrack = sourceName
1526
+                ? this.rtc.getLocalVideoTracks().find(track => track.getSourceName() === sourceName)
1527
+                : this.rtc.getLocalVideoTrack();
1527
 
1528
 
1528
-            return promise;
1529
+            return this.peerconnection.setSenderVideoConstraints(maxFrameHeight, jitsiLocalTrack);
1529
         }
1530
         }
1530
 
1531
 
1531
         return Promise.resolve();
1532
         return Promise.resolve();
2151
                             logger.debug(`${this} replaceTrack worker: configuring video stream`);
2152
                             logger.debug(`${this} replaceTrack worker: configuring video stream`);
2152
 
2153
 
2153
                             // Configure the video encodings after the track is replaced.
2154
                             // Configure the video encodings after the track is replaced.
2154
-                            return this.peerconnection.configureSenderVideoEncodings();
2155
+                            return this.peerconnection.configureSenderVideoEncodings(newTrack);
2155
                         }
2156
                         }
2156
                     });
2157
                     });
2157
                 })
2158
                 })
2299
                 // Configure the video encodings after the track is unmuted. If the user joins the call muted and
2300
                 // Configure the video encodings after the track is unmuted. If the user joins the call muted and
2300
                 // unmutes it the first time, all the parameters need to be configured.
2301
                 // unmutes it the first time, all the parameters need to be configured.
2301
                 if (track.isVideoTrack()) {
2302
                 if (track.isVideoTrack()) {
2302
-                    return this.peerconnection.configureSenderVideoEncodings();
2303
+                    return this.peerconnection.configureSenderVideoEncodings(track);
2303
                 }
2304
                 }
2304
             });
2305
             });
2305
     }
2306
     }

+ 5
- 0
types/auto/JitsiConference.d.ts 查看文件

316
      * @return {JitsiLocalTrack|null}
316
      * @return {JitsiLocalTrack|null}
317
      */
317
      */
318
     getLocalVideoTrack(): any | null;
318
     getLocalVideoTrack(): any | null;
319
+    /**
320
+     * Returns all the local video tracks.
321
+     * @returns {Array<JitsiLocalTrack>}
322
+     */
323
+    getLocalVideoTracks(): Array<any>;
319
     /**
324
     /**
320
      * Obtains the performance statistics.
325
      * Obtains the performance statistics.
321
      * @returns {Object|null}
326
      * @returns {Object|null}

+ 5
- 0
types/auto/modules/RTC/RTC.d.ts 查看文件

345
      * @returns {JitsiLocalTrack|undefined}
345
      * @returns {JitsiLocalTrack|undefined}
346
      */
346
      */
347
     getLocalVideoTrack(): JitsiLocalTrack | undefined;
347
     getLocalVideoTrack(): JitsiLocalTrack | undefined;
348
+    /**
349
+     * Returns all the local video tracks.
350
+     * @returns {Array<JitsiLocalTrack>}
351
+     */
352
+    getLocalVideoTracks(): Array<JitsiLocalTrack>;
348
     /**
353
     /**
349
      * Get local audio track.
354
      * Get local audio track.
350
      * @returns {JitsiLocalTrack|undefined}
355
      * @returns {JitsiLocalTrack|undefined}

+ 9
- 2
types/auto/modules/RTC/TraceablePeerConnection.d.ts 查看文件

254
      * explicitly disabled.
254
      * explicitly disabled.
255
      */
255
      */
256
     _senderVideoMaxHeight: number;
256
     _senderVideoMaxHeight: number;
257
+    /**
258
+     * The height constraints to be applied on the sender per local video source (source name as the key).
259
+     * @type {Map<string, number>}
260
+     */
261
+    _senderMaxHeights: Map<string, number>;
257
     trace: (what: any, info: any) => void;
262
     trace: (what: any, info: any) => void;
258
     onicecandidate: any;
263
     onicecandidate: any;
259
     onTrack: (evt: any) => void;
264
     onTrack: (evt: any) => void;
628
     /**
633
     /**
629
      * Configures the stream encodings depending on the video type and the bitrates configured.
634
      * Configures the stream encodings depending on the video type and the bitrates configured.
630
      *
635
      *
636
+     * @param {JitsiLocalTrack} - The local track for which the sender encodings have to configured.
631
      * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
637
      * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
632
      */
638
      */
633
-    configureSenderVideoEncodings(): Promise<any>;
639
+    configureSenderVideoEncodings(localVideoTrack?: any): Promise<any>;
634
     setLocalDescription(description: any): Promise<any>;
640
     setLocalDescription(description: any): Promise<any>;
635
     /**
641
     /**
636
      * Enables/disables audio media transmission on this peer connection. When
642
      * Enables/disables audio media transmission on this peer connection. When
653
      * bitrates on the send stream.
659
      * bitrates on the send stream.
654
      *
660
      *
655
      * @param {number} frameHeight - The max frame height to be imposed on the outgoing video stream.
661
      * @param {number} frameHeight - The max frame height to be imposed on the outgoing video stream.
662
+     * @param {JitsiLocalTrack} - The local track for which the sender constraints have to be applied.
656
      * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
663
      * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
657
      */
664
      */
658
-    setSenderVideoConstraints(frameHeight: number): Promise<any>;
665
+    setSenderVideoConstraints(frameHeight: number, localVideoTrack: any): Promise<any>;
659
     encodingsEnabledState: boolean[];
666
     encodingsEnabledState: boolean[];
660
     /**
667
     /**
661
      * Enables/disables video media transmission on this peer connection. When
668
      * Enables/disables video media transmission on this peer connection. When

+ 18
- 6
types/auto/modules/qualitycontrol/SendVideoController.d.ts 查看文件

14
      * @param {RTC} rtc - the rtc instance that is responsible for sending the messages on the bridge channel.
14
      * @param {RTC} rtc - the rtc instance that is responsible for sending the messages on the bridge channel.
15
      */
15
      */
16
     constructor(conference: any, rtc: any);
16
     constructor(conference: any, rtc: any);
17
-    conference: any;
18
-    layerSuspensionEnabled: any;
19
-    rtc: any;
20
-    _senderVideoConstraints: any;
17
+    _conference: any;
18
+    _rtc: any;
19
+    /**
20
+     * Source name based sender constraints.
21
+     * @type {Map<string, number>};
22
+     */
23
+    _sourceSenderConstraints: Map<string, number>;
21
     /**
24
     /**
22
      * Handles the {@link JitsiConferenceEvents.MEDIA_SESSION_STARTED}, that is when the conference creates new media
25
      * Handles the {@link JitsiConferenceEvents.MEDIA_SESSION_STARTED}, that is when the conference creates new media
23
      * session. It doesn't mean it's already active though. For example the JVB connection may be created after
26
      * session. It doesn't mean it's already active though. For example the JVB connection may be created after
27
      * @private
30
      * @private
28
      */
31
      */
29
     private _onMediaSessionStarted;
32
     private _onMediaSessionStarted;
33
+    /**
34
+     * Propagates the video constraints if they have changed.
35
+     *
36
+     * @param {Object} videoConstraints - The sender video constraints received from the bridge.
37
+     */
38
+    _onSenderConstraintsReceived(videoConstraints: any): void;
39
+    _senderVideoConstraints: any;
30
     /**
40
     /**
31
      * Figures out the send video constraint as specified by {@link selectSendMaxFrameHeight} and sets it on all media
41
      * Figures out the send video constraint as specified by {@link selectSendMaxFrameHeight} and sets it on all media
32
      * sessions for the reasons mentioned in this class description.
42
      * sessions for the reasons mentioned in this class description.
33
      *
43
      *
44
+     * @param {string} sourceName - The source for which sender constraints have changed.
34
      * @returns {Promise<void[]>}
45
      * @returns {Promise<void[]>}
35
      * @private
46
      * @private
36
      */
47
      */
39
      * Selects the lowest common value for the local video send constraint by looking at local user's preference and
50
      * Selects the lowest common value for the local video send constraint by looking at local user's preference and
40
      * the active media session's receive preference set by the remote party.
51
      * the active media session's receive preference set by the remote party.
41
      *
52
      *
53
+     * @param {string} sourceName - The source for which sender constraints have changed.
42
      * @returns {number|undefined}
54
      * @returns {number|undefined}
43
      */
55
      */
44
-    selectSendMaxFrameHeight(): number | undefined;
56
+    selectSendMaxFrameHeight(sourceName?: string): number | undefined;
45
     /**
57
     /**
46
      * Sets local preference for max send video frame height.
58
      * Sets local preference for max send video frame height.
47
      *
59
      *
49
      * @returns {Promise<void[]>} - resolved when the operation is complete.
61
      * @returns {Promise<void[]>} - resolved when the operation is complete.
50
      */
62
      */
51
     setPreferredSendMaxFrameHeight(maxFrameHeight: number): Promise<void[]>;
63
     setPreferredSendMaxFrameHeight(maxFrameHeight: number): Promise<void[]>;
52
-    preferredSendMaxFrameHeight: number;
64
+    _preferredSendMaxFrameHeight: number;
53
 }
65
 }

+ 2
- 1
types/auto/modules/xmpp/JingleSessionPC.d.ts 查看文件

355
     /**
355
     /**
356
      * Sets the resolution constraint on the local camera track.
356
      * Sets the resolution constraint on the local camera track.
357
      * @param {number} maxFrameHeight - The user preferred max frame height.
357
      * @param {number} maxFrameHeight - The user preferred max frame height.
358
+     * @param {string} sourceName - The source name of the track.
358
      * @returns {Promise} promise that will be resolved when the operation is
359
      * @returns {Promise} promise that will be resolved when the operation is
359
      * successful and rejected otherwise.
360
      * successful and rejected otherwise.
360
      */
361
      */
361
-    setSenderVideoConstraint(maxFrameHeight: number): Promise<any>;
362
+    setSenderVideoConstraint(maxFrameHeight: number, sourceName?: string): Promise<any>;
362
     /**
363
     /**
363
      *
364
      *
364
      * @param reasonCondition
365
      * @param reasonCondition

Loading…
取消
儲存