@@ -11,6 +11,7 @@ import { isRemoteVideoTrack } from '../utils';
1111import type RemoteTrack from './RemoteTrack' ;
1212import { Track , VideoQuality } from './Track' ;
1313import { TrackPublication } from './TrackPublication' ;
14+ import { areDimensionsSmaller , layerDimensionsFor } from './utils' ;
1415
1516export default class RemoteTrackPublication extends TrackPublication {
1617 track ?: RemoteTrack = undefined ;
@@ -21,11 +22,15 @@ export default class RemoteTrackPublication extends TrackPublication {
2122 // keeps track of client's desire to subscribe to a track, also true if autoSubscribe is active
2223 protected subscribed ?: boolean ;
2324
24- protected disabled : boolean = false ;
25+ protected requestedDisabled : boolean | undefined = undefined ;
2526
26- protected currentVideoQuality ?: VideoQuality = VideoQuality . HIGH ;
27+ protected visible : boolean = true ;
2728
28- protected videoDimensions ?: Track . Dimensions ;
29+ protected videoDimensionsAdaptiveStream ?: Track . Dimensions ;
30+
31+ protected requestedVideoDimensions ?: Track . Dimensions ;
32+
33+ protected requestedMaxQuality ?: VideoQuality ;
2934
3035 protected fps ?: number ;
3136
@@ -105,7 +110,9 @@ export default class RemoteTrackPublication extends TrackPublication {
105110 }
106111
107112 get isEnabled ( ) : boolean {
108- return ! this . disabled ;
113+ return this . requestedDisabled !== undefined
114+ ? ! this . requestedDisabled
115+ : this . isAdaptiveStream && this . visible ;
109116 }
110117
111118 get isLocal ( ) {
@@ -119,10 +126,10 @@ export default class RemoteTrackPublication extends TrackPublication {
119126 * @param enabled
120127 */
121128 setEnabled ( enabled : boolean ) {
122- if ( ! this . isManualOperationAllowed ( ) || this . disabled === ! enabled ) {
129+ if ( ! this . isManualOperationAllowed ( ) || this . requestedDisabled === ! enabled ) {
123130 return ;
124131 }
125- this . disabled = ! enabled ;
132+ this . requestedDisabled = ! enabled ;
126133
127134 this . emitTrackUpdate ( ) ;
128135 }
@@ -135,29 +142,36 @@ export default class RemoteTrackPublication extends TrackPublication {
135142 * optimize for uninterrupted video
136143 */
137144 setVideoQuality ( quality : VideoQuality ) {
138- if ( ! this . isManualOperationAllowed ( ) || this . currentVideoQuality === quality ) {
145+ if ( ! this . isManualOperationAllowed ( ) || this . requestedMaxQuality === quality ) {
139146 return ;
140147 }
141- this . currentVideoQuality = quality ;
142- this . videoDimensions = undefined ;
148+ this . requestedMaxQuality = quality ;
149+ this . requestedVideoDimensions = undefined ;
143150
144151 this . emitTrackUpdate ( ) ;
145152 }
146153
154+ /**
155+ * Explicitly set the video dimensions for this track.
156+ *
157+ * This will take precedence over adaptive stream dimensions.
158+ *
159+ * @param dimensions The video dimensions to set.
160+ */
147161 setVideoDimensions ( dimensions : Track . Dimensions ) {
148162 if ( ! this . isManualOperationAllowed ( ) ) {
149163 return ;
150164 }
151165 if (
152- this . videoDimensions ?. width === dimensions . width &&
153- this . videoDimensions ?. height === dimensions . height
166+ this . requestedVideoDimensions ?. width === dimensions . width &&
167+ this . requestedVideoDimensions ?. height === dimensions . height
154168 ) {
155169 return ;
156170 }
157171 if ( isRemoteVideoTrack ( this . track ) ) {
158- this . videoDimensions = dimensions ;
172+ this . requestedVideoDimensions = dimensions ;
159173 }
160- this . currentVideoQuality = undefined ;
174+ this . requestedMaxQuality = undefined ;
161175
162176 this . emitTrackUpdate ( ) ;
163177 }
@@ -180,7 +194,7 @@ export default class RemoteTrackPublication extends TrackPublication {
180194 }
181195
182196 get videoQuality ( ) : VideoQuality | undefined {
183- return this . currentVideoQuality ;
197+ return this . requestedMaxQuality ?? VideoQuality . HIGH ;
184198 }
185199
186200 /** @internal */
@@ -260,13 +274,6 @@ export default class RemoteTrackPublication extends TrackPublication {
260274 }
261275
262276 private isManualOperationAllowed ( ) : boolean {
263- if ( this . kind === Track . Kind . Video && this . isAdaptiveStream ) {
264- this . log . warn (
265- 'adaptive stream is enabled, cannot change video track settings' ,
266- this . logContext ,
267- ) ;
268- return false ;
269- }
270277 if ( ! this . isDesired ) {
271278 this . log . warn ( 'cannot update track settings when not subscribed' , this . logContext ) ;
272279 return false ;
@@ -288,7 +295,7 @@ export default class RemoteTrackPublication extends TrackPublication {
288295 `adaptivestream video visibility ${ this . trackSid } , visible=${ visible } ` ,
289296 this . logContext ,
290297 ) ;
291- this . disabled = ! visible ;
298+ this . visible = visible ;
292299 this . emitTrackUpdate ( ) ;
293300 } ;
294301
@@ -297,25 +304,75 @@ export default class RemoteTrackPublication extends TrackPublication {
297304 `adaptivestream video dimensions ${ dimensions . width } x${ dimensions . height } ` ,
298305 this . logContext ,
299306 ) ;
300- this . videoDimensions = dimensions ;
307+ this . videoDimensionsAdaptiveStream = dimensions ;
301308 this . emitTrackUpdate ( ) ;
302309 } ;
303310
304311 /* @internal */
305312 emitTrackUpdate ( ) {
306313 const settings : UpdateTrackSettings = new UpdateTrackSettings ( {
307314 trackSids : [ this . trackSid ] ,
308- disabled : this . disabled ,
315+ disabled : ! this . isEnabled ,
309316 fps : this . fps ,
310317 } ) ;
311- if ( this . videoDimensions ) {
312- settings . width = Math . ceil ( this . videoDimensions . width ) ;
313- settings . height = Math . ceil ( this . videoDimensions . height ) ;
314- } else if ( this . currentVideoQuality !== undefined ) {
315- settings . quality = this . currentVideoQuality ;
316- } else {
317- // defaults to high quality
318- settings . quality = VideoQuality . HIGH ;
318+
319+ if ( this . kind === Track . Kind . Video ) {
320+ let minDimensions = this . requestedVideoDimensions ;
321+
322+ if ( this . videoDimensionsAdaptiveStream !== undefined ) {
323+ if ( minDimensions ) {
324+ // check whether the adaptive stream dimensions are smaller than the requested dimensions and use smaller one
325+ const smallerAdaptive = areDimensionsSmaller (
326+ this . videoDimensionsAdaptiveStream ,
327+ minDimensions ,
328+ ) ;
329+ if ( smallerAdaptive ) {
330+ this . log . debug ( 'using adaptive stream dimensions instead of requested' , {
331+ ...this . logContext ,
332+ ...this . videoDimensionsAdaptiveStream ,
333+ } ) ;
334+ minDimensions = this . videoDimensionsAdaptiveStream ;
335+ }
336+ } else if ( this . requestedMaxQuality !== undefined && this . trackInfo ) {
337+ // check whether adaptive stream dimensions are smaller than the max quality layer and use smaller one
338+ const maxQualityLayer = layerDimensionsFor ( this . trackInfo , this . requestedMaxQuality ) ;
339+
340+ if (
341+ maxQualityLayer &&
342+ areDimensionsSmaller ( this . videoDimensionsAdaptiveStream , maxQualityLayer )
343+ ) {
344+ this . log . debug ( 'using adaptive stream dimensions instead of max quality layer' , {
345+ ...this . logContext ,
346+ ...this . videoDimensionsAdaptiveStream ,
347+ } ) ;
348+ minDimensions = this . videoDimensionsAdaptiveStream ;
349+ }
350+ } else {
351+ this . log . debug ( 'using adaptive stream dimensions' , {
352+ ...this . logContext ,
353+ ...this . videoDimensionsAdaptiveStream ,
354+ } ) ;
355+ minDimensions = this . videoDimensionsAdaptiveStream ;
356+ }
357+ }
358+
359+ if ( minDimensions ) {
360+ settings . width = Math . ceil ( minDimensions . width ) ;
361+ settings . height = Math . ceil ( minDimensions . height ) ;
362+ } else if ( this . requestedMaxQuality !== undefined ) {
363+ this . log . debug ( 'using requested max quality' , {
364+ ...this . logContext ,
365+ quality : this . requestedMaxQuality ,
366+ } ) ;
367+ settings . quality = this . requestedMaxQuality ;
368+ } else {
369+ this . log . debug ( 'using default quality' , {
370+ ...this . logContext ,
371+ quality : VideoQuality . HIGH ,
372+ } ) ;
373+ // defaults to high quality
374+ settings . quality = VideoQuality . HIGH ;
375+ }
319376 }
320377
321378 this . emit ( TrackEvent . UpdateSettings , settings ) ;
0 commit comments