@blockcast/mmt-container 0.1.0 → 0.3.0

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,128 @@
1
+ /**
2
+ * FecStarvationDetector — post-cutover source-starvation detection (BLO-9413/D4).
3
+ *
4
+ * The packet-presence watchdog (MulticastTransport, 5s) only catches TOTAL
5
+ * silence: any packet — including FEC repair — resets it. The observed
6
+ * BLO-9413 failure delivered repair symbols continuously while ZERO source
7
+ * symbols arrived (`sourceSymbols:0, repairSymbols:551, blocksComplete:0`):
8
+ * the watchdog stayed fed forever while nothing reconstructable reached the
9
+ * decoder. This detector closes that hole by watching delivery progress and
10
+ * driving the designed-but-previously-uncalled TrackSession loss arcs:
11
+ *
12
+ * starvation sustained ≥ windowMs → onStarvation() → session.lossDetected()
13
+ * block progress resumes → onRecovery() → session.lossRecovered()
14
+ *
15
+ * TrackSession's own FEC block-span hysteresis then decides whether a recovery
16
+ * cancels the failback — this detector deliberately does NOT add a second
17
+ * hysteresis layer.
18
+ *
19
+ * Push-fed: call update() with each FecTrackStats-shaped snapshot (e.g. from
20
+ * MulticastManager.setOnFecStatsUpdate or a host sampler). Hosts that can also
21
+ * observe decoded/appended media should include a monotonic mediaFrames count:
22
+ * media progress is delivery progress even if sparse FEC block counters do not
23
+ * advance in the same sample window. Evaluation happens only on update — a
24
+ * fully dead transport stops producing updates and stays the transport
25
+ * watchdog's responsibility (total-silence backstop).
26
+ */
27
+
28
+ /** Monotonic counters sampled from the FEC layer (FecTrackStats subset). */
29
+ export interface FecStarvationSnapshot {
30
+ sourceSymbols: number
31
+ repairSymbols: number
32
+ blocksComplete: number
33
+ blocksRecovered: number
34
+ /** Optional host-observed decoded/appended media frames for this packetId. */
35
+ mediaFrames?: number
36
+ }
37
+
38
+ export interface FecStarvationDetectorConfig {
39
+ /**
40
+ * How long starvation must persist before onStarvation fires. Derive from
41
+ * the stream's FEC block-span config — no magic defaults, matching the
42
+ * TrackSession hysteresis convention.
43
+ */
44
+ windowMs: number
45
+ /** Starvation sustained ≥ windowMs. Fires once per starvation episode. */
46
+ onStarvation(): void
47
+ /** Healthy delivery resumed after onStarvation fired. Fires once per episode. */
48
+ onRecovery(): void
49
+ /** Injectable clock for tests. Defaults to Date.now. */
50
+ now?: () => number
51
+ }
52
+
53
+ export class FecStarvationDetector {
54
+ #config: FecStarvationDetectorConfig
55
+ #now: () => number
56
+ #last: FecStarvationSnapshot | null = null
57
+ #lastSampleAt = 0
58
+ #starvedSince: number | null = null
59
+ #latched = false
60
+
61
+ constructor(config: FecStarvationDetectorConfig) {
62
+ if (config.windowMs <= 0) {
63
+ throw new Error(
64
+ `[FecStarvationDetector] windowMs=${config.windowMs}. Derive a positive window ` +
65
+ `from the stream's FEC block-span config — a non-positive ` +
66
+ `window would fire on the first repair packet of a healthy stream.`
67
+ )
68
+ }
69
+ this.#config = config
70
+ this.#now = config.now ?? Date.now
71
+ }
72
+
73
+ /** True while a starvation episode is active (onStarvation fired, no recovery yet). */
74
+ get isStarved(): boolean { return this.#latched }
75
+
76
+ update(snapshot: FecStarvationSnapshot): void {
77
+ const last = this.#last
78
+ const prevSampleAt = this.#lastSampleAt
79
+ const now = this.#now()
80
+ this.#last = { ...snapshot }
81
+ this.#lastSampleAt = now
82
+ if (last === null) return // first sample = baseline only
83
+
84
+ const srcDelta = snapshot.sourceSymbols - last.sourceSymbols
85
+ const repDelta = snapshot.repairSymbols - last.repairSymbols
86
+ const doneDelta =
87
+ (snapshot.blocksComplete - last.blocksComplete) +
88
+ (snapshot.blocksRecovered - last.blocksRecovered)
89
+ const mediaDelta = (snapshot.mediaFrames ?? 0) - (last.mediaFrames ?? 0)
90
+
91
+ const packetsFlowing = srcDelta > 0 || repDelta > 0
92
+ if (!packetsFlowing && mediaDelta <= 0) return // total silence — transport watchdog's domain
93
+
94
+ // Starving: traffic arrives but nothing reconstructable comes out. Source
95
+ // and repair symbols arrive at symbol cadence while complete/recovered
96
+ // blocks arrive at block cadence; requiring source and block deltas in the
97
+ // same snapshot false-fails healthy live streams. A repaired block is still
98
+ // decodable media, and host-observed frame progress is even stronger
99
+ // evidence, so either resets the starvation clock.
100
+ const starving = doneDelta === 0 && mediaDelta <= 0
101
+
102
+ if (starving) {
103
+ // The episode began when delivery was last known healthy — the previous
104
+ // sample's timestamp, not this sample's arrival (the deltas in THIS
105
+ // sample describe the interval since then).
106
+ if (this.#starvedSince === null) this.#starvedSince = prevSampleAt
107
+ if (!this.#latched && now - this.#starvedSince >= this.#config.windowMs) {
108
+ this.#latched = true
109
+ this.#config.onStarvation()
110
+ }
111
+ return
112
+ }
113
+
114
+ // Healthy sample: completed or recovered blocks are reaching the decoder.
115
+ this.#starvedSince = null
116
+ if (this.#latched) {
117
+ this.#latched = false
118
+ this.#config.onRecovery()
119
+ }
120
+ }
121
+
122
+ /** Reset episode state (e.g. on transport switch / re-join). Keeps no baseline. */
123
+ reset(): void {
124
+ this.#last = null
125
+ this.#starvedSince = null
126
+ this.#latched = false
127
+ }
128
+ }
@@ -0,0 +1,219 @@
1
+ // Typed FEC state shared by every player (hang/moq-lib, moqtail, Shaka MSF).
2
+ //
3
+ // A player's FEC counters are `null` in three unrelated situations: the
4
+ // session is on reliable MoQ, where FEC has nothing to protect (FEC protects
5
+ // only lossy multicast/AMT datagrams); no multicast bridge exists, so no lossy
6
+ // leg can be joined; or the catalog declares no FEC for the tracks the player
7
+ // selected. `null` also meant "nothing decoded yet" and "the pipeline broke",
8
+ // so an idle session and a broken one looked identical.
9
+ //
10
+ // `resolveFecState` names which case holds. Each reason is read from a fact the
11
+ // player already owns -- its catalog, its transport policy, its bridge probe
12
+ // and its physical subscription -- and never from counters, console text,
13
+ // timers or elapsed time. The rules live here so the three players cannot
14
+ // disagree about precedence.
15
+
16
+ import { isFecBlockProfile } from '@blockcast/mmt-base'
17
+
18
+ /**
19
+ * Minimum valid FEC interleave depth in milliseconds, per spec §5.1
20
+ * (the interactive/gaming floor; broadcast/ATSC 3.0 ranges up to 10000ms).
21
+ *
22
+ * A protocol constant, NOT a tuning knob. Values below this floor are almost
23
+ * certainly a raw frame count (e.g. `2`) that a caller passed when no framerate
24
+ * was available to convert to ms (common on audio tracks). Feeding such a value
25
+ * into computeFecTimeout treats it as `2ms`, yielding a near-zero FEC block
26
+ * timeout that abandons startup FEC blocks before their repair symbols arrive
27
+ * (measured: moqtail startupFailed=4, shaka dropped=5.8% on startup). Timing
28
+ * derivations MUST reject sub-floor values and fall back to the established
29
+ * timeout instead of collapsing.
30
+ */
31
+ export const MIN_INTERLEAVE_DEPTH_MS = 33
32
+
33
+ /** Why FEC is not protecting this session. */
34
+ export type FecInactiveReason = 'no-catalog-fec' | 'reliable-moq' | 'no-multicast-bridge'
35
+
36
+ /** Every inactive reason, in resolution order. */
37
+ export const FEC_INACTIVE_REASONS: readonly FecInactiveReason[] = Object.freeze([
38
+ 'no-catalog-fec',
39
+ 'reliable-moq',
40
+ 'no-multicast-bridge',
41
+ ] as const)
42
+
43
+ /** The transport policy vocabulary every player accepts. */
44
+ export type FecTransportPolicy = 'auto' | 'moq-only' | 'multicast-only'
45
+
46
+ const TRANSPORT_POLICIES: ReadonlySet<string> = new Set<FecTransportPolicy>(['auto', 'moq-only', 'multicast-only'])
47
+
48
+ /** FEC is not protecting this session; `reason` says why. Carries no counters. */
49
+ export interface FecInactiveState {
50
+ readonly state: 'inactive'
51
+ readonly reason: FecInactiveReason
52
+ }
53
+
54
+ /**
55
+ * FEC is the protection in force for this session's delivery path.
56
+ *
57
+ * Flat on purpose: the player's existing counters stay at the paths every
58
+ * consumer already reads (`fec.blocksRecovered`, `fec.tracks`, `fec.blocks`),
59
+ * with `state` added beside them. A consumer that ignores `state` reads an
60
+ * active report exactly as before and an inactive one as "no counters", which
61
+ * is what `null` meant to it.
62
+ */
63
+ export type FecActiveState<S extends object> = S & { readonly state: 'active' }
64
+
65
+ export type FecState<S extends object> = FecActiveState<S> | FecInactiveState
66
+
67
+ /** An active state whose decoder has not reported any counter yet. */
68
+ export type NoFecCounters = Record<never, never>
69
+
70
+ /** The authoritative facts `resolveFecState` reads. */
71
+ export interface FecStateEvidence<S extends object> {
72
+ /**
73
+ * The counters the player reports today, or null/undefined when it has none.
74
+ * Payload only: it never decides the state, because moqtail and Shaka report
75
+ * a zeroed snapshot as soon as a MulticastManager exists, which is before any
76
+ * bridge or subscription does.
77
+ */
78
+ readonly stats: S | null | undefined
79
+ /**
80
+ * Whether the catalog declares FEC (see `catalogDeclaresFec`) for at least
81
+ * one media track the player selected.
82
+ */
83
+ readonly catalogFec: boolean
84
+ /** The player's configured transport policy. */
85
+ readonly transportPolicy: FecTransportPolicy
86
+ /** Whether a multicast bridge (`window.multicast`) is available to the page. */
87
+ readonly bridgeAvailable: boolean
88
+ /**
89
+ * Whether a physical multicast/AMT subscription is live: the bridge accepted
90
+ * it and it has not been closed. A requested leg is not a joined one.
91
+ */
92
+ readonly multicastLegJoined: boolean
93
+ }
94
+
95
+ const INACTIVE: Readonly<Record<FecInactiveReason, FecInactiveState>> = Object.freeze({
96
+ 'no-catalog-fec': Object.freeze({ state: 'inactive', reason: 'no-catalog-fec' }),
97
+ 'reliable-moq': Object.freeze({ state: 'inactive', reason: 'reliable-moq' }),
98
+ 'no-multicast-bridge': Object.freeze({ state: 'inactive', reason: 'no-multicast-bridge' }),
99
+ })
100
+
101
+ function recordOf(value: unknown): Record<string, unknown> | undefined {
102
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
103
+ ? (value as Record<string, unknown>)
104
+ : undefined
105
+ }
106
+
107
+ function isPositiveSafeInteger(value: unknown): boolean {
108
+ return typeof value === 'number' && Number.isSafeInteger(value) && value > 0
109
+ }
110
+
111
+ /**
112
+ * Whether one catalog `fec` block (a hang rendition's `fec` or an MSF/CMSF
113
+ * track's `fec`) declares an FEC instance a receiver can configure: source
114
+ * symbols per block (K) and a symbol size (T) are both positive integers, the
115
+ * algorithm is not `none`, and `blockProfile` names a known block profile
116
+ * (BLO-35597). Total: it never throws, and answers false for any other value.
117
+ *
118
+ * `resolveCatalogTrackFec` reads this predicate, so the players' parameters and
119
+ * this state never disagree. Of the blocks this rejects, it returns no FEC
120
+ * geometry only for `algorithm: "none"`. One with any other algorithm is a
121
+ * malformed catalog (`FecCatalogConfig` marks both fields REQUIRED; the MSF
122
+ * schema and `validateCmsfMmtpCatalog` enforce them on `tracks[]`, but the
123
+ * hang dialect's `renditions` schema is permissive, so this is where a hang
124
+ * block fails closed), and `resolveCatalogTrackFec` throws a `RepairContractError` for
125
+ * it (`track_fec` unless another repair-contract violation fires first),
126
+ * whether or not the source has repair layers, rather than silently dropping
127
+ * the track's repair subscription.
128
+ *
129
+ * The block profile is part of this predicate because the profile selects the
130
+ * block math and is never defaulted: without a known one no receiver can
131
+ * configure the instance. `resolveCatalogTrackFec` resolves such a track to no
132
+ * FEC with a typed `fecUnavailable` reason (`track_fec_block_profile`), scoped
133
+ * to that track, so its parameters and this state still agree. The CMSF
134
+ * conformance validator (`validateCmsfMmtpCatalog`) still rejects the catalog
135
+ * with `track_fec_block_profile`. An `iso-ssbg1-v1` instance without a usable
136
+ * block span (`isoBlockSpanUsable`) is likewise no FEC for its track alone,
137
+ * with `fecUnavailable` code `track_fec` on its `interleaveDepthMs`.
138
+ *
139
+ * The repair-contract resolvers (`resolveRepairLayers`) gate a `depends` target
140
+ * on `algorithm` alone and never read a source's `symbolSize`. They check its
141
+ * `sourceSymbols` for the RaptorQ K bound, and require a positive integer
142
+ * `sourceSymbols` and `repairSymbols` only when the source has repair layers or
143
+ * an overlay beyond layer 0.
144
+ */
145
+ export function catalogDeclaresFec(fec: unknown): boolean {
146
+ const block = recordOf(fec)
147
+ if (block === undefined || block['algorithm'] === 'none') return false
148
+ return (
149
+ isPositiveSafeInteger(block['sourceSymbols']) &&
150
+ isPositiveSafeInteger(block['symbolSize']) &&
151
+ isFecBlockProfile(block['blockProfile']) &&
152
+ isoBlockSpanUsable(block)
153
+ )
154
+ }
155
+
156
+ /**
157
+ * Whether a `fec` block that names `iso-ssbg1-v1` carries the block span its
158
+ * block location is bounded by: `interleaveDepthMs`, a finite number of
159
+ * milliseconds no smaller than `MIN_INTERLEAVE_DEPTH_MS`. Without it a receiver
160
+ * cannot bound the sources it holds before a repair states their block, so the
161
+ * instance cannot be configured (BLO-35597). Any other block needs no span here.
162
+ */
163
+ export function isoBlockSpanUsable(fec: unknown): boolean {
164
+ const block = recordOf(fec)
165
+ if (block === undefined || block['blockProfile'] !== 'iso-ssbg1-v1') return true
166
+ const ms = block['interleaveDepthMs']
167
+ return typeof ms === 'number' && Number.isFinite(ms) && ms >= MIN_INTERLEAVE_DEPTH_MS
168
+ }
169
+
170
+ function requireBoolean(value: unknown, field: string): boolean {
171
+ if (typeof value !== 'boolean') {
172
+ throw new TypeError(`resolveFecState: ${field} must be a boolean, got ${typeof value}`)
173
+ }
174
+ return value
175
+ }
176
+
177
+ /**
178
+ * Resolve a player's FEC state. First match wins:
179
+ *
180
+ * 1. The catalog declares no FEC for a selected track: `no-catalog-fec`. FEC
181
+ * geometry comes only from the catalog, so there is nothing to configure on
182
+ * any path.
183
+ * 2. The policy is `moq-only`: `reliable-moq`. Media travels only over QUIC,
184
+ * which is reliable, so FEC has no loss to repair, bridge or not.
185
+ * 3. No multicast bridge: `no-multicast-bridge`. No lossy leg can exist, and on
186
+ * `auto` this is the reason the session is on reliable MoQ.
187
+ * 4. The policy is `multicast-only`, or a lossy subscription is live: active.
188
+ * `multicast-only` commits the session to the lossy leg, so FEC is in force
189
+ * before the join completes; whether the join succeeded is the physical
190
+ * attestation's question, not this one. The counters may be absent until
191
+ * the decoder reports.
192
+ * 5. Otherwise (`auto`, a bridge, no live subscription): `reliable-moq`.
193
+ *
194
+ * Throws on malformed evidence rather than picking a reason for it.
195
+ */
196
+ export function resolveFecState<S extends object>(evidence: FecStateEvidence<S> & { readonly stats: S }): FecState<S>
197
+ export function resolveFecState<S extends object>(evidence: FecStateEvidence<S>): FecState<S | NoFecCounters>
198
+ export function resolveFecState<S extends object>(evidence: FecStateEvidence<S>): FecState<S | NoFecCounters> {
199
+ const catalogFec = requireBoolean(evidence.catalogFec, 'catalogFec')
200
+ const bridgeAvailable = requireBoolean(evidence.bridgeAvailable, 'bridgeAvailable')
201
+ const multicastLegJoined = requireBoolean(evidence.multicastLegJoined, 'multicastLegJoined')
202
+ const { transportPolicy, stats } = evidence
203
+ if (typeof transportPolicy !== 'string' || !TRANSPORT_POLICIES.has(transportPolicy)) {
204
+ throw new TypeError(`resolveFecState: unsupported transportPolicy ${JSON.stringify(transportPolicy)}`)
205
+ }
206
+ if (stats !== null && stats !== undefined && recordOf(stats) === undefined) {
207
+ throw new TypeError('resolveFecState: stats must be a plain object, null or undefined')
208
+ }
209
+
210
+ if (!catalogFec) return INACTIVE['no-catalog-fec']
211
+ if (transportPolicy === 'moq-only') return INACTIVE['reliable-moq']
212
+ if (!bridgeAvailable) return INACTIVE['no-multicast-bridge']
213
+ if (transportPolicy === 'multicast-only' || multicastLegJoined) {
214
+ // The discriminant is written last so a stats field of the same name can
215
+ // never masquerade as a state.
216
+ return { ...(stats ?? {}), state: 'active' } as FecActiveState<S | NoFecCounters>
217
+ }
218
+ return INACTIVE['reliable-moq']
219
+ }
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Shared fec-setup helper.
3
+ *
4
+ * Wires a FecWorkerClient into a MulticastManager for a specific track.
5
+ * Both moq-lib (`hang-mmt-fec/js/watch/src/element.ts`) and moqtail
6
+ * (`moqtail-private/apps/client-js/src/lib/player.ts`) call this from their
7
+ * SessionManager `fec-setup` handler so the Worker+ALTA setup lives in one
8
+ * place instead of being duplicated across ~80 lines per player.
9
+ *
10
+ * Callers are responsible for holding the returned `dispose()` and calling it
11
+ * from their `fec-teardown` path (and/or effect cleanup). It unregisters the
12
+ * Worker from MulticastManager before terminating it, so no symbol is routed
13
+ * to a dead Worker; do not dispose the client directly.
14
+ */
15
+
16
+ import { parseFecBlockProfile, type FecBlockProfile } from '@blockcast/mmt-base'
17
+ import type { FecWorkerClient, FecTrackConfig } from '@blockcast/fec-worker'
18
+ import type { MulticastManager } from './multicast-manager.js'
19
+ import { deriveFecRetentionBlocks } from '@blockcast/mmt-fec'
20
+ import { computeFecDeliveryWindowMs } from './track-session.js'
21
+
22
+ /** Asset URLs the helper needs. Callers pass the already-resolved set. */
23
+ export interface FecWorkerAssetUrls {
24
+ /** URL to the fec-worker entry bundle (new Worker() target). */
25
+ fecWorker: string
26
+ /** URL to the RaptorQ WASM module (compiled via compileStreaming). */
27
+ rqWasm: string
28
+ /** URL to the ALTA WASM module. Fetched only when an ALTA key is provided. */
29
+ altaWasm: string
30
+ }
31
+
32
+ export interface FecWorkerSetupOptions {
33
+ /** MulticastManager that should receive the configured Worker. */
34
+ multicastManager: MulticastManager
35
+ /** MMTP packetId this track occupies (from catalog). */
36
+ packetId: number
37
+ /** Human-readable track name (catalog key). */
38
+ trackName: string
39
+ /** Track type from catalog. Never inferred from name. */
40
+ trackType: 'video' | 'audio'
41
+ /**
42
+ * The catalog `fec.blockProfile` (BLO-35597). Required: `k-padded-v1` or
43
+ * `iso-ssbg1-v1`; never defaulted, never inferred.
44
+ */
45
+ fecBlockProfile: FecBlockProfile
46
+ /** FEC K from catalog (source symbols per block). Under iso-ssbg1-v1 the maximum SSB_length. */
47
+ fecK: number
48
+ /** Symbol size in bytes (T) — the ALTA-adjusted value if ALTA is signed. */
49
+ fecSymbolSize: number
50
+ /** Repair symbols per block (P). */
51
+ fecRepairCount: number
52
+ /**
53
+ * Repair symbols per block this receiver actually joined: the sum of
54
+ * `repairSymbols` over the joined BASE layers (draft-ramadan-moq-fec 6.3).
55
+ * Reported as P by the worker snapshot and CMCD `x-bc-fec-p`, because the
56
+ * catalog total is not what this receiver joined. Falls back to
57
+ * `fecRepairCount`, which is the same value on a single-layer track.
58
+ */
59
+ joinedRepairCount?: number
60
+ /** Interleave depth in ms. */
61
+ fecInterleaveMs: number
62
+ /** Explicit catalog jitter/reorder allowance in ms. */
63
+ fecReorderToleranceMs?: number
64
+ /** Duration of one FEC media unit in ms (video frame or audio access unit). */
65
+ mediaUnitDurationMs: number
66
+ /** Optional repair track name (MoQ). Forwarded to FecTrackConfig. */
67
+ repairTrackName?: string
68
+ /** Audio sample rate (optional — audio tracks only). */
69
+ sampleRate?: number
70
+ /** Codec string (optional; "unknown" is acceptable for first setup). */
71
+ codec?: string
72
+ /** Video framerate (optional metadata forwarded to the worker). */
73
+ framerate?: number
74
+ /** Base64 SPKI public key (optional). Accepts padded/unpadded, std or url-safe alphabet. */
75
+ altaPublicKeySpki?: string
76
+ /** Absolute or origin-relative asset URLs. */
77
+ assetUrls: FecWorkerAssetUrls
78
+ /** Optional FecWorkerClient factory — main use is test injection. */
79
+ clientFactory?: (workerUrl: URL) => FecWorkerClient
80
+ }
81
+
82
+ export interface FecWorkerSetupResult {
83
+ /** The configured client (already registered with MulticastManager). */
84
+ client: FecWorkerClient
85
+ /** True when the ALTA public key decoded and the ALTA WASM compiled. */
86
+ altaEnabled: boolean
87
+ /** Removes the Worker from MulticastManager routing, then releases it. */
88
+ dispose: () => void
89
+ }
90
+
91
+ /**
92
+ * Configure a FecWorkerClient and attach it to `multicastManager` via
93
+ * `setFecWorker(packetId, client, trackType, config, trackName)`. Worker-path takes precedence
94
+ * over any sync WASM decoder already registered for the same packetId —
95
+ * sync decoders remain as a fallback.
96
+ *
97
+ * Any loader failure is re-thrown so the caller can log and leave the sync
98
+ * WASM decoder active as fallback (same pattern both players used before).
99
+ */
100
+ export async function setupFecWorkerForTrack(
101
+ opts: FecWorkerSetupOptions,
102
+ ): Promise<FecWorkerSetupResult> {
103
+ // These two were previously validated as a side effect of calling
104
+ // deriveFecInterleaveDepth() here. That call is gone (see below), so the
105
+ // guards are explicit — a zero or non-finite span/media-unit must still fail
106
+ // closed rather than size a window from a hardcoded depth.
107
+ //
108
+ // `mediaUnitDurationMs` no longer influences the retention this function
109
+ // computes: it survives only as `mediaUnitsPerSecond`, which
110
+ // `computeFecDeliveryWindowMs` (track-session.ts) documents as geometry
111
+ // accepted for existing callers and deliberately not fed to deadline math.
112
+ // The guard stays anyway — this is a trust boundary for a catalog-supplied
113
+ // value, and the test `rejects missing media-unit timing instead of using a
114
+ // hardcoded depth` pins it. Not dead code. Cite both by symbol, not by line:
115
+ // a line number here is invalidated by the next edit to the file it points
116
+ // at, and this comment is the guard's only stated defence.
117
+ if (!Number.isFinite(opts.fecInterleaveMs) || opts.fecInterleaveMs <= 0) {
118
+ // Names the catalog field (`fec.interleaveDepthMs`), not the local option
119
+ // (`opts.fecInterleaveMs`), because that is the knob an operator fixes.
120
+ throw new Error(
121
+ `[FEC] interleaveDepthMs (opts.fecInterleaveMs) must be finite and > 0 ` +
122
+ `(got ${opts.fecInterleaveMs})`,
123
+ )
124
+ }
125
+ if (!Number.isFinite(opts.mediaUnitDurationMs) || opts.mediaUnitDurationMs <= 0) {
126
+ throw new Error(
127
+ `[FEC] mediaUnitDurationMs must be finite and > 0 (got ${opts.mediaUnitDurationMs})`,
128
+ )
129
+ }
130
+ const blockProfile = parseFecBlockProfile(
131
+ opts.fecBlockProfile,
132
+ `[FEC] ${opts.trackName} fec.blockProfile`,
133
+ )
134
+ const deliveryWindowMs = computeFecDeliveryWindowMs({
135
+ interleaveDepthMs: opts.fecInterleaveMs,
136
+ sourceSymbols: opts.fecK,
137
+ repairSymbols: opts.fecRepairCount,
138
+ symbolSize: opts.fecSymbolSize,
139
+ mediaUnitsPerSecond: 1000 / opts.mediaUnitDurationMs,
140
+ jitterBufferMs: opts.fecReorderToleranceMs,
141
+ })
142
+ // `FecTrackConfig.interleaveDepth` is a BLOCK COUNT, not D. Every consumer
143
+ // measures SBN distance with it: the worker's `advanceMediaHorizon` does
144
+ // `liveSbn - interleaveDepth`, and `MmtFecDecoder::new` documents its
145
+ // argument as "the number of interleaved blocks" before `cleanup_by_sbn`
146
+ // subtracts it from an SBN and counts the remainder `blocks_failed`.
147
+ //
148
+ // `deriveFecInterleaveDepth` returns D — MEDIA UNITS per block — so feeding
149
+ // it here mixed units and sized the retention window in the wrong quantity.
150
+ // It survived where D happened to land near the real block count and retired
151
+ // live blocks where it did not. Measured against the live ISS catalog at
152
+ // reorderToleranceMs=100, retention vs the block's own deadline (the worker
153
+ // arms `deadlineTs = now + deliveryWindowMs` per block):
154
+ //
155
+ // 720p span 33ms D=1 -> 2 blocks = 66ms vs deadline 133ms UNDER by 67ms
156
+ // 480p span 67ms D=2 -> 3 blocks = 201ms vs deadline 167ms ok
157
+ // 360p span 67ms D=2 -> 3 blocks = 201ms vs deadline 167ms ok
158
+ // audio span 43ms D=2 -> 3 blocks = 129ms vs deadline 143ms UNDER by 14ms
159
+ //
160
+ // 480p/360p passed only because D=2 coincided with a workable block count.
161
+ // On 720p and audio the decoder expired blocks — counting them failed — while
162
+ // the receiver's own deadline for them had not yet passed.
163
+ //
164
+ // Derive the count from the two quantities that define it, so retention
165
+ // always covers the deadline already armed for that block: the blocks that
166
+ // can be in flight within one block's budget, plus the one being filled.
167
+ //
168
+ // `deriveFecRetentionBlocks` is THE one derivation of this horizon -- the
169
+ // FECManager's ordered-relay settlement consumes the same function, so the
170
+ // two cannot drift apart again (BLO-35597 Decision E). It fails closed above
171
+ // the 255 the WASM decoder and the ISO/IEC 23008-1 AL-FEC signaling byte
172
+ // accept, rather than clamping to a retention shorter than this window.
173
+ const interleaveDepthBlocks = deriveFecRetentionBlocks(
174
+ deliveryWindowMs,
175
+ opts.fecInterleaveMs,
176
+ )
177
+ // Resolve URL against location.origin when available (browser runtime).
178
+ // Absolute URLs pass through unchanged per the URL() spec.
179
+ const origin =
180
+ typeof location !== 'undefined' && location.origin ? location.origin : 'http://localhost'
181
+ const workerUrl = new URL(opts.assetUrls.fecWorker, origin)
182
+
183
+ const FecWorkerCtor = await import('@blockcast/fec-worker')
184
+ const client = opts.clientFactory
185
+ ? opts.clientFactory(workerUrl)
186
+ : new FecWorkerCtor.FecWorkerClient(workerUrl)
187
+
188
+ // Compile RaptorQ WASM once; ALTA WASM only when we have a key to decode.
189
+ const rqWasm = await WebAssembly.compileStreaming(fetch(opts.assetUrls.rqWasm))
190
+
191
+ let altaKeyBuffer: ArrayBuffer | undefined
192
+ let altaWasmModule: WebAssembly.Module | undefined
193
+ if (opts.altaPublicKeySpki) {
194
+ const b64 = opts.altaPublicKeySpki.replace(/-/g, '+').replace(/_/g, '/')
195
+ const padded = b64.padEnd(Math.ceil(b64.length / 4) * 4, '=')
196
+ try {
197
+ const keyBytes = Uint8Array.from(atob(padded), c => c.charCodeAt(0))
198
+ // SPKI size range: Ed25519=44, P-256=91; tolerate 32..=256 for forward-compat.
199
+ if (keyBytes.length >= 32 && keyBytes.length <= 256) {
200
+ altaKeyBuffer = keyBytes.buffer
201
+ altaWasmModule = await WebAssembly.compileStreaming(fetch(opts.assetUrls.altaWasm))
202
+ } else {
203
+ console.warn(
204
+ `[fec-worker-setup] ALTA SPKI wrong length for "${opts.trackName}": ` +
205
+ `${keyBytes.length} (expected 32..256) — ALTA disabled`,
206
+ )
207
+ }
208
+ } catch (e) {
209
+ console.warn(`[fec-worker-setup] ALTA key decode / WASM compile failed for "${opts.trackName}":`, e)
210
+ }
211
+ }
212
+
213
+ const altaEnabled = !!(altaKeyBuffer && altaWasmModule)
214
+ const fecTrackConfig = {
215
+ codec: opts.codec ?? 'unknown',
216
+ trackName: opts.trackName,
217
+ trackType: opts.trackType,
218
+ framerate: opts.framerate,
219
+ sampleRate: opts.sampleRate,
220
+ algorithm: 'raptor',
221
+ blockProfile,
222
+ k: opts.fecK,
223
+ // P as this receiver joined it, not the catalog total: the worker snapshot
224
+ // and CMCD `x-bc-fec-p` are read from this. Identity on a single layer.
225
+ repairCount: opts.joinedRepairCount ?? opts.fecRepairCount,
226
+ symbolSize: opts.fecSymbolSize,
227
+ interleaveDepth: interleaveDepthBlocks,
228
+ interleaveMs: opts.fecInterleaveMs,
229
+ deliveryWindowMs,
230
+ fecMode: 'subframe' as const,
231
+ repairTrack: opts.repairTrackName,
232
+ altaEnabled,
233
+ relayBlockSigEnabled: false,
234
+ } as unknown as FecTrackConfig
235
+
236
+ client.configure(fecTrackConfig, rqWasm, altaKeyBuffer, altaWasmModule)
237
+ try {
238
+ opts.multicastManager.setFecWorker(opts.packetId, client, opts.trackType, {
239
+ blockProfile,
240
+ k: opts.fecK,
241
+ symbolSize: opts.fecSymbolSize,
242
+ interleaveDepthMs: opts.fecInterleaveMs,
243
+ // FEC timing is expressed in media units. For audio this is the access-unit
244
+ // cadence (for example 1024/48kHz), not a video-only framerate field.
245
+ fps: 1000 / opts.mediaUnitDurationMs,
246
+ timeoutMs: deliveryWindowMs,
247
+ }, opts.trackName)
248
+ } catch (e) {
249
+ // The manager refused the registration (for example the stream still
250
+ // routes to another Worker). The Worker this call created is not in
251
+ // routing and nothing else holds it, so release it before reporting.
252
+ try {
253
+ client.dispose()
254
+ } catch {
255
+ /* dispose errors are non-fatal */
256
+ }
257
+ throw e
258
+ }
259
+
260
+ let disposed = false
261
+ return {
262
+ client,
263
+ altaEnabled,
264
+ dispose: () => {
265
+ if (disposed) return
266
+ disposed = true
267
+ // Unregister first so no symbol is routed to a dead Worker between the
268
+ // dispose below and the manager noticing. A false return means the
269
+ // Worker was already gone from routing, which this helper never does on
270
+ // its own, so make that loud instead of leaving it to the next symbol.
271
+ if (!opts.multicastManager.clearFecWorker(opts.packetId, opts.trackName)) {
272
+ console.warn(
273
+ `[fec-worker-setup] packetId=${opts.packetId} track=${opts.trackName} Worker was not registered when disposed`,
274
+ )
275
+ }
276
+ try {
277
+ client.dispose()
278
+ } catch {
279
+ /* dispose errors are non-fatal */
280
+ }
281
+ },
282
+ }
283
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * fMP4 data-unit completion policy (BLO-13291).
3
+ *
4
+ * FFmpeg's `mmt` muxer in fMP4-fragments mode (mfu_mode=0, mmtenc_fmp4.c
5
+ * send_media_fragment) delivers one complete moof+mdat (optionally
6
+ * sidx-prefixed) per MPU data unit, split across FI=1/2/3 MMTP fragments.
7
+ * Neither wire counter can prove the chain is byte-complete:
8
+ *
9
+ * - MPU payload header byte 3 is the eight-bit fragment counter. It proves
10
+ * ordering, but cannot declare the total byte length of a fragmented DU.
11
+ * - Each fragment's payload_length bounds that packet only; it does not declare
12
+ * the total size of the multi-packet fMP4 data unit.
13
+ * - packet_sequence_number has legitimate gaps: repair and signaling packets
14
+ * consume sequence slots in the same flow at every FEC block boundary.
15
+ *
16
+ * The data unit is self-describing instead: ISOBMFF top-level box headers
17
+ * declare their 32-bit sizes. A candidate assembly is complete exactly when
18
+ * it parses as a whole number of known top-level boxes covering its full
19
+ * length. Any interior hole shifts subsequent box headers (type/size garbage)
20
+ * or leaves a declared size overrunning the buffer; missing tail bytes leave
21
+ * the final box short.
22
+ */
23
+
24
+ /** Top-level box types the MMT fMP4 writers emit around a data unit. */
25
+ const TOP_LEVEL_BOX_TYPES = new Set(['ftyp', 'styp', 'moov', 'moof', 'mdat', 'sidx', 'free', 'skip', 'prft', 'emsg'])
26
+
27
+ /**
28
+ * True when `candidate` parses as one or more complete top-level ISOBMFF
29
+ * boxes covering exactly its byte length. size==0 ("to end of file") and
30
+ * size==1 (64-bit largesize) are treated as unverifiable and return false —
31
+ * the MMT muxers never emit them for streamed data units.
32
+ */
33
+ export function isCompleteFmp4DataUnit(candidate: Uint8Array): boolean {
34
+ if (candidate.length < 8) return false
35
+ const dv = new DataView(candidate.buffer, candidate.byteOffset, candidate.byteLength)
36
+ let pos = 0
37
+ while (pos < candidate.length) {
38
+ if (pos + 8 > candidate.length) return false
39
+ const size = dv.getUint32(pos)
40
+ if (size < 8) return false
41
+ const type = String.fromCharCode(candidate[pos + 4]!, candidate[pos + 5]!, candidate[pos + 6]!, candidate[pos + 7]!)
42
+ if (!TOP_LEVEL_BOX_TYPES.has(type)) return false
43
+ if (pos + size > candidate.length) return false
44
+ pos += size
45
+ }
46
+ return pos === candidate.length
47
+ }