@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.
- package/README.md +524 -0
- package/dist/.build-stamp +0 -0
- package/dist/__tests__/test-utils.d.ts +71 -0
- package/dist/__tests__/test-utils.d.ts.map +1 -0
- package/dist/align.d.ts +152 -0
- package/dist/align.d.ts.map +1 -0
- package/dist/align.js +88 -0
- package/dist/align.js.map +7 -0
- package/dist/audio-init-parser.d.ts +66 -0
- package/dist/audio-init-parser.d.ts.map +1 -0
- package/dist/audio-init-parser.js +118 -0
- package/dist/audio-init-parser.js.map +7 -0
- package/dist/audio-ring-buffer.d.ts +50 -0
- package/dist/audio-ring-buffer.d.ts.map +1 -0
- package/dist/audio-ring-buffer.js +80 -0
- package/dist/audio-ring-buffer.js.map +7 -0
- package/dist/authored-timing.d.ts +32 -0
- package/dist/authored-timing.d.ts.map +1 -0
- package/dist/authored-timing.js +32 -0
- package/dist/authored-timing.js.map +7 -0
- package/dist/block-policy.d.ts +314 -0
- package/dist/block-policy.d.ts.map +1 -0
- package/dist/block-policy.js +466 -0
- package/dist/block-policy.js.map +7 -0
- package/dist/browser-runtime.js +26549 -0
- package/dist/browser-runtime.js.map +7 -0
- package/dist/carp-catalog.d.ts +429 -0
- package/dist/carp-catalog.d.ts.map +1 -0
- package/dist/carp-catalog.js +985 -0
- package/dist/carp-catalog.js.map +7 -0
- package/dist/catalog-fec-params.d.ts +275 -0
- package/dist/catalog-fec-params.d.ts.map +1 -0
- package/dist/catalog-fec-params.js +702 -0
- package/dist/catalog-fec-params.js.map +7 -0
- package/dist/catalog-network-source.d.ts +42 -0
- package/dist/catalog-network-source.d.ts.map +1 -0
- package/dist/catalog-network-source.js +47 -0
- package/dist/catalog-network-source.js.map +7 -0
- package/dist/catalog-validator.d.ts +18 -0
- package/dist/catalog-validator.d.ts.map +1 -0
- package/dist/catalog-validator.js +7747 -0
- package/dist/catalog-validator.js.map +7 -0
- package/dist/cmaf-block-assembler.d.ts +285 -0
- package/dist/cmaf-block-assembler.d.ts.map +1 -0
- package/dist/cmaf-block-assembler.js +1966 -0
- package/dist/cmaf-block-assembler.js.map +7 -0
- package/dist/cmaf-group-batcher.d.ts +38 -0
- package/dist/cmaf-group-batcher.d.ts.map +1 -0
- package/dist/cmaf-group-batcher.js +176 -0
- package/dist/cmaf-group-batcher.js.map +7 -0
- package/dist/cmcd-producer.d.ts +104 -0
- package/dist/cmcd-producer.d.ts.map +1 -0
- package/dist/cmcd-producer.js +183 -0
- package/dist/cmcd-producer.js.map +7 -0
- package/dist/codec-utils.d.ts +384 -0
- package/dist/codec-utils.d.ts.map +1 -0
- package/dist/codec-utils.js +1546 -0
- package/dist/codec-utils.js.map +7 -0
- package/dist/conceal-timeline.d.ts +146 -0
- package/dist/conceal-timeline.d.ts.map +1 -0
- package/dist/conceal-timeline.js +137 -0
- package/dist/conceal-timeline.js.map +7 -0
- package/dist/delivery-gap.d.ts +75 -0
- package/dist/delivery-gap.d.ts.map +1 -0
- package/dist/delivery-gap.js +88 -0
- package/dist/delivery-gap.js.map +7 -0
- package/dist/duplicate-ledger.d.ts +197 -0
- package/dist/duplicate-ledger.d.ts.map +1 -0
- package/dist/duplicate-ledger.js +226 -0
- package/dist/duplicate-ledger.js.map +7 -0
- package/dist/fec-codec.d.ts +32 -0
- package/dist/fec-codec.d.ts.map +1 -0
- package/dist/fec-codec.js +47 -0
- package/dist/fec-codec.js.map +7 -0
- package/dist/fec-manager.d.ts +583 -0
- package/dist/fec-manager.d.ts.map +1 -0
- package/dist/fec-manager.js +3899 -0
- package/dist/fec-manager.js.map +7 -0
- package/dist/fec-starvation-detector.d.ts +59 -0
- package/dist/fec-starvation-detector.d.ts.map +1 -0
- package/dist/fec-starvation-detector.js +60 -0
- package/dist/fec-starvation-detector.js.map +7 -0
- package/dist/fec-state.d.ts +131 -0
- package/dist/fec-state.d.ts.map +1 -0
- package/dist/fec-state.js +87 -0
- package/dist/fec-state.js.map +7 -0
- package/dist/fec-worker-setup.d.ts +94 -0
- package/dist/fec-worker-setup.d.ts.map +1 -0
- package/dist/fec-worker-setup.js +673 -0
- package/dist/fec-worker-setup.js.map +7 -0
- package/dist/fmp4-completion.d.ts +30 -0
- package/dist/fmp4-completion.d.ts.map +1 -0
- package/dist/fmp4-completion.js +21 -0
- package/dist/fmp4-completion.js.map +7 -0
- package/dist/fmp4-reader.d.ts +37 -0
- package/dist/fmp4-reader.d.ts.map +1 -0
- package/dist/fmp4-reader.js +100 -0
- package/dist/fmp4-reader.js.map +7 -0
- package/dist/index.d.ts +44 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +460 -14
- package/dist/index.js.map +7 -1
- package/dist/iso-block-locator.d.ts +118 -0
- package/dist/iso-block-locator.d.ts.map +1 -0
- package/dist/iso-block-locator.js +289 -0
- package/dist/iso-block-locator.js.map +7 -0
- package/dist/iso-bmff-timing.d.ts +78 -0
- package/dist/iso-bmff-timing.d.ts.map +1 -0
- package/dist/iso-bmff-timing.js +593 -0
- package/dist/iso-bmff-timing.js.map +7 -0
- package/dist/loc.d.ts +70 -75
- package/dist/loc.d.ts.map +1 -1
- package/dist/loc.js +106 -192
- package/dist/loc.js.map +7 -1
- package/dist/manifest-auth-plan.d.ts +30 -0
- package/dist/manifest-auth-plan.d.ts.map +1 -0
- package/dist/manifest-auth-plan.js +1266 -0
- package/dist/manifest-auth-plan.js.map +7 -0
- package/dist/media-router.d.ts +262 -0
- package/dist/media-router.d.ts.map +1 -0
- package/dist/media-router.js +584 -0
- package/dist/media-router.js.map +7 -0
- package/dist/mfu-reassembler.d.ts +313 -9
- package/dist/mfu-reassembler.d.ts.map +1 -1
- package/dist/mfu-reassembler.js +3051 -285
- package/dist/mfu-reassembler.js.map +7 -1
- package/dist/mfu-reassembly-policy.d.ts +24 -0
- package/dist/mfu-reassembly-policy.d.ts.map +1 -0
- package/dist/mfu-reassembly-policy.js +99 -0
- package/dist/mfu-reassembly-policy.js.map +7 -0
- package/dist/mmtp-container-parser.d.ts +568 -0
- package/dist/mmtp-container-parser.d.ts.map +1 -0
- package/dist/mmtp-container-parser.js +6580 -0
- package/dist/mmtp-container-parser.js.map +7 -0
- package/dist/mmtp-container-parser.no-modules.js +9616 -0
- package/dist/mmtp-container-parser.no-modules.js.map +7 -0
- package/dist/mmtp-decode-pipeline.d.ts +138 -0
- package/dist/mmtp-decode-pipeline.d.ts.map +1 -0
- package/dist/mmtp-decode-pipeline.js +6814 -0
- package/dist/mmtp-decode-pipeline.js.map +7 -0
- package/dist/mmtp-router.d.ts +679 -0
- package/dist/mmtp-router.d.ts.map +1 -0
- package/dist/mmtp-router.js +11278 -0
- package/dist/mmtp-router.js.map +7 -0
- package/dist/mmtp-to-cmaf.d.ts +187 -0
- package/dist/mmtp-to-cmaf.d.ts.map +1 -0
- package/dist/mmtp-to-cmaf.js +716 -0
- package/dist/mmtp-to-cmaf.js.map +7 -0
- package/dist/multicast-auth-catalog.d.ts +115 -0
- package/dist/multicast-auth-catalog.d.ts.map +1 -0
- package/dist/multicast-auth-catalog.js +202 -0
- package/dist/multicast-auth-catalog.js.map +7 -0
- package/dist/multicast-input.d.ts +141 -0
- package/dist/multicast-input.d.ts.map +1 -0
- package/dist/multicast-input.js +390 -0
- package/dist/multicast-input.js.map +7 -0
- package/dist/multicast-manager.d.ts +669 -0
- package/dist/multicast-manager.d.ts.map +1 -0
- package/dist/multicast-manager.js +19101 -0
- package/dist/multicast-manager.js.map +7 -0
- package/dist/multicast-transport.d.ts +271 -0
- package/dist/multicast-transport.d.ts.map +1 -0
- package/dist/multicast-transport.js +2264 -0
- package/dist/multicast-transport.js.map +7 -0
- package/dist/multicast-unwrap.d.ts +57 -0
- package/dist/multicast-unwrap.d.ts.map +1 -0
- package/dist/multicast-unwrap.js +418 -0
- package/dist/multicast-unwrap.js.map +7 -0
- package/dist/no-modules.d.ts +10 -0
- package/dist/no-modules.d.ts.map +1 -0
- package/dist/no-modules.js +9491 -0
- package/dist/no-modules.js.map +7 -0
- package/dist/phase14-catalog-override.d.ts +126 -0
- package/dist/phase14-catalog-override.d.ts.map +1 -0
- package/dist/phase14-catalog-override.js +155 -0
- package/dist/phase14-catalog-override.js.map +7 -0
- package/dist/repair-fetch.d.ts +270 -0
- package/dist/repair-fetch.d.ts.map +1 -0
- package/dist/repair-fetch.js +381 -0
- package/dist/repair-fetch.js.map +7 -0
- package/dist/repair-layers.d.ts +158 -0
- package/dist/repair-layers.d.ts.map +1 -0
- package/dist/repair-layers.js +344 -0
- package/dist/repair-layers.js.map +7 -0
- package/dist/sample-combiner.d.ts +212 -0
- package/dist/sample-combiner.d.ts.map +1 -0
- package/dist/sample-combiner.js +595 -0
- package/dist/sample-combiner.js.map +7 -0
- package/dist/signaling.d.ts +29 -0
- package/dist/signaling.d.ts.map +1 -0
- package/dist/signaling.js +572 -0
- package/dist/signaling.js.map +7 -0
- package/dist/source-auth.d.ts +2 -0
- package/dist/source-auth.d.ts.map +1 -0
- package/dist/source-auth.js +1209 -0
- package/dist/source-auth.js.map +7 -0
- package/dist/switching-set-alignment.d.ts +61 -0
- package/dist/switching-set-alignment.d.ts.map +1 -0
- package/dist/switching-set-alignment.js +70 -0
- package/dist/switching-set-alignment.js.map +7 -0
- package/dist/timestamp-codec.d.ts +34 -0
- package/dist/timestamp-codec.d.ts.map +1 -0
- package/dist/timestamp-codec.js +473 -0
- package/dist/timestamp-codec.js.map +7 -0
- package/dist/track-pipeline-setup.d.ts +83 -0
- package/dist/track-pipeline-setup.d.ts.map +1 -0
- package/dist/track-pipeline-setup.js +291 -0
- package/dist/track-pipeline-setup.js.map +7 -0
- package/dist/track-pipeline.d.ts +121 -0
- package/dist/track-pipeline.d.ts.map +1 -0
- package/dist/track-pipeline.js +209 -0
- package/dist/track-pipeline.js.map +7 -0
- package/dist/track-session.d.ts +414 -0
- package/dist/track-session.d.ts.map +1 -0
- package/dist/track-session.js +754 -0
- package/dist/track-session.js.map +7 -0
- package/dist/transport-pool.d.ts +69 -0
- package/dist/transport-pool.d.ts.map +1 -0
- package/dist/transport-pool.js +74 -0
- package/dist/transport-pool.js.map +7 -0
- package/dist/wasm-mfu-reassembler.d.ts +97 -0
- package/dist/wasm-mfu-reassembler.d.ts.map +1 -0
- package/dist/wasm-mfu-reassembler.js +2133 -0
- package/dist/wasm-mfu-reassembler.js.map +7 -0
- package/dist/wasm-mmtp-container-parser.d.ts +10 -0
- package/dist/wasm-mmtp-container-parser.d.ts.map +1 -0
- package/dist/wasm-mmtp-container-parser.js +6834 -0
- package/dist/wasm-mmtp-container-parser.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/README.md +223 -0
- package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts +38 -0
- package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/block-order.js +78 -0
- package/node_modules/@blockcast/fec-worker/dist/block-order.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +93 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +346 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +380 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +11 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +14 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +859 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts +10 -0
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/index.js +8 -0
- package/node_modules/@blockcast/fec-worker/dist/index.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +20 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +370 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +104 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +181 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +194 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +62 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +9 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.js +13 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/package.json +59 -0
- package/node_modules/@blockcast/fec-worker/src/block-order.ts +93 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +392 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +399 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +1502 -0
- package/node_modules/@blockcast/fec-worker/src/index.ts +35 -0
- package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +589 -0
- package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +222 -0
- package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +209 -0
- package/node_modules/@blockcast/fec-worker/src/transfer.ts +12 -0
- package/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
- package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
- package/node_modules/@blockcast/mmt-base/README.md +134 -0
- package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
- package/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
- package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
- package/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
- package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
- package/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
- package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
- package/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/package.json +49 -0
- package/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
- package/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
- package/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
- package/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
- package/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
- package/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
- package/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
- package/node_modules/@blockcast/mmt-fec/README.md +271 -0
- package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +82 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +296 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +106 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +288 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +46 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +96 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +33 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +57 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +205 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +240 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +28 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.js +28 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +20 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +28 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +258 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.js +382 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +41 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +81 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +82 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +170 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +134 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +49 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
- package/node_modules/@blockcast/mmt-fec/package.json +79 -0
- package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +371 -0
- package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +439 -0
- package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +127 -0
- package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +68 -0
- package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +310 -0
- package/node_modules/@blockcast/mmt-fec/src/index.ts +94 -0
- package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +34 -0
- package/node_modules/@blockcast/mmt-fec/src/oti.ts +463 -0
- package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +101 -0
- package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +195 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +28 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +128 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +4 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +4 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +37 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +179 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +99 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +492 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/package.json +45 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +171 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +3 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +230 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +669 -0
- package/node_modules/@noble/hashes/LICENSE +21 -0
- package/node_modules/@noble/hashes/README.md +521 -0
- package/node_modules/@noble/hashes/_assert.d.ts +17 -0
- package/node_modules/@noble/hashes/_assert.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_assert.js +18 -0
- package/node_modules/@noble/hashes/_assert.js.map +1 -0
- package/node_modules/@noble/hashes/_blake.d.ts +14 -0
- package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_blake.js +50 -0
- package/node_modules/@noble/hashes/_blake.js.map +1 -0
- package/node_modules/@noble/hashes/_md.d.ts +51 -0
- package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_md.js +162 -0
- package/node_modules/@noble/hashes/_md.js.map +1 -0
- package/node_modules/@noble/hashes/_u64.d.ts +55 -0
- package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_u64.js +90 -0
- package/node_modules/@noble/hashes/_u64.js.map +1 -0
- package/node_modules/@noble/hashes/argon2.d.ts +32 -0
- package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/argon2.js +401 -0
- package/node_modules/@noble/hashes/argon2.js.map +1 -0
- package/node_modules/@noble/hashes/blake1.d.ts +106 -0
- package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake1.js +459 -0
- package/node_modules/@noble/hashes/blake1.js.map +1 -0
- package/node_modules/@noble/hashes/blake2.d.ts +116 -0
- package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2.js +420 -0
- package/node_modules/@noble/hashes/blake2.js.map +1 -0
- package/node_modules/@noble/hashes/blake2b.d.ts +11 -0
- package/node_modules/@noble/hashes/blake2b.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2b.js +14 -0
- package/node_modules/@noble/hashes/blake2b.js.map +1 -0
- package/node_modules/@noble/hashes/blake2s.d.ts +20 -0
- package/node_modules/@noble/hashes/blake2s.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2s.js +24 -0
- package/node_modules/@noble/hashes/blake2s.js.map +1 -0
- package/node_modules/@noble/hashes/blake3.d.ts +54 -0
- package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake3.js +255 -0
- package/node_modules/@noble/hashes/blake3.js.map +1 -0
- package/node_modules/@noble/hashes/crypto.d.ts +2 -0
- package/node_modules/@noble/hashes/crypto.d.ts.map +1 -0
- package/node_modules/@noble/hashes/crypto.js +5 -0
- package/node_modules/@noble/hashes/crypto.js.map +1 -0
- package/node_modules/@noble/hashes/cryptoNode.d.ts +2 -0
- package/node_modules/@noble/hashes/cryptoNode.d.ts.map +1 -0
- package/node_modules/@noble/hashes/cryptoNode.js +18 -0
- package/node_modules/@noble/hashes/cryptoNode.js.map +1 -0
- package/node_modules/@noble/hashes/eskdf.d.ts +47 -0
- package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/eskdf.js +166 -0
- package/node_modules/@noble/hashes/eskdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_assert.d.ts +17 -0
- package/node_modules/@noble/hashes/esm/_assert.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_assert.js +15 -0
- package/node_modules/@noble/hashes/esm/_assert.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_blake.d.ts +14 -0
- package/node_modules/@noble/hashes/esm/_blake.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_blake.js +45 -0
- package/node_modules/@noble/hashes/esm/_blake.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_md.d.ts +51 -0
- package/node_modules/@noble/hashes/esm/_md.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_md.js +155 -0
- package/node_modules/@noble/hashes/esm/_md.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_u64.d.ts +55 -0
- package/node_modules/@noble/hashes/esm/_u64.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_u64.js +67 -0
- package/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
- package/node_modules/@noble/hashes/esm/argon2.d.ts +32 -0
- package/node_modules/@noble/hashes/esm/argon2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/argon2.js +392 -0
- package/node_modules/@noble/hashes/esm/argon2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake1.d.ts +106 -0
- package/node_modules/@noble/hashes/esm/blake1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake1.js +452 -0
- package/node_modules/@noble/hashes/esm/blake1.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2.d.ts +116 -0
- package/node_modules/@noble/hashes/esm/blake2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2.js +413 -0
- package/node_modules/@noble/hashes/esm/blake2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2b.d.ts +11 -0
- package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2b.js +11 -0
- package/node_modules/@noble/hashes/esm/blake2b.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2s.d.ts +20 -0
- package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2s.js +21 -0
- package/node_modules/@noble/hashes/esm/blake2s.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake3.d.ts +54 -0
- package/node_modules/@noble/hashes/esm/blake3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake3.js +251 -0
- package/node_modules/@noble/hashes/esm/blake3.js.map +1 -0
- package/node_modules/@noble/hashes/esm/crypto.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/crypto.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/crypto.js +2 -0
- package/node_modules/@noble/hashes/esm/crypto.js.map +1 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.js +15 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.js.map +1 -0
- package/node_modules/@noble/hashes/esm/eskdf.d.ts +47 -0
- package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/eskdf.js +160 -0
- package/node_modules/@noble/hashes/esm/eskdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/hkdf.d.ts +36 -0
- package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/hkdf.js +82 -0
- package/node_modules/@noble/hashes/esm/hkdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/hmac.d.ts +35 -0
- package/node_modules/@noble/hashes/esm/hmac.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/hmac.js +86 -0
- package/node_modules/@noble/hashes/esm/hmac.js.map +1 -0
- package/node_modules/@noble/hashes/esm/index.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/index.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/index.js +33 -0
- package/node_modules/@noble/hashes/esm/index.js.map +1 -0
- package/node_modules/@noble/hashes/esm/legacy.d.ts +71 -0
- package/node_modules/@noble/hashes/esm/legacy.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/legacy.js +281 -0
- package/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
- package/node_modules/@noble/hashes/esm/package.json +10 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +23 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.js +97 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts +13 -0
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/ripemd160.js +13 -0
- package/node_modules/@noble/hashes/esm/ripemd160.js.map +1 -0
- package/node_modules/@noble/hashes/esm/scrypt.d.ts +34 -0
- package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/scrypt.js +228 -0
- package/node_modules/@noble/hashes/esm/scrypt.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha1.d.ts +11 -0
- package/node_modules/@noble/hashes/esm/sha1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha1.js +11 -0
- package/node_modules/@noble/hashes/esm/sha1.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha2.d.ts +159 -0
- package/node_modules/@noble/hashes/esm/sha2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha2.js +375 -0
- package/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha256.d.ts +20 -0
- package/node_modules/@noble/hashes/esm/sha256.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha256.js +20 -0
- package/node_modules/@noble/hashes/esm/sha256.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +142 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.js +393 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3.d.ts +53 -0
- package/node_modules/@noble/hashes/esm/sha3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3.js +234 -0
- package/node_modules/@noble/hashes/esm/sha3.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha512.d.ts +26 -0
- package/node_modules/@noble/hashes/esm/sha512.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha512.js +26 -0
- package/node_modules/@noble/hashes/esm/sha512.js.map +1 -0
- package/node_modules/@noble/hashes/esm/utils.d.ts +161 -0
- package/node_modules/@noble/hashes/esm/utils.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/utils.js +281 -0
- package/node_modules/@noble/hashes/esm/utils.js.map +1 -0
- package/node_modules/@noble/hashes/hkdf.d.ts +36 -0
- package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hkdf.js +88 -0
- package/node_modules/@noble/hashes/hkdf.js.map +1 -0
- package/node_modules/@noble/hashes/hmac.d.ts +35 -0
- package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hmac.js +91 -0
- package/node_modules/@noble/hashes/hmac.js.map +1 -0
- package/node_modules/@noble/hashes/index.d.ts +1 -0
- package/node_modules/@noble/hashes/index.d.ts.map +1 -0
- package/node_modules/@noble/hashes/index.js +33 -0
- package/node_modules/@noble/hashes/index.js.map +1 -0
- package/node_modules/@noble/hashes/legacy.d.ts +71 -0
- package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
- package/node_modules/@noble/hashes/legacy.js +287 -0
- package/node_modules/@noble/hashes/legacy.js.map +1 -0
- package/node_modules/@noble/hashes/package.json +266 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts +23 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/pbkdf2.js +101 -0
- package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
- package/node_modules/@noble/hashes/ripemd160.d.ts +13 -0
- package/node_modules/@noble/hashes/ripemd160.d.ts.map +1 -0
- package/node_modules/@noble/hashes/ripemd160.js +16 -0
- package/node_modules/@noble/hashes/ripemd160.js.map +1 -0
- package/node_modules/@noble/hashes/scrypt.d.ts +34 -0
- package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
- package/node_modules/@noble/hashes/scrypt.js +232 -0
- package/node_modules/@noble/hashes/scrypt.js.map +1 -0
- package/node_modules/@noble/hashes/sha1.d.ts +11 -0
- package/node_modules/@noble/hashes/sha1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha1.js +14 -0
- package/node_modules/@noble/hashes/sha1.js.map +1 -0
- package/node_modules/@noble/hashes/sha2.d.ts +159 -0
- package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha2.js +384 -0
- package/node_modules/@noble/hashes/sha2.js.map +1 -0
- package/node_modules/@noble/hashes/sha256.d.ts +20 -0
- package/node_modules/@noble/hashes/sha256.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha256.js +23 -0
- package/node_modules/@noble/hashes/sha256.js.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts +142 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.js +402 -0
- package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
- package/node_modules/@noble/hashes/sha3.d.ts +53 -0
- package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3.js +239 -0
- package/node_modules/@noble/hashes/sha3.js.map +1 -0
- package/node_modules/@noble/hashes/sha512.d.ts +26 -0
- package/node_modules/@noble/hashes/sha512.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha512.js +29 -0
- package/node_modules/@noble/hashes/sha512.js.map +1 -0
- package/node_modules/@noble/hashes/src/_assert.ts +22 -0
- package/node_modules/@noble/hashes/src/_blake.ts +50 -0
- package/node_modules/@noble/hashes/src/_md.ts +176 -0
- package/node_modules/@noble/hashes/src/_u64.ts +91 -0
- package/node_modules/@noble/hashes/src/argon2.ts +497 -0
- package/node_modules/@noble/hashes/src/blake1.ts +534 -0
- package/node_modules/@noble/hashes/src/blake2.ts +486 -0
- package/node_modules/@noble/hashes/src/blake2b.ts +10 -0
- package/node_modules/@noble/hashes/src/blake2s.ts +20 -0
- package/node_modules/@noble/hashes/src/blake3.ts +272 -0
- package/node_modules/@noble/hashes/src/crypto.ts +9 -0
- package/node_modules/@noble/hashes/src/cryptoNode.ts +15 -0
- package/node_modules/@noble/hashes/src/eskdf.ts +187 -0
- package/node_modules/@noble/hashes/src/hkdf.ts +88 -0
- package/node_modules/@noble/hashes/src/hmac.ts +94 -0
- package/node_modules/@noble/hashes/src/index.ts +31 -0
- package/node_modules/@noble/hashes/src/legacy.ts +293 -0
- package/node_modules/@noble/hashes/src/pbkdf2.ts +122 -0
- package/node_modules/@noble/hashes/src/ripemd160.ts +12 -0
- package/node_modules/@noble/hashes/src/scrypt.ts +257 -0
- package/node_modules/@noble/hashes/src/sha1.ts +10 -0
- package/node_modules/@noble/hashes/src/sha2.ts +402 -0
- package/node_modules/@noble/hashes/src/sha256.ts +24 -0
- package/node_modules/@noble/hashes/src/sha3-addons.ts +499 -0
- package/node_modules/@noble/hashes/src/sha3.ts +258 -0
- package/node_modules/@noble/hashes/src/sha512.ts +34 -0
- package/node_modules/@noble/hashes/src/utils.ts +395 -0
- package/node_modules/@noble/hashes/utils.d.ts +161 -0
- package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
- package/node_modules/@noble/hashes/utils.js +313 -0
- package/node_modules/@noble/hashes/utils.js.map +1 -0
- package/package.json +179 -8
- package/schemas/catalog.schema.json +357 -0
- package/src/align.ts +239 -0
- package/src/audio-init-parser.ts +189 -0
- package/src/audio-ring-buffer.ts +120 -0
- package/src/authored-timing.ts +63 -0
- package/src/block-policy.ts +903 -0
- package/src/carp-catalog.ts +1065 -0
- package/src/catalog-fec-params.ts +729 -0
- package/src/catalog-network-source.ts +74 -0
- package/src/catalog-validator.ts +34 -0
- package/src/cmaf-block-assembler.ts +1255 -0
- package/src/cmaf-group-batcher.ts +104 -0
- package/src/cmcd-producer.ts +329 -0
- package/src/codec-utils.ts +1984 -0
- package/src/conceal-timeline.ts +293 -0
- package/src/delivery-gap.ts +147 -0
- package/src/duplicate-ledger.ts +372 -0
- package/src/fec-codec.ts +61 -0
- package/src/fec-manager.ts +4298 -0
- package/src/fec-starvation-detector.ts +128 -0
- package/src/fec-state.ts +219 -0
- package/src/fec-worker-setup.ts +283 -0
- package/src/fmp4-completion.ts +47 -0
- package/src/fmp4-reader.ts +112 -0
- package/src/index.ts +590 -21
- package/src/iso-block-locator.ts +329 -0
- package/src/iso-bmff-timing.ts +813 -0
- package/src/loc.ts +128 -154
- package/src/manifest-auth-plan.ts +107 -0
- package/src/media-router.ts +841 -0
- package/src/mfu-reassembler.ts +3480 -155
- package/src/mfu-reassembly-policy.ts +134 -0
- package/src/mmtp-container-parser.ts +2380 -0
- package/src/mmtp-decode-pipeline.ts +406 -0
- package/src/mmtp-router.ts +4860 -0
- package/src/mmtp-to-cmaf.ts +977 -0
- package/src/multicast-auth-catalog.ts +340 -0
- package/src/multicast-input.ts +793 -0
- package/src/multicast-manager.ts +2783 -0
- package/src/multicast-transport.ts +1058 -0
- package/src/multicast-unwrap.ts +132 -0
- package/src/no-modules.ts +21 -0
- package/src/phase14-catalog-override.ts +336 -0
- package/src/repair-fetch.ts +772 -0
- package/src/repair-layers.ts +533 -0
- package/src/sample-combiner.ts +938 -0
- package/src/signaling.ts +78 -0
- package/src/source-auth.ts +1 -0
- package/src/switching-set-alignment.ts +109 -0
- package/src/timestamp-codec.ts +265 -0
- package/src/track-pipeline-setup.ts +205 -0
- package/src/track-pipeline.ts +332 -0
- package/src/track-session.ts +1010 -0
- package/src/transport-pool.ts +128 -0
- package/src/wasm-mfu-reassembler.ts +405 -0
- package/src/wasm-mmtp-container-parser.ts +23 -0
- package/test-vectors/align.json +199 -0
- package/test-vectors/catalog/README.md +106 -0
- package/test-vectors/catalog/negative/archive-origin-with-path.json +33 -0
- package/test-vectors/catalog/negative/archive-unknown-field.json +34 -0
- package/test-vectors/catalog/negative/fec-block-profile-missing.json +51 -0
- package/test-vectors/catalog/negative/fec-block-profile-unknown.json +52 -0
- package/test-vectors/catalog/negative/fec-enhancement-repair-removed.json +28 -0
- package/test-vectors/catalog/negative/fec-repair-layer-geometry.json +33 -0
- package/test-vectors/catalog/negative/fec-repair-layer-missing-symbols.json +31 -0
- package/test-vectors/catalog/negative/fec-repair-multiple-depends.json +32 -0
- package/test-vectors/catalog/negative/fec-repair-overlay-with-layer.json +34 -0
- package/test-vectors/catalog/negative/fec-repair-priority-out-of-band.json +24 -0
- package/test-vectors/catalog/negative/fec-repair-source-symbols-without-scope.json +33 -0
- package/test-vectors/catalog/negative/legacy-selection-params.json +15 -0
- package/test-vectors/catalog/negative/media-track-repair-layer.json +16 -0
- package/test-vectors/catalog/negative/missing-mmtp-fields.json +12 -0
- package/test-vectors/catalog/negative/multicast-auth-padded-key.json +37 -0
- package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +53 -0
- package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +37 -0
- package/test-vectors/catalog/negative/multicast-endpoint-missing-protocol-and-source.json +24 -0
- package/test-vectors/catalog/negative/multicast-network-source-empty.json +44 -0
- package/test-vectors/catalog/negative/multicast-packet-id-signaling.json +26 -0
- package/test-vectors/catalog/negative/network-source-object.json +25 -0
- package/test-vectors/catalog/negative/raptorq-source-symbols-over-max.json +24 -0
- package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +27 -0
- package/test-vectors/catalog/negative/repair-track-legacy-shape.json +19 -0
- package/test-vectors/catalog/negative/track-role-empty.json +16 -0
- package/test-vectors/catalog/negative/track-role-non-string.json +16 -0
- package/test-vectors/catalog/positive/archive-origin.json +34 -0
- package/test-vectors/catalog/positive/fec-iso-ssbg1.json +52 -0
- package/test-vectors/catalog/positive/fec-layered-repair.json +106 -0
- package/test-vectors/catalog/positive/fec-multicast.json +52 -0
- package/test-vectors/catalog/positive/flat-av.json +30 -0
- package/test-vectors/catalog/positive/multicast-auth-rotation.json +55 -0
- package/test-vectors/catalog/positive/multicast-native-ssm-no-network-source.json +43 -0
- package/test-vectors/catalog/positive/ticks-and-mixed-timescales.json +39 -0
- package/test-vectors/catalog/positive/track-role.json +49 -0
- package/test-vectors/catalog/releases/moqcast-native-v16-v1/catalog.json +65 -0
- package/test-vectors/catalog/releases/moqcast-native-v16-v1.archive.sha256 +1 -0
- package/test-vectors/catalog-multicast-auth-v1.json +26 -0
- package/test-vectors/catalog-validation.json +732 -0
- package/test-vectors/catalog-validator-public-api.mjs +25 -0
- package/test-vectors/generate-source-auth-fixture.mjs +114 -0
- package/test-vectors/hevc-x265-repeat-headers-v1.json +40 -0
- package/test-vectors/source-auth-v1.json +61 -0
- package/test-vectors/source-contiguity-v1.json +131 -0
- package/test-vectors/subsample-placement-v1.json +230 -0
- package/dist/mmtp.d.ts +0 -73
- package/dist/mmtp.d.ts.map +0 -1
- package/dist/mmtp.js +0 -210
- package/dist/mmtp.js.map +0 -1
- 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
|
+
}
|
package/src/fec-state.ts
ADDED
|
@@ -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
|
+
}
|