@webex/plugin-meetings 3.0.0-beta.31 → 3.0.0-beta.310

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/README.md +46 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +94 -15
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/edit-lock-error.js +52 -0
  11. package/dist/breakouts/edit-lock-error.js.map +1 -0
  12. package/dist/breakouts/events.js +45 -0
  13. package/dist/breakouts/events.js.map +1 -0
  14. package/dist/breakouts/index.js +709 -35
  15. package/dist/breakouts/index.js.map +1 -1
  16. package/dist/breakouts/utils.js +45 -1
  17. package/dist/breakouts/utils.js.map +1 -1
  18. package/dist/common/errors/no-meeting-info.js +51 -0
  19. package/dist/common/errors/no-meeting-info.js.map +1 -0
  20. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  21. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +48 -7
  23. package/dist/common/errors/webex-errors.js.map +1 -1
  24. package/dist/common/logs/logger-proxy.js +1 -1
  25. package/dist/common/logs/logger-proxy.js.map +1 -1
  26. package/dist/common/logs/request.js +5 -1
  27. package/dist/common/logs/request.js.map +1 -1
  28. package/dist/common/queue.js +24 -9
  29. package/dist/common/queue.js.map +1 -1
  30. package/dist/config.js +5 -11
  31. package/dist/config.js.map +1 -1
  32. package/dist/constants.js +233 -29
  33. package/dist/constants.js.map +1 -1
  34. package/dist/controls-options-manager/enums.js +14 -2
  35. package/dist/controls-options-manager/enums.js.map +1 -1
  36. package/dist/controls-options-manager/index.js +109 -15
  37. package/dist/controls-options-manager/index.js.map +1 -1
  38. package/dist/controls-options-manager/types.js +7 -0
  39. package/dist/controls-options-manager/types.js.map +1 -0
  40. package/dist/controls-options-manager/util.js +309 -18
  41. package/dist/controls-options-manager/util.js.map +1 -1
  42. package/dist/index.js +112 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/interpretation/collection.js +23 -0
  45. package/dist/interpretation/collection.js.map +1 -0
  46. package/dist/interpretation/index.js +366 -0
  47. package/dist/interpretation/index.js.map +1 -0
  48. package/dist/interpretation/siLanguage.js +25 -0
  49. package/dist/interpretation/siLanguage.js.map +1 -0
  50. package/dist/locus-info/controlsUtils.js +91 -2
  51. package/dist/locus-info/controlsUtils.js.map +1 -1
  52. package/dist/locus-info/index.js +383 -62
  53. package/dist/locus-info/index.js.map +1 -1
  54. package/dist/locus-info/infoUtils.js +7 -1
  55. package/dist/locus-info/infoUtils.js.map +1 -1
  56. package/dist/locus-info/mediaSharesUtils.js +57 -1
  57. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  58. package/dist/locus-info/parser.js +249 -72
  59. package/dist/locus-info/parser.js.map +1 -1
  60. package/dist/locus-info/selfUtils.js +89 -14
  61. package/dist/locus-info/selfUtils.js.map +1 -1
  62. package/dist/media/index.js +61 -116
  63. package/dist/media/index.js.map +1 -1
  64. package/dist/media/properties.js +73 -124
  65. package/dist/media/properties.js.map +1 -1
  66. package/dist/meeting/in-meeting-actions.js +82 -2
  67. package/dist/meeting/in-meeting-actions.js.map +1 -1
  68. package/dist/meeting/index.js +3777 -2929
  69. package/dist/meeting/index.js.map +1 -1
  70. package/dist/meeting/locusMediaRequest.js +292 -0
  71. package/dist/meeting/locusMediaRequest.js.map +1 -0
  72. package/dist/meeting/muteState.js +230 -124
  73. package/dist/meeting/muteState.js.map +1 -1
  74. package/dist/meeting/request.js +260 -196
  75. package/dist/meeting/request.js.map +1 -1
  76. package/dist/meeting/util.js +601 -417
  77. package/dist/meeting/util.js.map +1 -1
  78. package/dist/meeting-info/index.js +73 -7
  79. package/dist/meeting-info/index.js.map +1 -1
  80. package/dist/meeting-info/meeting-info-v2.js +192 -51
  81. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  82. package/dist/meeting-info/util.js +1 -1
  83. package/dist/meeting-info/util.js.map +1 -1
  84. package/dist/meeting-info/utilv2.js +36 -36
  85. package/dist/meeting-info/utilv2.js.map +1 -1
  86. package/dist/meetings/collection.js +39 -0
  87. package/dist/meetings/collection.js.map +1 -1
  88. package/dist/meetings/index.js +415 -115
  89. package/dist/meetings/index.js.map +1 -1
  90. package/dist/meetings/meetings.types.js +7 -0
  91. package/dist/meetings/meetings.types.js.map +1 -0
  92. package/dist/meetings/request.js +2 -0
  93. package/dist/meetings/request.js.map +1 -1
  94. package/dist/meetings/util.js +72 -6
  95. package/dist/meetings/util.js.map +1 -1
  96. package/dist/member/index.js +58 -0
  97. package/dist/member/index.js.map +1 -1
  98. package/dist/member/types.js +25 -0
  99. package/dist/member/types.js.map +1 -0
  100. package/dist/member/util.js +132 -25
  101. package/dist/member/util.js.map +1 -1
  102. package/dist/members/collection.js +10 -0
  103. package/dist/members/collection.js.map +1 -1
  104. package/dist/members/index.js +102 -6
  105. package/dist/members/index.js.map +1 -1
  106. package/dist/members/request.js +106 -38
  107. package/dist/members/request.js.map +1 -1
  108. package/dist/members/types.js +15 -0
  109. package/dist/members/types.js.map +1 -0
  110. package/dist/members/util.js +326 -232
  111. package/dist/members/util.js.map +1 -1
  112. package/dist/metrics/constants.js +13 -5
  113. package/dist/metrics/constants.js.map +1 -1
  114. package/dist/metrics/index.js +1 -468
  115. package/dist/metrics/index.js.map +1 -1
  116. package/dist/multistream/mediaRequestManager.js +238 -49
  117. package/dist/multistream/mediaRequestManager.js.map +1 -1
  118. package/dist/multistream/receiveSlot.js +29 -16
  119. package/dist/multistream/receiveSlot.js.map +1 -1
  120. package/dist/multistream/receiveSlotManager.js +39 -36
  121. package/dist/multistream/receiveSlotManager.js.map +1 -1
  122. package/dist/multistream/remoteMedia.js +44 -18
  123. package/dist/multistream/remoteMedia.js.map +1 -1
  124. package/dist/multistream/remoteMediaGroup.js +60 -3
  125. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  126. package/dist/multistream/remoteMediaManager.js +209 -59
  127. package/dist/multistream/remoteMediaManager.js.map +1 -1
  128. package/dist/multistream/sendSlotManager.js +233 -0
  129. package/dist/multistream/sendSlotManager.js.map +1 -0
  130. package/dist/reachability/index.js +225 -59
  131. package/dist/reachability/index.js.map +1 -1
  132. package/dist/reachability/request.js +17 -8
  133. package/dist/reachability/request.js.map +1 -1
  134. package/dist/reconnection-manager/index.js +201 -156
  135. package/dist/reconnection-manager/index.js.map +1 -1
  136. package/dist/recording-controller/index.js +21 -2
  137. package/dist/recording-controller/index.js.map +1 -1
  138. package/dist/recording-controller/util.js +9 -8
  139. package/dist/recording-controller/util.js.map +1 -1
  140. package/dist/roap/index.js +62 -32
  141. package/dist/roap/index.js.map +1 -1
  142. package/dist/roap/request.js +112 -97
  143. package/dist/roap/request.js.map +1 -1
  144. package/dist/roap/turnDiscovery.js +95 -36
  145. package/dist/roap/turnDiscovery.js.map +1 -1
  146. package/dist/rtcMetrics/constants.js +12 -0
  147. package/dist/rtcMetrics/constants.js.map +1 -0
  148. package/dist/rtcMetrics/index.js +117 -0
  149. package/dist/rtcMetrics/index.js.map +1 -0
  150. package/dist/statsAnalyzer/index.js +86 -78
  151. package/dist/statsAnalyzer/index.js.map +1 -1
  152. package/dist/statsAnalyzer/mqaUtil.js +11 -10
  153. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  154. package/dist/types/annotation/annotation.types.d.ts +42 -0
  155. package/dist/types/annotation/constants.d.ts +31 -0
  156. package/dist/types/annotation/index.d.ts +117 -0
  157. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  158. package/dist/types/breakouts/events.d.ts +8 -0
  159. package/dist/types/breakouts/utils.d.ts +14 -0
  160. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  161. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  162. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  163. package/dist/types/common/logs/request.d.ts +2 -0
  164. package/dist/types/common/queue.d.ts +9 -7
  165. package/dist/types/config.d.ts +1 -7
  166. package/dist/types/constants.d.ts +194 -24
  167. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  168. package/dist/types/controls-options-manager/index.d.ts +17 -1
  169. package/dist/types/controls-options-manager/types.d.ts +43 -0
  170. package/dist/types/controls-options-manager/util.d.ts +1 -7
  171. package/dist/types/index.d.ts +6 -4
  172. package/dist/types/interpretation/collection.d.ts +5 -0
  173. package/dist/types/interpretation/index.d.ts +5 -0
  174. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  175. package/dist/types/locus-info/index.d.ts +57 -4
  176. package/dist/types/locus-info/parser.d.ts +67 -6
  177. package/dist/types/media/index.d.ts +2 -0
  178. package/dist/types/media/properties.d.ts +34 -48
  179. package/dist/types/meeting/in-meeting-actions.d.ts +82 -2
  180. package/dist/types/meeting/index.d.ts +463 -510
  181. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  182. package/dist/types/meeting/muteState.d.ts +99 -23
  183. package/dist/types/meeting/request.d.ts +72 -43
  184. package/dist/types/meeting/util.d.ts +101 -1
  185. package/dist/types/meeting-info/index.d.ts +13 -1
  186. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  187. package/dist/types/meetings/collection.d.ts +17 -0
  188. package/dist/types/meetings/index.d.ts +98 -20
  189. package/dist/types/meetings/meetings.types.d.ts +4 -0
  190. package/dist/types/member/index.d.ts +14 -0
  191. package/dist/types/member/types.d.ts +32 -0
  192. package/dist/types/members/collection.d.ts +5 -0
  193. package/dist/types/members/index.d.ts +35 -2
  194. package/dist/types/members/request.d.ts +73 -9
  195. package/dist/types/members/types.d.ts +25 -0
  196. package/dist/types/members/util.d.ts +214 -1
  197. package/dist/types/metrics/constants.d.ts +12 -4
  198. package/dist/types/metrics/index.d.ts +4 -119
  199. package/dist/types/multistream/mediaRequestManager.d.ts +73 -5
  200. package/dist/types/multistream/receiveSlot.d.ts +13 -11
  201. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  202. package/dist/types/multistream/remoteMedia.d.ts +8 -29
  203. package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
  204. package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
  205. package/dist/types/multistream/sendSlotManager.d.ts +61 -0
  206. package/dist/types/reachability/index.d.ts +61 -7
  207. package/dist/types/reachability/request.d.ts +7 -3
  208. package/dist/types/reconnection-manager/index.d.ts +9 -0
  209. package/dist/types/recording-controller/index.d.ts +15 -1
  210. package/dist/types/recording-controller/util.d.ts +5 -4
  211. package/dist/types/roap/index.d.ts +2 -1
  212. package/dist/types/roap/request.d.ts +15 -11
  213. package/dist/types/roap/turnDiscovery.d.ts +21 -3
  214. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  215. package/dist/types/rtcMetrics/index.d.ts +47 -0
  216. package/dist/types/statsAnalyzer/index.d.ts +7 -1
  217. package/dist/types/webinar/collection.d.ts +16 -0
  218. package/dist/types/webinar/index.d.ts +5 -0
  219. package/dist/webinar/collection.js +44 -0
  220. package/dist/webinar/collection.js.map +1 -0
  221. package/dist/webinar/index.js +69 -0
  222. package/dist/webinar/index.js.map +1 -0
  223. package/package.json +23 -20
  224. package/src/annotation/annotation.types.ts +50 -0
  225. package/src/annotation/constants.ts +36 -0
  226. package/src/annotation/index.ts +328 -0
  227. package/src/breakouts/README.md +42 -12
  228. package/src/breakouts/breakout.ts +67 -9
  229. package/src/breakouts/edit-lock-error.ts +25 -0
  230. package/src/breakouts/events.ts +56 -0
  231. package/src/breakouts/index.ts +592 -20
  232. package/src/breakouts/utils.ts +42 -0
  233. package/src/common/errors/no-meeting-info.ts +24 -0
  234. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  235. package/src/common/errors/webex-errors.ts +44 -2
  236. package/src/common/logs/logger-proxy.ts +1 -1
  237. package/src/common/logs/request.ts +5 -1
  238. package/src/common/queue.ts +22 -8
  239. package/src/config.ts +4 -10
  240. package/src/constants.ts +221 -19
  241. package/src/controls-options-manager/enums.ts +12 -0
  242. package/src/controls-options-manager/index.ts +116 -21
  243. package/src/controls-options-manager/types.ts +59 -0
  244. package/src/controls-options-manager/util.ts +294 -14
  245. package/src/index.ts +40 -0
  246. package/src/interpretation/README.md +60 -0
  247. package/src/interpretation/collection.ts +19 -0
  248. package/src/interpretation/index.ts +332 -0
  249. package/src/interpretation/siLanguage.ts +18 -0
  250. package/src/locus-info/controlsUtils.ts +108 -0
  251. package/src/locus-info/index.ts +413 -59
  252. package/src/locus-info/infoUtils.ts +10 -2
  253. package/src/locus-info/mediaSharesUtils.ts +64 -0
  254. package/src/locus-info/parser.ts +258 -47
  255. package/src/locus-info/selfUtils.ts +81 -5
  256. package/src/media/index.ts +102 -122
  257. package/src/media/properties.ts +87 -110
  258. package/src/meeting/in-meeting-actions.ts +163 -3
  259. package/src/meeting/index.ts +3132 -2541
  260. package/src/meeting/locusMediaRequest.ts +313 -0
  261. package/src/meeting/muteState.ts +229 -131
  262. package/src/meeting/request.ts +177 -121
  263. package/src/meeting/util.ts +588 -394
  264. package/src/meeting-info/index.ts +81 -8
  265. package/src/meeting-info/meeting-info-v2.ts +170 -14
  266. package/src/meeting-info/util.ts +1 -1
  267. package/src/meeting-info/utilv2.ts +23 -23
  268. package/src/meetings/collection.ts +33 -0
  269. package/src/meetings/index.ts +445 -123
  270. package/src/meetings/meetings.types.ts +12 -0
  271. package/src/meetings/request.ts +2 -0
  272. package/src/meetings/util.ts +80 -11
  273. package/src/member/index.ts +58 -0
  274. package/src/member/types.ts +38 -0
  275. package/src/member/util.ts +141 -25
  276. package/src/members/collection.ts +8 -0
  277. package/src/members/index.ts +134 -8
  278. package/src/members/request.ts +97 -17
  279. package/src/members/types.ts +29 -0
  280. package/src/members/util.ts +333 -240
  281. package/src/metrics/constants.ts +12 -4
  282. package/src/metrics/index.ts +1 -490
  283. package/src/multistream/mediaRequestManager.ts +289 -79
  284. package/src/multistream/receiveSlot.ts +31 -17
  285. package/src/multistream/receiveSlotManager.ts +34 -24
  286. package/src/multistream/remoteMedia.ts +27 -2
  287. package/src/multistream/remoteMediaGroup.ts +59 -0
  288. package/src/multistream/remoteMediaManager.ts +148 -30
  289. package/src/multistream/sendSlotManager.ts +170 -0
  290. package/src/reachability/index.ts +228 -37
  291. package/src/reachability/request.ts +17 -8
  292. package/src/reconnection-manager/index.ts +83 -56
  293. package/src/recording-controller/index.ts +20 -3
  294. package/src/recording-controller/util.ts +26 -9
  295. package/src/roap/index.ts +63 -32
  296. package/src/roap/request.ts +100 -104
  297. package/src/roap/turnDiscovery.ts +48 -26
  298. package/src/rtcMetrics/constants.ts +3 -0
  299. package/src/rtcMetrics/index.ts +100 -0
  300. package/src/statsAnalyzer/index.ts +105 -91
  301. package/src/statsAnalyzer/mqaUtil.ts +13 -14
  302. package/src/webinar/collection.ts +31 -0
  303. package/src/webinar/index.ts +62 -0
  304. package/test/integration/spec/converged-space-meetings.js +60 -3
  305. package/test/integration/spec/journey.js +320 -261
  306. package/test/integration/spec/space-meeting.js +76 -3
  307. package/test/unit/spec/annotation/index.ts +418 -0
  308. package/test/unit/spec/breakouts/breakout.ts +118 -28
  309. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  310. package/test/unit/spec/breakouts/events.ts +89 -0
  311. package/test/unit/spec/breakouts/index.ts +1395 -69
  312. package/test/unit/spec/breakouts/utils.js +52 -1
  313. package/test/unit/spec/common/queue.js +31 -2
  314. package/test/unit/spec/controls-options-manager/index.js +163 -0
  315. package/test/unit/spec/controls-options-manager/util.js +576 -60
  316. package/test/unit/spec/fixture/locus.js +1 -0
  317. package/test/unit/spec/interpretation/collection.ts +15 -0
  318. package/test/unit/spec/interpretation/index.ts +589 -0
  319. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  320. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  321. package/test/unit/spec/locus-info/index.js +1304 -33
  322. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  323. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  324. package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
  325. package/test/unit/spec/locus-info/parser.js +116 -35
  326. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  327. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  328. package/test/unit/spec/media/index.ts +104 -37
  329. package/test/unit/spec/media/properties.ts +2 -2
  330. package/test/unit/spec/meeting/in-meeting-actions.ts +81 -3
  331. package/test/unit/spec/meeting/index.js +5216 -1956
  332. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  333. package/test/unit/spec/meeting/muteState.js +408 -208
  334. package/test/unit/spec/meeting/request.js +483 -49
  335. package/test/unit/spec/meeting/utils.js +679 -64
  336. package/test/unit/spec/meeting-info/index.js +300 -0
  337. package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
  338. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  339. package/test/unit/spec/meetings/collection.js +26 -0
  340. package/test/unit/spec/meetings/index.js +1011 -205
  341. package/test/unit/spec/meetings/utils.js +202 -2
  342. package/test/unit/spec/member/index.js +61 -6
  343. package/test/unit/spec/member/util.js +510 -34
  344. package/test/unit/spec/members/index.js +432 -1
  345. package/test/unit/spec/members/request.js +206 -27
  346. package/test/unit/spec/members/utils.js +210 -0
  347. package/test/unit/spec/metrics/index.js +1 -50
  348. package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
  349. package/test/unit/spec/multistream/receiveSlot.ts +28 -20
  350. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  351. package/test/unit/spec/multistream/remoteMedia.ts +30 -0
  352. package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
  353. package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
  354. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  355. package/test/unit/spec/reachability/index.ts +549 -9
  356. package/test/unit/spec/reachability/request.js +68 -0
  357. package/test/unit/spec/reconnection-manager/index.js +85 -9
  358. package/test/unit/spec/recording-controller/index.js +294 -218
  359. package/test/unit/spec/recording-controller/util.js +223 -96
  360. package/test/unit/spec/roap/index.ts +178 -64
  361. package/test/unit/spec/roap/request.ts +203 -85
  362. package/test/unit/spec/roap/turnDiscovery.ts +82 -36
  363. package/test/unit/spec/rtcMetrics/index.ts +73 -0
  364. package/test/unit/spec/stats-analyzer/index.js +136 -2
  365. package/test/unit/spec/webinar/collection.ts +13 -0
  366. package/test/unit/spec/webinar/index.ts +60 -0
  367. package/test/utils/integrationTestUtils.js +46 -0
  368. package/test/utils/testUtils.js +0 -52
  369. package/dist/meeting/effectsState.js +0 -262
  370. package/dist/meeting/effectsState.js.map +0 -1
  371. package/dist/metrics/config.js +0 -299
  372. package/dist/metrics/config.js.map +0 -1
  373. package/dist/types/meeting/effectsState.d.ts +0 -42
  374. package/dist/types/metrics/config.d.ts +0 -178
  375. package/src/index.js +0 -16
  376. package/src/meeting/effectsState.ts +0 -211
  377. package/src/metrics/config.ts +0 -495
  378. package/test/unit/spec/meeting/effectsState.js +0 -285
@@ -3,23 +3,28 @@ import {ReceiveSlot} from '@webex/plugin-meetings/src/multistream/receiveSlot';
3
3
  import sinon from 'sinon';
4
4
  import {assert} from '@webex/test-helper-chai';
5
5
  import {getMaxFs} from '@webex/plugin-meetings/src/multistream/remoteMedia';
6
+ import FakeTimers from '@sinonjs/fake-timers';
7
+ import * as mediaCore from '@webex/internal-media-core';
8
+ import { expect } from 'chai';
6
9
 
7
10
  type ExpectedActiveSpeaker = {
8
11
  policy: 'active-speaker';
12
+ maxPayloadBitsPerSecond?: number;
9
13
  priority: number;
10
14
  receiveSlots: Array<ReceiveSlot>;
11
- maxFs: number;
15
+ maxFs?: number;
16
+ maxMbps?: number;
12
17
  };
13
18
  type ExpectedReceiverSelected = {
14
19
  policy: 'receiver-selected';
20
+ maxPayloadBitsPerSecond?: number;
15
21
  csi: number;
16
22
  receiveSlot: ReceiveSlot;
17
- maxFs: number;
23
+ maxFs?: number;
24
+ maxMbps?: number;
18
25
  };
19
26
  type ExpectedRequest = ExpectedActiveSpeaker | ExpectedReceiverSelected;
20
27
 
21
- const maxPayloadBitsPerSecond = 10 * 1000 * 1000; // for now we always send this fixed constant
22
-
23
28
  const degradationPreferences = {
24
29
  maxMacroblocksLimit: Infinity, // no limit
25
30
  };
@@ -27,11 +32,18 @@ const degradationPreferences = {
27
32
  describe('MediaRequestManager', () => {
28
33
  const CROSS_PRIORITY_DUPLICATION = true;
29
34
  const CROSS_POLICY_DUPLICATION = true;
30
- const PREFER_LIVE_VIDEO = true;
31
- const ACTIVE_SPEAKER_MAX_FS = 3600;
32
- const RECEIVER_SELECTED_MAX_FS = 8190;
33
-
34
- const NUM_SLOTS = 10;
35
+ const MAX_FPS = 3000;
36
+ const MAX_FS_360p = 920;
37
+ const MAX_FS_720p = 3600;
38
+ const MAX_FS_1080p = 8192;
39
+ const MAX_MBPS_360p = 27600;
40
+ const MAX_MBPS_720p = 108000;
41
+ const MAX_MBPS_1080p = 245760;
42
+ const MAX_PAYLOADBITSPS_360p = 640000;
43
+ const MAX_PAYLOADBITSPS_720p = 2500000;
44
+ const MAX_PAYLOADBITSPS_1080p = 4000000;
45
+
46
+ const NUM_SLOTS = 15;
35
47
 
36
48
  let mediaRequestManager: MediaRequestManager;
37
49
  let sendMediaRequestsCallback;
@@ -40,10 +52,11 @@ describe('MediaRequestManager', () => {
40
52
 
41
53
  beforeEach(() => {
42
54
  sendMediaRequestsCallback = sinon.stub();
43
- mediaRequestManager = new MediaRequestManager(
55
+ mediaRequestManager = new MediaRequestManager(sendMediaRequestsCallback, {
44
56
  degradationPreferences,
45
- sendMediaRequestsCallback
46
- );
57
+ kind: 'video',
58
+ trimRequestsToNumOfSources: false,
59
+ });
47
60
 
48
61
  // create some fake receive slots used by the tests
49
62
  fakeWcmeSlots = Array(NUM_SLOTS)
@@ -58,14 +71,16 @@ describe('MediaRequestManager', () => {
58
71
  (_, index) =>
59
72
  ({
60
73
  id: `fake receive slot ${index}`,
74
+ on: sinon.stub(),
75
+ off: sinon.stub(),
76
+ sourceState: 'live',
61
77
  wcmeReceiveSlot: fakeWcmeSlots[index],
62
- resetSourceState: sinon.stub(),
63
78
  } as unknown as ReceiveSlot)
64
79
  );
65
80
  });
66
81
 
67
82
  // helper function for adding an active speaker request
68
- const addActiveSpeakerRequest = (priority, receiveSlots, maxFs, commit = false) =>
83
+ const addActiveSpeakerRequest = (priority, receiveSlots, maxFs, commit = false, preferLiveVideo = true) =>
69
84
  mediaRequestManager.addRequest(
70
85
  {
71
86
  policyInfo: {
@@ -73,7 +88,7 @@ describe('MediaRequestManager', () => {
73
88
  priority,
74
89
  crossPriorityDuplication: CROSS_PRIORITY_DUPLICATION,
75
90
  crossPolicyDuplication: CROSS_POLICY_DUPLICATION,
76
- preferLiveVideo: PREFER_LIVE_VIDEO,
91
+ preferLiveVideo,
77
92
  },
78
93
  receiveSlots,
79
94
  codecInfo: {
@@ -106,7 +121,12 @@ describe('MediaRequestManager', () => {
106
121
  // It should be used only for verifying requests created with
107
122
  // addActiveSpeakerRequest() or addReceiverSelectedRequest(), because of some
108
123
  // hardcoded values used in them
109
- const checkMediaRequestsSent = (expectedRequests: ExpectedRequest[]) => {
124
+ const checkMediaRequestsSent = (
125
+ expectedRequests: ExpectedRequest[], {
126
+ isCodecInfoDefined = true,
127
+ preferLiveVideo = true,
128
+ } = {}
129
+ ) => {
110
130
  assert.calledOnce(sendMediaRequestsCallback);
111
131
  assert.calledWith(
112
132
  sendMediaRequestsCallback,
@@ -118,18 +138,21 @@ describe('MediaRequestManager', () => {
118
138
  priority: expectedRequest.priority,
119
139
  crossPriorityDuplication: CROSS_PRIORITY_DUPLICATION,
120
140
  crossPolicyDuplication: CROSS_POLICY_DUPLICATION,
121
- preferLiveVideo: PREFER_LIVE_VIDEO,
141
+ preferLiveVideo,
122
142
  }),
123
143
  receiveSlots: expectedRequest.receiveSlots,
124
- maxPayloadBitsPerSecond,
125
- codecInfos: [
126
- sinon.match({
127
- payloadType: 0x80,
128
- h264: sinon.match({
129
- maxFs: expectedRequest.maxFs,
130
- }),
131
- }),
132
- ],
144
+ maxPayloadBitsPerSecond: expectedRequest.maxPayloadBitsPerSecond,
145
+ codecInfos: isCodecInfoDefined
146
+ ? [
147
+ sinon.match({
148
+ payloadType: 0x80,
149
+ h264: sinon.match({
150
+ maxMbps: expectedRequest.maxMbps,
151
+ maxFs: expectedRequest.maxFs,
152
+ }),
153
+ }),
154
+ ]
155
+ : [],
133
156
  });
134
157
  }
135
158
  if (expectedRequest.policy === 'receiver-selected') {
@@ -139,15 +162,18 @@ describe('MediaRequestManager', () => {
139
162
  csi: expectedRequest.csi,
140
163
  }),
141
164
  receiveSlots: [expectedRequest.receiveSlot],
142
- maxPayloadBitsPerSecond,
143
- codecInfos: [
144
- sinon.match({
145
- payloadType: 0x80,
146
- h264: sinon.match({
147
- maxFs: expectedRequest.maxFs,
148
- }),
149
- }),
150
- ],
165
+ maxPayloadBitsPerSecond: expectedRequest.maxPayloadBitsPerSecond,
166
+ codecInfos: isCodecInfoDefined
167
+ ? [
168
+ sinon.match({
169
+ payloadType: 0x80,
170
+ h264: sinon.match({
171
+ maxMbps: expectedRequest.maxMbps,
172
+ maxFs: expectedRequest.maxFs,
173
+ }),
174
+ }),
175
+ ]
176
+ : [],
151
177
  });
152
178
  }
153
179
 
@@ -181,8 +207,8 @@ describe('MediaRequestManager', () => {
181
207
  receiveSlots: [fakeReceiveSlots[0], fakeReceiveSlots[1], fakeReceiveSlots[2]],
182
208
  codecInfo: {
183
209
  codec: 'h264',
184
- maxFs: 1620,
185
- maxFps: 1500,
210
+ maxFs: MAX_FS_360p,
211
+ maxFps: MAX_FPS,
186
212
  },
187
213
  },
188
214
  false
@@ -196,9 +222,9 @@ describe('MediaRequestManager', () => {
196
222
  receiveSlots: [fakeReceiveSlots[3]],
197
223
  codecInfo: {
198
224
  codec: 'h264',
199
- maxFs: 3600,
200
- maxFps: 2500,
201
- maxMbps: 90000,
225
+ maxFs: MAX_FS_720p,
226
+ maxFps: MAX_FPS,
227
+ maxMbps: MAX_MBPS_720p,
202
228
  },
203
229
  },
204
230
  false
@@ -214,9 +240,9 @@ describe('MediaRequestManager', () => {
214
240
  receiveSlots: [fakeReceiveSlots[4]],
215
241
  codecInfo: {
216
242
  codec: 'h264',
217
- maxFs: 8192,
218
- maxFps: 2500,
219
- maxMbps: 204800,
243
+ maxFs: MAX_FS_1080p,
244
+ maxFps: MAX_FPS,
245
+ maxMbps: MAX_MBPS_1080p,
220
246
  },
221
247
  },
222
248
  true
@@ -234,13 +260,14 @@ describe('MediaRequestManager', () => {
234
260
  preferLiveVideo: false,
235
261
  }),
236
262
  receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1], fakeWcmeSlots[2]],
263
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
237
264
  codecInfos: [
238
265
  sinon.match({
239
266
  payloadType: 0x80,
240
267
  h264: sinon.match({
241
- maxFs: 1620,
242
- maxFps: 1500,
243
- maxMbps: 245760,
268
+ maxFs: MAX_FS_360p,
269
+ maxFps: MAX_FPS,
270
+ maxMbps: MAX_MBPS_360p,
244
271
  }),
245
272
  }),
246
273
  ],
@@ -251,13 +278,14 @@ describe('MediaRequestManager', () => {
251
278
  csi: 123,
252
279
  }),
253
280
  receiveSlots: [fakeWcmeSlots[3]],
281
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
254
282
  codecInfos: [
255
283
  sinon.match({
256
284
  payloadType: 0x80,
257
285
  h264: sinon.match({
258
- maxFs: 3600,
259
- maxFps: 2500,
260
- maxMbps: 90000,
286
+ maxFs: MAX_FS_720p,
287
+ maxFps: MAX_FPS,
288
+ maxMbps: MAX_MBPS_720p,
261
289
  }),
262
290
  }),
263
291
  ],
@@ -268,13 +296,14 @@ describe('MediaRequestManager', () => {
268
296
  csi: 123,
269
297
  }),
270
298
  receiveSlots: [fakeWcmeSlots[4]],
299
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
271
300
  codecInfos: [
272
301
  sinon.match({
273
302
  payloadType: 0x80,
274
303
  h264: sinon.match({
275
- maxFs: 8192,
276
- maxFps: 2500,
277
- maxMbps: 204800,
304
+ maxFs: MAX_FS_1080p,
305
+ maxFps: MAX_FPS,
306
+ maxMbps: MAX_MBPS_1080p,
278
307
  }),
279
308
  }),
280
309
  ],
@@ -284,32 +313,38 @@ describe('MediaRequestManager', () => {
284
313
 
285
314
  it('keeps adding requests with every call to addRequest()', () => {
286
315
  // start with 1 request
287
- addReceiverSelectedRequest(100, fakeReceiveSlots[0], RECEIVER_SELECTED_MAX_FS, true);
316
+ addReceiverSelectedRequest(100, fakeReceiveSlots[0], MAX_FS_1080p, true);
288
317
 
289
318
  checkMediaRequestsSent([
290
319
  {
291
320
  policy: 'receiver-selected',
292
321
  csi: 100,
293
322
  receiveSlot: fakeWcmeSlots[0],
294
- maxFs: RECEIVER_SELECTED_MAX_FS,
323
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
324
+ maxFs: MAX_FS_1080p,
325
+ maxMbps: MAX_MBPS_1080p,
295
326
  },
296
327
  ]);
297
328
 
298
329
  // now add another one
299
- addReceiverSelectedRequest(101, fakeReceiveSlots[1], RECEIVER_SELECTED_MAX_FS, true);
330
+ addReceiverSelectedRequest(101, fakeReceiveSlots[1], MAX_FS_1080p, true);
300
331
 
301
332
  checkMediaRequestsSent([
302
333
  {
303
334
  policy: 'receiver-selected',
304
335
  csi: 100,
305
336
  receiveSlot: fakeWcmeSlots[0],
306
- maxFs: RECEIVER_SELECTED_MAX_FS,
337
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
338
+ maxFs: MAX_FS_1080p,
339
+ maxMbps: MAX_MBPS_1080p,
307
340
  },
308
341
  {
309
342
  policy: 'receiver-selected',
310
343
  csi: 101,
311
344
  receiveSlot: fakeWcmeSlots[1],
312
- maxFs: RECEIVER_SELECTED_MAX_FS,
345
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
346
+ maxFs: MAX_FS_1080p,
347
+ maxMbps: MAX_MBPS_1080p,
313
348
  },
314
349
  ]);
315
350
 
@@ -317,7 +352,7 @@ describe('MediaRequestManager', () => {
317
352
  addActiveSpeakerRequest(
318
353
  1,
319
354
  [fakeReceiveSlots[2], fakeReceiveSlots[3], fakeReceiveSlots[4]],
320
- ACTIVE_SPEAKER_MAX_FS,
355
+ MAX_FS_720p,
321
356
  true
322
357
  );
323
358
 
@@ -326,37 +361,55 @@ describe('MediaRequestManager', () => {
326
361
  policy: 'receiver-selected',
327
362
  csi: 100,
328
363
  receiveSlot: fakeWcmeSlots[0],
329
- maxFs: RECEIVER_SELECTED_MAX_FS,
364
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
365
+ maxFs: MAX_FS_1080p,
366
+ maxMbps: MAX_MBPS_1080p,
330
367
  },
331
368
  {
332
369
  policy: 'receiver-selected',
333
370
  csi: 101,
334
371
  receiveSlot: fakeWcmeSlots[1],
335
- maxFs: RECEIVER_SELECTED_MAX_FS,
372
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
373
+ maxFs: MAX_FS_1080p,
374
+ maxMbps: MAX_MBPS_1080p,
336
375
  },
337
376
  {
338
377
  policy: 'active-speaker',
339
378
  priority: 1,
340
379
  receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3], fakeWcmeSlots[4]],
341
- maxFs: ACTIVE_SPEAKER_MAX_FS,
380
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
381
+ maxFs: MAX_FS_720p,
382
+ maxMbps: MAX_MBPS_720p,
342
383
  },
343
384
  ]);
344
385
  });
345
386
 
387
+ it('removes the events maxFsUpdate and sourceUpdate when cancelRequest() is called', async () => {
388
+
389
+ const requestId = addActiveSpeakerRequest(255, [fakeReceiveSlots[2], fakeReceiveSlots[3]], MAX_FS_720p);
390
+
391
+ mediaRequestManager.cancelRequest(requestId, true);
392
+
393
+ const sourceUpdateHandler = fakeReceiveSlots[2].off.getCall(0);
394
+
395
+ const maxFsHandlerCall = fakeReceiveSlots[2].off.getCall(1);
396
+
397
+ const maxFsEventName = maxFsHandlerCall.args[0];
398
+ const sourceUpdateEventName = sourceUpdateHandler.args[0];
399
+
400
+ expect(sourceUpdateHandler.args[1]).to.be.a('function');
401
+ expect(maxFsHandlerCall.args[1]).to.be.a('function');
402
+
403
+ assert.equal(maxFsEventName, 'maxFsUpdate')
404
+ assert.equal(sourceUpdateEventName, 'sourceUpdate')
405
+ });
406
+
346
407
  it('cancels the requests correctly when cancelRequest() is called with commit=true', () => {
347
408
  const requestIds = [
348
- addActiveSpeakerRequest(
349
- 255,
350
- [fakeReceiveSlots[0], fakeReceiveSlots[1]],
351
- ACTIVE_SPEAKER_MAX_FS
352
- ),
353
- addActiveSpeakerRequest(
354
- 255,
355
- [fakeReceiveSlots[2], fakeReceiveSlots[3]],
356
- ACTIVE_SPEAKER_MAX_FS
357
- ),
358
- addReceiverSelectedRequest(100, fakeReceiveSlots[4], RECEIVER_SELECTED_MAX_FS),
359
- addReceiverSelectedRequest(200, fakeReceiveSlots[5], RECEIVER_SELECTED_MAX_FS),
409
+ addActiveSpeakerRequest(255, [fakeReceiveSlots[0], fakeReceiveSlots[1]], MAX_FS_720p),
410
+ addActiveSpeakerRequest(255, [fakeReceiveSlots[2], fakeReceiveSlots[3]], MAX_FS_720p),
411
+ addReceiverSelectedRequest(100, fakeReceiveSlots[4], MAX_FS_1080p),
412
+ addReceiverSelectedRequest(200, fakeReceiveSlots[5], MAX_FS_1080p),
360
413
  ];
361
414
 
362
415
  // cancel one of the active speaker requests
@@ -368,19 +421,25 @@ describe('MediaRequestManager', () => {
368
421
  policy: 'active-speaker',
369
422
  priority: 255,
370
423
  receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]],
371
- maxFs: ACTIVE_SPEAKER_MAX_FS,
424
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
425
+ maxFs: MAX_FS_720p,
426
+ maxMbps: MAX_MBPS_720p,
372
427
  },
373
428
  {
374
429
  policy: 'receiver-selected',
375
430
  csi: 100,
376
431
  receiveSlot: fakeWcmeSlots[4],
377
- maxFs: RECEIVER_SELECTED_MAX_FS,
432
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
433
+ maxFs: MAX_FS_1080p,
434
+ maxMbps: MAX_MBPS_1080p,
378
435
  },
379
436
  {
380
437
  policy: 'receiver-selected',
381
438
  csi: 200,
382
439
  receiveSlot: fakeWcmeSlots[5],
383
- maxFs: RECEIVER_SELECTED_MAX_FS,
440
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
441
+ maxFs: MAX_FS_1080p,
442
+ maxMbps: MAX_MBPS_1080p,
384
443
  },
385
444
  ]);
386
445
 
@@ -393,13 +452,17 @@ describe('MediaRequestManager', () => {
393
452
  policy: 'active-speaker',
394
453
  priority: 255,
395
454
  receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]],
396
- maxFs: ACTIVE_SPEAKER_MAX_FS,
455
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
456
+ maxFs: MAX_FS_720p,
457
+ maxMbps: MAX_MBPS_720p,
397
458
  },
398
459
  {
399
460
  policy: 'receiver-selected',
400
461
  csi: 100,
401
462
  receiveSlot: fakeWcmeSlots[4],
402
- maxFs: RECEIVER_SELECTED_MAX_FS,
463
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
464
+ maxFs: MAX_FS_1080p,
465
+ maxMbps: MAX_MBPS_1080p,
403
466
  },
404
467
  ]);
405
468
  });
@@ -408,10 +471,10 @@ describe('MediaRequestManager', () => {
408
471
  addActiveSpeakerRequest(
409
472
  10,
410
473
  [fakeReceiveSlots[0], fakeReceiveSlots[1], fakeReceiveSlots[2]],
411
- ACTIVE_SPEAKER_MAX_FS,
474
+ MAX_FS_720p,
412
475
  false
413
476
  );
414
- addReceiverSelectedRequest(123, fakeReceiveSlots[3], RECEIVER_SELECTED_MAX_FS, false);
477
+ addReceiverSelectedRequest(123, fakeReceiveSlots[3], MAX_FS_1080p, false);
415
478
 
416
479
  // nothing should be sent out as we didn't commit the requests
417
480
  assert.notCalled(sendMediaRequestsCallback);
@@ -425,13 +488,17 @@ describe('MediaRequestManager', () => {
425
488
  policy: 'active-speaker',
426
489
  priority: 10,
427
490
  receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1], fakeWcmeSlots[2]],
428
- maxFs: ACTIVE_SPEAKER_MAX_FS,
491
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
492
+ maxFs: MAX_FS_720p,
493
+ maxMbps: MAX_MBPS_720p,
429
494
  },
430
495
  {
431
496
  policy: 'receiver-selected',
432
497
  csi: 123,
433
498
  receiveSlot: fakeWcmeSlots[3],
434
- maxFs: RECEIVER_SELECTED_MAX_FS,
499
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
500
+ maxFs: MAX_FS_1080p,
501
+ maxMbps: MAX_MBPS_1080p,
435
502
  },
436
503
  ]);
437
504
  });
@@ -442,12 +509,12 @@ describe('MediaRequestManager', () => {
442
509
  addActiveSpeakerRequest(
443
510
  250,
444
511
  [fakeReceiveSlots[0], fakeReceiveSlots[1], fakeReceiveSlots[2]],
445
- ACTIVE_SPEAKER_MAX_FS,
512
+ MAX_FS_720p,
446
513
  false
447
514
  ),
448
- addReceiverSelectedRequest(98765, fakeReceiveSlots[3], RECEIVER_SELECTED_MAX_FS, false),
449
- addReceiverSelectedRequest(99999, fakeReceiveSlots[4], RECEIVER_SELECTED_MAX_FS, false),
450
- addReceiverSelectedRequest(88888, fakeReceiveSlots[5], RECEIVER_SELECTED_MAX_FS, true),
515
+ addReceiverSelectedRequest(98765, fakeReceiveSlots[3], MAX_FS_1080p, false),
516
+ addReceiverSelectedRequest(99999, fakeReceiveSlots[4], MAX_FS_1080p, false),
517
+ addReceiverSelectedRequest(88888, fakeReceiveSlots[5], MAX_FS_1080p, true),
451
518
  ];
452
519
 
453
520
  checkMediaRequestsSent([
@@ -455,25 +522,33 @@ describe('MediaRequestManager', () => {
455
522
  policy: 'active-speaker',
456
523
  priority: 250,
457
524
  receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1], fakeWcmeSlots[2]],
458
- maxFs: ACTIVE_SPEAKER_MAX_FS,
525
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
526
+ maxFs: MAX_FS_720p,
527
+ maxMbps: MAX_MBPS_720p,
459
528
  },
460
529
  {
461
530
  policy: 'receiver-selected',
462
531
  csi: 98765,
463
532
  receiveSlot: fakeWcmeSlots[3],
464
- maxFs: RECEIVER_SELECTED_MAX_FS,
533
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
534
+ maxFs: MAX_FS_1080p,
535
+ maxMbps: MAX_MBPS_1080p,
465
536
  },
466
537
  {
467
538
  policy: 'receiver-selected',
468
539
  csi: 99999,
469
540
  receiveSlot: fakeWcmeSlots[4],
470
- maxFs: RECEIVER_SELECTED_MAX_FS,
541
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
542
+ maxFs: MAX_FS_1080p,
543
+ maxMbps: MAX_MBPS_1080p,
471
544
  },
472
545
  {
473
546
  policy: 'receiver-selected',
474
547
  csi: 88888,
475
548
  receiveSlot: fakeWcmeSlots[5],
476
- maxFs: RECEIVER_SELECTED_MAX_FS,
549
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
550
+ maxFs: MAX_FS_1080p,
551
+ maxMbps: MAX_MBPS_1080p,
477
552
  },
478
553
  ]);
479
554
 
@@ -492,25 +567,27 @@ describe('MediaRequestManager', () => {
492
567
  policy: 'receiver-selected',
493
568
  csi: 98765,
494
569
  receiveSlot: fakeWcmeSlots[3],
495
- maxFs: RECEIVER_SELECTED_MAX_FS,
570
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
571
+ maxFs: MAX_FS_1080p,
572
+ maxMbps: MAX_MBPS_1080p,
496
573
  },
497
574
  ]);
498
575
  });
499
576
 
500
577
  it('sends the wcme media requests when commit() is called', () => {
501
578
  // send some requests, all of them with commit=false
502
- addReceiverSelectedRequest(123000, fakeReceiveSlots[0], RECEIVER_SELECTED_MAX_FS, false);
503
- addReceiverSelectedRequest(456000, fakeReceiveSlots[1], RECEIVER_SELECTED_MAX_FS, false);
579
+ addReceiverSelectedRequest(123000, fakeReceiveSlots[0], MAX_FS_1080p, false);
580
+ addReceiverSelectedRequest(456000, fakeReceiveSlots[1], MAX_FS_1080p, false);
504
581
  addActiveSpeakerRequest(
505
582
  255,
506
583
  [fakeReceiveSlots[2], fakeReceiveSlots[3], fakeReceiveSlots[4]],
507
- ACTIVE_SPEAKER_MAX_FS,
584
+ MAX_FS_720p,
508
585
  false
509
586
  );
510
587
  addActiveSpeakerRequest(
511
588
  254,
512
589
  [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
513
- ACTIVE_SPEAKER_MAX_FS,
590
+ MAX_FS_720p,
514
591
  false
515
592
  );
516
593
 
@@ -526,78 +603,99 @@ describe('MediaRequestManager', () => {
526
603
  policy: 'receiver-selected',
527
604
  csi: 123000,
528
605
  receiveSlot: fakeWcmeSlots[0],
529
- maxFs: RECEIVER_SELECTED_MAX_FS,
606
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
607
+ maxFs: MAX_FS_1080p,
608
+ maxMbps: MAX_MBPS_1080p,
530
609
  },
531
610
  {
532
611
  policy: 'receiver-selected',
533
612
  csi: 456000,
534
613
  receiveSlot: fakeWcmeSlots[1],
535
- maxFs: RECEIVER_SELECTED_MAX_FS,
614
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
615
+ maxFs: MAX_FS_1080p,
616
+ maxMbps: MAX_MBPS_1080p,
536
617
  },
537
618
  {
538
619
  policy: 'active-speaker',
539
620
  priority: 255,
540
621
  receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3], fakeWcmeSlots[4]],
541
- maxFs: ACTIVE_SPEAKER_MAX_FS,
622
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
623
+ maxFs: MAX_FS_720p,
624
+ maxMbps: MAX_MBPS_720p,
542
625
  },
543
626
  {
544
627
  policy: 'active-speaker',
545
628
  priority: 254,
546
629
  receiveSlots: [fakeWcmeSlots[5], fakeWcmeSlots[6], fakeWcmeSlots[7]],
547
- maxFs: ACTIVE_SPEAKER_MAX_FS,
630
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
631
+ maxFs: MAX_FS_720p,
632
+ maxMbps: MAX_MBPS_720p,
548
633
  },
549
634
  ]);
550
635
  });
551
636
 
552
- it('clears all the requests on reset()', () => {
637
+ it('avoids sending duplicate requests and clears all the requests on reset()', () => {
553
638
  // send some requests and commit them one by one
554
- addReceiverSelectedRequest(1500, fakeReceiveSlots[0], RECEIVER_SELECTED_MAX_FS, true);
555
- addReceiverSelectedRequest(1501, fakeReceiveSlots[1], RECEIVER_SELECTED_MAX_FS, true);
639
+ addReceiverSelectedRequest(1500, fakeReceiveSlots[0], MAX_FS_1080p, false);
640
+ addReceiverSelectedRequest(1501, fakeReceiveSlots[1], MAX_FS_1080p, false);
556
641
  addActiveSpeakerRequest(
557
642
  255,
558
643
  [fakeReceiveSlots[2], fakeReceiveSlots[3], fakeReceiveSlots[4]],
559
- ACTIVE_SPEAKER_MAX_FS,
560
- true
644
+ MAX_FS_720p,
645
+ false
561
646
  );
562
647
  addActiveSpeakerRequest(
563
648
  254,
564
649
  [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
565
- ACTIVE_SPEAKER_MAX_FS,
566
- true
650
+ MAX_FS_720p,
651
+ false
567
652
  );
568
653
 
569
- sendMediaRequestsCallback.resetHistory();
654
+ // nothing should be sent out as we didn't commit the requests
655
+ assert.notCalled(sendMediaRequestsCallback);
570
656
 
571
- // check that when calling commit() all requests are re-sent again
572
657
  mediaRequestManager.commit();
573
-
574
658
  checkMediaRequestsSent([
575
659
  {
576
660
  policy: 'receiver-selected',
577
661
  csi: 1500,
578
662
  receiveSlot: fakeWcmeSlots[0],
579
- maxFs: RECEIVER_SELECTED_MAX_FS,
663
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
664
+ maxFs: MAX_FS_1080p,
665
+ maxMbps: MAX_MBPS_1080p,
580
666
  },
581
667
  {
582
668
  policy: 'receiver-selected',
583
669
  csi: 1501,
584
670
  receiveSlot: fakeWcmeSlots[1],
585
- maxFs: RECEIVER_SELECTED_MAX_FS,
671
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
672
+ maxFs: MAX_FS_1080p,
673
+ maxMbps: MAX_MBPS_1080p,
586
674
  },
587
675
  {
588
676
  policy: 'active-speaker',
589
677
  priority: 255,
590
678
  receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3], fakeWcmeSlots[4]],
591
- maxFs: ACTIVE_SPEAKER_MAX_FS,
679
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
680
+ maxFs: MAX_FS_720p,
681
+ maxMbps: MAX_MBPS_720p,
592
682
  },
593
683
  {
594
684
  policy: 'active-speaker',
595
685
  priority: 254,
596
686
  receiveSlots: [fakeWcmeSlots[5], fakeWcmeSlots[6], fakeWcmeSlots[7]],
597
- maxFs: ACTIVE_SPEAKER_MAX_FS,
687
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
688
+ maxFs: MAX_FS_720p,
689
+ maxMbps: MAX_MBPS_720p,
598
690
  },
599
691
  ]);
600
692
 
693
+ // check that when calling commit()
694
+ // all requests are not re-sent again (avoid duplicate requests)
695
+ mediaRequestManager.commit();
696
+
697
+ assert.notCalled(sendMediaRequestsCallback);
698
+
601
699
  // now reset everything
602
700
  mediaRequestManager.reset();
603
701
 
@@ -606,76 +704,81 @@ describe('MediaRequestManager', () => {
606
704
  checkMediaRequestsSent([]);
607
705
  });
608
706
 
609
- it('calls resetSourceState() on slots that are stopped being used', () => {
610
- const requestIds = [
611
- addActiveSpeakerRequest(
612
- 255,
613
- [fakeReceiveSlots[0], fakeReceiveSlots[1]],
614
- ACTIVE_SPEAKER_MAX_FS
615
- ),
616
- addActiveSpeakerRequest(
617
- 255,
618
- [fakeReceiveSlots[2], fakeReceiveSlots[3]],
619
- ACTIVE_SPEAKER_MAX_FS
620
- ),
621
- addReceiverSelectedRequest(100, fakeReceiveSlots[4], RECEIVER_SELECTED_MAX_FS),
622
- addReceiverSelectedRequest(200, fakeReceiveSlots[5], RECEIVER_SELECTED_MAX_FS),
623
- ];
707
+ it('makes sure to call requests correctly after reset was called and another request was added', () => {
708
+ addReceiverSelectedRequest(1500, fakeReceiveSlots[0], MAX_FS_1080p, false);
709
+
710
+ assert.notCalled(sendMediaRequestsCallback);
624
711
 
625
712
  mediaRequestManager.commit();
626
713
  checkMediaRequestsSent([
627
714
  {
628
- policy: 'active-speaker',
629
- priority: 255,
630
- receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]],
631
- maxFs: ACTIVE_SPEAKER_MAX_FS,
632
- },
633
- {
634
- policy: 'active-speaker',
635
- priority: 255,
636
- receiveSlots: [fakeWcmeSlots[2], fakeWcmeSlots[3]],
637
- maxFs: ACTIVE_SPEAKER_MAX_FS,
715
+ policy: 'receiver-selected',
716
+ csi: 1500,
717
+ receiveSlot: fakeWcmeSlots[0],
718
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
719
+ maxFs: MAX_FS_1080p,
720
+ maxMbps: MAX_MBPS_1080p,
638
721
  },
722
+ ]);
723
+
724
+ // now reset everything
725
+ mediaRequestManager.reset();
726
+
727
+ // calling commit now should not cause any requests to be sent out
728
+ mediaRequestManager.commit();
729
+ checkMediaRequestsSent([]);
730
+
731
+ //add new request
732
+ addReceiverSelectedRequest(1501, fakeReceiveSlots[1], MAX_FS_1080p, false);
733
+
734
+ // commit
735
+ mediaRequestManager.commit();
736
+
737
+ // check the new request was sent
738
+ checkMediaRequestsSent([
639
739
  {
640
740
  policy: 'receiver-selected',
641
- csi: 100,
642
- receiveSlot: fakeWcmeSlots[4],
643
- maxFs: RECEIVER_SELECTED_MAX_FS,
741
+ csi: 1501,
742
+ receiveSlot: fakeWcmeSlots[1],
743
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
744
+ maxFs: MAX_FS_1080p,
745
+ maxMbps: MAX_MBPS_1080p,
644
746
  },
747
+ ]);
748
+ });
749
+
750
+ it('can send same media request after previous requests have been cleared', () => {
751
+ // add a request and commit
752
+ addReceiverSelectedRequest(1500, fakeReceiveSlots[0], MAX_FS_1080p, false);
753
+ mediaRequestManager.commit();
754
+ checkMediaRequestsSent([
645
755
  {
646
756
  policy: 'receiver-selected',
647
- csi: 200,
648
- receiveSlot: fakeWcmeSlots[5],
649
- maxFs: RECEIVER_SELECTED_MAX_FS,
757
+ csi: 1500,
758
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
759
+ receiveSlot: fakeWcmeSlots[0],
760
+ maxFs: MAX_FS_1080p,
761
+ maxMbps: MAX_MBPS_1080p,
650
762
  },
651
763
  ]);
652
764
 
653
- // cancel 2 of the requests
654
- mediaRequestManager.cancelRequest(requestIds[1], false);
655
- mediaRequestManager.cancelRequest(requestIds[3], false);
765
+ // clear previous requests
766
+ mediaRequestManager.clearPreviousRequests();
656
767
 
768
+ // commit same request
657
769
  mediaRequestManager.commit();
658
770
 
659
- // expect only the 2 remaining requests to be sent out
771
+ // check the request was sent
660
772
  checkMediaRequestsSent([
661
- {
662
- policy: 'active-speaker',
663
- priority: 255,
664
- receiveSlots: [fakeWcmeSlots[0], fakeWcmeSlots[1]],
665
- maxFs: ACTIVE_SPEAKER_MAX_FS,
666
- },
667
773
  {
668
774
  policy: 'receiver-selected',
669
- csi: 100,
670
- receiveSlot: fakeWcmeSlots[4],
671
- maxFs: RECEIVER_SELECTED_MAX_FS,
775
+ csi: 1500,
776
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
777
+ receiveSlot: fakeWcmeSlots[0],
778
+ maxFs: MAX_FS_1080p,
779
+ maxMbps: MAX_MBPS_1080p,
672
780
  },
673
781
  ]);
674
-
675
- // and that the receive slots of the 2 cancelled ones had resetSourceState() called
676
- assert.calledOnce(fakeReceiveSlots[2].resetSourceState);
677
- assert.calledOnce(fakeReceiveSlots[3].resetSourceState);
678
- assert.calledOnce(fakeReceiveSlots[5].resetSourceState);
679
782
  });
680
783
 
681
784
  it('re-sends media requests after degradation preferences are set', () => {
@@ -684,6 +787,32 @@ describe('MediaRequestManager', () => {
684
787
  assert.calledOnce(sendMediaRequestsCallback);
685
788
  });
686
789
 
790
+ it('should not degrade max-fs if receive slot sources are not live', () => {
791
+ // set receive slot source states to "no source"
792
+ fakeReceiveSlots.forEach((slot) => {
793
+ slot.sourceState = 'no source';
794
+ });
795
+
796
+ // set max macroblocks limit
797
+ mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: 32400});
798
+ sendMediaRequestsCallback.resetHistory();
799
+
800
+ // request 4 "large" 1080p streams, which should degrade to 720p if live
801
+ addActiveSpeakerRequest(255, fakeReceiveSlots.slice(0, 4), getMaxFs('large'), true);
802
+
803
+ // check that resulting requests are 4 "large" 1080p streams
804
+ checkMediaRequestsSent([
805
+ {
806
+ policy: 'active-speaker',
807
+ priority: 255,
808
+ receiveSlots: fakeWcmeSlots.slice(0, 4),
809
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
810
+ maxFs: getMaxFs('large'),
811
+ maxMbps: MAX_MBPS_1080p,
812
+ },
813
+ ]);
814
+ });
815
+
687
816
  it('can degrade max-fs once when request exceeds max macroblocks limit', () => {
688
817
  // set max macroblocks limit
689
818
  mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: 32400});
@@ -706,13 +835,17 @@ describe('MediaRequestManager', () => {
706
835
  policy: 'active-speaker',
707
836
  priority: 255,
708
837
  receiveSlots: fakeWcmeSlots.slice(0, 3),
838
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
709
839
  maxFs: getMaxFs('medium'),
840
+ maxMbps: MAX_MBPS_720p,
710
841
  },
711
842
  {
712
843
  policy: 'receiver-selected',
713
844
  csi: 123,
714
845
  receiveSlot: fakeWcmeSlots[3],
846
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
715
847
  maxFs: getMaxFs('medium'),
848
+ maxMbps: MAX_MBPS_720p,
716
849
  },
717
850
  ]);
718
851
 
@@ -725,7 +858,9 @@ describe('MediaRequestManager', () => {
725
858
  policy: 'active-speaker',
726
859
  priority: 255,
727
860
  receiveSlots: fakeWcmeSlots.slice(0, 3),
861
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
728
862
  maxFs: getMaxFs('large'),
863
+ maxMbps: MAX_MBPS_1080p,
729
864
  },
730
865
  ]);
731
866
  });
@@ -744,7 +879,9 @@ describe('MediaRequestManager', () => {
744
879
  policy: 'active-speaker',
745
880
  priority: 255,
746
881
  receiveSlots: fakeWcmeSlots.slice(0, 10),
882
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
747
883
  maxFs: getMaxFs('small'),
884
+ maxMbps: MAX_MBPS_360p,
748
885
  },
749
886
  ]);
750
887
  });
@@ -764,14 +901,518 @@ describe('MediaRequestManager', () => {
764
901
  policy: 'active-speaker',
765
902
  priority: 255,
766
903
  receiveSlots: fakeWcmeSlots.slice(0, 5),
904
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
767
905
  maxFs: getMaxFs('medium'),
906
+ maxMbps: MAX_MBPS_720p,
768
907
  },
769
908
  {
770
909
  policy: 'active-speaker',
771
910
  priority: 254,
772
911
  receiveSlots: fakeWcmeSlots.slice(5, 10),
912
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
773
913
  maxFs: getMaxFs('small'),
914
+ maxMbps: MAX_MBPS_360p,
915
+ },
916
+ ]);
917
+ });
918
+
919
+ it('respects the preferredMaxFs if set', () => {
920
+ sendMediaRequestsCallback.resetHistory();
921
+ const clock = FakeTimers.install({now: Date.now()});
922
+
923
+ addActiveSpeakerRequest(255, fakeReceiveSlots.slice(0, 10), getMaxFs('large'), true);
924
+
925
+ sendMediaRequestsCallback.resetHistory();
926
+
927
+ const maxFsHandlerCall = fakeReceiveSlots[0].on.getCall(1);
928
+
929
+ const maxFsHandler = maxFsHandlerCall.args[1];
930
+ const eventName = maxFsHandlerCall.args[0];
931
+
932
+ assert.equal(eventName, 'maxFsUpdate');
933
+
934
+ const preferredFrameSize = 100;
935
+
936
+ maxFsHandler({maxFs: preferredFrameSize});
937
+
938
+ clock.tick(999);
939
+
940
+ assert.notCalled(sendMediaRequestsCallback);
941
+
942
+ clock.tick(1);
943
+
944
+ checkMediaRequestsSent([
945
+ {
946
+ policy: 'active-speaker',
947
+ priority: 255,
948
+ receiveSlots: fakeWcmeSlots.slice(0, 10),
949
+ maxFs: preferredFrameSize,
950
+ maxPayloadBitsPerSecond: 99000,
951
+ maxMbps: 3000,
774
952
  },
775
953
  ]);
776
954
  });
955
+
956
+ describe('maxPayloadBitsPerSecond', () => {
957
+ let getRecommendedMaxBitrateForFrameSizeSpy;
958
+
959
+ beforeEach(() => {
960
+ sendMediaRequestsCallback.resetHistory();
961
+ getRecommendedMaxBitrateForFrameSizeSpy = sinon.spy(
962
+ mediaCore,
963
+ 'getRecommendedMaxBitrateForFrameSize'
964
+ );
965
+ });
966
+
967
+ afterEach(() => {
968
+ getRecommendedMaxBitrateForFrameSizeSpy.restore();
969
+ });
970
+
971
+ it('returns the default maxPayloadBitsPerSecond if kind is "audio"', () => {
972
+ const mediaRequestManagerAudio = new MediaRequestManager(sendMediaRequestsCallback, {
973
+ degradationPreferences,
974
+ kind: 'audio',
975
+ trimRequestsToNumOfSources: false,
976
+ });
977
+ mediaRequestManagerAudio.setNumCurrentSources(100, 100);
978
+ sendMediaRequestsCallback.resetHistory();
979
+
980
+ mediaRequestManagerAudio.addRequest(
981
+ {
982
+ policyInfo: {
983
+ policy: 'receiver-selected',
984
+ csi: 123,
985
+ },
986
+ receiveSlots: [fakeReceiveSlots[0]],
987
+ codecInfo: undefined,
988
+ },
989
+ false
990
+ );
991
+
992
+ mediaRequestManagerAudio.commit();
993
+
994
+ checkMediaRequestsSent(
995
+ [
996
+ {
997
+ policy: 'receiver-selected',
998
+ csi: 123,
999
+ receiveSlot: fakeWcmeSlots[0],
1000
+ // returns RecommendedOpusBitrates.FB_MONO_MUSIC as expected:
1001
+ maxPayloadBitsPerSecond: 64000,
1002
+ },
1003
+ // set isCodecInfoDefined to false, since we don't pass in a codec info when audio:
1004
+ ],
1005
+ {isCodecInfoDefined: false}
1006
+ );
1007
+
1008
+ assert.notCalled(getRecommendedMaxBitrateForFrameSizeSpy);
1009
+ });
1010
+
1011
+ it('returns the recommended maxPayloadBitsPerSecond if kind is "video"', () => {
1012
+ mediaRequestManager.addRequest(
1013
+ {
1014
+ policyInfo: {
1015
+ policy: 'receiver-selected',
1016
+ csi: 123,
1017
+ },
1018
+ receiveSlots: [fakeReceiveSlots[0]],
1019
+ codecInfo: {
1020
+ codec: 'h264',
1021
+ maxFs: MAX_FS_1080p,
1022
+ maxFps: MAX_FPS,
1023
+ maxMbps: MAX_MBPS_1080p,
1024
+ },
1025
+ },
1026
+ false
1027
+ );
1028
+
1029
+ mediaRequestManager.commit();
1030
+
1031
+ checkMediaRequestsSent([
1032
+ {
1033
+ policy: 'receiver-selected',
1034
+ csi: 123,
1035
+ receiveSlot: fakeWcmeSlots[0],
1036
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
1037
+ maxFs: MAX_FS_1080p,
1038
+ maxMbps: MAX_MBPS_1080p,
1039
+ },
1040
+ ]);
1041
+
1042
+ // calls the utility function as expected with maxFs passed in (no need to do
1043
+ // further tests here, since the util function itself should be tested for different inputs)
1044
+ assert.calledWith(getRecommendedMaxBitrateForFrameSizeSpy, MAX_FS_1080p);
1045
+ });
1046
+ });
1047
+
1048
+ describe('maxMbps', () => {
1049
+ beforeEach(() => {
1050
+ sendMediaRequestsCallback.resetHistory();
1051
+ });
1052
+
1053
+ it('returns the correct maxMbps value', () => {
1054
+ mediaRequestManager.addRequest(
1055
+ {
1056
+ policyInfo: {
1057
+ policy: 'receiver-selected',
1058
+ csi: 123,
1059
+ },
1060
+ receiveSlots: [fakeReceiveSlots[0]],
1061
+ codecInfo: {
1062
+ codec: 'h264',
1063
+ maxFs: MAX_FS_1080p,
1064
+ maxFps: MAX_FPS,
1065
+ // random value to pass in, to show that the output (below) is calculated
1066
+ // from the maxFs and maxFps values only:
1067
+ maxMbps: 123,
1068
+ },
1069
+ },
1070
+ false
1071
+ );
1072
+
1073
+ mediaRequestManager.commit();
1074
+
1075
+ checkMediaRequestsSent([
1076
+ {
1077
+ policy: 'receiver-selected',
1078
+ csi: 123,
1079
+ receiveSlot: fakeWcmeSlots[0],
1080
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
1081
+ maxFs: MAX_FS_1080p,
1082
+ maxMbps: MAX_MBPS_1080p,
1083
+ },
1084
+ ]);
1085
+ });
1086
+ });
1087
+
1088
+ describe('trimming of requested receive slots', () => {
1089
+ beforeEach(() => {
1090
+ mediaRequestManager = new MediaRequestManager(sendMediaRequestsCallback, {
1091
+ degradationPreferences,
1092
+ kind: 'video',
1093
+ trimRequestsToNumOfSources: true,
1094
+ });
1095
+ });
1096
+
1097
+ const limitNumAvailableStreams = (preferLiveVideo, limit) => {
1098
+ if (preferLiveVideo) {
1099
+ mediaRequestManager.setNumCurrentSources(100, limit);
1100
+ } else {
1101
+ mediaRequestManager.setNumCurrentSources(limit, 1);
1102
+ }
1103
+ };
1104
+
1105
+ [true, false].forEach((preferLiveVideo) =>
1106
+ describe(`preferLiveVideo=${preferLiveVideo}`, () => {
1107
+ it(`trims the active speaker request with lowest priority first and maintains slot order`, () => {
1108
+ // add some receiver-selected and active-speaker requests, in a mixed up order
1109
+ addReceiverSelectedRequest(100, fakeReceiveSlots[0], MAX_FS_360p, false);
1110
+ addActiveSpeakerRequest( // AS request 1 - it will get 1 slot trimmed
1111
+ 254,
1112
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1113
+ MAX_FS_360p,
1114
+ false,
1115
+ preferLiveVideo
1116
+ );
1117
+ addActiveSpeakerRequest( // AS request 2 - lowest priority, it will have all slots trimmed
1118
+ 253,
1119
+ [fakeReceiveSlots[7], fakeReceiveSlots[8], fakeReceiveSlots[9]],
1120
+ MAX_FS_360p,
1121
+ false,
1122
+ preferLiveVideo
1123
+ );
1124
+ addActiveSpeakerRequest( // AS request 3 - highest priority, nothing will be trimmed
1125
+ 255,
1126
+ [fakeReceiveSlots[4], fakeReceiveSlots[5], fakeReceiveSlots[6]],
1127
+ MAX_FS_360p,
1128
+ false,
1129
+ preferLiveVideo
1130
+ );
1131
+ addReceiverSelectedRequest(101, fakeReceiveSlots[10], MAX_FS_360p, false);
1132
+
1133
+ /* Set number of available streams to 7 so that there will be enough sources only for
1134
+ the 2 RS requests and 2 of the 3 AS requests. The lowest priority AS request will
1135
+ have all the slots trimmed, the second lowest priority AS request will have 1 slot trimmed */
1136
+ limitNumAvailableStreams(preferLiveVideo, 7);
1137
+
1138
+ // check what got trimmed
1139
+ checkMediaRequestsSent([
1140
+ {
1141
+ policy: 'receiver-selected',
1142
+ csi: 100,
1143
+ receiveSlot: fakeWcmeSlots[0],
1144
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1145
+ maxFs: MAX_FS_360p,
1146
+ maxMbps: MAX_MBPS_360p,
1147
+ },
1148
+ {
1149
+ policy: 'active-speaker',
1150
+ priority: 254,
1151
+ receiveSlots: [fakeWcmeSlots[1], fakeWcmeSlots[2]], // fakeWcmeSlots[3] got trimmed
1152
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1153
+ maxFs: MAX_FS_360p,
1154
+ maxMbps: MAX_MBPS_360p,
1155
+ },
1156
+ // AS request with priority 253 is missing, because all of its slots got trimmed
1157
+ {
1158
+ policy: 'active-speaker',
1159
+ priority: 255,
1160
+ receiveSlots: [fakeWcmeSlots[4], fakeWcmeSlots[5], fakeWcmeSlots[6]],
1161
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1162
+ maxFs: MAX_FS_360p,
1163
+ maxMbps: MAX_MBPS_360p,
1164
+ },
1165
+ {
1166
+ policy: 'receiver-selected',
1167
+ csi: 101,
1168
+ receiveSlot: fakeWcmeSlots[10],
1169
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1170
+ maxFs: MAX_FS_360p,
1171
+ maxMbps: MAX_MBPS_360p,
1172
+ },
1173
+ ], {preferLiveVideo});
1174
+
1175
+ // now increase the number of available streams so only the last AS request is trimmed by 1
1176
+ limitNumAvailableStreams(preferLiveVideo, 10);
1177
+
1178
+ checkMediaRequestsSent([
1179
+ {
1180
+ policy: 'receiver-selected',
1181
+ csi: 100,
1182
+ receiveSlot: fakeWcmeSlots[0],
1183
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1184
+ maxFs: MAX_FS_360p,
1185
+ maxMbps: MAX_MBPS_360p,
1186
+ },
1187
+ {
1188
+ policy: 'active-speaker',
1189
+ priority: 254,
1190
+ receiveSlots: [fakeWcmeSlots[1], fakeWcmeSlots[2], fakeWcmeSlots[3]], // all slots are used, nothing trimmed
1191
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1192
+ maxFs: MAX_FS_360p,
1193
+ maxMbps: MAX_MBPS_360p,
1194
+ },
1195
+ {
1196
+ policy: 'active-speaker',
1197
+ priority: 253,
1198
+ receiveSlots: [fakeWcmeSlots[7], fakeWcmeSlots[8]], // only 1 slot is trimmed
1199
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1200
+ maxFs: MAX_FS_360p,
1201
+ maxMbps: MAX_MBPS_360p,
1202
+ },
1203
+ {
1204
+ policy: 'active-speaker',
1205
+ priority: 255,
1206
+ receiveSlots: [fakeWcmeSlots[4], fakeWcmeSlots[5], fakeWcmeSlots[6]], // all slots are used, nothing trimmed
1207
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1208
+ maxFs: MAX_FS_360p,
1209
+ maxMbps: MAX_MBPS_360p,
1210
+ },
1211
+ {
1212
+ policy: 'receiver-selected',
1213
+ csi: 101,
1214
+ receiveSlot: fakeWcmeSlots[10],
1215
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1216
+ maxFs: MAX_FS_360p,
1217
+ maxMbps: MAX_MBPS_360p,
1218
+ },
1219
+ ], {preferLiveVideo});
1220
+ })
1221
+
1222
+ it('does not trim the receiver selected requests', async () => {
1223
+ // add some receiver-selected and active-speaker requests, in a mixed up order
1224
+ addReceiverSelectedRequest(200, fakeReceiveSlots[0], MAX_FS_360p, false);
1225
+ addActiveSpeakerRequest(
1226
+ 255,
1227
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1228
+ MAX_FS_360p,
1229
+ false,
1230
+ preferLiveVideo
1231
+ );
1232
+ addReceiverSelectedRequest(201, fakeReceiveSlots[4], MAX_FS_720p, false);
1233
+ addActiveSpeakerRequest(
1234
+ 254,
1235
+ [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
1236
+ MAX_FS_720p,
1237
+ false,
1238
+ preferLiveVideo
1239
+ );
1240
+
1241
+ /* Set number of available streams to 1, which is lower than the number of RS requests,
1242
+ so all AS requests will be trimmed to 0 but RS requests should be unaltered */
1243
+ limitNumAvailableStreams(preferLiveVideo, 1);
1244
+
1245
+ // check what got trimmed - only RS requests should remain
1246
+ checkMediaRequestsSent([
1247
+ {
1248
+ policy: 'receiver-selected',
1249
+ csi: 200,
1250
+ receiveSlot: fakeWcmeSlots[0],
1251
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1252
+ maxFs: MAX_FS_360p,
1253
+ maxMbps: MAX_MBPS_360p,
1254
+ },
1255
+ {
1256
+ policy: 'receiver-selected',
1257
+ csi: 201,
1258
+ receiveSlot: fakeWcmeSlots[4],
1259
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
1260
+ maxFs: MAX_FS_720p,
1261
+ maxMbps: MAX_MBPS_720p,
1262
+ },
1263
+ ], {preferLiveVideo});
1264
+ });
1265
+
1266
+ it('does trimming first and applies degradationPreferences after that', async () => {
1267
+ // add some receiver-selected and active-speaker requests
1268
+ addReceiverSelectedRequest(200, fakeReceiveSlots[0], MAX_FS_360p, false);
1269
+ addActiveSpeakerRequest(
1270
+ 255,
1271
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1272
+ MAX_FS_360p,
1273
+ false,
1274
+ preferLiveVideo
1275
+ );
1276
+ addReceiverSelectedRequest(201, fakeReceiveSlots[4], MAX_FS_720p, false);
1277
+ addActiveSpeakerRequest(
1278
+ 254,
1279
+ [fakeReceiveSlots[5], fakeReceiveSlots[6], fakeReceiveSlots[7]],
1280
+ MAX_FS_720p,
1281
+ false,
1282
+ preferLiveVideo
1283
+ );
1284
+
1285
+ // Set maxMacroblocksLimit to a value that's big enough just for the 2 RS requests and 1 AS with 1 slot of 360p.
1286
+ // but not big enough for all of the RS and AS requests. If maxMacroblocksLimit
1287
+ // was applied first, the resolution of all requests (including RS ones) would be degraded
1288
+ // This test verifies that it's not happening and the resolutions are not affected.
1289
+ mediaRequestManager.setDegradationPreferences({maxMacroblocksLimit: MAX_FS_360p + MAX_FS_720p + MAX_FS_360p});
1290
+ sendMediaRequestsCallback.resetHistory();
1291
+
1292
+ /* Limit the num of streams so that only 2 RS requests and 1 AS with 1 slot can be sent out */
1293
+ limitNumAvailableStreams(preferLiveVideo, 3);
1294
+
1295
+ // check what got trimmed - the remaining requests should have unchanged resolutions
1296
+ checkMediaRequestsSent([
1297
+ {
1298
+ policy: 'receiver-selected',
1299
+ csi: 200,
1300
+ receiveSlot: fakeWcmeSlots[0],
1301
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1302
+ maxFs: MAX_FS_360p,
1303
+ maxMbps: MAX_MBPS_360p,
1304
+ },
1305
+ {
1306
+ policy: 'active-speaker',
1307
+ priority: 255,
1308
+ receiveSlots: [fakeWcmeSlots[1]],
1309
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1310
+ maxFs: MAX_FS_360p,
1311
+ maxMbps: MAX_MBPS_360p,
1312
+ },
1313
+ {
1314
+ policy: 'receiver-selected',
1315
+ csi: 201,
1316
+ receiveSlot: fakeWcmeSlots[4],
1317
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
1318
+ maxFs: MAX_FS_720p,
1319
+ maxMbps: MAX_MBPS_720p,
1320
+ },
1321
+ ], {preferLiveVideo});
1322
+ });
1323
+
1324
+ it('trims all AS requests completely until setNumCurrentSources() is called with non-zero values', async () => {
1325
+ // add some receiver-selected and active-speaker requests
1326
+ addReceiverSelectedRequest(200, fakeReceiveSlots[0], MAX_FS_360p, false);
1327
+ addActiveSpeakerRequest(
1328
+ 255,
1329
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1330
+ MAX_FS_360p,
1331
+ false,
1332
+ preferLiveVideo
1333
+ );
1334
+ addActiveSpeakerRequest(
1335
+ 254,
1336
+ [fakeReceiveSlots[5]],
1337
+ MAX_FS_360p,
1338
+ false,
1339
+ preferLiveVideo
1340
+ );
1341
+
1342
+ mediaRequestManager.commit();
1343
+
1344
+ // we're not calling setNumCurrentSources(), so it should use the initial values of 0 for sources count
1345
+ // and completely trim all AS requests to 0
1346
+ checkMediaRequestsSent([
1347
+ {
1348
+ policy: 'receiver-selected',
1349
+ csi: 200,
1350
+ receiveSlot: fakeWcmeSlots[0],
1351
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1352
+ maxFs: MAX_FS_360p,
1353
+ maxMbps: MAX_MBPS_360p,
1354
+ },
1355
+ ], {preferLiveVideo});
1356
+ });
1357
+
1358
+ it('resets num of sources to 0 when reset() is called', async () => {
1359
+ // set available streams to non-zero value
1360
+ limitNumAvailableStreams(preferLiveVideo, 4);
1361
+ sendMediaRequestsCallback.resetHistory();
1362
+
1363
+ // do the reset
1364
+ mediaRequestManager.reset();
1365
+
1366
+ // add some receiver-selected and active-speaker requests
1367
+ addReceiverSelectedRequest(200, fakeReceiveSlots[0], MAX_FS_360p, false);
1368
+ addActiveSpeakerRequest(
1369
+ 255,
1370
+ [fakeReceiveSlots[1], fakeReceiveSlots[2], fakeReceiveSlots[3]],
1371
+ MAX_FS_360p,
1372
+ false,
1373
+ preferLiveVideo
1374
+ );
1375
+
1376
+ mediaRequestManager.commit();
1377
+
1378
+ // verify that AS request was trimmed to 0, because we've reset mediaRequestManager so available streams count is 0 now
1379
+ checkMediaRequestsSent([
1380
+ {
1381
+ policy: 'receiver-selected',
1382
+ csi: 200,
1383
+ receiveSlot: fakeWcmeSlots[0],
1384
+ maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_360p,
1385
+ maxFs: MAX_FS_360p,
1386
+ maxMbps: MAX_MBPS_360p,
1387
+ },
1388
+ ], {preferLiveVideo});
1389
+ });
1390
+ })
1391
+ );
1392
+
1393
+
1394
+ it('throws if there are 2 active-speaker requests with different preferLiveVideo values', () => {
1395
+ addActiveSpeakerRequest(
1396
+ 255,
1397
+ [fakeReceiveSlots[0]],
1398
+ MAX_FS_360p,
1399
+ false,
1400
+ true
1401
+ );
1402
+ addReceiverSelectedRequest(201, fakeReceiveSlots[4], MAX_FS_720p, false);
1403
+ addActiveSpeakerRequest(
1404
+ 254,
1405
+ [fakeReceiveSlots[2]],
1406
+ MAX_FS_360p,
1407
+ false,
1408
+ false
1409
+ );
1410
+
1411
+ assert.throws(() => mediaRequestManager.commit(), 'a mix of active-speaker groups with different values for preferLiveVideo is not supported');
1412
+ })
1413
+ })
777
1414
  });
1415
+ function assertEqual(arg0: any, arg1: string) {
1416
+ throw new Error('Function not implemented.');
1417
+ }
1418
+