diff --git a/packages/@webex/plugin-meetings/src/multistream/remoteMedia.ts b/packages/@webex/plugin-meetings/src/multistream/remoteMedia.ts index 98828e9b846..d3a65e435c1 100644 --- a/packages/@webex/plugin-meetings/src/multistream/remoteMedia.ts +++ b/packages/@webex/plugin-meetings/src/multistream/remoteMedia.ts @@ -19,6 +19,14 @@ export type RemoteVideoResolution = | 'large' // 1080p or less | 'best'; // highest possible resolution +const MAX_FS_VALUES = { + '90p': 60, + '180p': 240, + '360p': 920, + '720p': 3600, + '1080p': 8192, +}; + /** * Converts pane size into h264 maxFs * @param {PaneSize} paneSize @@ -29,28 +37,28 @@ export function getMaxFs(paneSize: RemoteVideoResolution): number { switch (paneSize) { case 'thumbnail': - maxFs = 60; + maxFs = MAX_FS_VALUES['90p']; break; case 'very small': - maxFs = 240; + maxFs = MAX_FS_VALUES['180p']; break; case 'small': - maxFs = 920; + maxFs = MAX_FS_VALUES['360p']; break; case 'medium': - maxFs = 3600; + maxFs = MAX_FS_VALUES['720p']; break; case 'large': - maxFs = 8192; + maxFs = MAX_FS_VALUES['1080p']; break; case 'best': - maxFs = 8192; // for now 'best' is 1080p, so same as 'large' + maxFs = MAX_FS_VALUES['1080p']; // for now 'best' is 1080p, so same as 'large' break; default: LoggerProxy.logger.warn( `RemoteMedia#getMaxFs --> unsupported paneSize: ${paneSize}, using "medium" instead` ); - maxFs = 3600; + maxFs = MAX_FS_VALUES['720p']; } return maxFs; @@ -117,16 +125,21 @@ export class RemoteMedia extends EventsScope { return; } - if (height < 135) { - fs = 60; - } else if (height < 270) { - fs = 240; - } else if (height < 540) { - fs = 920; + // we switch to the next resolution level when the height is 10% more than the current resolution height + // except for 1080p - we switch to it immediately when the height is more than 720p + const threshold = 1.1; + const getThresholdHeight = (h: number) => Math.round(h * threshold); + + if (height < getThresholdHeight(90)) { + fs = MAX_FS_VALUES['90p']; + } else if (height < getThresholdHeight(180)) { + fs = MAX_FS_VALUES['180p']; + } else if (height < getThresholdHeight(360)) { + fs = MAX_FS_VALUES['360p']; } else if (height <= 720) { - fs = 3600; + fs = MAX_FS_VALUES['720p']; } else { - fs = 8192; + fs = MAX_FS_VALUES['1080p']; } this.receiveSlot?.setMaxFs(fs); diff --git a/packages/@webex/plugin-meetings/test/unit/spec/multistream/remoteMedia.ts b/packages/@webex/plugin-meetings/test/unit/spec/multistream/remoteMedia.ts index 48eed0bd395..4dac250f82a 100644 --- a/packages/@webex/plugin-meetings/test/unit/spec/multistream/remoteMedia.ts +++ b/packages/@webex/plugin-meetings/test/unit/spec/multistream/remoteMedia.ts @@ -249,14 +249,18 @@ describe('RemoteMedia', () => { forEach( [ - {height: 134, fs: 60}, - {height: 135, fs: 240}, - {height: 269, fs: 240}, - {height: 270, fs: 920}, - {height: 539, fs: 920}, - {height: 540, fs: 3600}, + {height: 90, fs: 60}, // 90p + {height: 98, fs: 60}, + {height: 99, fs: 240}, // 180p + {height: 180, fs: 240}, + {height: 197, fs: 240}, + {height: 198, fs: 920}, // 360p + {height: 360, fs: 920}, + {height: 395, fs: 920}, + {height: 396, fs: 3600}, // 720p {height: 720, fs: 3600}, - {height: 721, fs: 8192}, + {height: 721, fs: 8192}, // 1080p + {height: 1080, fs: 8192}, ], ({height, fs}) => { it(`sets the max fs to ${fs} correctly when height is ${height}`, () => {