瀏覽代碼

ref: Handles video constraints from the bridge. (#1227)

master
George Politis 4 年之前
父節點
當前提交
f79fcaa13e
No account linked to committer's email address

+ 11
- 6
modules/RTC/BridgeChannel.js 查看文件

@@ -20,9 +20,10 @@ export default class BridgeChannel {
20 20
      * @param {RTCPeerConnection} [peerconnection] WebRTC peer connection
21 21
      * instance.
22 22
      * @param {string} [wsUrl] WebSocket URL.
23
-     * @param {EventEmitter} eventEmitter EventEmitter instance.
23
+     * @param {EventEmitter} emitter the EventEmitter instance to use for event emission.
24
+     * @param {function} senderVideoConstraintsChanged callback to call when the sender video constraints change.
24 25
      */
25
-    constructor(peerconnection, wsUrl, emitter) {
26
+    constructor(peerconnection, wsUrl, emitter, senderVideoConstraintsChanged) {
26 27
         if (!peerconnection && !wsUrl) {
27 28
             throw new TypeError(
28 29
                 'At least peerconnection or wsUrl must be given');
@@ -54,6 +55,8 @@ export default class BridgeChannel {
54 55
         // Indicates whether the connection was closed from the client or not.
55 56
         this._closedFromClient = false;
56 57
 
58
+        this._senderVideoConstraintsChanged = senderVideoConstraintsChanged;
59
+
57 60
         // If a RTCPeerConnection is given, listen for new RTCDataChannel
58 61
         // event.
59 62
         if (peerconnection) {
@@ -344,11 +347,13 @@ export default class BridgeChannel {
344 347
 
345 348
                 break;
346 349
             }
347
-            case 'SelectedUpdateEvent': {
348
-                const isSelected = obj.isSelected;
350
+            case 'SenderVideoConstraints': {
351
+                const videoConstraints = obj.videoConstraints;
349 352
 
350
-                logger.info(`SelectedUpdateEvent isSelected? ${isSelected}`);
351
-                emitter.emit(RTCEvents.IS_SELECTED_CHANGED, isSelected);
353
+                if (videoConstraints) {
354
+                    logger.info(`SenderVideoConstraints: ${JSON.stringify(videoConstraints)}`);
355
+                    this._senderVideoConstraintsChanged(videoConstraints);
356
+                }
352 357
                 break;
353 358
             }
354 359
             default: {

+ 24
- 1
modules/RTC/RTC.js 查看文件

@@ -163,6 +163,11 @@ export default class RTC extends Listenable {
163 163
          */
164 164
         this._lastNEndpoints = null;
165 165
 
166
+        /*
167
+         * Holds the sender video constraints signaled from the bridge.
168
+         */
169
+        this._senderVideoConstraints = {};
170
+
166 171
         /**
167 172
          * The number representing the maximum video height the local client
168 173
          * should receive from the bridge.
@@ -284,7 +289,7 @@ export default class RTC extends Listenable {
284 289
      */
285 290
     initializeBridgeChannel(peerconnection, wsUrl) {
286 291
         this._channel = new BridgeChannel(
287
-            peerconnection, wsUrl, this.eventEmitter);
292
+            peerconnection, wsUrl, this.eventEmitter, this._senderVideoConstraintsChanged.bind(this));
288 293
 
289 294
         this._channelOpenListener = () => {
290 295
             // Mark that channel as opened.
@@ -346,6 +351,17 @@ export default class RTC extends Listenable {
346 351
         this._updateAudioOutputForAudioTracks(RTCUtils.getAudioOutputDevice());
347 352
     }
348 353
 
354
+    /**
355
+     * Notifies this instance that the sender video constraints signaled from the bridge have changed.
356
+     *
357
+     * @param {Object} senderVideoConstraints the sender video constraints from the bridge.
358
+     * @private
359
+     */
360
+    _senderVideoConstraintsChanged(senderVideoConstraints) {
361
+        this._senderVideoConstraints = senderVideoConstraints;
362
+        this.eventEmitter.emit(RTCEvents.SENDER_VIDEO_CONSTRAINTS_CHANGED);
363
+    }
364
+
349 365
     /**
350 366
      * Receives events when Last N had changed.
351 367
      * @param {array} lastNEndpoints The new Last N endpoints.
@@ -583,6 +599,13 @@ export default class RTC extends Listenable {
583 599
         return this._lastN;
584 600
     }
585 601
 
602
+    /**
603
+     * @return {Object} The sender video constraints signaled from the brridge.
604
+     */
605
+    getSenderVideoConstraints() {
606
+        return this._senderVideoConstraints;
607
+    }
608
+
586 609
     /**
587 610
      * Get local video track.
588 611
      * @returns {JitsiLocalTrack|undefined}

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

@@ -51,9 +51,6 @@ const DEGRADATION_PREFERENCE_DESKTOP = 'maintain-resolution';
51 51
  *      disabled by removing it from the SDP.
52 52
  * @param {boolean} options.preferH264 if set to 'true' H264 will be preferred
53 53
  * over other video codecs.
54
- * @param {boolean} options.enableLayerSuspension if set to 'true', we will
55
- * cap the video send bitrate when we are told we have not been selected by
56
- * any endpoints (and therefore the non-thumbnail streams are not in use).
57 54
  * @param {boolean} options.startSilent If set to 'true' no audio will be sent or received.
58 55
  *
59 56
  * FIXME: initially the purpose of TraceablePeerConnection was to be able to
@@ -2661,60 +2658,6 @@ TraceablePeerConnection.prototype.generateNewStreamSSRCInfo = function(track) {
2661 2658
     return ssrcInfo;
2662 2659
 };
2663 2660
 
2664
-const handleLayerSuspension = function(peerConnection, isSelected) {
2665
-    if (!peerConnection.getSenders) {
2666
-        logger.debug('Browser doesn\'t support RTPSender');
2667
-
2668
-        return;
2669
-    }
2670
-
2671
-    const videoSender = peerConnection.getSenders()
2672
-        .find(sender => sender.track.kind === 'video');
2673
-
2674
-    if (!videoSender) {
2675
-        logger.warn('handleLayerSuspension unable to find video sender');
2676
-
2677
-        return;
2678
-    }
2679
-    if (!videoSender.getParameters) {
2680
-        logger.debug('Browser doesn\'t support RTPSender parameters');
2681
-
2682
-        return;
2683
-    }
2684
-    const parameters = videoSender.getParameters();
2685
-
2686
-    if (isSelected) {
2687
-        logger.debug('Currently selected, enabling all sim layers');
2688
-
2689
-        // Make sure all encodings are enabled
2690
-        parameters.encodings.forEach(e => {
2691
-            e.active = true;
2692
-        });
2693
-    } else {
2694
-        logger.debug('Not currently selected, disabling upper layers');
2695
-
2696
-        // Turn off the upper simulcast layers
2697
-        [ 1, 2 ].forEach(simIndex => {
2698
-            if (parameters.encodings[simIndex]) {
2699
-                parameters.encodings[simIndex].active = false;
2700
-            }
2701
-        });
2702
-    }
2703
-    videoSender.setParameters(parameters);
2704
-};
2705
-
2706
-/**
2707
- * Set whether or not the endpoint is 'selected' by other endpoints, meaning
2708
- * it appears on their main stage
2709
- */
2710
-TraceablePeerConnection.prototype.setIsSelected = function(isSelected) {
2711
-    if (this.options.enableLayerSuspension) {
2712
-        logger.debug('Layer suspension enabled,'
2713
-            + `currently selected? ${isSelected}`);
2714
-        handleLayerSuspension(this.peerconnection, isSelected);
2715
-    }
2716
-};
2717
-
2718 2661
 /**
2719 2662
  * Creates a text representation of this <tt>TraceablePeerConnection</tt>
2720 2663
  * instance.

+ 18
- 20
modules/xmpp/JingleSessionPC.js 查看文件

@@ -282,6 +282,8 @@ export default class JingleSessionPC extends JingleSession {
282 282
                 XmppConnection.Events.CONN_STATUS_CHANGED,
283 283
                 this.onXmppStatusChanged.bind(this))
284 284
         );
285
+
286
+        this._removeSenderVideoConstraintsChangeListener = undefined;
285 287
     }
286 288
 
287 289
     /* eslint-enable max-params */
@@ -341,7 +343,6 @@ export default class JingleSessionPC extends JingleSession {
341 343
                 = options.disableSimulcast
342 344
                     || (options.preferH264 && !options.disableH264);
343 345
             pcOptions.preferH264 = options.preferH264;
344
-            pcOptions.enableLayerSuspension = options.enableLayerSuspension;
345 346
 
346 347
             // disable simulcast for screenshare and set the max bitrate to
347 348
             // 500Kbps if the testing flag is present in config.js.
@@ -577,19 +578,12 @@ export default class JingleSessionPC extends JingleSession {
577 578
 
578 579
         if (!this.isP2P && options.enableLayerSuspension) {
579 580
             // If this is the bridge session, we'll listen for
580
-            // IS_SELECTED_CHANGED events and notify the peer connection
581
-            this.rtc.addListener(RTCEvents.IS_SELECTED_CHANGED,
582
-                isSelected => {
583
-                    this.peerconnection.setIsSelected(isSelected);
584
-                    logger.info('Doing local O/A due to '
585
-                        + 'IS_SELECTED_CHANGED event');
586
-                    this.modificationQueue.push(finishedCallback => {
587
-                        this._renegotiate()
588
-                            .then(finishedCallback)
589
-                            .catch(finishedCallback);
590
-                    });
591
-                }
592
-            );
581
+            // SENDER_VIDEO_CONSTRAINTS_CHANGED events and notify the peer connection
582
+            this._removeSenderVideoConstraintsChangeListener = this.rtc.addListener(
583
+                RTCEvents.SENDER_VIDEO_CONSTRAINTS_CHANGED, () => {
584
+                    this.eventEmitter.emit(
585
+                        MediaSessionEvents.REMOTE_VIDEO_CONSTRAINTS_CHANGED, this);
586
+                });
593 587
         }
594 588
     }
595 589
 
@@ -599,9 +593,11 @@ export default class JingleSessionPC extends JingleSession {
599 593
      * @returns {Number|undefined}
600 594
      */
601 595
     getRemoteRecvMaxFrameHeight() {
602
-        return this.isP2P
603
-            ? this.remoteRecvMaxFrameHeight
604
-            : undefined; // FIXME George: put a getter for the JVB's preference here
596
+        if (this.isP2P) {
597
+            return this.remoteRecvMaxFrameHeight;
598
+        }
599
+
600
+        return this.options.enableLayerSuspension ? this.rtc.getSenderVideoConstraints().idealHeight : undefined;
605 601
     }
606 602
 
607 603
     /**
@@ -1480,6 +1476,10 @@ export default class JingleSessionPC extends JingleSession {
1480 1476
         this._xmppListeners.forEach(removeListener => removeListener());
1481 1477
         this._xmppListeners = [];
1482 1478
 
1479
+        if (this._removeSenderVideoConstraintsChangeListener) {
1480
+            this._removeSenderVideoConstraintsChangeListener();
1481
+        }
1482
+
1483 1483
         this.close();
1484 1484
     }
1485 1485
 
@@ -2235,9 +2235,7 @@ export default class JingleSessionPC extends JingleSession {
2235 2235
             logger.info(`${this} received remote max frame height: ${newMaxFrameHeight}`);
2236 2236
             this.remoteRecvMaxFrameHeight = newMaxFrameHeight;
2237 2237
             this.eventEmitter.emit(
2238
-                MediaSessionEvents.REMOTE_VIDEO_CONSTRAINTS_CHANGED,
2239
-                this,
2240
-                newMaxFrameHeight);
2238
+                MediaSessionEvents.REMOTE_VIDEO_CONSTRAINTS_CHANGED, this);
2241 2239
         }
2242 2240
 
2243 2241
         if (newVideoSenders === null) {

+ 2
- 2
modules/xmpp/JingleSessionPC.spec.js 查看文件

@@ -93,8 +93,8 @@ describe('JingleSessionPC', () => {
93 93
         });
94 94
         it('fires an event when remote peer sends content-modify', () => {
95 95
             let remoteRecvMaxFrameHeight;
96
-            const remoteVideoConstraintsListener = (session, maxFrameHeight) => {
97
-                remoteRecvMaxFrameHeight = maxFrameHeight;
96
+            const remoteVideoConstraintsListener = session => {
97
+                remoteRecvMaxFrameHeight = session.getRemoteRecvMaxFrameHeight();
98 98
             };
99 99
 
100 100
             jingleSession.addListener(

+ 1
- 1
service/RTC/RTCEvents.js 查看文件

@@ -20,7 +20,7 @@ const RTCEvents = {
20 20
      */
21 21
     GRANTED_PERMISSIONS: 'rtc.granted_permissions',
22 22
 
23
-    IS_SELECTED_CHANGED: 'rtc.is_selected_change',
23
+    SENDER_VIDEO_CONSTRAINTS_CHANGED: 'rtc.sender_video_constraints_changed',
24 24
 
25 25
     /**
26 26
      * Event emitted when {@link RTC.setLastN} method is called to update with

Loading…
取消
儲存