Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(TPC): make screen share bitrate configurable #2215

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 39 additions & 27 deletions modules/RTC/TPCUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,44 +38,52 @@ export class TPCUtils {
const standardBitrates = {
low: LD_BITRATE,
standard: SD_BITRATE,
high: HD_BITRATE
high: HD_BITRATE,
ssHigh: HD_BITRATE
};

// Check if the max. bitrates for video are specified through config.js videoQuality settings.
// Right now only VP8 bitrates are configured on the simulcast encodings, VP9 bitrates have to be
// configured on the SDP using b:AS line.
this.videoBitrates = bitrateSettings ?? standardBitrates;
const encodingBitrates = this.videoBitrates.VP8 ?? this.videoBitrates;

/**
* The startup configuration for the stream encodings that are applicable to
* the video stream when a new sender is created on the peerconnection. The initial
* config takes into account the differences in browser's simulcast implementation.
*
* Encoding parameters:
* active - determine the on/off state of a particular encoding.
* maxBitrate - max. bitrate value to be applied to that particular encoding
* based on the encoding's resolution and config.js videoQuality settings if applicable.
* rid - Rtp Stream ID that is configured for a particular simulcast stream.
* scaleResolutionDownBy - the factor by which the encoding is scaled down from the
* original resolution of the captured video.
*/
this.localStreamEncodingsConfig = [
this.encodingBitrates = this.videoBitrates.VP8 ?? this.videoBitrates;
}

/**
* The startup configuration for the stream encodings that are applicable to
* the video stream when a new sender is created on the peerconnection. The initial
* config takes into account the differences in browser's simulcast implementation.
*
* Encoding parameters:
* active - determine the on/off state of a particular encoding.
* maxBitrate - max. bitrate value to be applied to that particular encoding
* based on the encoding's resolution and config.js videoQuality settings if applicable.
* rid - Rtp Stream ID that is configured for a particular simulcast stream.
* scaleResolutionDownBy - the factor by which the encoding is scaled down from the
* original resolution of the captured video.
*
* @param {VideoType} videoType
*/
_getVideoStreamEncodings(videoType) {
DanielMcAssey marked this conversation as resolved.
Show resolved Hide resolved
const maxVideoRate = videoType === VideoType.DESKTOP
? this.encodingBitrates.ssHigh : this.encodingBitrates.high;
DanielMcAssey marked this conversation as resolved.
Show resolved Hide resolved

return [
{
active: true,
maxBitrate: browser.isFirefox() ? encodingBitrates.high : encodingBitrates.low,
maxBitrate: browser.isFirefox() ? maxVideoRate : this.encodingBitrates.low,
rid: SIM_LAYER_1_RID,
scaleResolutionDownBy: browser.isFirefox() ? HD_SCALE_FACTOR : LD_SCALE_FACTOR
},
{
active: true,
maxBitrate: encodingBitrates.standard,
maxBitrate: this.encodingBitrates.standard,
rid: SIM_LAYER_2_RID,
scaleResolutionDownBy: SD_SCALE_FACTOR
},
{
active: true,
maxBitrate: browser.isFirefox() ? encodingBitrates.low : encodingBitrates.high,
maxBitrate: browser.isFirefox() ? this.encodingBitrates.low : maxVideoRate,
rid: SIM_LAYER_3_RID,
scaleResolutionDownBy: browser.isFirefox() ? LD_SCALE_FACTOR : HD_SCALE_FACTOR
}
Expand All @@ -89,7 +97,7 @@ export class TPCUtils {
*/
_getStreamEncodings(localTrack) {
if (this.pc.isSimulcastOn() && localTrack.isVideoTrack()) {
return this.localStreamEncodingsConfig;
return this._getVideoStreamEncodings(localTrack.getVideoType());
}

return localTrack.isVideoTrack()
Expand Down Expand Up @@ -277,7 +285,8 @@ export class TPCUtils {
calculateEncodingsActiveState(localVideoTrack, newHeight) {
const localTrack = localVideoTrack.getTrack();
const { height } = localTrack.getSettings();
const encodingsState = this.localStreamEncodingsConfig
const videoStreamEncodings = this._getVideoStreamEncodings(localVideoTrack.getVideoType());
const encodingsState = videoStreamEncodings
.map(encoding => height / encoding.scaleResolutionDownBy)
.map((frameHeight, idx) => {
let active = localVideoTrack.getVideoType() === VideoType.CAMERA
Expand All @@ -286,7 +295,7 @@ export class TPCUtils {
// resolution. This can happen when camera is captured at resolutions higher than 720p but the
// requested resolution is 180. Since getParameters doesn't give us information about the resolutions
// of the simulcast encodings, we have to rely on our initial config for the simulcast streams.
? newHeight > 0 && this.localStreamEncodingsConfig[idx]?.scaleResolutionDownBy === LD_SCALE_FACTOR
? newHeight > 0 && videoStreamEncodings[idx]?.scaleResolutionDownBy === LD_SCALE_FACTOR
? true
: frameHeight <= newHeight

Expand All @@ -302,7 +311,7 @@ export class TPCUtils {
&& this.pc._capScreenshareBitrate
&& this.pc.usesUnifiedPlan()
&& !browser.isWebKitBased()
&& this.localStreamEncodingsConfig[idx].scaleResolutionDownBy !== HD_SCALE_FACTOR) {
&& videoStreamEncodings[idx].scaleResolutionDownBy !== HD_SCALE_FACTOR) {
active = false;
}

Expand All @@ -325,7 +334,7 @@ export class TPCUtils {
const lowFpsScreenshare = localVideoTrack.getVideoType() === VideoType.DESKTOP
&& this.pc._capScreenshareBitrate
&& !browser.isWebKitBased();
const encodingsBitrates = this.localStreamEncodingsConfig
const encodingsBitrates = this._getVideoStreamEncodings(localVideoTrack.getVideoType())
.map(encoding => {
const bitrate = lowFpsScreenshare
? desktopShareBitrate
Expand Down Expand Up @@ -491,10 +500,11 @@ export class TPCUtils {
* that were configured on the RTCRtpSender when the source was added to the peerconnection.
* This should prevent us from overriding the default values if the browser returns
* erroneous values when RTCRtpSender.getParameters is used for getting the encodings info.
* @param {JitsiLocalTrack} localVideoTrack The local video track.
* @param {Object} parameters - the RTCRtpEncodingParameters obtained from the browser.
* @returns {void}
*/
updateEncodingsResolution(parameters) {
updateEncodingsResolution(localVideoTrack, parameters) {
if (!(browser.isWebKitBased() && parameters.encodings && Array.isArray(parameters.encodings))) {
return;
}
Expand All @@ -504,8 +514,10 @@ export class TPCUtils {

// Implement the workaround only when all the encodings report the same resolution.
if (allEqualEncodings(parameters.encodings)) {
const videoStreamEncodings = this._getVideoStreamEncodings(localVideoTrack.getVideoType());

parameters.encodings.forEach((encoding, idx) => {
encoding.scaleResolutionDownBy = this.localStreamEncodingsConfig[idx].scaleResolutionDownBy;
encoding.scaleResolutionDownBy = videoStreamEncodings[idx].scaleResolutionDownBy;
});
}
}
Expand Down
5 changes: 3 additions & 2 deletions modules/RTC/TraceablePeerConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -2396,11 +2396,12 @@ TraceablePeerConnection.prototype._setVp9MaxBitrates = function(description, isL
if (this.codecPreference.mimeType === CodecMimeType.VP9) {
const bitrates = this.tpcUtils.videoBitrates.VP9 || this.tpcUtils.videoBitrates;
const hdBitrate = bitrates.high ? bitrates.high : HD_BITRATE;
const ssHdBitrate = bitrates.ssHigh ? bitrates.ssHigh : HD_BITRATE;
const mid = mLine.mid;
const isSharingScreen = FeatureFlags.isMultiStreamSendSupportEnabled()
? mid === this._getDesktopTrackMid()
: this._isSharingScreen();
const limit = Math.floor((isSharingScreen ? HD_BITRATE : hdBitrate) / 1000);
const limit = Math.floor((isSharingScreen ? ssHdBitrate : hdBitrate) / 1000);

// Use only the HD bitrate for now as there is no API available yet for configuring
// the bitrates on the individual SVC layers.
Expand Down Expand Up @@ -2641,7 +2642,7 @@ TraceablePeerConnection.prototype.setSenderVideoConstraints = function(frameHeig
}
}
}
this.tpcUtils.updateEncodingsResolution(parameters);
this.tpcUtils.updateEncodingsResolution(localVideoTrack, parameters);

// For p2p and cases and where simulcast is explicitly disabled.
} else if (frameHeight > 0) {
Expand Down