@@ -50,43 +50,57 @@ describe('Codec Selection', () => {
5050 } ;
5151
5252 qualityController = new QualityController ( conference , options ) ;
53+ jasmine . clock ( ) . install ( ) ;
5354 spyOn ( jingleSession , 'setVideoCodecs' ) ;
5455 } ) ;
5556
56- it ( 'and remote endpoints use the new codec selection logic' , ( ) => {
57+ afterEach ( ( ) => {
58+ jasmine . clock ( ) . uninstall ( ) ;
59+ } ) ;
60+
61+ it ( 'and remote endpoints use the new codec selection logic' , async ( ) => {
5762 // Add a second user joining the call.
5863 participant1 = new MockParticipant ( 'remote-1' ) ;
5964 conference . addParticipant ( participant1 , [ 'vp9' , 'vp8' ] ) ;
6065
66+ await nextTick ( 1000 ) ;
67+
6168 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 1 ) ;
69+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp9' , 'vp8' ] , 'vp9' ) ;
6270
6371 // Add a third user joining the call with a subset of codecs.
6472 participant2 = new MockParticipant ( 'remote-2' ) ;
6573 conference . addParticipant ( participant2 , [ 'vp8' ] ) ;
6674
67- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp8' ] , 'vp9' ) ;
68-
69- // Make p2 leave the call
75+ // Make p2 leave the call.
7076 conference . removeParticipant ( participant2 ) ;
71- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 3 ) ;
77+
78+ await nextTick ( 1000 ) ;
79+
80+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 2 ) ;
81+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp9' , 'vp8' ] , 'vp9' ) ;
7282 } ) ;
7383
74- it ( 'and remote endpoints use the old codec selection logic (RN)' , ( ) => {
84+ it ( 'and remote endpoints use the old codec selection logic (RN)' , async ( ) => {
7585 // Add a second user joining the call.
7686 participant1 = new MockParticipant ( 'remote-1' ) ;
7787 conference . addParticipant ( participant1 , null , 'vp8' ) ;
7888
89+ await nextTick ( 1000 ) ;
90+
91+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 1 ) ;
7992 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp8' ] , 'vp9' ) ;
8093
8194 // Add a third user (newer) to the call.
8295 participant2 = new MockParticipant ( 'remote-2' ) ;
8396 conference . addParticipant ( participant2 , [ 'vp9' , 'vp8' ] ) ;
8497
85- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp8' ] , 'vp9' ) ;
86-
8798 // Make p1 leave the call
8899 conference . removeParticipant ( participant1 ) ;
89- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 3 ) ;
100+
101+ await nextTick ( 1000 ) ;
102+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 2 ) ;
103+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp9' , 'vp8' ] , 'vp9' ) ;
90104 } ) ;
91105 } ) ;
92106
@@ -102,50 +116,61 @@ describe('Codec Selection', () => {
102116
103117 qualityController = new QualityController ( conference , options ) ;
104118 spyOn ( jingleSession , 'setVideoCodecs' ) ;
119+ jasmine . clock ( ) . install ( ) ;
105120 } ) ;
106121
107- it ( 'and remote endpoints use the new codec selection logic' , ( ) => {
122+ afterEach ( ( ) => {
123+ jasmine . clock ( ) . uninstall ( ) ;
124+ } ) ;
125+
126+ it ( 'and remote endpoints use the new codec selection logic' , async ( ) => {
108127 // Add a second user joining the call.
109128 participant1 = new MockParticipant ( 'remote-1' ) ;
110129 conference . addParticipant ( participant1 , [ 'vp9' , 'vp8' , 'h264' ] ) ;
111130
131+ await nextTick ( 1000 ) ;
112132 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 1 ) ;
133+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp9' , 'vp8' ] , undefined ) ;
113134
114135 // Add a third user joining the call with a subset of codecs.
115136 participant2 = new MockParticipant ( 'remote-2' ) ;
116137 conference . addParticipant ( participant2 , [ 'vp8' ] ) ;
117138
118- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp8' ] , undefined ) ;
119-
120139 // Make p2 leave the call
121140 conference . removeParticipant ( participant2 ) ;
122- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 3 ) ;
141+
142+ await nextTick ( 1000 ) ;
143+
144+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 2 ) ;
123145 } ) ;
124146
125- it ( 'and remote endpoint prefers a codec that is locally disabled' , ( ) => {
147+ it ( 'and remote endpoint prefers a codec that is locally disabled' , async ( ) => {
126148 // Add a second user joining the call the prefers H.264 and VP8.
127149 participant1 = new MockParticipant ( 'remote-1' ) ;
128150 conference . addParticipant ( participant1 , [ 'h264' , 'vp8' ] ) ;
129151
152+ await nextTick ( 1200 ) ;
130153 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp8' ] , undefined ) ;
131154 } ) ;
132155
133- it ( 'and remote endpoints use the old codec selection logic (RN)' , ( ) => {
156+ it ( 'and remote endpoints use the old codec selection logic (RN)' , async ( ) => {
134157 // Add a second user joining the call.
135158 participant1 = new MockParticipant ( 'remote-1' ) ;
136159 conference . addParticipant ( participant1 , null , 'vp8' ) ;
137160
161+ await nextTick ( 1000 ) ;
162+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 1 ) ;
138163 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp8' ] , undefined ) ;
139164
140165 // Add a third user (newer) to the call.
141166 participant2 = new MockParticipant ( 'remote-2' ) ;
142167 conference . addParticipant ( participant2 , [ 'vp9' , 'vp8' , 'h264' ] ) ;
143168
144- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp8' ] , undefined ) ;
145-
146169 // Make p1 leave the call
147170 conference . removeParticipant ( participant1 ) ;
148- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 3 ) ;
171+
172+ jasmine . clock ( ) . tick ( 1000 ) ;
173+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 2 ) ;
149174 } ) ;
150175 } ) ;
151176
@@ -171,11 +196,14 @@ describe('Codec Selection', () => {
171196
172197 participant1 = new MockParticipant ( 'remote-1' ) ;
173198 conference . addParticipant ( participant1 , [ 'av1' , 'vp9' , 'vp8' ] ) ;
199+
200+ await nextTick ( 1000 ) ;
201+
174202 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'av1' , 'vp9' , 'vp8' ] , undefined ) ;
175203
176204 participant2 = new MockParticipant ( 'remote-2' ) ;
177205 conference . addParticipant ( participant2 , [ 'av1' , 'vp9' , 'vp8' ] ) ;
178- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'av1' , 'vp9' , 'vp8' ] , undefined ) ;
206+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 1 ) ;
179207
180208 qualityController . codecController . changeCodecPreferenceOrder ( localTrack , 'av1' ) ;
181209
@@ -187,6 +215,7 @@ describe('Codec Selection', () => {
187215
188216 // Expect the local endpoint to continue sending VP9.
189217 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp9' , 'av1' , 'vp8' ] , undefined ) ;
218+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 3 ) ;
190219 } ) ;
191220
192221 it ( 'and does not change codec if the current codec is already the lowest complexity codec' , async ( ) => {
@@ -196,6 +225,8 @@ describe('Codec Selection', () => {
196225
197226 participant1 = new MockParticipant ( 'remote-1' ) ;
198227 conference . addParticipant ( participant1 , [ 'av1' , 'vp9' , 'vp8' ] ) ;
228+
229+ await nextTick ( 1000 ) ;
199230 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp8' , 'vp9' , 'av1' ] , undefined ) ;
200231
201232 participant2 = new MockParticipant ( 'remote-2' ) ;
@@ -239,11 +270,14 @@ describe('Codec Selection', () => {
239270
240271 participant1 = new MockParticipant ( 'remote-1' ) ;
241272 conference . addParticipant ( participant1 , [ 'av1' , 'vp9' , 'vp8' ] ) ;
273+
274+ await nextTick ( 1000 ) ;
275+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 1 ) ;
242276 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'av1' , 'vp9' , 'vp8' ] , undefined ) ;
243277
244278 participant2 = new MockParticipant ( 'remote-2' ) ;
245279 conference . addParticipant ( participant2 , [ 'av1' , 'vp9' , 'vp8' ] ) ;
246- expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'av1' , 'vp9' , 'vp8' ] , undefined ) ;
280+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 1 ) ;
247281
248282 const sourceStats = {
249283 avgEncodeTime : 12 ,
@@ -269,6 +303,8 @@ describe('Codec Selection', () => {
269303 participant3 = new MockParticipant ( 'remote-3' ) ;
270304 conference . addParticipant ( participant3 , [ 'av1' , 'vp9' , 'vp8' ] ) ;
271305
306+ await nextTick ( 1000 ) ;
307+
272308 // Expect the local endpoint to continue sending VP9.
273309 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'vp9' , 'av1' , 'vp8' ] , undefined ) ;
274310
@@ -328,4 +364,41 @@ describe('Codec Selection', () => {
328364 expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 0 ) ;
329365 } ) ;
330366 } ) ;
367+
368+ describe ( 'When multiple joins and leaves happen in a quick burst' , ( ) => {
369+ beforeEach ( ( ) => {
370+ options = {
371+ jvb : {
372+ preferenceOrder : [ 'AV1' , 'VP9' , 'VP8' ] ,
373+ screenshareCodec : 'VP9'
374+ } ,
375+ p2p : { }
376+ } ;
377+ jasmine . clock ( ) . install ( ) ;
378+ qualityController = new QualityController ( conference , options ) ;
379+ spyOn ( jingleSession , 'setVideoCodecs' ) ;
380+ } ) ;
381+
382+ afterEach ( ( ) => {
383+ jasmine . clock ( ) . uninstall ( ) ;
384+ } ) ;
385+
386+ it ( 'should call setVideoCodecs only once within the same tick' , async ( ) => {
387+ participant1 = new MockParticipant ( 'remote-1' ) ;
388+ conference . addParticipant ( participant1 , [ 'vp9' , 'vp8' ] ) ;
389+
390+ // Add a third user joining the call with a subset of codecs.
391+ participant2 = new MockParticipant ( 'remote-2' ) ;
392+ conference . addParticipant ( participant2 , [ 'vp8' ] ) ;
393+
394+ // Make p1 and p2 leave the call.
395+ conference . removeParticipant ( participant2 ) ;
396+ conference . removeParticipant ( participant1 ) ;
397+
398+ await nextTick ( 1000 ) ;
399+
400+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledTimes ( 1 ) ;
401+ expect ( jingleSession . setVideoCodecs ) . toHaveBeenCalledWith ( [ 'av1' , 'vp9' , 'vp8' ] , 'vp9' ) ;
402+ } ) ;
403+ } ) ;
331404} ) ;
0 commit comments