@blockcast/mmt-container 0.1.0 → 0.3.0-main.d9354616fdf2

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 (799) hide show
  1. package/README.md +524 -0
  2. package/dist/.build-stamp +0 -0
  3. package/dist/__tests__/test-utils.d.ts +71 -0
  4. package/dist/__tests__/test-utils.d.ts.map +1 -0
  5. package/dist/align.d.ts +152 -0
  6. package/dist/align.d.ts.map +1 -0
  7. package/dist/align.js +88 -0
  8. package/dist/align.js.map +7 -0
  9. package/dist/audio-init-parser.d.ts +66 -0
  10. package/dist/audio-init-parser.d.ts.map +1 -0
  11. package/dist/audio-init-parser.js +118 -0
  12. package/dist/audio-init-parser.js.map +7 -0
  13. package/dist/audio-ring-buffer.d.ts +50 -0
  14. package/dist/audio-ring-buffer.d.ts.map +1 -0
  15. package/dist/audio-ring-buffer.js +80 -0
  16. package/dist/audio-ring-buffer.js.map +7 -0
  17. package/dist/authored-timing.d.ts +32 -0
  18. package/dist/authored-timing.d.ts.map +1 -0
  19. package/dist/authored-timing.js +32 -0
  20. package/dist/authored-timing.js.map +7 -0
  21. package/dist/block-policy.d.ts +314 -0
  22. package/dist/block-policy.d.ts.map +1 -0
  23. package/dist/block-policy.js +466 -0
  24. package/dist/block-policy.js.map +7 -0
  25. package/dist/browser-runtime.js +26549 -0
  26. package/dist/browser-runtime.js.map +7 -0
  27. package/dist/carp-catalog.d.ts +429 -0
  28. package/dist/carp-catalog.d.ts.map +1 -0
  29. package/dist/carp-catalog.js +985 -0
  30. package/dist/carp-catalog.js.map +7 -0
  31. package/dist/catalog-fec-params.d.ts +275 -0
  32. package/dist/catalog-fec-params.d.ts.map +1 -0
  33. package/dist/catalog-fec-params.js +702 -0
  34. package/dist/catalog-fec-params.js.map +7 -0
  35. package/dist/catalog-network-source.d.ts +42 -0
  36. package/dist/catalog-network-source.d.ts.map +1 -0
  37. package/dist/catalog-network-source.js +47 -0
  38. package/dist/catalog-network-source.js.map +7 -0
  39. package/dist/catalog-validator.d.ts +18 -0
  40. package/dist/catalog-validator.d.ts.map +1 -0
  41. package/dist/catalog-validator.js +7747 -0
  42. package/dist/catalog-validator.js.map +7 -0
  43. package/dist/cmaf-block-assembler.d.ts +285 -0
  44. package/dist/cmaf-block-assembler.d.ts.map +1 -0
  45. package/dist/cmaf-block-assembler.js +1966 -0
  46. package/dist/cmaf-block-assembler.js.map +7 -0
  47. package/dist/cmaf-group-batcher.d.ts +38 -0
  48. package/dist/cmaf-group-batcher.d.ts.map +1 -0
  49. package/dist/cmaf-group-batcher.js +176 -0
  50. package/dist/cmaf-group-batcher.js.map +7 -0
  51. package/dist/cmcd-producer.d.ts +104 -0
  52. package/dist/cmcd-producer.d.ts.map +1 -0
  53. package/dist/cmcd-producer.js +183 -0
  54. package/dist/cmcd-producer.js.map +7 -0
  55. package/dist/codec-utils.d.ts +384 -0
  56. package/dist/codec-utils.d.ts.map +1 -0
  57. package/dist/codec-utils.js +1546 -0
  58. package/dist/codec-utils.js.map +7 -0
  59. package/dist/conceal-timeline.d.ts +146 -0
  60. package/dist/conceal-timeline.d.ts.map +1 -0
  61. package/dist/conceal-timeline.js +137 -0
  62. package/dist/conceal-timeline.js.map +7 -0
  63. package/dist/delivery-gap.d.ts +75 -0
  64. package/dist/delivery-gap.d.ts.map +1 -0
  65. package/dist/delivery-gap.js +88 -0
  66. package/dist/delivery-gap.js.map +7 -0
  67. package/dist/duplicate-ledger.d.ts +197 -0
  68. package/dist/duplicate-ledger.d.ts.map +1 -0
  69. package/dist/duplicate-ledger.js +226 -0
  70. package/dist/duplicate-ledger.js.map +7 -0
  71. package/dist/fec-codec.d.ts +32 -0
  72. package/dist/fec-codec.d.ts.map +1 -0
  73. package/dist/fec-codec.js +47 -0
  74. package/dist/fec-codec.js.map +7 -0
  75. package/dist/fec-manager.d.ts +583 -0
  76. package/dist/fec-manager.d.ts.map +1 -0
  77. package/dist/fec-manager.js +3899 -0
  78. package/dist/fec-manager.js.map +7 -0
  79. package/dist/fec-starvation-detector.d.ts +59 -0
  80. package/dist/fec-starvation-detector.d.ts.map +1 -0
  81. package/dist/fec-starvation-detector.js +60 -0
  82. package/dist/fec-starvation-detector.js.map +7 -0
  83. package/dist/fec-state.d.ts +131 -0
  84. package/dist/fec-state.d.ts.map +1 -0
  85. package/dist/fec-state.js +87 -0
  86. package/dist/fec-state.js.map +7 -0
  87. package/dist/fec-worker-setup.d.ts +94 -0
  88. package/dist/fec-worker-setup.d.ts.map +1 -0
  89. package/dist/fec-worker-setup.js +673 -0
  90. package/dist/fec-worker-setup.js.map +7 -0
  91. package/dist/fmp4-completion.d.ts +30 -0
  92. package/dist/fmp4-completion.d.ts.map +1 -0
  93. package/dist/fmp4-completion.js +21 -0
  94. package/dist/fmp4-completion.js.map +7 -0
  95. package/dist/fmp4-reader.d.ts +37 -0
  96. package/dist/fmp4-reader.d.ts.map +1 -0
  97. package/dist/fmp4-reader.js +100 -0
  98. package/dist/fmp4-reader.js.map +7 -0
  99. package/dist/index.d.ts +44 -3
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +460 -14
  102. package/dist/index.js.map +7 -1
  103. package/dist/iso-block-locator.d.ts +118 -0
  104. package/dist/iso-block-locator.d.ts.map +1 -0
  105. package/dist/iso-block-locator.js +289 -0
  106. package/dist/iso-block-locator.js.map +7 -0
  107. package/dist/iso-bmff-timing.d.ts +78 -0
  108. package/dist/iso-bmff-timing.d.ts.map +1 -0
  109. package/dist/iso-bmff-timing.js +593 -0
  110. package/dist/iso-bmff-timing.js.map +7 -0
  111. package/dist/loc.d.ts +70 -75
  112. package/dist/loc.d.ts.map +1 -1
  113. package/dist/loc.js +106 -192
  114. package/dist/loc.js.map +7 -1
  115. package/dist/manifest-auth-plan.d.ts +30 -0
  116. package/dist/manifest-auth-plan.d.ts.map +1 -0
  117. package/dist/manifest-auth-plan.js +1266 -0
  118. package/dist/manifest-auth-plan.js.map +7 -0
  119. package/dist/media-router.d.ts +262 -0
  120. package/dist/media-router.d.ts.map +1 -0
  121. package/dist/media-router.js +584 -0
  122. package/dist/media-router.js.map +7 -0
  123. package/dist/mfu-reassembler.d.ts +313 -9
  124. package/dist/mfu-reassembler.d.ts.map +1 -1
  125. package/dist/mfu-reassembler.js +3051 -285
  126. package/dist/mfu-reassembler.js.map +7 -1
  127. package/dist/mfu-reassembly-policy.d.ts +24 -0
  128. package/dist/mfu-reassembly-policy.d.ts.map +1 -0
  129. package/dist/mfu-reassembly-policy.js +99 -0
  130. package/dist/mfu-reassembly-policy.js.map +7 -0
  131. package/dist/mmtp-container-parser.d.ts +568 -0
  132. package/dist/mmtp-container-parser.d.ts.map +1 -0
  133. package/dist/mmtp-container-parser.js +6580 -0
  134. package/dist/mmtp-container-parser.js.map +7 -0
  135. package/dist/mmtp-container-parser.no-modules.js +9616 -0
  136. package/dist/mmtp-container-parser.no-modules.js.map +7 -0
  137. package/dist/mmtp-decode-pipeline.d.ts +138 -0
  138. package/dist/mmtp-decode-pipeline.d.ts.map +1 -0
  139. package/dist/mmtp-decode-pipeline.js +6814 -0
  140. package/dist/mmtp-decode-pipeline.js.map +7 -0
  141. package/dist/mmtp-router.d.ts +679 -0
  142. package/dist/mmtp-router.d.ts.map +1 -0
  143. package/dist/mmtp-router.js +11278 -0
  144. package/dist/mmtp-router.js.map +7 -0
  145. package/dist/mmtp-to-cmaf.d.ts +187 -0
  146. package/dist/mmtp-to-cmaf.d.ts.map +1 -0
  147. package/dist/mmtp-to-cmaf.js +716 -0
  148. package/dist/mmtp-to-cmaf.js.map +7 -0
  149. package/dist/multicast-auth-catalog.d.ts +115 -0
  150. package/dist/multicast-auth-catalog.d.ts.map +1 -0
  151. package/dist/multicast-auth-catalog.js +202 -0
  152. package/dist/multicast-auth-catalog.js.map +7 -0
  153. package/dist/multicast-input.d.ts +141 -0
  154. package/dist/multicast-input.d.ts.map +1 -0
  155. package/dist/multicast-input.js +390 -0
  156. package/dist/multicast-input.js.map +7 -0
  157. package/dist/multicast-manager.d.ts +669 -0
  158. package/dist/multicast-manager.d.ts.map +1 -0
  159. package/dist/multicast-manager.js +19101 -0
  160. package/dist/multicast-manager.js.map +7 -0
  161. package/dist/multicast-transport.d.ts +271 -0
  162. package/dist/multicast-transport.d.ts.map +1 -0
  163. package/dist/multicast-transport.js +2264 -0
  164. package/dist/multicast-transport.js.map +7 -0
  165. package/dist/multicast-unwrap.d.ts +57 -0
  166. package/dist/multicast-unwrap.d.ts.map +1 -0
  167. package/dist/multicast-unwrap.js +418 -0
  168. package/dist/multicast-unwrap.js.map +7 -0
  169. package/dist/no-modules.d.ts +10 -0
  170. package/dist/no-modules.d.ts.map +1 -0
  171. package/dist/no-modules.js +9491 -0
  172. package/dist/no-modules.js.map +7 -0
  173. package/dist/phase14-catalog-override.d.ts +126 -0
  174. package/dist/phase14-catalog-override.d.ts.map +1 -0
  175. package/dist/phase14-catalog-override.js +155 -0
  176. package/dist/phase14-catalog-override.js.map +7 -0
  177. package/dist/repair-fetch.d.ts +270 -0
  178. package/dist/repair-fetch.d.ts.map +1 -0
  179. package/dist/repair-fetch.js +381 -0
  180. package/dist/repair-fetch.js.map +7 -0
  181. package/dist/repair-layers.d.ts +158 -0
  182. package/dist/repair-layers.d.ts.map +1 -0
  183. package/dist/repair-layers.js +344 -0
  184. package/dist/repair-layers.js.map +7 -0
  185. package/dist/sample-combiner.d.ts +212 -0
  186. package/dist/sample-combiner.d.ts.map +1 -0
  187. package/dist/sample-combiner.js +595 -0
  188. package/dist/sample-combiner.js.map +7 -0
  189. package/dist/signaling.d.ts +29 -0
  190. package/dist/signaling.d.ts.map +1 -0
  191. package/dist/signaling.js +572 -0
  192. package/dist/signaling.js.map +7 -0
  193. package/dist/source-auth.d.ts +2 -0
  194. package/dist/source-auth.d.ts.map +1 -0
  195. package/dist/source-auth.js +1209 -0
  196. package/dist/source-auth.js.map +7 -0
  197. package/dist/switching-set-alignment.d.ts +61 -0
  198. package/dist/switching-set-alignment.d.ts.map +1 -0
  199. package/dist/switching-set-alignment.js +70 -0
  200. package/dist/switching-set-alignment.js.map +7 -0
  201. package/dist/timestamp-codec.d.ts +34 -0
  202. package/dist/timestamp-codec.d.ts.map +1 -0
  203. package/dist/timestamp-codec.js +473 -0
  204. package/dist/timestamp-codec.js.map +7 -0
  205. package/dist/track-pipeline-setup.d.ts +83 -0
  206. package/dist/track-pipeline-setup.d.ts.map +1 -0
  207. package/dist/track-pipeline-setup.js +291 -0
  208. package/dist/track-pipeline-setup.js.map +7 -0
  209. package/dist/track-pipeline.d.ts +121 -0
  210. package/dist/track-pipeline.d.ts.map +1 -0
  211. package/dist/track-pipeline.js +209 -0
  212. package/dist/track-pipeline.js.map +7 -0
  213. package/dist/track-session.d.ts +414 -0
  214. package/dist/track-session.d.ts.map +1 -0
  215. package/dist/track-session.js +754 -0
  216. package/dist/track-session.js.map +7 -0
  217. package/dist/transport-pool.d.ts +69 -0
  218. package/dist/transport-pool.d.ts.map +1 -0
  219. package/dist/transport-pool.js +74 -0
  220. package/dist/transport-pool.js.map +7 -0
  221. package/dist/wasm-mfu-reassembler.d.ts +97 -0
  222. package/dist/wasm-mfu-reassembler.d.ts.map +1 -0
  223. package/dist/wasm-mfu-reassembler.js +2133 -0
  224. package/dist/wasm-mfu-reassembler.js.map +7 -0
  225. package/dist/wasm-mmtp-container-parser.d.ts +10 -0
  226. package/dist/wasm-mmtp-container-parser.d.ts.map +1 -0
  227. package/dist/wasm-mmtp-container-parser.js +6834 -0
  228. package/dist/wasm-mmtp-container-parser.js.map +7 -0
  229. package/node_modules/@blockcast/fec-worker/README.md +223 -0
  230. package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
  231. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts +38 -0
  232. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts.map +1 -0
  233. package/node_modules/@blockcast/fec-worker/dist/block-order.js +78 -0
  234. package/node_modules/@blockcast/fec-worker/dist/block-order.js.map +1 -0
  235. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +93 -0
  236. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +1 -0
  237. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +346 -0
  238. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +1 -0
  239. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +380 -0
  240. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +1 -0
  241. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +11 -0
  242. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +1 -0
  243. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +14 -0
  244. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +1 -0
  245. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +859 -0
  246. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +7 -0
  247. package/node_modules/@blockcast/fec-worker/dist/index.d.ts +10 -0
  248. package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +1 -0
  249. package/node_modules/@blockcast/fec-worker/dist/index.js +8 -0
  250. package/node_modules/@blockcast/fec-worker/dist/index.js.map +1 -0
  251. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +20 -0
  252. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +1 -0
  253. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +370 -0
  254. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +7 -0
  255. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +104 -0
  256. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +1 -0
  257. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +181 -0
  258. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +1 -0
  259. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +194 -0
  260. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +1 -0
  261. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +62 -0
  262. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +1 -0
  263. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +9 -0
  264. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +1 -0
  265. package/node_modules/@blockcast/fec-worker/dist/transfer.js +13 -0
  266. package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +1 -0
  267. package/node_modules/@blockcast/fec-worker/package.json +59 -0
  268. package/node_modules/@blockcast/fec-worker/src/block-order.ts +93 -0
  269. package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +392 -0
  270. package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +399 -0
  271. package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +1502 -0
  272. package/node_modules/@blockcast/fec-worker/src/index.ts +35 -0
  273. package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +589 -0
  274. package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +222 -0
  275. package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +209 -0
  276. package/node_modules/@blockcast/fec-worker/src/transfer.ts +12 -0
  277. package/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
  278. package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  279. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
  280. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
  281. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
  282. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
  283. package/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
  284. package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
  285. package/node_modules/@blockcast/mmt-base/README.md +134 -0
  286. package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  287. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
  288. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
  289. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
  290. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
  291. package/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
  292. package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
  293. package/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
  294. package/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
  295. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
  296. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
  297. package/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
  298. package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
  299. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
  300. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
  301. package/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
  302. package/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
  303. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
  304. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
  305. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
  306. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
  307. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
  308. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
  309. package/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
  310. package/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
  311. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
  312. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
  313. package/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
  314. package/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
  315. package/node_modules/@blockcast/mmt-base/package.json +49 -0
  316. package/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
  317. package/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
  318. package/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
  319. package/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
  320. package/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
  321. package/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
  322. package/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
  323. package/node_modules/@blockcast/mmt-fec/README.md +271 -0
  324. package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
  325. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +82 -0
  326. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +1 -0
  327. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +296 -0
  328. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +1 -0
  329. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +106 -0
  330. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +1 -0
  331. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +288 -0
  332. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +1 -0
  333. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +46 -0
  334. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +1 -0
  335. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +96 -0
  336. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +1 -0
  337. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +33 -0
  338. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +1 -0
  339. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +57 -0
  340. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +1 -0
  341. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +205 -0
  342. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +1 -0
  343. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +240 -0
  344. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +1 -0
  345. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +28 -0
  346. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -0
  347. package/node_modules/@blockcast/mmt-fec/dist/index.js +28 -0
  348. package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -0
  349. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +20 -0
  350. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +1 -0
  351. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +28 -0
  352. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +1 -0
  353. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +258 -0
  354. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +1 -0
  355. package/node_modules/@blockcast/mmt-fec/dist/oti.js +382 -0
  356. package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +1 -0
  357. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +41 -0
  358. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +1 -0
  359. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +81 -0
  360. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +1 -0
  361. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +82 -0
  362. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +1 -0
  363. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +170 -0
  364. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +1 -0
  365. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
  366. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  367. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
  368. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
  369. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
  370. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
  371. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
  372. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
  373. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +134 -0
  374. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  375. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
  376. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
  377. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
  378. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
  379. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
  380. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
  381. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
  382. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
  383. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
  384. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
  385. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
  386. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
  387. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
  388. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
  389. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
  390. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
  391. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
  392. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
  393. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
  394. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
  395. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
  396. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
  397. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
  398. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
  399. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
  400. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
  401. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
  402. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
  403. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +49 -0
  404. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
  405. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
  406. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
  407. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
  408. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
  409. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
  410. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
  411. package/node_modules/@blockcast/mmt-fec/package.json +79 -0
  412. package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +371 -0
  413. package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +439 -0
  414. package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +127 -0
  415. package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +68 -0
  416. package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +310 -0
  417. package/node_modules/@blockcast/mmt-fec/src/index.ts +94 -0
  418. package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +34 -0
  419. package/node_modules/@blockcast/mmt-fec/src/oti.ts +463 -0
  420. package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +101 -0
  421. package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +195 -0
  422. package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
  423. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +28 -0
  424. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +1 -0
  425. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +128 -0
  426. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +1 -0
  427. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +4 -0
  428. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +1 -0
  429. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +4 -0
  430. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +1 -0
  431. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +37 -0
  432. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +1 -0
  433. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +179 -0
  434. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +1 -0
  435. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +99 -0
  436. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +1 -0
  437. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +492 -0
  438. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +1 -0
  439. package/node_modules/@blockcast/mmt-manifest-verify/package.json +45 -0
  440. package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +171 -0
  441. package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +3 -0
  442. package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +230 -0
  443. package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +669 -0
  444. package/node_modules/@noble/hashes/LICENSE +21 -0
  445. package/node_modules/@noble/hashes/README.md +521 -0
  446. package/node_modules/@noble/hashes/_assert.d.ts +17 -0
  447. package/node_modules/@noble/hashes/_assert.d.ts.map +1 -0
  448. package/node_modules/@noble/hashes/_assert.js +18 -0
  449. package/node_modules/@noble/hashes/_assert.js.map +1 -0
  450. package/node_modules/@noble/hashes/_blake.d.ts +14 -0
  451. package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
  452. package/node_modules/@noble/hashes/_blake.js +50 -0
  453. package/node_modules/@noble/hashes/_blake.js.map +1 -0
  454. package/node_modules/@noble/hashes/_md.d.ts +51 -0
  455. package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
  456. package/node_modules/@noble/hashes/_md.js +162 -0
  457. package/node_modules/@noble/hashes/_md.js.map +1 -0
  458. package/node_modules/@noble/hashes/_u64.d.ts +55 -0
  459. package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
  460. package/node_modules/@noble/hashes/_u64.js +90 -0
  461. package/node_modules/@noble/hashes/_u64.js.map +1 -0
  462. package/node_modules/@noble/hashes/argon2.d.ts +32 -0
  463. package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
  464. package/node_modules/@noble/hashes/argon2.js +401 -0
  465. package/node_modules/@noble/hashes/argon2.js.map +1 -0
  466. package/node_modules/@noble/hashes/blake1.d.ts +106 -0
  467. package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
  468. package/node_modules/@noble/hashes/blake1.js +459 -0
  469. package/node_modules/@noble/hashes/blake1.js.map +1 -0
  470. package/node_modules/@noble/hashes/blake2.d.ts +116 -0
  471. package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
  472. package/node_modules/@noble/hashes/blake2.js +420 -0
  473. package/node_modules/@noble/hashes/blake2.js.map +1 -0
  474. package/node_modules/@noble/hashes/blake2b.d.ts +11 -0
  475. package/node_modules/@noble/hashes/blake2b.d.ts.map +1 -0
  476. package/node_modules/@noble/hashes/blake2b.js +14 -0
  477. package/node_modules/@noble/hashes/blake2b.js.map +1 -0
  478. package/node_modules/@noble/hashes/blake2s.d.ts +20 -0
  479. package/node_modules/@noble/hashes/blake2s.d.ts.map +1 -0
  480. package/node_modules/@noble/hashes/blake2s.js +24 -0
  481. package/node_modules/@noble/hashes/blake2s.js.map +1 -0
  482. package/node_modules/@noble/hashes/blake3.d.ts +54 -0
  483. package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
  484. package/node_modules/@noble/hashes/blake3.js +255 -0
  485. package/node_modules/@noble/hashes/blake3.js.map +1 -0
  486. package/node_modules/@noble/hashes/crypto.d.ts +2 -0
  487. package/node_modules/@noble/hashes/crypto.d.ts.map +1 -0
  488. package/node_modules/@noble/hashes/crypto.js +5 -0
  489. package/node_modules/@noble/hashes/crypto.js.map +1 -0
  490. package/node_modules/@noble/hashes/cryptoNode.d.ts +2 -0
  491. package/node_modules/@noble/hashes/cryptoNode.d.ts.map +1 -0
  492. package/node_modules/@noble/hashes/cryptoNode.js +18 -0
  493. package/node_modules/@noble/hashes/cryptoNode.js.map +1 -0
  494. package/node_modules/@noble/hashes/eskdf.d.ts +47 -0
  495. package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
  496. package/node_modules/@noble/hashes/eskdf.js +166 -0
  497. package/node_modules/@noble/hashes/eskdf.js.map +1 -0
  498. package/node_modules/@noble/hashes/esm/_assert.d.ts +17 -0
  499. package/node_modules/@noble/hashes/esm/_assert.d.ts.map +1 -0
  500. package/node_modules/@noble/hashes/esm/_assert.js +15 -0
  501. package/node_modules/@noble/hashes/esm/_assert.js.map +1 -0
  502. package/node_modules/@noble/hashes/esm/_blake.d.ts +14 -0
  503. package/node_modules/@noble/hashes/esm/_blake.d.ts.map +1 -0
  504. package/node_modules/@noble/hashes/esm/_blake.js +45 -0
  505. package/node_modules/@noble/hashes/esm/_blake.js.map +1 -0
  506. package/node_modules/@noble/hashes/esm/_md.d.ts +51 -0
  507. package/node_modules/@noble/hashes/esm/_md.d.ts.map +1 -0
  508. package/node_modules/@noble/hashes/esm/_md.js +155 -0
  509. package/node_modules/@noble/hashes/esm/_md.js.map +1 -0
  510. package/node_modules/@noble/hashes/esm/_u64.d.ts +55 -0
  511. package/node_modules/@noble/hashes/esm/_u64.d.ts.map +1 -0
  512. package/node_modules/@noble/hashes/esm/_u64.js +67 -0
  513. package/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
  514. package/node_modules/@noble/hashes/esm/argon2.d.ts +32 -0
  515. package/node_modules/@noble/hashes/esm/argon2.d.ts.map +1 -0
  516. package/node_modules/@noble/hashes/esm/argon2.js +392 -0
  517. package/node_modules/@noble/hashes/esm/argon2.js.map +1 -0
  518. package/node_modules/@noble/hashes/esm/blake1.d.ts +106 -0
  519. package/node_modules/@noble/hashes/esm/blake1.d.ts.map +1 -0
  520. package/node_modules/@noble/hashes/esm/blake1.js +452 -0
  521. package/node_modules/@noble/hashes/esm/blake1.js.map +1 -0
  522. package/node_modules/@noble/hashes/esm/blake2.d.ts +116 -0
  523. package/node_modules/@noble/hashes/esm/blake2.d.ts.map +1 -0
  524. package/node_modules/@noble/hashes/esm/blake2.js +413 -0
  525. package/node_modules/@noble/hashes/esm/blake2.js.map +1 -0
  526. package/node_modules/@noble/hashes/esm/blake2b.d.ts +11 -0
  527. package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +1 -0
  528. package/node_modules/@noble/hashes/esm/blake2b.js +11 -0
  529. package/node_modules/@noble/hashes/esm/blake2b.js.map +1 -0
  530. package/node_modules/@noble/hashes/esm/blake2s.d.ts +20 -0
  531. package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +1 -0
  532. package/node_modules/@noble/hashes/esm/blake2s.js +21 -0
  533. package/node_modules/@noble/hashes/esm/blake2s.js.map +1 -0
  534. package/node_modules/@noble/hashes/esm/blake3.d.ts +54 -0
  535. package/node_modules/@noble/hashes/esm/blake3.d.ts.map +1 -0
  536. package/node_modules/@noble/hashes/esm/blake3.js +251 -0
  537. package/node_modules/@noble/hashes/esm/blake3.js.map +1 -0
  538. package/node_modules/@noble/hashes/esm/crypto.d.ts +2 -0
  539. package/node_modules/@noble/hashes/esm/crypto.d.ts.map +1 -0
  540. package/node_modules/@noble/hashes/esm/crypto.js +2 -0
  541. package/node_modules/@noble/hashes/esm/crypto.js.map +1 -0
  542. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +2 -0
  543. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +1 -0
  544. package/node_modules/@noble/hashes/esm/cryptoNode.js +15 -0
  545. package/node_modules/@noble/hashes/esm/cryptoNode.js.map +1 -0
  546. package/node_modules/@noble/hashes/esm/eskdf.d.ts +47 -0
  547. package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +1 -0
  548. package/node_modules/@noble/hashes/esm/eskdf.js +160 -0
  549. package/node_modules/@noble/hashes/esm/eskdf.js.map +1 -0
  550. package/node_modules/@noble/hashes/esm/hkdf.d.ts +36 -0
  551. package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +1 -0
  552. package/node_modules/@noble/hashes/esm/hkdf.js +82 -0
  553. package/node_modules/@noble/hashes/esm/hkdf.js.map +1 -0
  554. package/node_modules/@noble/hashes/esm/hmac.d.ts +35 -0
  555. package/node_modules/@noble/hashes/esm/hmac.d.ts.map +1 -0
  556. package/node_modules/@noble/hashes/esm/hmac.js +86 -0
  557. package/node_modules/@noble/hashes/esm/hmac.js.map +1 -0
  558. package/node_modules/@noble/hashes/esm/index.d.ts +2 -0
  559. package/node_modules/@noble/hashes/esm/index.d.ts.map +1 -0
  560. package/node_modules/@noble/hashes/esm/index.js +33 -0
  561. package/node_modules/@noble/hashes/esm/index.js.map +1 -0
  562. package/node_modules/@noble/hashes/esm/legacy.d.ts +71 -0
  563. package/node_modules/@noble/hashes/esm/legacy.d.ts.map +1 -0
  564. package/node_modules/@noble/hashes/esm/legacy.js +281 -0
  565. package/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
  566. package/node_modules/@noble/hashes/esm/package.json +10 -0
  567. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +23 -0
  568. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +1 -0
  569. package/node_modules/@noble/hashes/esm/pbkdf2.js +97 -0
  570. package/node_modules/@noble/hashes/esm/pbkdf2.js.map +1 -0
  571. package/node_modules/@noble/hashes/esm/ripemd160.d.ts +13 -0
  572. package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +1 -0
  573. package/node_modules/@noble/hashes/esm/ripemd160.js +13 -0
  574. package/node_modules/@noble/hashes/esm/ripemd160.js.map +1 -0
  575. package/node_modules/@noble/hashes/esm/scrypt.d.ts +34 -0
  576. package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +1 -0
  577. package/node_modules/@noble/hashes/esm/scrypt.js +228 -0
  578. package/node_modules/@noble/hashes/esm/scrypt.js.map +1 -0
  579. package/node_modules/@noble/hashes/esm/sha1.d.ts +11 -0
  580. package/node_modules/@noble/hashes/esm/sha1.d.ts.map +1 -0
  581. package/node_modules/@noble/hashes/esm/sha1.js +11 -0
  582. package/node_modules/@noble/hashes/esm/sha1.js.map +1 -0
  583. package/node_modules/@noble/hashes/esm/sha2.d.ts +159 -0
  584. package/node_modules/@noble/hashes/esm/sha2.d.ts.map +1 -0
  585. package/node_modules/@noble/hashes/esm/sha2.js +375 -0
  586. package/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
  587. package/node_modules/@noble/hashes/esm/sha256.d.ts +20 -0
  588. package/node_modules/@noble/hashes/esm/sha256.d.ts.map +1 -0
  589. package/node_modules/@noble/hashes/esm/sha256.js +20 -0
  590. package/node_modules/@noble/hashes/esm/sha256.js.map +1 -0
  591. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +142 -0
  592. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +1 -0
  593. package/node_modules/@noble/hashes/esm/sha3-addons.js +393 -0
  594. package/node_modules/@noble/hashes/esm/sha3-addons.js.map +1 -0
  595. package/node_modules/@noble/hashes/esm/sha3.d.ts +53 -0
  596. package/node_modules/@noble/hashes/esm/sha3.d.ts.map +1 -0
  597. package/node_modules/@noble/hashes/esm/sha3.js +234 -0
  598. package/node_modules/@noble/hashes/esm/sha3.js.map +1 -0
  599. package/node_modules/@noble/hashes/esm/sha512.d.ts +26 -0
  600. package/node_modules/@noble/hashes/esm/sha512.d.ts.map +1 -0
  601. package/node_modules/@noble/hashes/esm/sha512.js +26 -0
  602. package/node_modules/@noble/hashes/esm/sha512.js.map +1 -0
  603. package/node_modules/@noble/hashes/esm/utils.d.ts +161 -0
  604. package/node_modules/@noble/hashes/esm/utils.d.ts.map +1 -0
  605. package/node_modules/@noble/hashes/esm/utils.js +281 -0
  606. package/node_modules/@noble/hashes/esm/utils.js.map +1 -0
  607. package/node_modules/@noble/hashes/hkdf.d.ts +36 -0
  608. package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
  609. package/node_modules/@noble/hashes/hkdf.js +88 -0
  610. package/node_modules/@noble/hashes/hkdf.js.map +1 -0
  611. package/node_modules/@noble/hashes/hmac.d.ts +35 -0
  612. package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
  613. package/node_modules/@noble/hashes/hmac.js +91 -0
  614. package/node_modules/@noble/hashes/hmac.js.map +1 -0
  615. package/node_modules/@noble/hashes/index.d.ts +1 -0
  616. package/node_modules/@noble/hashes/index.d.ts.map +1 -0
  617. package/node_modules/@noble/hashes/index.js +33 -0
  618. package/node_modules/@noble/hashes/index.js.map +1 -0
  619. package/node_modules/@noble/hashes/legacy.d.ts +71 -0
  620. package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
  621. package/node_modules/@noble/hashes/legacy.js +287 -0
  622. package/node_modules/@noble/hashes/legacy.js.map +1 -0
  623. package/node_modules/@noble/hashes/package.json +266 -0
  624. package/node_modules/@noble/hashes/pbkdf2.d.ts +23 -0
  625. package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
  626. package/node_modules/@noble/hashes/pbkdf2.js +101 -0
  627. package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
  628. package/node_modules/@noble/hashes/ripemd160.d.ts +13 -0
  629. package/node_modules/@noble/hashes/ripemd160.d.ts.map +1 -0
  630. package/node_modules/@noble/hashes/ripemd160.js +16 -0
  631. package/node_modules/@noble/hashes/ripemd160.js.map +1 -0
  632. package/node_modules/@noble/hashes/scrypt.d.ts +34 -0
  633. package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
  634. package/node_modules/@noble/hashes/scrypt.js +232 -0
  635. package/node_modules/@noble/hashes/scrypt.js.map +1 -0
  636. package/node_modules/@noble/hashes/sha1.d.ts +11 -0
  637. package/node_modules/@noble/hashes/sha1.d.ts.map +1 -0
  638. package/node_modules/@noble/hashes/sha1.js +14 -0
  639. package/node_modules/@noble/hashes/sha1.js.map +1 -0
  640. package/node_modules/@noble/hashes/sha2.d.ts +159 -0
  641. package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
  642. package/node_modules/@noble/hashes/sha2.js +384 -0
  643. package/node_modules/@noble/hashes/sha2.js.map +1 -0
  644. package/node_modules/@noble/hashes/sha256.d.ts +20 -0
  645. package/node_modules/@noble/hashes/sha256.d.ts.map +1 -0
  646. package/node_modules/@noble/hashes/sha256.js +23 -0
  647. package/node_modules/@noble/hashes/sha256.js.map +1 -0
  648. package/node_modules/@noble/hashes/sha3-addons.d.ts +142 -0
  649. package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
  650. package/node_modules/@noble/hashes/sha3-addons.js +402 -0
  651. package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
  652. package/node_modules/@noble/hashes/sha3.d.ts +53 -0
  653. package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
  654. package/node_modules/@noble/hashes/sha3.js +239 -0
  655. package/node_modules/@noble/hashes/sha3.js.map +1 -0
  656. package/node_modules/@noble/hashes/sha512.d.ts +26 -0
  657. package/node_modules/@noble/hashes/sha512.d.ts.map +1 -0
  658. package/node_modules/@noble/hashes/sha512.js +29 -0
  659. package/node_modules/@noble/hashes/sha512.js.map +1 -0
  660. package/node_modules/@noble/hashes/src/_assert.ts +22 -0
  661. package/node_modules/@noble/hashes/src/_blake.ts +50 -0
  662. package/node_modules/@noble/hashes/src/_md.ts +176 -0
  663. package/node_modules/@noble/hashes/src/_u64.ts +91 -0
  664. package/node_modules/@noble/hashes/src/argon2.ts +497 -0
  665. package/node_modules/@noble/hashes/src/blake1.ts +534 -0
  666. package/node_modules/@noble/hashes/src/blake2.ts +486 -0
  667. package/node_modules/@noble/hashes/src/blake2b.ts +10 -0
  668. package/node_modules/@noble/hashes/src/blake2s.ts +20 -0
  669. package/node_modules/@noble/hashes/src/blake3.ts +272 -0
  670. package/node_modules/@noble/hashes/src/crypto.ts +9 -0
  671. package/node_modules/@noble/hashes/src/cryptoNode.ts +15 -0
  672. package/node_modules/@noble/hashes/src/eskdf.ts +187 -0
  673. package/node_modules/@noble/hashes/src/hkdf.ts +88 -0
  674. package/node_modules/@noble/hashes/src/hmac.ts +94 -0
  675. package/node_modules/@noble/hashes/src/index.ts +31 -0
  676. package/node_modules/@noble/hashes/src/legacy.ts +293 -0
  677. package/node_modules/@noble/hashes/src/pbkdf2.ts +122 -0
  678. package/node_modules/@noble/hashes/src/ripemd160.ts +12 -0
  679. package/node_modules/@noble/hashes/src/scrypt.ts +257 -0
  680. package/node_modules/@noble/hashes/src/sha1.ts +10 -0
  681. package/node_modules/@noble/hashes/src/sha2.ts +402 -0
  682. package/node_modules/@noble/hashes/src/sha256.ts +24 -0
  683. package/node_modules/@noble/hashes/src/sha3-addons.ts +499 -0
  684. package/node_modules/@noble/hashes/src/sha3.ts +258 -0
  685. package/node_modules/@noble/hashes/src/sha512.ts +34 -0
  686. package/node_modules/@noble/hashes/src/utils.ts +395 -0
  687. package/node_modules/@noble/hashes/utils.d.ts +161 -0
  688. package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
  689. package/node_modules/@noble/hashes/utils.js +313 -0
  690. package/node_modules/@noble/hashes/utils.js.map +1 -0
  691. package/package.json +179 -8
  692. package/schemas/catalog.schema.json +357 -0
  693. package/src/align.ts +239 -0
  694. package/src/audio-init-parser.ts +189 -0
  695. package/src/audio-ring-buffer.ts +120 -0
  696. package/src/authored-timing.ts +63 -0
  697. package/src/block-policy.ts +903 -0
  698. package/src/carp-catalog.ts +1065 -0
  699. package/src/catalog-fec-params.ts +729 -0
  700. package/src/catalog-network-source.ts +74 -0
  701. package/src/catalog-validator.ts +34 -0
  702. package/src/cmaf-block-assembler.ts +1255 -0
  703. package/src/cmaf-group-batcher.ts +104 -0
  704. package/src/cmcd-producer.ts +329 -0
  705. package/src/codec-utils.ts +1984 -0
  706. package/src/conceal-timeline.ts +293 -0
  707. package/src/delivery-gap.ts +147 -0
  708. package/src/duplicate-ledger.ts +372 -0
  709. package/src/fec-codec.ts +61 -0
  710. package/src/fec-manager.ts +4298 -0
  711. package/src/fec-starvation-detector.ts +128 -0
  712. package/src/fec-state.ts +219 -0
  713. package/src/fec-worker-setup.ts +283 -0
  714. package/src/fmp4-completion.ts +47 -0
  715. package/src/fmp4-reader.ts +112 -0
  716. package/src/index.ts +590 -21
  717. package/src/iso-block-locator.ts +329 -0
  718. package/src/iso-bmff-timing.ts +813 -0
  719. package/src/loc.ts +128 -154
  720. package/src/manifest-auth-plan.ts +107 -0
  721. package/src/media-router.ts +841 -0
  722. package/src/mfu-reassembler.ts +3480 -155
  723. package/src/mfu-reassembly-policy.ts +134 -0
  724. package/src/mmtp-container-parser.ts +2380 -0
  725. package/src/mmtp-decode-pipeline.ts +406 -0
  726. package/src/mmtp-router.ts +4860 -0
  727. package/src/mmtp-to-cmaf.ts +977 -0
  728. package/src/multicast-auth-catalog.ts +340 -0
  729. package/src/multicast-input.ts +793 -0
  730. package/src/multicast-manager.ts +2783 -0
  731. package/src/multicast-transport.ts +1058 -0
  732. package/src/multicast-unwrap.ts +132 -0
  733. package/src/no-modules.ts +21 -0
  734. package/src/phase14-catalog-override.ts +336 -0
  735. package/src/repair-fetch.ts +772 -0
  736. package/src/repair-layers.ts +533 -0
  737. package/src/sample-combiner.ts +938 -0
  738. package/src/signaling.ts +78 -0
  739. package/src/source-auth.ts +1 -0
  740. package/src/switching-set-alignment.ts +109 -0
  741. package/src/timestamp-codec.ts +265 -0
  742. package/src/track-pipeline-setup.ts +205 -0
  743. package/src/track-pipeline.ts +332 -0
  744. package/src/track-session.ts +1010 -0
  745. package/src/transport-pool.ts +128 -0
  746. package/src/wasm-mfu-reassembler.ts +405 -0
  747. package/src/wasm-mmtp-container-parser.ts +23 -0
  748. package/test-vectors/align.json +199 -0
  749. package/test-vectors/catalog/README.md +106 -0
  750. package/test-vectors/catalog/negative/archive-origin-with-path.json +33 -0
  751. package/test-vectors/catalog/negative/archive-unknown-field.json +34 -0
  752. package/test-vectors/catalog/negative/fec-block-profile-missing.json +51 -0
  753. package/test-vectors/catalog/negative/fec-block-profile-unknown.json +52 -0
  754. package/test-vectors/catalog/negative/fec-enhancement-repair-removed.json +28 -0
  755. package/test-vectors/catalog/negative/fec-repair-layer-geometry.json +33 -0
  756. package/test-vectors/catalog/negative/fec-repair-layer-missing-symbols.json +31 -0
  757. package/test-vectors/catalog/negative/fec-repair-multiple-depends.json +32 -0
  758. package/test-vectors/catalog/negative/fec-repair-overlay-with-layer.json +34 -0
  759. package/test-vectors/catalog/negative/fec-repair-priority-out-of-band.json +24 -0
  760. package/test-vectors/catalog/negative/fec-repair-source-symbols-without-scope.json +33 -0
  761. package/test-vectors/catalog/negative/legacy-selection-params.json +15 -0
  762. package/test-vectors/catalog/negative/media-track-repair-layer.json +16 -0
  763. package/test-vectors/catalog/negative/missing-mmtp-fields.json +12 -0
  764. package/test-vectors/catalog/negative/multicast-auth-padded-key.json +37 -0
  765. package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +53 -0
  766. package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +37 -0
  767. package/test-vectors/catalog/negative/multicast-endpoint-missing-protocol-and-source.json +24 -0
  768. package/test-vectors/catalog/negative/multicast-network-source-empty.json +44 -0
  769. package/test-vectors/catalog/negative/multicast-packet-id-signaling.json +26 -0
  770. package/test-vectors/catalog/negative/network-source-object.json +25 -0
  771. package/test-vectors/catalog/negative/raptorq-source-symbols-over-max.json +24 -0
  772. package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +27 -0
  773. package/test-vectors/catalog/negative/repair-track-legacy-shape.json +19 -0
  774. package/test-vectors/catalog/negative/track-role-empty.json +16 -0
  775. package/test-vectors/catalog/negative/track-role-non-string.json +16 -0
  776. package/test-vectors/catalog/positive/archive-origin.json +34 -0
  777. package/test-vectors/catalog/positive/fec-iso-ssbg1.json +52 -0
  778. package/test-vectors/catalog/positive/fec-layered-repair.json +106 -0
  779. package/test-vectors/catalog/positive/fec-multicast.json +52 -0
  780. package/test-vectors/catalog/positive/flat-av.json +30 -0
  781. package/test-vectors/catalog/positive/multicast-auth-rotation.json +55 -0
  782. package/test-vectors/catalog/positive/multicast-native-ssm-no-network-source.json +43 -0
  783. package/test-vectors/catalog/positive/ticks-and-mixed-timescales.json +39 -0
  784. package/test-vectors/catalog/positive/track-role.json +49 -0
  785. package/test-vectors/catalog/releases/moqcast-native-v16-v1/catalog.json +65 -0
  786. package/test-vectors/catalog/releases/moqcast-native-v16-v1.archive.sha256 +1 -0
  787. package/test-vectors/catalog-multicast-auth-v1.json +26 -0
  788. package/test-vectors/catalog-validation.json +732 -0
  789. package/test-vectors/catalog-validator-public-api.mjs +25 -0
  790. package/test-vectors/generate-source-auth-fixture.mjs +114 -0
  791. package/test-vectors/hevc-x265-repeat-headers-v1.json +40 -0
  792. package/test-vectors/source-auth-v1.json +61 -0
  793. package/test-vectors/source-contiguity-v1.json +131 -0
  794. package/test-vectors/subsample-placement-v1.json +230 -0
  795. package/dist/mmtp.d.ts +0 -73
  796. package/dist/mmtp.d.ts.map +0 -1
  797. package/dist/mmtp.js +0 -210
  798. package/dist/mmtp.js.map +0 -1
  799. package/src/mmtp.ts +0 -277
@@ -0,0 +1,903 @@
1
+ /**
2
+ * Keyframe-protected FEC repair policy.
3
+ *
4
+ * Every FEC block still gets in-band FEC decode. What this module decides is
5
+ * (1) which blocks may hold a keyframe (RAP), so a block short of K at its
6
+ * repair deadline can be repaired over QUIC with the right priority, and
7
+ * (2) what a sink must do with the first frame released after a gap: stall
8
+ * until the next RAP, or conceal and keep playing.
9
+ *
10
+ * The two decisions are deliberately independent. Classification only sets
11
+ * repair priority. The stall/conceal decision is made again per released gap
12
+ * from the media that is actually missing, so a wrong classification can only
13
+ * lower a block's repair priority; it can never make playback wrong.
14
+ *
15
+ * Everything here is derived from catalog-authored timing and in-band MMTP
16
+ * evidence. There are no timers, no cadence heuristics, and no defaults: a
17
+ * track whose geometry cannot be derived exactly runs in the defined
18
+ * fail-closed mode `all-protected`, where every block is treated as possibly
19
+ * keyframe-bearing.
20
+ *
21
+ * All three players (moqtail, hang, Shaka) consume this one implementation.
22
+ */
23
+
24
+ import { deriveFecInterleaveDepth } from '@blockcast/mmt-fec'
25
+
26
+ // ─── Classes and priorities ─────────────────────────────────────────
27
+
28
+ /**
29
+ * Repair class of one FEC block.
30
+ *
31
+ * - `keyframe`: the block holds (or held) a RAP / MPU start.
32
+ * - `delta`: the block provably holds only non-RAP video frames.
33
+ * - `unknown`: neither could be proven; treated exactly like `keyframe`.
34
+ * - `audio`: an audio block.
35
+ */
36
+ export type BlockClass = 'keyframe' | 'delta' | 'unknown' | 'audio'
37
+
38
+ /** Repair priority. Lower is more urgent. */
39
+ export type RepairPriority = 0 | 1 | 2
40
+
41
+ export type TrackKind = 'video' | 'audio'
42
+
43
+ /** P0 = keyframe/unknown (stall-preventing), P1 = audio, P2 = delta. */
44
+ export function repairPriorityForClass(blockClass: BlockClass): RepairPriority {
45
+ switch (blockClass) {
46
+ case 'keyframe':
47
+ case 'unknown':
48
+ return 0
49
+ case 'audio':
50
+ return 1
51
+ case 'delta':
52
+ return 2
53
+ }
54
+ }
55
+
56
+ // ─── Geometry ───────────────────────────────────────────────────────
57
+
58
+ export type ClassifierMode = 'classifying' | 'all-protected'
59
+
60
+ /** Why a track runs `all-protected`. */
61
+ export type ClassifierReason =
62
+ // Geometry (catalog) reasons.
63
+ | 'framerate-absent'
64
+ | 'keyframe-cadence-absent'
65
+ | 'keyframe-interval-not-integral'
66
+ | 'block-spans-gop'
67
+ /**
68
+ * The catalog keyframe interval is not an exact integer number of ticks
69
+ * in the media track's own timescale (ISO-BMFF `mdhd`), so released RAP
70
+ * spacing cannot be verified and hold-last cannot predict the next RAP.
71
+ * Nothing is wrong with the stream; the cadence is simply unprovable.
72
+ */
73
+ | 'keyframe-interval-not-media-integral'
74
+ /**
75
+ * Another stream on this packetId was configured with its own geometry
76
+ * and this one was not, so no geometry provably belongs to it (ABR rungs
77
+ * sharing a packetId).
78
+ */
79
+ | 'stream-geometry-absent'
80
+ // In-band invariant violations (positive evidence only).
81
+ | 'rap-not-mpu-start'
82
+ | 'mpu-longer-than-gop'
83
+ | 'block-not-contiguous'
84
+ | 'rap-spacing-mismatch'
85
+ | 'mpu-multiple-fragments'
86
+ | 'block-wider-than-interleave'
87
+
88
+ /** Raw catalog timing for one track. Never a resolved cadence. */
89
+ export interface BlockClassifierGeometryInput {
90
+ readonly trackKind: TrackKind
91
+ /** Catalog `framerate` (frames per second). */
92
+ readonly framerate?: number
93
+ /** Catalog `fec.interleaveDepthMs`: the full FEC block span (§5.1). */
94
+ readonly interleaveDepthMs: number
95
+ /** Catalog track `timescale` for `keyframeIntervalTicks`. */
96
+ readonly timescale?: number
97
+ /** Catalog `keyframeIntervalTicks` (preferred when the timescale is present). */
98
+ readonly keyframeIntervalTicks?: number
99
+ /** Catalog `keyframeIntervalMs`. */
100
+ readonly keyframeIntervalMs?: number
101
+ }
102
+
103
+ /** Exact keyframe interval as a rational number of seconds: ticks / timescale. */
104
+ export interface KeyframeInterval {
105
+ readonly ticks: number
106
+ readonly timescale: number
107
+ }
108
+
109
+ export type BlockClassifierGeometry =
110
+ | { readonly trackKind: 'audio' }
111
+ | {
112
+ readonly trackKind: 'video'
113
+ readonly mode: 'classifying'
114
+ /** F: one frame's duration in milliseconds (1000 / framerate). */
115
+ readonly frameDurationMs: number
116
+ /** D: media units per FEC block (deriveFecInterleaveDepth). */
117
+ readonly interleaveUnits: number
118
+ /** G: frames per GOP. */
119
+ readonly gopFrames: number
120
+ readonly keyframeInterval: KeyframeInterval
121
+ }
122
+ | {
123
+ readonly trackKind: 'video'
124
+ readonly mode: 'all-protected'
125
+ readonly reason: ClassifierReason
126
+ }
127
+
128
+ /**
129
+ * Integer value of `numerator / denominator` when it is one, else null.
130
+ *
131
+ * Catalog framerates are JSON numbers, so an NTSC rate arrives as the double
132
+ * nearest 30000/1001. One multiply and one divide each add at most half an
133
+ * ulp of relative error (IEEE-754), so a quotient within two ulps of an
134
+ * integer IS that integer; anything further is genuinely non-integral.
135
+ */
136
+ function exactInteger(numerator: number, denominator: number): number | null {
137
+ if (!Number.isFinite(numerator) || !Number.isFinite(denominator) || denominator === 0) {
138
+ return null
139
+ }
140
+ const quotient = numerator / denominator
141
+ const rounded = Math.round(quotient)
142
+ if (rounded < 1) return null
143
+ const representationError = 2 * Number.EPSILON * Math.abs(quotient)
144
+ return Math.abs(quotient - rounded) <= representationError ? rounded : null
145
+ }
146
+
147
+ function isPositiveFinite(value: number | undefined): value is number {
148
+ return value !== undefined && Number.isFinite(value) && value > 0
149
+ }
150
+
151
+ /**
152
+ * Derive the per-track classifier geometry from raw catalog fields.
153
+ *
154
+ * `all-protected` is the policy's defined fail-closed state, not a default:
155
+ * it is returned with the exact reason. The only throw is for a value the
156
+ * catalog validator already rejects (a non-positive block span).
157
+ */
158
+ export function deriveBlockClassifierGeometry(
159
+ input: BlockClassifierGeometryInput,
160
+ ): BlockClassifierGeometry {
161
+ if (!isPositiveFinite(input.interleaveDepthMs)) {
162
+ throw new Error(
163
+ `[BlockPolicy] interleaveDepthMs=${input.interleaveDepthMs} is not a positive block span; ` +
164
+ 'the catalog validator rejects this',
165
+ )
166
+ }
167
+ if (input.trackKind === 'audio') return { trackKind: 'audio' }
168
+
169
+ if (!isPositiveFinite(input.framerate)) {
170
+ return { trackKind: 'video', mode: 'all-protected', reason: 'framerate-absent' }
171
+ }
172
+ const framerate = input.framerate
173
+
174
+ let keyframeInterval: KeyframeInterval
175
+ if (isPositiveFinite(input.keyframeIntervalTicks) && isPositiveFinite(input.timescale)) {
176
+ keyframeInterval = { ticks: input.keyframeIntervalTicks, timescale: input.timescale }
177
+ } else if (isPositiveFinite(input.keyframeIntervalMs)) {
178
+ keyframeInterval = { ticks: input.keyframeIntervalMs, timescale: 1000 }
179
+ } else {
180
+ return { trackKind: 'video', mode: 'all-protected', reason: 'keyframe-cadence-absent' }
181
+ }
182
+
183
+ const gopFrames = exactInteger(keyframeInterval.ticks * framerate, keyframeInterval.timescale)
184
+ if (gopFrames === null) {
185
+ return {
186
+ trackKind: 'video',
187
+ mode: 'all-protected',
188
+ reason: 'keyframe-interval-not-integral',
189
+ }
190
+ }
191
+
192
+ const frameDurationMs = 1000 / framerate
193
+ const interleaveUnits = deriveFecInterleaveDepth(input.interleaveDepthMs, frameDurationMs)
194
+ if (interleaveUnits >= gopFrames) {
195
+ return { trackKind: 'video', mode: 'all-protected', reason: 'block-spans-gop' }
196
+ }
197
+
198
+ return {
199
+ trackKind: 'video',
200
+ mode: 'classifying',
201
+ frameDurationMs,
202
+ interleaveUnits,
203
+ gopFrames,
204
+ keyframeInterval,
205
+ }
206
+ }
207
+
208
+ /**
209
+ * The keyframe interval expressed in a media track's timescale, or null when
210
+ * the geometry is not `classifying` or the interval is not an exact integer
211
+ * number of media ticks.
212
+ */
213
+ export function keyframeIntervalMediaTicks(
214
+ geometry: BlockClassifierGeometry,
215
+ mediaTimescale: number,
216
+ ): bigint | null {
217
+ if (geometry.trackKind !== 'video' || geometry.mode !== 'classifying') return null
218
+ if (!Number.isSafeInteger(mediaTimescale) || mediaTimescale <= 0) return null
219
+ const { ticks, timescale } = geometry.keyframeInterval
220
+ if (!Number.isSafeInteger(ticks) || !Number.isSafeInteger(timescale)) return null
221
+ const scaled = BigInt(ticks) * BigInt(mediaTimescale)
222
+ const divisor = BigInt(timescale)
223
+ if (scaled % divisor !== 0n) return null
224
+ return scaled / divisor
225
+ }
226
+
227
+ // ─── Evidence ───────────────────────────────────────────────────────
228
+
229
+ /**
230
+ * In-band evidence from ONE first-arrival source symbol received from the
231
+ * network. Recovered symbols and repair symbols never contribute, and the
232
+ * MFU `priority > 0x80` hint is not evidence.
233
+ */
234
+ export interface SourceSymbolEvidence {
235
+ /** The MMTP header R (RAP) bit. */
236
+ readonly rap: boolean
237
+ /** MPU_sequence_number, when parsed from this packet. */
238
+ readonly mpu?: number
239
+ /**
240
+ * 0-based sample position within the MPU: the MFU DU-header
241
+ * `sample_number` minus one (ISO/IEC 23008-1 numbers samples from 1, and
242
+ * the parser rejects `sample_number` 0). Present only when this packet
243
+ * carried a DU header.
244
+ */
245
+ readonly idx?: number
246
+ /** movie_fragment_sequence_number from the DU header, when present. */
247
+ readonly movieFragment?: number
248
+ /**
249
+ * DU-header `offset`: the data unit's authored byte position within its
250
+ * sample (0 for a whole-sample data unit, the partition boundary for a
251
+ * subsample data unit). Present only with `idx`; absent reads as 0.
252
+ */
253
+ readonly offset?: number
254
+ /**
255
+ * The MMTP header packet_sequence_number (contiguous per packet_id). Not
256
+ * classification evidence: FECManager uses it to bound how many blocks the
257
+ * producer can have started between two source symbols, so an outage is
258
+ * never mistaken for a source restart.
259
+ */
260
+ readonly packetSequenceNumber?: number
261
+ }
262
+
263
+ export type ReclassificationEvidence = 'rap' | 'mpu-span' | 'window' | 'classifier-disabled'
264
+
265
+ export type ClassifierChange =
266
+ | {
267
+ readonly kind: 'reclassified'
268
+ readonly sbn: number
269
+ readonly from: BlockClass
270
+ readonly to: BlockClass
271
+ readonly evidence: ReclassificationEvidence
272
+ }
273
+ | {
274
+ readonly kind: 'mode'
275
+ readonly mode: 'all-protected'
276
+ readonly reason: ClassifierReason
277
+ }
278
+
279
+ interface BlockEvidence {
280
+ rapSeen: boolean
281
+ mpus: Set<number>
282
+ idxMin?: number
283
+ idxMax?: number
284
+ cls: BlockClass
285
+ }
286
+
287
+ /** A data-unit start (a packet carrying a DU header) and the block it is in. */
288
+ interface DataUnitStart {
289
+ readonly movieFragment: number
290
+ readonly idx: number
291
+ readonly offset: number
292
+ readonly sbn: number
293
+ }
294
+
295
+ /** Authored order of two data-unit starts of one MPU. */
296
+ function compareDataUnitStarts(
297
+ a: Omit<DataUnitStart, 'sbn'>,
298
+ b: Omit<DataUnitStart, 'sbn'>,
299
+ ): number {
300
+ return a.movieFragment - b.movieFragment || a.idx - b.idx || a.offset - b.offset
301
+ }
302
+
303
+ /**
304
+ * Per-stream block classifier.
305
+ *
306
+ * Classes only move toward more protection or narrower evidence:
307
+ * `unknown→delta` and `unknown→keyframe` / `delta→keyframe` on evidence, and
308
+ * `delta→unknown` when an invariant disables classification. `keyframe` is
309
+ * terminal.
310
+ *
311
+ * The delta window rule rests on three premises, each guarded by an
312
+ * invariant that fires on positive evidence only:
313
+ *
314
+ * - P1: the source packets of one block are one contiguous run of the
315
+ * stream's authored order, and blocks follow each other in SBN order
316
+ * (`block-not-contiguous`). The producer assigns SS_IDs in authored order
317
+ * and a block is the SS_ID range [SBN*K, SBN*K + K), so this holds for a
318
+ * block that closes at K symbols in the middle of a frame: that frame's
319
+ * fragments then land in two ADJACENT blocks, which is still one run each.
320
+ * A frame split across adjacent blocks is not a violation.
321
+ * - P2: that run touches at most D media units, counting a frame continued
322
+ * from the previous block (`block-wider-than-interleave`). The producer
323
+ * counts a media-unit boundary only once the open block holds a symbol.
324
+ * - P3: an MPU starts with its only RAP and holds at most G frames
325
+ * (`rap-not-mpu-start`, `mpu-longer-than-gop`, `rap-spacing-mismatch`), in
326
+ * one movie fragment (`mpu-multiple-fragments`).
327
+ *
328
+ * P1 and P2 are what make a block's frames contiguous and lie within
329
+ * [idxMax − D + 1, idxMin + D − 1] of its MPU. What refutes P1 is a pair of
330
+ * source packets whose wire-stated authored order and SBN order disagree:
331
+ * a later MPU in an earlier block, a later data unit of one MPU (by
332
+ * movie_fragment_sequence_number, sample_number, then DU offset) in an
333
+ * earlier block, or one data unit in two blocks. That is the signature of a
334
+ * round-robin interleave, which scatters one run over several concurrent
335
+ * blocks. Non-adjacency alone is not: a sample larger than K packets
336
+ * legitimately spans blocks SBN..SBN+n.
337
+ */
338
+ export class BlockClassifier {
339
+ #geometry: BlockClassifierGeometry
340
+ #mode: ClassifierMode
341
+ #reason: ClassifierReason | null
342
+ /**
343
+ * False once the stream showed that an MPU boundary does not bound its
344
+ * RAPs (a RAP inside an MPU, or an MPU longer than a GOP). Recorded in
345
+ * every mode: the stall/conceal decision relies on it even when the
346
+ * catalog geometry already runs the classifier `all-protected`.
347
+ */
348
+ #mpuBoundsRaps = true
349
+ #blocks = new Map<number, BlockEvidence>()
350
+ /**
351
+ * P1 ledger, kept for the MPUs within the classification horizon (the
352
+ * highest MPU seen and the one before it): the SBN span of every source
353
+ * packet of each MPU, and each MPU's data-unit starts in authored order.
354
+ * Valid only within one continuous SBN sequence; a source discontinuity
355
+ * clears it (`noteSourceDiscontinuity`).
356
+ */
357
+ #mpuSbnSpans = new Map<number, { min: number; max: number }>()
358
+ #dataUnitStarts = new Map<number, DataUnitStart[]>()
359
+ #highestMpu: number | null = null
360
+ /** MPU → movie_fragment_sequence_number observed in it. */
361
+ #mpuFragments = new Map<number, number>()
362
+ #lastRap: { mpu: number; presentationTime: bigint; mediaTimescale: number } | null = null
363
+
364
+ constructor(geometry: BlockClassifierGeometry) {
365
+ this.#geometry = geometry
366
+ this.#mode = 'classifying'
367
+ this.#reason = null
368
+ this.reset(geometry)
369
+ }
370
+
371
+ get geometry(): BlockClassifierGeometry {
372
+ return this.#geometry
373
+ }
374
+
375
+ get mode(): ClassifierMode {
376
+ return this.#mode
377
+ }
378
+
379
+ get reason(): ClassifierReason | null {
380
+ return this.#reason
381
+ }
382
+
383
+ /**
384
+ * Whether "same MPU on both sides of a gap" still proves the gap held no
385
+ * RAP. It stops holding for the rest of the epoch once a RAP was received
386
+ * inside an MPU or an MPU ran longer than a GOP.
387
+ */
388
+ get mpuBoundsRaps(): boolean {
389
+ return this.#mpuBoundsRaps
390
+ }
391
+
392
+ /** Begin a fresh epoch (catalog change or track reset). */
393
+ reset(geometry: BlockClassifierGeometry = this.#geometry): void {
394
+ this.#geometry = geometry
395
+ this.#blocks.clear()
396
+ this.#clearContiguityLedger()
397
+ this.#mpuFragments.clear()
398
+ this.#lastRap = null
399
+ this.#mpuBoundsRaps = true
400
+ if (geometry.trackKind === 'video' && geometry.mode === 'all-protected') {
401
+ this.#mode = 'all-protected'
402
+ this.#reason = geometry.reason
403
+ } else {
404
+ this.#mode = 'classifying'
405
+ this.#reason = null
406
+ }
407
+ }
408
+
409
+ /**
410
+ * Retire this classifier (its stream moves to a new catalog epoch). Every
411
+ * block it had classified `delta` loses the evidence behind that class and
412
+ * reads `unknown` from now on; the returned changes say so.
413
+ */
414
+ retire(): ClassifierChange[] {
415
+ const changes: ClassifierChange[] = []
416
+ for (const [sbn, block] of this.#blocks) {
417
+ if (block.cls !== 'delta') continue
418
+ block.cls = 'unknown'
419
+ changes.push({
420
+ kind: 'reclassified',
421
+ sbn,
422
+ from: 'delta',
423
+ to: 'unknown',
424
+ evidence: 'classifier-disabled',
425
+ })
426
+ }
427
+ return changes
428
+ }
429
+
430
+ /**
431
+ * The stream's SBN sequence restarted (FECManager source discontinuity:
432
+ * a publisher restart, or the SS_ID space wrapped). Authored order and SBN
433
+ * order are comparable only within one continuous sequence, so the P1
434
+ * ledger starts again.
435
+ */
436
+ noteSourceDiscontinuity(): void {
437
+ this.#clearContiguityLedger()
438
+ }
439
+
440
+ /** Register a block that exists without evidence (a vanished block). */
441
+ touch(sbn: number): void {
442
+ this.#blockFor(sbn)
443
+ }
444
+
445
+ /** Forget a resolved block. */
446
+ forget(sbn: number): void {
447
+ this.#blocks.delete(sbn)
448
+ }
449
+
450
+ classOf(sbn: number): BlockClass {
451
+ if (this.#geometry.trackKind === 'audio') return 'audio'
452
+ return this.#blocks.get(sbn)?.cls ?? 'unknown'
453
+ }
454
+
455
+ /** Record one first-arrival source symbol's evidence for block `sbn`. */
456
+ observe(sbn: number, evidence: SourceSymbolEvidence): ClassifierChange[] {
457
+ if (this.#geometry.trackKind === 'audio') return []
458
+ const changes: ClassifierChange[] = []
459
+ const block = this.#blockFor(sbn)
460
+
461
+ if (evidence.rap) block.rapSeen = true
462
+ if (evidence.mpu !== undefined) block.mpus.add(evidence.mpu)
463
+ if (evidence.idx !== undefined) {
464
+ block.idxMin = block.idxMin === undefined ? evidence.idx : Math.min(block.idxMin, evidence.idx)
465
+ block.idxMax = block.idxMax === undefined ? evidence.idx : Math.max(block.idxMax, evidence.idx)
466
+ }
467
+
468
+ // A RAP inside an MPU refutes "an MPU boundary bounds RAPs" whatever the
469
+ // classifier mode, because gap decisions rely on it in every mode.
470
+ if (evidence.rap && evidence.idx !== undefined && evidence.idx !== 0) {
471
+ this.#mpuBoundsRaps = false
472
+ }
473
+
474
+ const violation = this.#checkInvariants(sbn, block, evidence)
475
+ if (violation !== null) changes.push(...this.#disable(violation))
476
+
477
+ const next = this.#classify(block)
478
+ if (next !== block.cls && this.#allowed(block.cls, next)) {
479
+ changes.push({
480
+ kind: 'reclassified',
481
+ sbn,
482
+ from: block.cls,
483
+ to: next,
484
+ evidence: this.#evidenceFor(block, next),
485
+ })
486
+ block.cls = next
487
+ }
488
+ return changes
489
+ }
490
+
491
+ /**
492
+ * Record a RAP frame released in order. Released MPU-start RAPs of MPUs m
493
+ * and m+n must be exactly n keyframe intervals apart in the media
494
+ * timescale, compared as integers.
495
+ *
496
+ * Comparing only consecutive MPUs would miss exactly the case the window
497
+ * rule cannot survive: a short MPU whose successor's RAP was lost (that
498
+ * RAP-bearing block is the one a wrong G calls delta), because the next
499
+ * released RAP then belongs to m+2. Every MPU is one interval long, so the
500
+ * span to any later released RAP proves or refutes all MPUs in between.
501
+ */
502
+ noteReleasedRap(
503
+ mpu: number,
504
+ presentationTime: bigint,
505
+ mediaTimescale: number,
506
+ ): ClassifierChange[] {
507
+ if (this.#geometry.trackKind === 'audio' || this.#mode === 'all-protected') {
508
+ return []
509
+ }
510
+ // Verification compares integers in the media timescale. When the
511
+ // catalog interval is not an exact tick count there, spacing is
512
+ // unprovable: fail closed, naming the cause, rather than blaming the
513
+ // encoder with rap-spacing-mismatch on a perfectly spaced RAP.
514
+ const interval = keyframeIntervalMediaTicks(this.#geometry, mediaTimescale)
515
+ if (interval === null) return this.#disable('keyframe-interval-not-media-integral')
516
+ const previous = this.#lastRap
517
+ // A further RAP inside an already-anchored MPU is not an MPU start; the
518
+ // MPU keeps its first RAP as the spacing anchor (rap-not-mpu-start owns
519
+ // mid-MPU RAPs).
520
+ if (previous !== null && previous.mpu === mpu && previous.mediaTimescale === mediaTimescale) {
521
+ return []
522
+ }
523
+ this.#lastRap = { mpu, presentationTime, mediaTimescale }
524
+ if (
525
+ previous === null ||
526
+ mpu < previous.mpu ||
527
+ previous.mediaTimescale !== mediaTimescale
528
+ ) {
529
+ return []
530
+ }
531
+ if (
532
+ presentationTime - previous.presentationTime === interval * BigInt(mpu - previous.mpu)
533
+ ) {
534
+ return []
535
+ }
536
+ return this.#disable('rap-spacing-mismatch')
537
+ }
538
+
539
+ #blockFor(sbn: number): BlockEvidence {
540
+ let block = this.#blocks.get(sbn)
541
+ if (!block) {
542
+ block = { rapSeen: false, mpus: new Set(), cls: 'unknown' }
543
+ this.#blocks.set(sbn, block)
544
+ }
545
+ return block
546
+ }
547
+
548
+ #checkInvariants(
549
+ sbn: number,
550
+ block: BlockEvidence,
551
+ evidence: SourceSymbolEvidence,
552
+ ): ClassifierReason | null {
553
+ if (this.#mode === 'all-protected' || this.#geometry.trackKind !== 'video') return null
554
+ const geometry = this.#geometry
555
+ if (geometry.mode !== 'classifying') return null
556
+ if (evidence.rap && evidence.idx !== undefined && evidence.idx !== 0) {
557
+ return 'rap-not-mpu-start'
558
+ }
559
+ if (evidence.idx !== undefined && evidence.idx >= geometry.gopFrames) {
560
+ return 'mpu-longer-than-gop'
561
+ }
562
+ // A block closes at the latest after D media units, so the DU headers it
563
+ // carries from one MPU lie within D consecutive positions. A wider span
564
+ // means the producer closes blocks some other way (at K symbols, or
565
+ // round-robin across concurrent blocks) and the window rule is void.
566
+ if (
567
+ block.mpus.size === 1 &&
568
+ block.idxMin !== undefined &&
569
+ block.idxMax !== undefined &&
570
+ block.idxMax - block.idxMin >= geometry.interleaveUnits
571
+ ) {
572
+ return 'block-wider-than-interleave'
573
+ }
574
+ if (evidence.mpu !== undefined && evidence.movieFragment !== undefined) {
575
+ const fragment = this.#mpuFragments.get(evidence.mpu)
576
+ if (fragment === undefined) {
577
+ this.#mpuFragments.set(evidence.mpu, evidence.movieFragment)
578
+ // One entry per MPU still inside the classification horizon.
579
+ for (const mpu of this.#mpuFragments.keys()) {
580
+ if (mpu + 1 < evidence.mpu) this.#mpuFragments.delete(mpu)
581
+ }
582
+ } else if (fragment !== evidence.movieFragment) {
583
+ // sample_number is then a position within a movie fragment, not
584
+ // within the MPU, and the window rule's geometry does not hold.
585
+ return 'mpu-multiple-fragments'
586
+ }
587
+ }
588
+ if (evidence.mpu !== undefined && this.#contradictsAuthoredOrder(sbn, evidence.mpu, evidence)) {
589
+ return 'block-not-contiguous'
590
+ }
591
+ return null
592
+ }
593
+
594
+ #clearContiguityLedger(): void {
595
+ this.#mpuSbnSpans.clear()
596
+ this.#dataUnitStarts.clear()
597
+ this.#highestMpu = null
598
+ }
599
+
600
+ /**
601
+ * P1 check for one source packet of MPU `mpu` in block `sbn`, then record
602
+ * it. True when some recorded packet's authored order and SBN order
603
+ * disagree with this one's (see the class comment). Only positions the
604
+ * wire states are compared: MPU order for every packet, and data-unit
605
+ * order for packets that carry a DU header. A packet of one data unit
606
+ * that continues into the next block carries no DU header and so only
607
+ * takes part through its MPU, which is exactly what makes an adjacent
608
+ * straddle consistent.
609
+ */
610
+ #contradictsAuthoredOrder(sbn: number, mpu: number, evidence: SourceSymbolEvidence): boolean {
611
+ // Every packet of MPU m precedes every packet of MPU m' > m.
612
+ for (const [other, span] of this.#mpuSbnSpans) {
613
+ if (other < mpu && span.max > sbn) return true
614
+ if (other > mpu && span.min < sbn) return true
615
+ }
616
+ const inHorizon = this.#highestMpu === null || mpu + 1 >= this.#highestMpu
617
+ let insertAt = -1
618
+ let starts: DataUnitStart[] | undefined
619
+ let start: DataUnitStart | undefined
620
+ if (evidence.idx !== undefined) {
621
+ start = {
622
+ movieFragment: evidence.movieFragment ?? 0,
623
+ idx: evidence.idx,
624
+ offset: evidence.offset ?? 0,
625
+ sbn,
626
+ }
627
+ starts = this.#dataUnitStarts.get(mpu)
628
+ if (starts !== undefined) {
629
+ let lo = 0
630
+ let hi = starts.length
631
+ while (lo < hi) {
632
+ const mid = (lo + hi) >>> 1
633
+ if (compareDataUnitStarts(starts[mid]!, start) < 0) lo = mid + 1
634
+ else hi = mid
635
+ }
636
+ const at = starts[lo]
637
+ if (at !== undefined && compareDataUnitStarts(at, start) === 0) {
638
+ // One data unit has one first packet: seen in another block, the
639
+ // SBN-to-authored-order map is not a function.
640
+ if (at.sbn !== sbn) return true
641
+ } else {
642
+ const before = starts[lo - 1]
643
+ if (before !== undefined && before.sbn > sbn) return true
644
+ if (at !== undefined && at.sbn < sbn) return true
645
+ insertAt = lo
646
+ }
647
+ }
648
+ }
649
+ if (!inHorizon) return false
650
+ const span = this.#mpuSbnSpans.get(mpu)
651
+ if (span === undefined) this.#mpuSbnSpans.set(mpu, { min: sbn, max: sbn })
652
+ else {
653
+ if (sbn < span.min) span.min = sbn
654
+ if (sbn > span.max) span.max = sbn
655
+ }
656
+ if (start !== undefined) {
657
+ if (starts === undefined) this.#dataUnitStarts.set(mpu, [start])
658
+ else if (insertAt >= 0) starts.splice(insertAt, 0, start)
659
+ }
660
+ if (this.#highestMpu === null || mpu > this.#highestMpu) {
661
+ this.#highestMpu = mpu
662
+ for (const other of [...this.#mpuSbnSpans.keys()]) {
663
+ if (other + 1 < mpu) {
664
+ this.#mpuSbnSpans.delete(other)
665
+ this.#dataUnitStarts.delete(other)
666
+ }
667
+ }
668
+ }
669
+ return false
670
+ }
671
+
672
+ #disable(reason: ClassifierReason): ClassifierChange[] {
673
+ if (reason === 'rap-not-mpu-start' || reason === 'mpu-longer-than-gop') {
674
+ this.#mpuBoundsRaps = false
675
+ }
676
+ if (this.#mode === 'all-protected') return []
677
+ this.#mode = 'all-protected'
678
+ this.#reason = reason
679
+ const changes: ClassifierChange[] = [{ kind: 'mode', mode: 'all-protected', reason }]
680
+ for (const [sbn, block] of this.#blocks) {
681
+ if (block.cls !== 'delta') continue
682
+ block.cls = 'unknown'
683
+ changes.push({
684
+ kind: 'reclassified',
685
+ sbn,
686
+ from: 'delta',
687
+ to: 'unknown',
688
+ evidence: 'classifier-disabled',
689
+ })
690
+ }
691
+ return changes
692
+ }
693
+
694
+ #classify(block: BlockEvidence): BlockClass {
695
+ if (block.rapSeen || block.mpus.size >= 2) return 'keyframe'
696
+ if (this.#mode === 'all-protected') return 'unknown'
697
+ const geometry = this.#geometry
698
+ if (geometry.trackKind !== 'video' || geometry.mode !== 'classifying') return 'unknown'
699
+ if (
700
+ block.mpus.size === 1 &&
701
+ block.idxMin !== undefined &&
702
+ block.idxMax !== undefined
703
+ ) {
704
+ // A block closes every D media units, so its frames are contiguous and
705
+ // lie in [idxMax − D + 1, idxMin + D − 1] of MPU m. Index 0 is the only
706
+ // RAP of an MPU and G bounds its length.
707
+ const span = geometry.interleaveUnits - 1
708
+ if (block.idxMax - span >= 1 && block.idxMin + span <= geometry.gopFrames - 1) {
709
+ return 'delta'
710
+ }
711
+ }
712
+ return 'unknown'
713
+ }
714
+
715
+ #allowed(from: BlockClass, to: BlockClass): boolean {
716
+ if (from === 'keyframe') return false
717
+ if (from === 'unknown') return to === 'delta' || to === 'keyframe'
718
+ if (from === 'delta') return to === 'keyframe'
719
+ return false
720
+ }
721
+
722
+ #evidenceFor(block: BlockEvidence, to: BlockClass): ReclassificationEvidence {
723
+ if (to === 'delta') return 'window'
724
+ return block.rapSeen ? 'rap' : 'mpu-span'
725
+ }
726
+ }
727
+
728
+ // ─── Stall vs conceal ───────────────────────────────────────────────
729
+
730
+ export interface GapStreamIdentity {
731
+ readonly packetId: number
732
+ /** Non-empty catalog identity, or null when the producer has no track name. */
733
+ readonly catalogTrackName: string | null
734
+ }
735
+
736
+ /** What the sink knows about one side of a released gap. */
737
+ export interface GapFrameEvidence {
738
+ /**
739
+ * Codec-aware RAP check: `MmtpContainerParser.isKeyframe(data, rapFlag,
740
+ * codec)`, bitstream-only for recovered frames. Never the priority hint.
741
+ */
742
+ readonly rap: boolean
743
+ /**
744
+ * MPU_sequence_number of the frame. Omit it once the stream showed that
745
+ * an MPU boundary does not bound its RAPs (`BlockClassifier.mpuBoundsRaps`):
746
+ * same-MPU then no longer proves a gap lost only deltas.
747
+ */
748
+ readonly mpu?: number
749
+ /** 0-based sample position within the MPU, when the geometry verifies it. */
750
+ readonly idx?: number
751
+ /** Authored presentation time in `timescale` ticks. */
752
+ readonly pts?: bigint
753
+ /** Authored sample duration in `timescale` ticks. */
754
+ readonly durationTicks?: number
755
+ /** The media timescale of `pts` and `durationTicks`. */
756
+ readonly timescale?: number
757
+ }
758
+
759
+ export type FrameGapAction = 'stall' | 'conceal'
760
+
761
+ export type FrameGapReason =
762
+ | 'rap-lost'
763
+ | 'rap-unknown'
764
+ | 'discontinuity'
765
+ | 'delta-lost'
766
+ | 'rap-next'
767
+ | 'audio-gap'
768
+ | 'audio-discontinuity'
769
+
770
+ /**
771
+ * The decision attached to the first frame released after a gap
772
+ * (`RoutedFrameMeta.gapBefore`). It is the same frozen object the manager
773
+ * emits as its `gap` repair lifecycle event, so a sink that acts on the frame
774
+ * and an observer that counts events see one fact.
775
+ */
776
+ export interface FrameGapDecision {
777
+ readonly version: 2
778
+ readonly type: 'gap'
779
+ readonly stream: GapStreamIdentity
780
+ readonly trackKind: TrackKind
781
+ readonly action: FrameGapAction
782
+ readonly reason: FrameGapReason
783
+ /** FEC blocks in the gap whose media was lost (failed or vanished). */
784
+ readonly blocks: readonly number[]
785
+ /** Missing video frames or audio access units, when exactly known. */
786
+ readonly missingFrames: number | null
787
+ /** Authored duration of the missing media in milliseconds, when known. */
788
+ readonly missingMs: number | null
789
+ /** Manager epoch of the stream when the decision was made. */
790
+ readonly epoch: number
791
+ }
792
+
793
+ export interface DecideGapInput {
794
+ readonly stream: GapStreamIdentity
795
+ readonly trackKind: TrackKind
796
+ /** Last frame released before the gap. */
797
+ readonly before: GapFrameEvidence
798
+ /** First frame released after the gap. */
799
+ readonly after: GapFrameEvidence
800
+ /** The stream restarted (FEC SBN went backwards or the publisher reset). */
801
+ readonly discontinuity: boolean
802
+ readonly blocks: readonly number[]
803
+ /**
804
+ * The most media units the gap can hold: the FEC blocks spanned from the
805
+ * frame before to the frame after, times D (media units per block,
806
+ * ceil(interleaveDepthMs / unit duration), §5.1). A block touches at most D
807
+ * units whether it closes at D or at K symbols. Null when the span or D is
808
+ * unknown. An audio PTS delta that implies more AUs than this is a clock
809
+ * jump, not loss, and re-anchors instead of concealing every slot.
810
+ */
811
+ readonly maxMissingUnits: number | null
812
+ readonly epoch: number
813
+ }
814
+
815
+ function durationMs(units: number, before: GapFrameEvidence): number | null {
816
+ if (
817
+ before.durationTicks === undefined ||
818
+ before.timescale === undefined ||
819
+ before.timescale <= 0
820
+ ) {
821
+ return null
822
+ }
823
+ return (units * before.durationTicks * 1000) / before.timescale
824
+ }
825
+
826
+ /**
827
+ * Pure stall/conceal decision for the first frame released after a gap.
828
+ *
829
+ * Video stalls only when a RAP may be inside the gap: the frame after it is
830
+ * not a RAP and either sits in another MPU (`rap-lost`) or the MPU cannot be
831
+ * proven on both sides (`rap-unknown`), or the stream restarted
832
+ * (`discontinuity`). A gap inside one MPU lost only deltas (`delta-lost`) and
833
+ * a RAP after the gap resynchronises by itself (`rap-next`). Audio never
834
+ * stalls: an exact gap is concealed per access unit (`audio-gap`), anything
835
+ * else re-anchors at the next frame (`audio-discontinuity`).
836
+ */
837
+ export function decideGap(input: DecideGapInput): FrameGapDecision {
838
+ const { before, after } = input
839
+ let action: FrameGapAction
840
+ let reason: FrameGapReason
841
+ let missingFrames: number | null = null
842
+
843
+ if (input.trackKind === 'audio') {
844
+ action = 'conceal'
845
+ reason = 'audio-discontinuity'
846
+ if (
847
+ !input.discontinuity &&
848
+ before.pts !== undefined &&
849
+ after.pts !== undefined &&
850
+ before.durationTicks !== undefined &&
851
+ Number.isSafeInteger(before.durationTicks) &&
852
+ before.durationTicks > 0
853
+ ) {
854
+ const auDuration = BigInt(before.durationTicks)
855
+ const missingTicks = after.pts - before.pts - auDuration
856
+ const bound = input.maxMissingUnits
857
+ if (
858
+ missingTicks > 0n &&
859
+ missingTicks % auDuration === 0n &&
860
+ bound !== null &&
861
+ missingTicks / auDuration <= BigInt(bound)
862
+ ) {
863
+ reason = 'audio-gap'
864
+ missingFrames = Number(missingTicks / auDuration)
865
+ }
866
+ }
867
+ } else if (input.discontinuity) {
868
+ action = 'stall'
869
+ reason = 'discontinuity'
870
+ } else if (after.rap) {
871
+ action = 'conceal'
872
+ reason = 'rap-next'
873
+ } else if (before.mpu === undefined || after.mpu === undefined) {
874
+ action = 'stall'
875
+ reason = 'rap-unknown'
876
+ } else if (before.mpu !== after.mpu) {
877
+ action = 'stall'
878
+ reason = 'rap-lost'
879
+ } else {
880
+ action = 'conceal'
881
+ reason = 'delta-lost'
882
+ if (before.idx !== undefined && after.idx !== undefined) {
883
+ const missing = after.idx - before.idx - 1
884
+ missingFrames = missing > 0 ? missing : null
885
+ }
886
+ }
887
+
888
+ return Object.freeze({
889
+ version: 2 as const,
890
+ type: 'gap' as const,
891
+ stream: Object.freeze({
892
+ packetId: input.stream.packetId,
893
+ catalogTrackName: input.stream.catalogTrackName,
894
+ }),
895
+ trackKind: input.trackKind,
896
+ action,
897
+ reason,
898
+ blocks: Object.freeze([...input.blocks]),
899
+ missingFrames,
900
+ missingMs: missingFrames === null ? null : durationMs(missingFrames, before),
901
+ epoch: input.epoch,
902
+ })
903
+ }