Parcourir la source

feat(video-quality): Implement max bitrates for video on p2p sessions

Calculate the bitrate based on the sender video constraint applied on the track and the bitrates specified for different resolutions.
dev1
Jaya Allamsetty il y a 5 ans
Parent
révision
71b867233c

+ 4
- 6
modules/RTC/TPCUtils.js Voir le fichier

@@ -232,8 +232,8 @@ export class TPCUtils {
232 232
             this.pc.peerconnection.addTrack(track);
233 233
         }
234 234
 
235
-        // Construct the simulcast stream constraints for the newly added track.
236
-        if (localTrack.isVideoTrack() && localTrack.videoType === VideoType.CAMERA && this.pc.isSimulcastOn()) {
235
+        // Construct the stream constraints for the newly added track.
236
+        if (localTrack.isVideoTrack() && localTrack.videoType === VideoType.CAMERA) {
237 237
             this.setSimulcastStreamConstraints(localTrack.getTrack());
238 238
         }
239 239
     }
@@ -269,10 +269,8 @@ export class TPCUtils {
269 269
                     this.pc.localTracks.set(localTrack.rtcId, localTrack);
270 270
                     transceiver.direction = 'sendrecv';
271 271
 
272
-                    // Construct the simulcast stream constraints for the newly added track.
273
-                    if (localTrack.isVideoTrack()
274
-                        && localTrack.videoType === VideoType.CAMERA
275
-                        && this.pc.isSimulcastOn()) {
272
+                    // Construct the stream constraints for the newly added track.
273
+                    if (localTrack.isVideoTrack() && localTrack.videoType === VideoType.CAMERA) {
276 274
                         this.setSimulcastStreamConstraints(localTrack.getTrack());
277 275
                     }
278 276
                 });

+ 69
- 55
modules/RTC/TraceablePeerConnection.js Voir le fichier

@@ -227,12 +227,12 @@ export default function TraceablePeerConnection(
227 227
     };
228 228
 
229 229
     // Check if the max. bitrates for video are specified through config.js videoQuality settings.
230
-    // These bitrates will be applied on all browsers for camera sources in simulcast mode.
231
-    const videoBitrates = this.options.videoQuality && this.options.videoQuality.maxBitratesVideo
230
+    // These bitrates will be applied on all browsers for camera sources in both simulcast and p2p mode.
231
+    this.videoBitrates = this.options.videoQuality && this.options.videoQuality.maxBitratesVideo
232 232
         ? this.options.videoQuality.maxBitratesVideo
233 233
         : standardVideoBitrates;
234 234
 
235
-    this.tpcUtils = new TPCUtils(this, videoBitrates);
235
+    this.tpcUtils = new TPCUtils(this, this.videoBitrates);
236 236
     this.updateLog = [];
237 237
     this.stats = {};
238 238
     this.statsinterval = null;
@@ -1638,8 +1638,8 @@ TraceablePeerConnection.prototype.addTrack = function(track, isInitiator = false
1638 1638
         promiseChain = this.tpcUtils.setEncodings(track);
1639 1639
     }
1640 1640
 
1641
-    // Construct the simulcast stream constraints for the newly added track.
1642
-    if (track.isVideoTrack() && track.videoType === VideoType.CAMERA && this.isSimulcastOn()) {
1641
+    // Construct the stream constraints for the newly added track.
1642
+    if (track.isVideoTrack() && track.videoType === VideoType.CAMERA) {
1643 1643
         this.tpcUtils.setSimulcastStreamConstraints(track.getTrack());
1644 1644
     }
1645 1645
 
@@ -2074,17 +2074,19 @@ TraceablePeerConnection.prototype.setSenderVideoDegradationPreference = function
2074 2074
  * max bitrate is to be configured.
2075 2075
  * @returns {Promise<void>}
2076 2076
  */
2077
-TraceablePeerConnection.prototype.setMaxBitRate = function(localTrack = null) {
2078
-    if (!localTrack) {
2079
-        // eslint-disable-next-line no-param-reassign
2080
-        localTrack = this.getLocalVideoTrack();
2077
+TraceablePeerConnection.prototype.setMaxBitRate = function() {
2078
+    if (!this.peerconnection.getSenders) {
2079
+        logger.debug('Browser doesn\'t support RTCRtpSender');
2081 2080
 
2082
-        if (!localTrack) {
2083
-            return Promise.resolve();
2084
-        }
2081
+        return Promise.resolve();
2082
+    }
2083
+    const localVideoTrack = this.getLocalVideoTrack();
2084
+
2085
+    if (!localVideoTrack) {
2086
+        return Promise.resolve();
2085 2087
     }
2086
-    const trackId = localTrack.track.id;
2087
-    const videoType = localTrack.videoType;
2088
+
2089
+    const videoType = localVideoTrack.videoType;
2088 2090
 
2089 2091
     // Apply the maxbitrates on the video track when one of the conditions is met.
2090 2092
     // 1. Max. bitrates for video are specified through videoQuality settings in config.js
@@ -2096,52 +2098,57 @@ TraceablePeerConnection.prototype.setMaxBitRate = function(localTrack = null) {
2096 2098
         return Promise.resolve();
2097 2099
     }
2098 2100
 
2099
-    if (!this.peerconnection.getSenders) {
2100
-        logger.debug('Browser doesn\'t support RTCRtpSender');
2101
+    const presenterEnabled = localVideoTrack._originalStream
2102
+        && localVideoTrack._originalStream.id !== localVideoTrack.getStreamId();
2103
+    const videoSender = this.findSenderByKind(MediaType.VIDEO);
2101 2104
 
2102
-        return Promise.resolve();
2105
+    if (!videoSender) {
2106
+        return Promise.reject(new Error('RTCRtpSender not found for local video'));
2103 2107
     }
2104
-    const presenterEnabled = localTrack._originalStream
2105
-        && localTrack._originalStream.id !== localTrack.getStreamId();
2106
-
2107
-    const setSenderParamPromises = [];
2108
+    const parameters = videoSender.getParameters();
2108 2109
 
2109
-    this.peerconnection.getSenders()
2110
-        .filter(s => s.track && s.track.id === trackId)
2111
-        .forEach(sender => {
2112
-            try {
2113
-                const parameters = sender.getParameters();
2110
+    if (!(parameters.encodings && parameters.encodings.length)) {
2111
+        return Promise.reject(new Error('RTCRtpEncodingParameters not found for local video'));
2112
+    }
2114 2113
 
2115
-                if (!parameters.encodings || !parameters.encodings.length) {
2116
-                    return;
2117
-                }
2118
-                logger.debug('Setting max bitrate on video stream');
2119
-                for (const encoding in parameters.encodings) {
2120
-                    if (parameters.encodings.hasOwnProperty(encoding)) {
2121
-                        // On chromium, set a max bitrate of 500 Kbps for screenshare when
2122
-                        // capScreenshareBitrate is enabled through config.js and presenter
2123
-                        // is not turned on.
2124
-                        parameters.encodings[encoding].maxBitrate
2125
-                            = browser.usesPlanB() && videoType === VideoType.DESKTOP
2126
-                                ? presenterEnabled ? HD_BITRATE : DESKSTOP_SHARE_RATE
2127
-
2128
-                                // In unified plan, simulcast for SS is on by default.
2129
-                                // When simulcast is disabled through a config.js option,
2130
-                                // we cap the bitrate on desktop and camera tracks to 2500 Kbps.
2131
-                                : this.isSimulcastOn()
2132
-                                    ? this.tpcUtils.simulcastEncodings[encoding].maxBitrate
2133
-                                    : HD_BITRATE;
2134
-                    }
2135
-                }
2136
-                setSenderParamPromises.push(sender.setParameters(parameters));
2137
-            } catch (err) {
2138
-                logger.error('Browser does not support getParameters/setParamters '
2139
-                    + 'or setting max bitrate on the encodings: ', err);
2114
+    if (this.isSimulcastOn()) {
2115
+        for (const encoding in parameters.encodings) {
2116
+            if (parameters.encodings.hasOwnProperty(encoding)) {
2117
+                // On chromium, set a max bitrate of 500 Kbps for screenshare when
2118
+                // capScreenshareBitrate is enabled through config.js and presenter
2119
+                // is not turned on.
2120
+                const bitrate = browser.usesPlanB()
2121
+                    && videoType === VideoType.DESKTOP
2122
+                    && this.options.capScreenshareBitrate
2123
+                    ? presenterEnabled ? this.videoBitrates.high : DESKSTOP_SHARE_RATE
2124
+                    : this.tpcUtils.simulcastEncodings[encoding].maxBitrate;
2125
+
2126
+                logger.info(`${this} Setting a max bitrate of ${bitrate} bps on layer `
2127
+                    + `${this.tpcUtils.simulcastEncodings[encoding].rid}`);
2128
+                parameters.encodings[encoding].maxBitrate = bitrate;
2140 2129
             }
2141
-        });
2130
+        }
2131
+    } else {
2132
+        // Do not change the max bitrate for desktop tracks in non-simulcast mode.
2133
+        let bitrate = this.videoBitrates.high;
2134
+
2135
+        if (videoType === VideoType.CAMERA) {
2136
+            // Determine the bitrates based on the sender constraint applied for unicast tracks.
2137
+            const scaleFactor = this.senderVideoMaxHeight
2138
+                ? Math.floor(localVideoTrack.resolution / this.senderVideoMaxHeight)
2139
+                : 1;
2140
+            const encoding = this.tpcUtils.simulcastEncodings
2141
+                .find(layer => layer.scaleResolutionDownBy === scaleFactor);
2142
+
2143
+            if (encoding) {
2144
+                logger.info(`${this} Setting a max bitrate of ${encoding.maxBitrate} bps on local video track`);
2145
+                bitrate = encoding.maxBitrate;
2146
+            }
2147
+        }
2148
+        parameters.encodings[0].maxBitrate = bitrate;
2149
+    }
2142 2150
 
2143
-    return Promise.all(setSenderParamPromises)
2144
-        .then(() => Promise.resolve());
2151
+    return videoSender.setParameters(parameters);
2145 2152
 };
2146 2153
 
2147 2154
 TraceablePeerConnection.prototype.setRemoteDescription = function(description) {
@@ -2265,7 +2272,9 @@ TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeigh
2265 2272
             }
2266 2273
         }
2267 2274
     } else if (newHeight > 0) {
2268
-        parameters.encodings[0].scaleResolutionDownBy = Math.floor(localVideoTrack.resolution / newHeight);
2275
+        parameters.encodings[0].scaleResolutionDownBy = localVideoTrack.resolution >= newHeight
2276
+            ? Math.floor(localVideoTrack.resolution / newHeight)
2277
+            : 1;
2269 2278
         parameters.encodings[0].active = true;
2270 2279
     } else {
2271 2280
         parameters.encodings[0].scaleResolutionDownBy = undefined;
@@ -2277,6 +2286,11 @@ TraceablePeerConnection.prototype.setSenderVideoConstraint = function(frameHeigh
2277 2286
     return videoSender.setParameters(parameters).then(() => {
2278 2287
         localVideoTrack.maxEnabledResolution = newHeight;
2279 2288
         this.eventEmitter.emit(RTCEvents.LOCAL_TRACK_MAX_ENABLED_RESOLUTION_CHANGED, localVideoTrack);
2289
+
2290
+        // Max bitrate needs to be reconfigured on the p2p connection if needed when the send resolution changes.
2291
+        if (this.isP2P) {
2292
+            return this.setMaxBitRate();
2293
+        }
2280 2294
     });
2281 2295
 };
2282 2296
 

+ 4
- 10
modules/xmpp/JingleSessionPC.js Voir le fichier

@@ -1389,14 +1389,13 @@ export default class JingleSessionPC extends JingleSession {
1389 1389
     }
1390 1390
 
1391 1391
     /**
1392
-     * Sets the maximum bitrates on the local video track if the current
1393
-     * session is a JVB session. Bitrate values from videoQuality settings
1394
-     * in config.js will be used for configuring the sender.
1392
+     * Sets the maximum bitrates on the local video track. Bitrate values from
1393
+     * videoQuality settings in config.js will be used for configuring the sender.
1395 1394
      * @returns {Promise<void>} promise that will be resolved when the operation is
1396 1395
      * successful and rejected otherwise.
1397 1396
      */
1398 1397
     setSenderMaxBitrates() {
1399
-        if (this._assertNotEnded() && !this.isP2P) {
1398
+        if (this._assertNotEnded()) {
1400 1399
             return this.peerconnection.setMaxBitRate();
1401 1400
         }
1402 1401
 
@@ -1929,12 +1928,7 @@ export default class JingleSessionPC extends JingleSession {
1929 1928
 
1930 1929
                                 // Apply the cached video constraints on the new video sender.
1931 1930
                                 .then(() => this.peerconnection.setSenderVideoConstraint())
1932
-                                .then(() => {
1933
-                                    // Configure max bitrate on the video sender when media is routed through JVB.
1934
-                                    if (!this.isP2P) {
1935
-                                        return this.peerconnection.setMaxBitRate(newTrack);
1936
-                                    }
1937
-                                });
1931
+                                .then(() => this.peerconnection.setMaxBitRate());
1938 1932
                         }
1939 1933
                     });
1940 1934
                 })

Chargement…
Annuler
Enregistrer