Skip to content

Commit e148ece

Browse files
authored
feat(TS) Migrated modules/RTC/TPCUtils.ts to TS (#2882)
1 parent 044b217 commit e148ece

File tree

2 files changed

+103
-55
lines changed

2 files changed

+103
-55
lines changed

modules/RTC/TPCUtils.js renamed to modules/RTC/TPCUtils.ts

Lines changed: 79 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,40 @@ import { VideoType } from '../../service/RTC/VideoType';
1717
import browser from '../browser';
1818
import SDPUtil from '../sdp/SDPUtil';
1919

20+
import JitsiLocalTrack from './JitsiLocalTrack';
21+
import TraceablePeerConnection, { IAudioQuality, IRTCRtpEncodingParameters, IVideoQuality } from './TraceablePeerConnection';
22+
2023
const logger = getLogger('modules/RTC/TPCUtils');
2124
const VIDEO_CODECS = [ CodecMimeType.AV1, CodecMimeType.H264, CodecMimeType.VP8, CodecMimeType.VP9 ];
2225

26+
27+
// Codec configuration interface (reusable for all video codecs)
28+
export interface ICodecConfig {
29+
maxBitratesVideo?: {
30+
[key: string]: number;
31+
};
32+
scalabilityModeEnabled?: boolean;
33+
useKSVC?: boolean;
34+
useSimulcast?: boolean;
35+
}
36+
37+
export interface ITPCUtilsOptions {
38+
audioQuality?: IAudioQuality;
39+
isP2P?: boolean;
40+
videoQuality?: IVideoQuality;
41+
}
42+
2343
/**
2444
* Handles all the utility functions for the TraceablePeerConnection class, like calculating the encoding parameters,
2545
* determining the media direction, calculating bitrates based on the current codec settings, etc.
2646
*/
2747
export class TPCUtils {
48+
private pc: TraceablePeerConnection;
49+
private options: ITPCUtilsOptions;
50+
/**
51+
* @internal
52+
*/
53+
codecSettings: IVideoQuality;
2854
/**
2955
* Creates a new instance for a given TraceablePeerConnection
3056
*
@@ -34,18 +60,11 @@ export class TPCUtils {
3460
* @param options.isP2P - whether the connection is a P2P connection.
3561
* @param options.videoQuality - the video quality settings that are used to calculate the encoding parameters.
3662
*/
37-
constructor(peerconnection, options = {}) {
63+
constructor(peerconnection: TraceablePeerConnection, options: ITPCUtilsOptions = {}) {
3864
this.pc = peerconnection;
3965
this.options = options;
4066
this.codecSettings = cloneDeep(STANDARD_CODEC_SETTINGS);
4167

42-
/**
43-
* Flag indicating bridge support for AV1 codec. On the bridge connection, it is supported only when support for
44-
* Dependency Descriptor header extensions is offered by Jicofo. H.264 simulcast is also possible when these
45-
* header extensions are negotiated.
46-
*/
47-
this.supportsDDHeaderExt = false;
48-
4968
/**
5069
* Reads videoQuality settings from config.js and overrides the code defaults for video codecs.
5170
*/
@@ -57,8 +76,7 @@ export class TPCUtils {
5776
const bitrateSettings = codecConfig?.maxBitratesVideo
5877

5978
// Read the deprecated settings for max bitrates.
60-
?? (videoQualitySettings.maxbitratesvideo
61-
&& videoQualitySettings.maxbitratesvideo[codec.toUpperCase()]);
79+
?? (videoQualitySettings?.maxbitratesvideo?.[codec.toUpperCase()]);
6280

6381
if (bitrateSettings) {
6482
const settings = Object.values(VIDEO_QUALITY_SETTINGS);
@@ -100,7 +118,7 @@ export class TPCUtils {
100118
* @returns {Object} configuration.
101119
* @private
102120
*/
103-
_calculateActiveEncodingParams(localVideoTrack, codec, newHeight) {
121+
private _calculateActiveEncodingParams(localVideoTrack: JitsiLocalTrack, codec: CodecMimeType, newHeight: number): IRTCRtpEncodingParameters {
104122
const codecBitrates = this.codecSettings[codec].maxBitratesVideo;
105123
const trackCaptureHeight = localVideoTrack.getCaptureResolution();
106124
const effectiveNewHeight = newHeight > trackCaptureHeight ? trackCaptureHeight : newHeight;
@@ -127,9 +145,10 @@ export class TPCUtils {
127145
}
128146
}
129147

130-
const config = {
148+
const config: IRTCRtpEncodingParameters = {
131149
active: effectiveNewHeight > 0,
132150
maxBitrate,
151+
rid: undefined,
133152
scalabilityMode,
134153
scaleResolutionDownBy
135154
};
@@ -164,13 +183,13 @@ export class TPCUtils {
164183
* @returns {Array<CodecMimeType>}
165184
* @private
166185
*/
167-
_getConfiguredVideoCodecsImpl(parsedSdp) {
186+
private _getConfiguredVideoCodecsImpl(parsedSdp: transform.SessionDescription): CodecMimeType[] {
168187
const mLine = parsedSdp.media.find(m => m.type === MediaType.VIDEO);
169188
const codecs = new Set(mLine.rtp
170189
.filter(pt => pt.codec.toLowerCase() !== 'rtx')
171190
.map(pt => pt.codec.toLowerCase()));
172191

173-
return Array.from(codecs);
192+
return Array.from(codecs) as CodecMimeType[];
174193
}
175194

176195
/**
@@ -191,7 +210,7 @@ export class TPCUtils {
191210
* @returns {Array<Object>} - The initial configuration for the stream encodings.
192211
* @private
193212
*/
194-
_getVideoStreamEncodings(localTrack, codec) {
213+
private _getVideoStreamEncodings(localTrack: JitsiLocalTrack, codec: string): Partial<IRTCRtpEncodingParameters>[] {
195214
const captureResolution = localTrack.getCaptureResolution();
196215
const codecBitrates = this.codecSettings[codec].maxBitratesVideo;
197216
const videoType = localTrack.getVideoType();
@@ -226,7 +245,7 @@ export class TPCUtils {
226245
effectiveScaleFactors = effectiveScaleFactors.reverse();
227246
}
228247

229-
const standardSimulcastEncodings = [
248+
const standardSimulcastEncodings: IRTCRtpEncodingParameters[] = [
230249
{
231250
active: this.pc.videoTransferActive,
232251
maxBitrate: effectiveBitrates[0],
@@ -290,7 +309,7 @@ export class TPCUtils {
290309
* @returns boolean - true if the video encoder is running in full SVC mode, false otherwise.
291310
* @private
292311
*/
293-
_isRunningInFullSvcMode(codec) {
312+
private _isRunningInFullSvcMode(codec: CodecMimeType): boolean {
294313
return (codec === CodecMimeType.VP9 || codec === CodecMimeType.AV1)
295314
&& this.codecSettings[codec].scalabilityModeEnabled
296315
&& !this.codecSettings[codec].useSimulcast;
@@ -308,7 +327,7 @@ export class TPCUtils {
308327
* @returns {boolean} - true if the bitrate needs to be capped for the screenshare track, false otherwise.
309328
* @private
310329
*/
311-
_isScreenshareBitrateCapped(localVideoTrack) {
330+
private _isScreenshareBitrateCapped(localVideoTrack: JitsiLocalTrack): boolean {
312331
return localVideoTrack.getVideoType() === VideoType.DESKTOP
313332
&& this.pc._capScreenshareBitrate
314333
&& !browser.isWebKitBased();
@@ -322,8 +341,9 @@ export class TPCUtils {
322341
* @param {CodecMimeType} codec - The codec currently in use.
323342
* @param {number} newHeight The resolution requested for the video track.
324343
* @returns {Array<boolean>}
344+
* @internal
325345
*/
326-
calculateEncodingsActiveState(localVideoTrack, codec, newHeight) {
346+
calculateEncodingsActiveState(localVideoTrack: JitsiLocalTrack, codec: CodecMimeType, newHeight: number): boolean[] {
327347
const height = localVideoTrack.getCaptureResolution();
328348
const videoStreamEncodings = this._getVideoStreamEncodings(localVideoTrack, codec);
329349
const encodingsState = videoStreamEncodings
@@ -375,8 +395,9 @@ export class TPCUtils {
375395
* @param {CodecMimeType} codec - The codec currently in use.
376396
* @param {number} newHeight The resolution requested for the video track.
377397
* @returns {Array<number>}
398+
* @internal
378399
*/
379-
calculateEncodingsBitrates(localVideoTrack, codec, newHeight) {
400+
calculateEncodingsBitrates(localVideoTrack: JitsiLocalTrack, codec: CodecMimeType, newHeight: number): number[] {
380401
const codecBitrates = this.codecSettings[codec].maxBitratesVideo;
381402
const desktopShareBitrate = this.options.videoQuality?.desktopbitrate || codecBitrates.ssHigh;
382403
const encodingsBitrates = this._getVideoStreamEncodings(localVideoTrack, codec)
@@ -408,8 +429,9 @@ export class TPCUtils {
408429
* @param {CodecMimeType} codec - The codec currently in use.
409430
* @param {number} maxHeight The resolution requested for the video track.
410431
* @returns {Optional<Array<VideoEncoderScalabilityMode>>}
432+
* @internal
411433
*/
412-
calculateEncodingsScalabilityMode(localVideoTrack, codec, maxHeight) {
434+
calculateEncodingsScalabilityMode(localVideoTrack: JitsiLocalTrack, codec: CodecMimeType, maxHeight: number): Optional<Optional<VideoEncoderScalabilityMode>[]> {
413435
if (!this.codecSettings[codec].scalabilityModeEnabled) {
414436
return;
415437
}
@@ -431,7 +453,7 @@ export class TPCUtils {
431453
const { scalabilityMode }
432454
= this._calculateActiveEncodingParams(localVideoTrack, codec, maxHeight);
433455

434-
scalabilityModes[0] = scalabilityMode;
456+
scalabilityModes[0] = scalabilityMode as VideoEncoderScalabilityMode;
435457
scalabilityModes[1] = undefined;
436458
scalabilityModes[2] = undefined;
437459

@@ -449,8 +471,9 @@ export class TPCUtils {
449471
* @param {CodecMimeType} codec - The codec currently in use.
450472
* @param {number} maxHeight The resolution requested for the video track.
451473
* @returns {Array<float>}
474+
* @internal
452475
*/
453-
calculateEncodingsScaleFactor(localVideoTrack, codec, maxHeight) {
476+
calculateEncodingsScaleFactor(localVideoTrack: JitsiLocalTrack, codec: CodecMimeType, maxHeight: number): number[] {
454477
if (this.pc.isSpatialScalabilityOn() && this.isRunningInSimulcastMode(codec)) {
455478
return this._getVideoStreamEncodings(localVideoTrack, codec)
456479
.map(encoding => encoding.scaleResolutionDownBy);
@@ -469,15 +492,16 @@ export class TPCUtils {
469492
* media description.
470493
* @param {Object} description the webRTC session description instance for the remote description.
471494
* @returns {Object} the modified webRTC session description instance.
495+
* @internal
472496
*/
473-
ensureCorrectOrderOfSsrcs(description) {
497+
ensureCorrectOrderOfSsrcs(description: RTCSessionDescription) {
474498
const parsedSdp = transform.parse(description.sdp);
475499

476500
parsedSdp.media.forEach(mLine => {
477501
if (mLine.type === MediaType.AUDIO) {
478502
return;
479503
}
480-
if (!mLine.ssrcGroups || !mLine.ssrcGroups.length) {
504+
if (!mLine.ssrcGroups?.length) {
481505
return;
482506
}
483507
let reorderedSsrcs = [];
@@ -499,24 +523,26 @@ export class TPCUtils {
499523
mLine.ssrcs = reorderedSsrcs;
500524
});
501525

502-
return {
526+
return new RTCSessionDescription({
503527
sdp: transform.write(parsedSdp),
504528
type: description.type
505-
};
529+
});
506530
}
507531

508532
/**
509533
* Returns the codec that is configured on the client as the preferred video codec for the given local video track.
510534
*
511535
* @param {JitsiLocalTrack} localTrack - The local video track.
512536
* @returns {CodecMimeType} The codec that is set as the preferred codec for the given local video track.
537+
* @internal
513538
*/
514-
getConfiguredVideoCodec(localTrack) {
539+
getConfiguredVideoCodec(localTrack: JitsiLocalTrack): CodecMimeType | string {
515540
const localVideoTrack = localTrack ?? this.pc.getLocalVideoTracks()[0];
516541
const rtpSender = this.pc.findSenderForTrack(localVideoTrack.getTrack());
517542

518543
if (this.pc.usesCodecSelectionAPI() && rtpSender) {
519-
const { encodings } = rtpSender.getParameters();
544+
// added any to remove the subsequrnt @ts-ignore comments
545+
const { encodings } = rtpSender.getParameters() as any;
520546

521547
if (encodings[0].codec) {
522548
return encodings[0].codec.mimeType.split('/')[1].toLowerCase();
@@ -546,8 +572,9 @@ export class TPCUtils {
546572
*
547573
* @param {string} - The local SDP to be used.
548574
* @returns {Array}
575+
* @internal
549576
*/
550-
getConfiguredVideoCodecs(sdp) {
577+
getConfiguredVideoCodecs(sdp: Optional<string>): CodecMimeType[] {
551578
const currentSdp = sdp ?? this.pc.localDescription?.sdp;
552579

553580
if (!currentSdp) {
@@ -564,8 +591,9 @@ export class TPCUtils {
564591
* @param {MediaType} mediaType - The media type for which the desired media direction is to be obtained.
565592
* @param {boolean} isAddOperation - Whether the direction is being set for a source add operation.
566593
* @returns {MediaDirection} - The desired media direction for the given media type.
594+
* @internal
567595
*/
568-
getDesiredMediaDirection(mediaType, isAddOperation = false) {
596+
getDesiredMediaDirection(mediaType: MediaType, isAddOperation = false): MediaDirection {
569597
const hasLocalSource = this.pc.getLocalTracks(mediaType).length > 0;
570598

571599
if (isAddOperation) {
@@ -579,8 +607,9 @@ export class TPCUtils {
579607
* Obtains stream encodings that need to be configured on the given track based
580608
* on the track media type and the simulcast setting.
581609
* @param {JitsiLocalTrack} localTrack
610+
* @internal
582611
*/
583-
getStreamEncodings(localTrack) {
612+
getStreamEncodings(localTrack: JitsiLocalTrack): Partial<IRTCRtpEncodingParameters>[] {
584613
if (localTrack.isAudioTrack()) {
585614
return [ { active: this.pc.audioTransferActive } ];
586615
}
@@ -603,8 +632,9 @@ export class TPCUtils {
603632
*
604633
* @param desc A session description object (with 'type' and 'sdp' fields)
605634
* @return A session description object with its sdp field modified to contain an inject ssrc-group for simulcast.
635+
* @internal
606636
*/
607-
injectSsrcGroupForSimulcast(desc) {
637+
injectSsrcGroupForSimulcast(desc: RTCSessionDescription): RTCSessionDescription {
608638
const sdp = transform.parse(desc.sdp);
609639
const video = sdp.media.find(mline => mline.type === 'video');
610640

@@ -615,7 +645,7 @@ export class TPCUtils {
615645
if (video.simulcast || video.simulcast_03) {
616646
const ssrcs = [];
617647

618-
if (fidGroups && fidGroups.length) {
648+
if (fidGroups?.length) {
619649
fidGroups.forEach(group => {
620650
ssrcs.push(group.ssrcs.split(' ')[0]);
621651
});
@@ -642,22 +672,22 @@ export class TPCUtils {
642672
}
643673
}
644674

645-
return {
675+
return new RTCSessionDescription({
646676
sdp: transform.write(sdp),
647677
type: desc.type
648-
};
678+
});
649679
}
650680

651681
/**
652682
* Takes in a *unified plan* offer and inserts the appropriate parameters for adding simulcast receive support.
653683
* @param {Object} desc - A session description object
654684
* @param {String} desc.type - the type (offer/answer)
655685
* @param {String} desc.sdp - the sdp content
656-
*
686+
* @internal
657687
* @return {Object} A session description (same format as above) object with its sdp field modified to advertise
658688
* simulcast receive support.
659689
*/
660-
insertUnifiedPlanSimulcastReceive(desc) {
690+
insertUnifiedPlanSimulcastReceive(desc: RTCSessionDescription): RTCSessionDescription {
661691
// a=simulcast line is not needed on browsers where we SDP munging is used for enabling on simulcast.
662692
// Remove this check when the client switches to RID/MID based simulcast on all browsers.
663693
if (browser.usesSdpMungingForSimulcast()) {
@@ -704,10 +734,10 @@ export class TPCUtils {
704734
}
705735
});
706736

707-
return {
737+
return new RTCSessionDescription({
708738
sdp: transform.write(sdp),
709739
type: desc.type
710-
};
740+
});
711741
}
712742

713743
/**
@@ -716,9 +746,10 @@ export class TPCUtils {
716746
*
717747
* @param {CodecMimeType} videoCodec - The video codec in use.
718748
* @returns {boolean}
749+
* @internal
719750
*/
720-
isRunningInSimulcastMode(videoCodec) {
721-
if (!this.codecSettings || !this.codecSettings[videoCodec]) {
751+
isRunningInSimulcastMode(videoCodec: CodecMimeType): boolean {
752+
if (!this.codecSettings?.[videoCodec]) {
722753
// If codec settings are not available, assume no simulcast
723754
return false;
724755
}
@@ -746,8 +777,9 @@ export class TPCUtils {
746777
*
747778
* @param {transform.SessionDescription} parsedSdp that needs to be munged
748779
* @returns {transform.SessionDescription} the munged SDP.
780+
* @internal
749781
*/
750-
mungeCodecOrder(parsedSdp) {
782+
mungeCodecOrder(parsedSdp: transform.SessionDescription): transform.SessionDescription {
751783
const codecSettings = this.pc.codecSettings;
752784

753785
if (!codecSettings) {
@@ -797,8 +829,9 @@ export class TPCUtils {
797829
*
798830
* @param {transform.SessionDescription} parsedSdp that needs to be munged.
799831
* @returns {transform.SessionDescription} the munged SDP.
832+
* @internal
800833
*/
801-
mungeOpus(parsedSdp) {
834+
mungeOpus(parsedSdp: transform.SessionDescription): transform.SessionDescription {
802835
const { audioQuality } = this.options;
803836

804837
if (!audioQuality?.enableOpusDtx && !audioQuality?.stereo && !audioQuality?.opusMaxAverageBitrate) {
@@ -867,8 +900,9 @@ export class TPCUtils {
867900
* @param {transform.SessionDescription} parsedSdp that needs to be munged.
868901
* @param {boolean} isLocalSdp - Whether the max bitrate (via b=AS line in SDP) is set on local SDP.
869902
* @returns {transform.SessionDescription} The munged SDP.
903+
* @internal
870904
*/
871-
setMaxBitrates(parsedSdp, isLocalSdp = false) {
905+
setMaxBitrates(parsedSdp: transform.SessionDescription, isLocalSdp = false): transform.SessionDescription {
872906
const pcCodecSettings = this.pc.codecSettings;
873907

874908
if (!pcCodecSettings) {

0 commit comments

Comments
 (0)