@@ -538,22 +538,14 @@ getSelectElement('sendselect').onchange = async function(e) {
538538 if ( ! ( this instanceof HTMLSelectElement ) )
539539 throw new Error ( 'Unexpected type for this' ) ;
540540 updateSettings ( { send : this . value } ) ;
541- let t = getMaxVideoThroughput ( ) ;
542- for ( let id in serverConnection . up ) {
543- let c = serverConnection . up [ id ] ;
544- await setMaxVideoThroughput ( c , t ) ;
545- }
541+ await reconsiderSendParameters ( ) ;
546542} ;
547543
548544getSelectElement ( 'simulcastselect' ) . onchange = async function ( e ) {
549545 if ( ! ( this instanceof HTMLSelectElement ) )
550546 throw new Error ( 'Unexpected type for this' ) ;
551547 updateSettings ( { simulcast : this . value } ) ;
552- let t = getMaxVideoThroughput ( ) ;
553- for ( let id in serverConnection . up ) {
554- let c = serverConnection . up [ id ] ;
555- await setMaxVideoThroughput ( c , t ) ;
556- }
548+ await reconsiderSendParameters ( ) ;
557549} ;
558550
559551/**
@@ -826,11 +818,15 @@ function newUpStream(localId) {
826818}
827819
828820/**
821+ * Sets an up stream's video throughput and simulcast parameters.
822+ *
829823 * @param {Stream } c
830- * @param {number } [bps]
824+ * @param {number } bps
825+ * @param {boolean } simulcast
831826 */
832- async function setMaxVideoThroughput ( c , bps ) {
833- let simulcast = doSimulcast ( ) ;
827+ async function setSendParameters ( c , bps , simulcast ) {
828+ if ( ! c . up )
829+ throw new Error ( 'Setting throughput of down stream' ) ;
834830 let senders = c . pc . getSenders ( ) ;
835831 for ( let i = 0 ; i < senders . length ; i ++ ) {
836832 let s = senders [ i ] ;
@@ -853,6 +849,40 @@ async function setMaxVideoThroughput(c, bps) {
853849 }
854850}
855851
852+ let reconsiderParametersTimer = null ;
853+
854+ /**
855+ * Sets the send parameters for all up streams.
856+ */
857+ async function reconsiderSendParameters ( ) {
858+ cancelReconsiderParameters ( ) ;
859+ let t = getMaxVideoThroughput ( ) ;
860+ let s = doSimulcast ( ) ;
861+ let promises = [ ] ;
862+ for ( let id in serverConnection . up ) {
863+ let c = serverConnection . up [ id ] ;
864+ promises . push ( setSendParameters ( c , t , s ) ) ;
865+ }
866+ await Promise . all ( promises ) ;
867+ }
868+
869+ /**
870+ * Schedules a call to reconsiderSendParameters after a delay.
871+ * The delay avoids excessive flapping.
872+ */
873+ function scheduleReconsiderParameters ( ) {
874+ cancelReconsiderParameters ( ) ;
875+ reconsiderParametersTimer =
876+ setTimeout ( reconsiderSendParameters , 10000 + Math . random ( ) * 10000 ) ;
877+ }
878+
879+ function cancelReconsiderParameters ( ) {
880+ if ( reconsiderParametersTimer ) {
881+ clearTimeout ( reconsiderParametersTimer ) ;
882+ reconsiderParametersTimer = null ;
883+ }
884+ }
885+
856886/**
857887 * @typedef {Object } filterDefinition
858888 * @property {string } [description]
@@ -1057,6 +1087,8 @@ const unlimitedRate = 1000000000;
10571087const simulcastRate = 100000 ;
10581088
10591089/**
1090+ * Decide whether we want to send simulcast.
1091+ *
10601092 * @returns {boolean }
10611093 */
10621094function doSimulcast ( ) {
@@ -1066,6 +1098,8 @@ function doSimulcast() {
10661098 case 'off' :
10671099 return false ;
10681100 default :
1101+ if ( Object . keys ( serverConnection . users ) . length <= 2 )
1102+ return false ;
10691103 let bps = getMaxVideoThroughput ( ) ;
10701104 return bps <= 0 || bps >= 2 * simulcastRate ;
10711105 }
@@ -1872,9 +1906,13 @@ function gotUser(id, kind) {
18721906 switch ( kind ) {
18731907 case 'add' :
18741908 addUser ( id , serverConnection . users [ id ] . username ) ;
1909+ if ( Object . keys ( serverConnection . users ) . length == 3 )
1910+ reconsiderSendParameters ( ) ;
18751911 break ;
18761912 case 'delete' :
18771913 delUser ( id ) ;
1914+ if ( Object . keys ( serverConnection . users ) . length < 3 )
1915+ scheduleReconsiderParameters ( ) ;
18781916 break ;
18791917 case 'change' :
18801918 changeUser ( id , serverConnection . users [ id ] . username ) ;
0 commit comments