@blockcast/mmt-container 0.3.0 → 0.4.0-main.d6f2737828fc
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 +22 -8
- package/dist/browser-runtime.js +1185 -1049
- package/dist/browser-runtime.js.map +4 -4
- package/dist/carp-catalog.d.ts +24 -8
- package/dist/carp-catalog.d.ts.map +1 -1
- package/dist/carp-catalog.js +21 -8
- package/dist/carp-catalog.js.map +2 -2
- package/dist/catalog-fec-params.d.ts +88 -28
- package/dist/catalog-fec-params.d.ts.map +1 -1
- package/dist/catalog-fec-params.js +59 -17
- package/dist/catalog-fec-params.js.map +3 -3
- package/dist/catalog-network-source.js +0 -1
- package/dist/catalog-network-source.js.map +2 -2
- package/dist/cmaf-block-assembler.d.ts +0 -2
- package/dist/cmaf-block-assembler.d.ts.map +1 -1
- package/dist/cmaf-block-assembler.js +0 -1
- package/dist/cmaf-block-assembler.js.map +2 -2
- package/dist/delta-fallback-config.d.ts +42 -0
- package/dist/delta-fallback-config.d.ts.map +1 -0
- package/dist/delta-fallback-config.js +59 -0
- package/dist/delta-fallback-config.js.map +7 -0
- package/dist/fec-manager.d.ts +35 -26
- package/dist/fec-manager.d.ts.map +1 -1
- package/dist/fec-manager.js +300 -273
- package/dist/fec-manager.js.map +2 -2
- package/dist/fec-state.d.ts +19 -31
- package/dist/fec-state.d.ts.map +1 -1
- package/dist/fec-state.js +3 -4
- package/dist/fec-state.js.map +2 -2
- package/dist/fec-worker-setup.d.ts +16 -6
- package/dist/fec-worker-setup.d.ts.map +1 -1
- package/dist/fec-worker-setup.js +72 -34
- package/dist/fec-worker-setup.js.map +2 -2
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +2 -2
- package/dist/iso-block-locator.js +0 -1
- package/dist/iso-block-locator.js.map +2 -2
- package/dist/media-router.d.ts +20 -8
- package/dist/media-router.d.ts.map +1 -1
- package/dist/media-router.js +46 -21
- package/dist/media-router.js.map +2 -2
- package/dist/mfu-reassembler.js +0 -1
- package/dist/mfu-reassembler.js.map +2 -2
- package/dist/mmtp-container-parser.d.ts +5 -0
- package/dist/mmtp-container-parser.d.ts.map +1 -1
- package/dist/mmtp-container-parser.js +22 -1
- package/dist/mmtp-container-parser.js.map +2 -2
- package/dist/mmtp-container-parser.no-modules.js +37 -9
- package/dist/mmtp-container-parser.no-modules.js.map +2 -2
- package/dist/mmtp-decode-pipeline.js +22 -1
- package/dist/mmtp-decode-pipeline.js.map +2 -2
- package/dist/mmtp-router.d.ts +36 -16
- package/dist/mmtp-router.d.ts.map +1 -1
- package/dist/mmtp-router.js +126 -213
- package/dist/mmtp-router.js.map +2 -2
- package/dist/multicast-input.js +0 -1
- package/dist/multicast-input.js.map +2 -2
- package/dist/multicast-manager.d.ts +33 -3
- package/dist/multicast-manager.d.ts.map +1 -1
- package/dist/multicast-manager.js +660 -529
- package/dist/multicast-manager.js.map +4 -4
- package/dist/multicast-transport.d.ts +1 -1
- package/dist/multicast-transport.d.ts.map +1 -1
- package/dist/multicast-transport.js +42 -14
- package/dist/multicast-transport.js.map +3 -3
- package/dist/multicast-unwrap.js +0 -1
- package/dist/multicast-unwrap.js.map +2 -2
- package/dist/no-modules.js +36 -8
- package/dist/no-modules.js.map +2 -2
- package/dist/repair-fetch.d.ts +30 -19
- package/dist/repair-fetch.d.ts.map +1 -1
- package/dist/repair-fetch.js +32 -18
- package/dist/repair-fetch.js.map +3 -3
- package/dist/repair-layers.d.ts +18 -7
- package/dist/repair-layers.d.ts.map +1 -1
- package/dist/repair-layers.js +11 -4
- package/dist/repair-layers.js.map +2 -2
- package/dist/signaling.js +0 -4
- package/dist/signaling.js.map +2 -2
- package/dist/timestamp-codec.js +0 -1
- package/dist/timestamp-codec.js.map +2 -2
- package/dist/track-session.d.ts +7 -0
- package/dist/track-session.d.ts.map +1 -1
- package/dist/track-session.js +15 -8
- package/dist/track-session.js.map +2 -2
- package/dist/wasm-mfu-reassembler.js +0 -1
- package/dist/wasm-mfu-reassembler.js.map +2 -2
- package/dist/wasm-mmtp-container-parser.js +22 -1
- package/dist/wasm-mmtp-container-parser.js.map +2 -2
- package/package.json +8 -14
- package/schemas/catalog.schema.json +3 -3
- package/src/carp-catalog.ts +35 -13
- package/src/catalog-fec-params.ts +173 -64
- package/src/cmaf-block-assembler.ts +1 -4
- package/src/delta-fallback-config.ts +72 -0
- package/src/fec-manager.ts +413 -317
- package/src/fec-state.ts +20 -32
- package/src/fec-worker-setup.ts +105 -55
- package/src/index.ts +10 -0
- package/src/media-router.ts +59 -21
- package/src/mmtp-container-parser.ts +26 -0
- package/src/mmtp-router.ts +145 -303
- package/src/multicast-manager.ts +172 -60
- package/src/multicast-transport.ts +16 -9
- package/src/repair-fetch.ts +46 -27
- package/src/repair-layers.ts +28 -8
- package/src/track-session.ts +28 -9
- package/test-vectors/catalog/README.md +34 -17
- package/test-vectors/catalog/negative/fec-block-profile-retired.json +52 -0
- package/test-vectors/catalog/negative/fec-enhancement-repair-removed.json +1 -1
- package/test-vectors/catalog/negative/fec-repair-layer-geometry.json +1 -1
- package/test-vectors/catalog/negative/fec-repair-layer-missing-symbols.json +1 -1
- package/test-vectors/catalog/negative/fec-repair-multiple-depends.json +1 -1
- package/test-vectors/catalog/negative/fec-repair-overlay-with-layer.json +1 -1
- package/test-vectors/catalog/negative/fec-repair-priority-out-of-band.json +1 -1
- package/test-vectors/catalog/negative/fec-repair-source-symbols-without-scope.json +1 -1
- package/test-vectors/catalog/negative/multicast-network-source-empty.json +1 -1
- package/test-vectors/catalog/negative/raptorq-source-symbols-over-max.json +1 -1
- package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +1 -1
- package/test-vectors/catalog/positive/fec-layered-repair.json +2 -2
- package/test-vectors/catalog/positive/fec-multicast.json +2 -1
- package/test-vectors/catalog/positive/multicast-native-ssm-no-network-source.json +2 -1
- package/test-vectors/catalog-timing.json +356 -0
- package/test-vectors/catalog-validation.json +40 -5
- package/node_modules/@blockcast/fec-worker/README.md +0 -223
- package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts +0 -38
- package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/block-order.js +0 -78
- package/node_modules/@blockcast/fec-worker/dist/block-order.js.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +0 -93
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +0 -346
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +0 -380
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +0 -11
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +0 -14
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +0 -859
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +0 -7
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts +0 -10
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/index.js +0 -8
- package/node_modules/@blockcast/fec-worker/dist/index.js.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +0 -20
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +0 -370
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +0 -7
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +0 -104
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +0 -181
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +0 -194
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +0 -62
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +0 -9
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +0 -1
- package/node_modules/@blockcast/fec-worker/dist/transfer.js +0 -13
- package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +0 -1
- package/node_modules/@blockcast/fec-worker/package.json +0 -59
- package/node_modules/@blockcast/fec-worker/src/block-order.ts +0 -93
- package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +0 -392
- package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +0 -399
- package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +0 -1502
- package/node_modules/@blockcast/fec-worker/src/index.ts +0 -35
- package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +0 -589
- package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +0 -222
- package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +0 -209
- package/node_modules/@blockcast/fec-worker/src/transfer.ts +0 -12
- package/node_modules/@blockcast/mmt-alta-parse/README.md +0 -181
- package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +0 -57
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +0 -115
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +0 -1
- package/node_modules/@blockcast/mmt-alta-parse/package.json +0 -50
- package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +0 -136
- package/node_modules/@blockcast/mmt-base/README.md +0 -134
- package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +0 -55
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +0 -128
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts +0 -7
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/index.js +0 -7
- package/node_modules/@blockcast/mmt-base/dist/index.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +0 -292
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js +0 -612
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +0 -18
- package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/net-constants.js +0 -18
- package/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +0 -47
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.js +0 -54
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +0 -57
- package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/serial-number.js +0 -98
- package/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +0 -312
- package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/signalling.js +0 -637
- package/node_modules/@blockcast/mmt-base/dist/signalling.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/package.json +0 -49
- package/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +0 -145
- package/node_modules/@blockcast/mmt-base/src/index.ts +0 -6
- package/node_modules/@blockcast/mmt-base/src/mmtp.ts +0 -892
- package/node_modules/@blockcast/mmt-base/src/net-constants.ts +0 -17
- package/node_modules/@blockcast/mmt-base/src/ntp-short.ts +0 -67
- package/node_modules/@blockcast/mmt-base/src/serial-number.ts +0 -107
- package/node_modules/@blockcast/mmt-base/src/signalling.ts +0 -862
- package/node_modules/@blockcast/mmt-fec/README.md +0 -271
- package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +0 -82
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +0 -296
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +0 -106
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +0 -288
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +0 -46
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +0 -96
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +0 -33
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +0 -57
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +0 -205
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +0 -240
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +0 -28
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/index.js +0 -28
- package/node_modules/@blockcast/mmt-fec/dist/index.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +0 -20
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +0 -28
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +0 -258
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/oti.js +0 -382
- package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +0 -41
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +0 -81
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +0 -82
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +0 -170
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +0 -181
- 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 +0 -57
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +0 -115
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +0 -50
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +0 -136
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +0 -134
- 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 +0 -55
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +0 -128
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +0 -7
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +0 -7
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +0 -292
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +0 -612
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +0 -18
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js +0 -18
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +0 -47
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js +0 -54
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +0 -57
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js +0 -98
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +0 -312
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js +0 -637
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js.map +0 -1
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +0 -49
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +0 -145
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +0 -6
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +0 -892
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/net-constants.ts +0 -17
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/ntp-short.ts +0 -67
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/serial-number.ts +0 -107
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/signalling.ts +0 -862
- package/node_modules/@blockcast/mmt-fec/package.json +0 -79
- package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +0 -371
- package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +0 -439
- package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +0 -127
- package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +0 -68
- package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +0 -310
- package/node_modules/@blockcast/mmt-fec/src/index.ts +0 -94
- package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +0 -34
- package/node_modules/@blockcast/mmt-fec/src/oti.ts +0 -463
- package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +0 -101
- package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +0 -195
- package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +0 -28
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +0 -128
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +0 -1
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +0 -4
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +0 -4
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +0 -1
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +0 -37
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +0 -179
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +0 -1
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +0 -99
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +0 -492
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +0 -1
- package/node_modules/@blockcast/mmt-manifest-verify/package.json +0 -45
- package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +0 -171
- package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +0 -3
- package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +0 -230
- package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +0 -669
- package/node_modules/@noble/hashes/LICENSE +0 -21
- package/node_modules/@noble/hashes/README.md +0 -521
- package/node_modules/@noble/hashes/_assert.d.ts +0 -17
- package/node_modules/@noble/hashes/_assert.d.ts.map +0 -1
- package/node_modules/@noble/hashes/_assert.js +0 -18
- package/node_modules/@noble/hashes/_assert.js.map +0 -1
- package/node_modules/@noble/hashes/_blake.d.ts +0 -14
- package/node_modules/@noble/hashes/_blake.d.ts.map +0 -1
- package/node_modules/@noble/hashes/_blake.js +0 -50
- package/node_modules/@noble/hashes/_blake.js.map +0 -1
- package/node_modules/@noble/hashes/_md.d.ts +0 -51
- package/node_modules/@noble/hashes/_md.d.ts.map +0 -1
- package/node_modules/@noble/hashes/_md.js +0 -162
- package/node_modules/@noble/hashes/_md.js.map +0 -1
- package/node_modules/@noble/hashes/_u64.d.ts +0 -55
- package/node_modules/@noble/hashes/_u64.d.ts.map +0 -1
- package/node_modules/@noble/hashes/_u64.js +0 -90
- package/node_modules/@noble/hashes/_u64.js.map +0 -1
- package/node_modules/@noble/hashes/argon2.d.ts +0 -32
- package/node_modules/@noble/hashes/argon2.d.ts.map +0 -1
- package/node_modules/@noble/hashes/argon2.js +0 -401
- package/node_modules/@noble/hashes/argon2.js.map +0 -1
- package/node_modules/@noble/hashes/blake1.d.ts +0 -106
- package/node_modules/@noble/hashes/blake1.d.ts.map +0 -1
- package/node_modules/@noble/hashes/blake1.js +0 -459
- package/node_modules/@noble/hashes/blake1.js.map +0 -1
- package/node_modules/@noble/hashes/blake2.d.ts +0 -116
- package/node_modules/@noble/hashes/blake2.d.ts.map +0 -1
- package/node_modules/@noble/hashes/blake2.js +0 -420
- package/node_modules/@noble/hashes/blake2.js.map +0 -1
- package/node_modules/@noble/hashes/blake2b.d.ts +0 -11
- package/node_modules/@noble/hashes/blake2b.d.ts.map +0 -1
- package/node_modules/@noble/hashes/blake2b.js +0 -14
- package/node_modules/@noble/hashes/blake2b.js.map +0 -1
- package/node_modules/@noble/hashes/blake2s.d.ts +0 -20
- package/node_modules/@noble/hashes/blake2s.d.ts.map +0 -1
- package/node_modules/@noble/hashes/blake2s.js +0 -24
- package/node_modules/@noble/hashes/blake2s.js.map +0 -1
- package/node_modules/@noble/hashes/blake3.d.ts +0 -54
- package/node_modules/@noble/hashes/blake3.d.ts.map +0 -1
- package/node_modules/@noble/hashes/blake3.js +0 -255
- package/node_modules/@noble/hashes/blake3.js.map +0 -1
- package/node_modules/@noble/hashes/crypto.d.ts +0 -2
- package/node_modules/@noble/hashes/crypto.d.ts.map +0 -1
- package/node_modules/@noble/hashes/crypto.js +0 -5
- package/node_modules/@noble/hashes/crypto.js.map +0 -1
- package/node_modules/@noble/hashes/cryptoNode.d.ts +0 -2
- package/node_modules/@noble/hashes/cryptoNode.d.ts.map +0 -1
- package/node_modules/@noble/hashes/cryptoNode.js +0 -18
- package/node_modules/@noble/hashes/cryptoNode.js.map +0 -1
- package/node_modules/@noble/hashes/eskdf.d.ts +0 -47
- package/node_modules/@noble/hashes/eskdf.d.ts.map +0 -1
- package/node_modules/@noble/hashes/eskdf.js +0 -166
- package/node_modules/@noble/hashes/eskdf.js.map +0 -1
- package/node_modules/@noble/hashes/esm/_assert.d.ts +0 -17
- package/node_modules/@noble/hashes/esm/_assert.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/_assert.js +0 -15
- package/node_modules/@noble/hashes/esm/_assert.js.map +0 -1
- package/node_modules/@noble/hashes/esm/_blake.d.ts +0 -14
- package/node_modules/@noble/hashes/esm/_blake.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/_blake.js +0 -45
- package/node_modules/@noble/hashes/esm/_blake.js.map +0 -1
- package/node_modules/@noble/hashes/esm/_md.d.ts +0 -51
- package/node_modules/@noble/hashes/esm/_md.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/_md.js +0 -155
- package/node_modules/@noble/hashes/esm/_md.js.map +0 -1
- package/node_modules/@noble/hashes/esm/_u64.d.ts +0 -55
- package/node_modules/@noble/hashes/esm/_u64.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/_u64.js +0 -67
- package/node_modules/@noble/hashes/esm/_u64.js.map +0 -1
- package/node_modules/@noble/hashes/esm/argon2.d.ts +0 -32
- package/node_modules/@noble/hashes/esm/argon2.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/argon2.js +0 -392
- package/node_modules/@noble/hashes/esm/argon2.js.map +0 -1
- package/node_modules/@noble/hashes/esm/blake1.d.ts +0 -106
- package/node_modules/@noble/hashes/esm/blake1.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/blake1.js +0 -452
- package/node_modules/@noble/hashes/esm/blake1.js.map +0 -1
- package/node_modules/@noble/hashes/esm/blake2.d.ts +0 -116
- package/node_modules/@noble/hashes/esm/blake2.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/blake2.js +0 -413
- package/node_modules/@noble/hashes/esm/blake2.js.map +0 -1
- package/node_modules/@noble/hashes/esm/blake2b.d.ts +0 -11
- package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/blake2b.js +0 -11
- package/node_modules/@noble/hashes/esm/blake2b.js.map +0 -1
- package/node_modules/@noble/hashes/esm/blake2s.d.ts +0 -20
- package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/blake2s.js +0 -21
- package/node_modules/@noble/hashes/esm/blake2s.js.map +0 -1
- package/node_modules/@noble/hashes/esm/blake3.d.ts +0 -54
- package/node_modules/@noble/hashes/esm/blake3.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/blake3.js +0 -251
- package/node_modules/@noble/hashes/esm/blake3.js.map +0 -1
- package/node_modules/@noble/hashes/esm/crypto.d.ts +0 -2
- package/node_modules/@noble/hashes/esm/crypto.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/crypto.js +0 -2
- package/node_modules/@noble/hashes/esm/crypto.js.map +0 -1
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +0 -2
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/cryptoNode.js +0 -15
- package/node_modules/@noble/hashes/esm/cryptoNode.js.map +0 -1
- package/node_modules/@noble/hashes/esm/eskdf.d.ts +0 -47
- package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/eskdf.js +0 -160
- package/node_modules/@noble/hashes/esm/eskdf.js.map +0 -1
- package/node_modules/@noble/hashes/esm/hkdf.d.ts +0 -36
- package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/hkdf.js +0 -82
- package/node_modules/@noble/hashes/esm/hkdf.js.map +0 -1
- package/node_modules/@noble/hashes/esm/hmac.d.ts +0 -35
- package/node_modules/@noble/hashes/esm/hmac.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/hmac.js +0 -86
- package/node_modules/@noble/hashes/esm/hmac.js.map +0 -1
- package/node_modules/@noble/hashes/esm/index.d.ts +0 -2
- package/node_modules/@noble/hashes/esm/index.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/index.js +0 -33
- package/node_modules/@noble/hashes/esm/index.js.map +0 -1
- package/node_modules/@noble/hashes/esm/legacy.d.ts +0 -71
- package/node_modules/@noble/hashes/esm/legacy.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/legacy.js +0 -281
- package/node_modules/@noble/hashes/esm/legacy.js.map +0 -1
- package/node_modules/@noble/hashes/esm/package.json +0 -10
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +0 -23
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/pbkdf2.js +0 -97
- package/node_modules/@noble/hashes/esm/pbkdf2.js.map +0 -1
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts +0 -13
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/ripemd160.js +0 -13
- package/node_modules/@noble/hashes/esm/ripemd160.js.map +0 -1
- package/node_modules/@noble/hashes/esm/scrypt.d.ts +0 -34
- package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/scrypt.js +0 -228
- package/node_modules/@noble/hashes/esm/scrypt.js.map +0 -1
- package/node_modules/@noble/hashes/esm/sha1.d.ts +0 -11
- package/node_modules/@noble/hashes/esm/sha1.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/sha1.js +0 -11
- package/node_modules/@noble/hashes/esm/sha1.js.map +0 -1
- package/node_modules/@noble/hashes/esm/sha2.d.ts +0 -159
- package/node_modules/@noble/hashes/esm/sha2.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/sha2.js +0 -375
- package/node_modules/@noble/hashes/esm/sha2.js.map +0 -1
- package/node_modules/@noble/hashes/esm/sha256.d.ts +0 -20
- package/node_modules/@noble/hashes/esm/sha256.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/sha256.js +0 -20
- package/node_modules/@noble/hashes/esm/sha256.js.map +0 -1
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +0 -142
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/sha3-addons.js +0 -393
- package/node_modules/@noble/hashes/esm/sha3-addons.js.map +0 -1
- package/node_modules/@noble/hashes/esm/sha3.d.ts +0 -53
- package/node_modules/@noble/hashes/esm/sha3.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/sha3.js +0 -234
- package/node_modules/@noble/hashes/esm/sha3.js.map +0 -1
- package/node_modules/@noble/hashes/esm/sha512.d.ts +0 -26
- package/node_modules/@noble/hashes/esm/sha512.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/sha512.js +0 -26
- package/node_modules/@noble/hashes/esm/sha512.js.map +0 -1
- package/node_modules/@noble/hashes/esm/utils.d.ts +0 -161
- package/node_modules/@noble/hashes/esm/utils.d.ts.map +0 -1
- package/node_modules/@noble/hashes/esm/utils.js +0 -281
- package/node_modules/@noble/hashes/esm/utils.js.map +0 -1
- package/node_modules/@noble/hashes/hkdf.d.ts +0 -36
- package/node_modules/@noble/hashes/hkdf.d.ts.map +0 -1
- package/node_modules/@noble/hashes/hkdf.js +0 -88
- package/node_modules/@noble/hashes/hkdf.js.map +0 -1
- package/node_modules/@noble/hashes/hmac.d.ts +0 -35
- package/node_modules/@noble/hashes/hmac.d.ts.map +0 -1
- package/node_modules/@noble/hashes/hmac.js +0 -91
- package/node_modules/@noble/hashes/hmac.js.map +0 -1
- package/node_modules/@noble/hashes/index.d.ts +0 -1
- package/node_modules/@noble/hashes/index.d.ts.map +0 -1
- package/node_modules/@noble/hashes/index.js +0 -33
- package/node_modules/@noble/hashes/index.js.map +0 -1
- package/node_modules/@noble/hashes/legacy.d.ts +0 -71
- package/node_modules/@noble/hashes/legacy.d.ts.map +0 -1
- package/node_modules/@noble/hashes/legacy.js +0 -287
- package/node_modules/@noble/hashes/legacy.js.map +0 -1
- package/node_modules/@noble/hashes/package.json +0 -266
- package/node_modules/@noble/hashes/pbkdf2.d.ts +0 -23
- package/node_modules/@noble/hashes/pbkdf2.d.ts.map +0 -1
- package/node_modules/@noble/hashes/pbkdf2.js +0 -101
- package/node_modules/@noble/hashes/pbkdf2.js.map +0 -1
- package/node_modules/@noble/hashes/ripemd160.d.ts +0 -13
- package/node_modules/@noble/hashes/ripemd160.d.ts.map +0 -1
- package/node_modules/@noble/hashes/ripemd160.js +0 -16
- package/node_modules/@noble/hashes/ripemd160.js.map +0 -1
- package/node_modules/@noble/hashes/scrypt.d.ts +0 -34
- package/node_modules/@noble/hashes/scrypt.d.ts.map +0 -1
- package/node_modules/@noble/hashes/scrypt.js +0 -232
- package/node_modules/@noble/hashes/scrypt.js.map +0 -1
- package/node_modules/@noble/hashes/sha1.d.ts +0 -11
- package/node_modules/@noble/hashes/sha1.d.ts.map +0 -1
- package/node_modules/@noble/hashes/sha1.js +0 -14
- package/node_modules/@noble/hashes/sha1.js.map +0 -1
- package/node_modules/@noble/hashes/sha2.d.ts +0 -159
- package/node_modules/@noble/hashes/sha2.d.ts.map +0 -1
- package/node_modules/@noble/hashes/sha2.js +0 -384
- package/node_modules/@noble/hashes/sha2.js.map +0 -1
- package/node_modules/@noble/hashes/sha256.d.ts +0 -20
- package/node_modules/@noble/hashes/sha256.d.ts.map +0 -1
- package/node_modules/@noble/hashes/sha256.js +0 -23
- package/node_modules/@noble/hashes/sha256.js.map +0 -1
- package/node_modules/@noble/hashes/sha3-addons.d.ts +0 -142
- package/node_modules/@noble/hashes/sha3-addons.d.ts.map +0 -1
- package/node_modules/@noble/hashes/sha3-addons.js +0 -402
- package/node_modules/@noble/hashes/sha3-addons.js.map +0 -1
- package/node_modules/@noble/hashes/sha3.d.ts +0 -53
- package/node_modules/@noble/hashes/sha3.d.ts.map +0 -1
- package/node_modules/@noble/hashes/sha3.js +0 -239
- package/node_modules/@noble/hashes/sha3.js.map +0 -1
- package/node_modules/@noble/hashes/sha512.d.ts +0 -26
- package/node_modules/@noble/hashes/sha512.d.ts.map +0 -1
- package/node_modules/@noble/hashes/sha512.js +0 -29
- package/node_modules/@noble/hashes/sha512.js.map +0 -1
- package/node_modules/@noble/hashes/src/_assert.ts +0 -22
- package/node_modules/@noble/hashes/src/_blake.ts +0 -50
- package/node_modules/@noble/hashes/src/_md.ts +0 -176
- package/node_modules/@noble/hashes/src/_u64.ts +0 -91
- package/node_modules/@noble/hashes/src/argon2.ts +0 -497
- package/node_modules/@noble/hashes/src/blake1.ts +0 -534
- package/node_modules/@noble/hashes/src/blake2.ts +0 -486
- package/node_modules/@noble/hashes/src/blake2b.ts +0 -10
- package/node_modules/@noble/hashes/src/blake2s.ts +0 -20
- package/node_modules/@noble/hashes/src/blake3.ts +0 -272
- package/node_modules/@noble/hashes/src/crypto.ts +0 -9
- package/node_modules/@noble/hashes/src/cryptoNode.ts +0 -15
- package/node_modules/@noble/hashes/src/eskdf.ts +0 -187
- package/node_modules/@noble/hashes/src/hkdf.ts +0 -88
- package/node_modules/@noble/hashes/src/hmac.ts +0 -94
- package/node_modules/@noble/hashes/src/index.ts +0 -31
- package/node_modules/@noble/hashes/src/legacy.ts +0 -293
- package/node_modules/@noble/hashes/src/pbkdf2.ts +0 -122
- package/node_modules/@noble/hashes/src/ripemd160.ts +0 -12
- package/node_modules/@noble/hashes/src/scrypt.ts +0 -257
- package/node_modules/@noble/hashes/src/sha1.ts +0 -10
- package/node_modules/@noble/hashes/src/sha2.ts +0 -402
- package/node_modules/@noble/hashes/src/sha256.ts +0 -24
- package/node_modules/@noble/hashes/src/sha3-addons.ts +0 -499
- package/node_modules/@noble/hashes/src/sha3.ts +0 -258
- package/node_modules/@noble/hashes/src/sha512.ts +0 -34
- package/node_modules/@noble/hashes/src/utils.ts +0 -395
- package/node_modules/@noble/hashes/utils.d.ts +0 -161
- package/node_modules/@noble/hashes/utils.d.ts.map +0 -1
- package/node_modules/@noble/hashes/utils.js +0 -313
- package/node_modules/@noble/hashes/utils.js.map +0 -1
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": [
|
|
3
|
+
"Canonical receiver vectors for catalog-derived FEC timing (BLO-45476).",
|
|
4
|
+
"Hand-authored; expect null = undefined, expect 'throws' = the value cannot be derived and must fail closed.",
|
|
5
|
+
"keyframeCadence, mediaUnitsPerSecond and groupDuration pin the neutral catalog rules native receiver adapters share (catalogKeyframeCadenceMs, catalogFecMediaUnitsPerSecond, catalogGroupDurationMs). They are NOT what libmmt's own receiver runs today: resolveCatalogTrackFec reads audio rate from sampleRate ?? samplerate (numeric strings admitted) with no endpoint or timescale fallback, so 'audio MP4-shaped timescale' resolves no rate there; computeBlockClassifierGeometry reads only keyframeInterval*. Converging those is a behaviour change, not part of this extraction.",
|
|
6
|
+
"deliveryWindow and trackFec run against libmmt's production paths (computeFecDeliveryWindowMs, resolveCatalogTrackFec), so an adapter that drops a catalog field (fec.reorderToleranceMs, say) fails here instead of in the field. An iso-ssbg1-v1 span that is 0 or absent keeps in-band geometry but supplies no elapsed-time deadline; local receiver retention remains bounded without inventing a catalog span.",
|
|
7
|
+
"interleaveDepth: every row names its D basis. 'access-unit' is what libmmt's receiver and the current publisher run today (D = round(span / (1000/framerate)), multicast-manager FecBlockMapper, fec-manager, block-policy); an adapter must match it to agree with them on block geometry. 'group' is draft-ramadan-moq-fec \u00a75.1/\u00a79 (D over the MoQ group duration); it is the target, not live, and moves only together with the producer contract (BLO-35597). Tick-only groupDurationTicks is authoritative for the group duration."
|
|
8
|
+
],
|
|
9
|
+
"keyframeCadence": [
|
|
10
|
+
{
|
|
11
|
+
"name": "interval ticks win over every ms field",
|
|
12
|
+
"rendition": {
|
|
13
|
+
"timescale": 90000,
|
|
14
|
+
"keyframeIntervalTicks": 180000,
|
|
15
|
+
"keyframeIntervalMs": 1000,
|
|
16
|
+
"gopDurationMs": 500
|
|
17
|
+
},
|
|
18
|
+
"expect": 2000
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "ticks without a timescale fall through to ms",
|
|
22
|
+
"rendition": {
|
|
23
|
+
"keyframeIntervalTicks": 180000,
|
|
24
|
+
"keyframeIntervalMs": 1000
|
|
25
|
+
},
|
|
26
|
+
"expect": 1000
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "keyframe duration before GOP duration",
|
|
30
|
+
"rendition": {
|
|
31
|
+
"keyframeDurationMs": 1500,
|
|
32
|
+
"gopDurationMs": 500
|
|
33
|
+
},
|
|
34
|
+
"expect": 1500
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "GOP ticks",
|
|
38
|
+
"rendition": {
|
|
39
|
+
"timescale": 1000,
|
|
40
|
+
"gopDurationTicks": 2002
|
|
41
|
+
},
|
|
42
|
+
"expect": 2002
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "a group duration is not a keyframe cadence",
|
|
46
|
+
"rendition": {
|
|
47
|
+
"timescale": 90000,
|
|
48
|
+
"groupDurationTicks": 90000,
|
|
49
|
+
"groupDurationMs": 1000
|
|
50
|
+
},
|
|
51
|
+
"expect": null
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "non-positive values are not stated",
|
|
55
|
+
"rendition": {
|
|
56
|
+
"keyframeIntervalMs": 0,
|
|
57
|
+
"gopDurationMs": -1
|
|
58
|
+
},
|
|
59
|
+
"expect": null
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"mediaUnitsPerSecond": [
|
|
63
|
+
{
|
|
64
|
+
"name": "video framerate",
|
|
65
|
+
"type": "video",
|
|
66
|
+
"rendition": {
|
|
67
|
+
"framerate": 30,
|
|
68
|
+
"timescale": 90000
|
|
69
|
+
},
|
|
70
|
+
"expect": 30
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "video never reads its timescale",
|
|
74
|
+
"type": "video",
|
|
75
|
+
"rendition": {
|
|
76
|
+
"timescale": 90000
|
|
77
|
+
},
|
|
78
|
+
"expect": null
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "audio endpoint rate first",
|
|
82
|
+
"type": "audio",
|
|
83
|
+
"rendition": {
|
|
84
|
+
"sampleRate": 44100
|
|
85
|
+
},
|
|
86
|
+
"endpointSampleRate": 48000,
|
|
87
|
+
"expect": 46.875
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "audio catalog sampleRate",
|
|
91
|
+
"type": "audio",
|
|
92
|
+
"rendition": {
|
|
93
|
+
"sampleRate": 44100,
|
|
94
|
+
"timescale": 48000
|
|
95
|
+
},
|
|
96
|
+
"expect": 43.06640625
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "audio MP4-shaped timescale",
|
|
100
|
+
"type": "audio",
|
|
101
|
+
"rendition": {
|
|
102
|
+
"timescale": 48000
|
|
103
|
+
},
|
|
104
|
+
"expect": 46.875
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"name": "a declared but unusable rate is not replaced",
|
|
108
|
+
"type": "audio",
|
|
109
|
+
"rendition": {
|
|
110
|
+
"sampleRate": 0,
|
|
111
|
+
"timescale": 48000
|
|
112
|
+
},
|
|
113
|
+
"expect": null
|
|
114
|
+
}
|
|
115
|
+
],
|
|
116
|
+
"deliveryWindow": [
|
|
117
|
+
{
|
|
118
|
+
"name": "span plus the signaled reorder tolerance",
|
|
119
|
+
"fec": {
|
|
120
|
+
"interleaveDepthMs": 133,
|
|
121
|
+
"sourceSymbols": 32,
|
|
122
|
+
"reorderToleranceMs": 40
|
|
123
|
+
},
|
|
124
|
+
"expect": 173
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "fractional sum rounds up",
|
|
128
|
+
"fec": {
|
|
129
|
+
"interleaveDepthMs": 66.7,
|
|
130
|
+
"sourceSymbols": 8,
|
|
131
|
+
"reorderToleranceMs": 10.1
|
|
132
|
+
},
|
|
133
|
+
"expect": 77
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"name": "a declared 0 tolerance adds nothing",
|
|
137
|
+
"fec": {
|
|
138
|
+
"interleaveDepthMs": 100,
|
|
139
|
+
"sourceSymbols": 8,
|
|
140
|
+
"reorderToleranceMs": 0
|
|
141
|
+
},
|
|
142
|
+
"expect": 100
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "absent tolerance stays absent",
|
|
146
|
+
"fec": {
|
|
147
|
+
"interleaveDepthMs": 100.2,
|
|
148
|
+
"sourceSymbols": 8
|
|
149
|
+
},
|
|
150
|
+
"expect": 101
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"name": "K and P never widen the span",
|
|
154
|
+
"fec": {
|
|
155
|
+
"interleaveDepthMs": 100,
|
|
156
|
+
"sourceSymbols": 512,
|
|
157
|
+
"repairSymbols": 512,
|
|
158
|
+
"reorderToleranceMs": 20
|
|
159
|
+
},
|
|
160
|
+
"expect": 120
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"name": "no span fails closed",
|
|
164
|
+
"fec": {
|
|
165
|
+
"sourceSymbols": 8,
|
|
166
|
+
"reorderToleranceMs": 20
|
|
167
|
+
},
|
|
168
|
+
"expect": "throws"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"name": "no K fails closed",
|
|
172
|
+
"fec": {
|
|
173
|
+
"interleaveDepthMs": 100,
|
|
174
|
+
"reorderToleranceMs": 20
|
|
175
|
+
},
|
|
176
|
+
"expect": "throws"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "negative tolerance fails closed",
|
|
180
|
+
"fec": {
|
|
181
|
+
"interleaveDepthMs": 100,
|
|
182
|
+
"sourceSymbols": 8,
|
|
183
|
+
"reorderToleranceMs": -1
|
|
184
|
+
},
|
|
185
|
+
"expect": "throws"
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
"groupDuration": [
|
|
189
|
+
{
|
|
190
|
+
"name": "tick-only group duration is authoritative",
|
|
191
|
+
"rendition": {
|
|
192
|
+
"timescale": 90000,
|
|
193
|
+
"groupDurationTicks": 90000
|
|
194
|
+
},
|
|
195
|
+
"expect": 1000
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"name": "ticks win over a disagreeing ms field",
|
|
199
|
+
"rendition": {
|
|
200
|
+
"timescale": 90000,
|
|
201
|
+
"groupDurationTicks": 180000,
|
|
202
|
+
"groupDurationMs": 1000
|
|
203
|
+
},
|
|
204
|
+
"expect": 2000
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"name": "ms-only group duration",
|
|
208
|
+
"rendition": {
|
|
209
|
+
"groupDurationMs": 1001
|
|
210
|
+
},
|
|
211
|
+
"expect": 1001
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"name": "ticks without a timescale fall through to ms",
|
|
215
|
+
"rendition": {
|
|
216
|
+
"groupDurationTicks": 90000,
|
|
217
|
+
"groupDurationMs": 1000
|
|
218
|
+
},
|
|
219
|
+
"expect": 1000
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"name": "nothing stated",
|
|
223
|
+
"rendition": {
|
|
224
|
+
"timescale": 90000
|
|
225
|
+
},
|
|
226
|
+
"expect": null
|
|
227
|
+
}
|
|
228
|
+
],
|
|
229
|
+
"interleaveDepth": [
|
|
230
|
+
{
|
|
231
|
+
"name": "live basis: 30 fps access units, span 4000 ms -> D=120",
|
|
232
|
+
"basis": "access-unit",
|
|
233
|
+
"interleaveDepthMs": 4000,
|
|
234
|
+
"framerate": 30,
|
|
235
|
+
"expect": 120
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"name": "draft basis: same stream over the 1000 ms group -> D=4 (target, BLO-35597)",
|
|
239
|
+
"basis": "group",
|
|
240
|
+
"interleaveDepthMs": 4000,
|
|
241
|
+
"groupDurationMs": 1000,
|
|
242
|
+
"expect": 4
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"name": "NTSC group is exact (4004/1001 = 4)",
|
|
246
|
+
"basis": "group",
|
|
247
|
+
"interleaveDepthMs": 4004,
|
|
248
|
+
"groupDurationMs": 1001,
|
|
249
|
+
"expect": 4
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"name": "exact half rounds up",
|
|
253
|
+
"basis": "group",
|
|
254
|
+
"interleaveDepthMs": 4500,
|
|
255
|
+
"groupDurationMs": 1000,
|
|
256
|
+
"expect": 5
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"name": "just below half rounds down",
|
|
260
|
+
"basis": "group",
|
|
261
|
+
"interleaveDepthMs": 4499,
|
|
262
|
+
"groupDurationMs": 1000,
|
|
263
|
+
"expect": 4
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
"name": "zero span fails closed",
|
|
267
|
+
"basis": "group",
|
|
268
|
+
"interleaveDepthMs": 0,
|
|
269
|
+
"groupDurationMs": 1000,
|
|
270
|
+
"expect": "throws"
|
|
271
|
+
}
|
|
272
|
+
],
|
|
273
|
+
"trackFec": [
|
|
274
|
+
{
|
|
275
|
+
"name": "positive span keeps FEC",
|
|
276
|
+
"fec": {
|
|
277
|
+
"interleaveDepthMs": 4000
|
|
278
|
+
},
|
|
279
|
+
"expect": {
|
|
280
|
+
"interleaveMs": 4000,
|
|
281
|
+
"unavailable": null
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"name": "zero span: in-band FEC stays active without a deadline",
|
|
286
|
+
"fec": {
|
|
287
|
+
"interleaveDepthMs": 0
|
|
288
|
+
},
|
|
289
|
+
"expect": {
|
|
290
|
+
"interleaveMs": 0,
|
|
291
|
+
"unavailable": null
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"name": "absent span: in-band FEC stays active without a default",
|
|
296
|
+
"fec": {},
|
|
297
|
+
"expect": {
|
|
298
|
+
"interleaveMs": 0,
|
|
299
|
+
"unavailable": null
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"name": "one millisecond is a valid positive span",
|
|
304
|
+
"fec": {
|
|
305
|
+
"interleaveDepthMs": 1
|
|
306
|
+
},
|
|
307
|
+
"expect": {
|
|
308
|
+
"interleaveMs": 1,
|
|
309
|
+
"unavailable": null
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"name": "negative span fails closed",
|
|
314
|
+
"fec": {
|
|
315
|
+
"interleaveDepthMs": -1
|
|
316
|
+
},
|
|
317
|
+
"expect": {
|
|
318
|
+
"interleaveMs": 0,
|
|
319
|
+
"unavailable": "track_fec"
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"name": "fractional span fails closed",
|
|
324
|
+
"fec": {
|
|
325
|
+
"interleaveDepthMs": 1.5
|
|
326
|
+
},
|
|
327
|
+
"expect": {
|
|
328
|
+
"interleaveMs": 0,
|
|
329
|
+
"unavailable": "track_fec"
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"name": "absent reorder tolerance stays absent",
|
|
334
|
+
"fec": {
|
|
335
|
+
"interleaveDepthMs": 4000
|
|
336
|
+
},
|
|
337
|
+
"expect": {
|
|
338
|
+
"interleaveMs": 4000,
|
|
339
|
+
"unavailable": null,
|
|
340
|
+
"reorderToleranceMs": null
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"name": "explicit zero reorder tolerance is kept",
|
|
345
|
+
"fec": {
|
|
346
|
+
"interleaveDepthMs": 4000,
|
|
347
|
+
"reorderToleranceMs": 0
|
|
348
|
+
},
|
|
349
|
+
"expect": {
|
|
350
|
+
"interleaveMs": 4000,
|
|
351
|
+
"unavailable": null,
|
|
352
|
+
"reorderToleranceMs": 0
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
]
|
|
356
|
+
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"groupDurationTicks": 360000,
|
|
22
22
|
"fec": {
|
|
23
23
|
"algorithm": "raptorq",
|
|
24
|
-
"blockProfile": "
|
|
24
|
+
"blockProfile": "iso-ssbg1-v1",
|
|
25
25
|
"sourceSymbols": 32,
|
|
26
26
|
"repairSymbols": 8,
|
|
27
27
|
"symbolSize": 1320,
|
|
@@ -182,7 +182,7 @@
|
|
|
182
182
|
"groupDurationMs": 4000,
|
|
183
183
|
"fec": {
|
|
184
184
|
"algorithm": "raptorq",
|
|
185
|
-
"blockProfile": "
|
|
185
|
+
"blockProfile": "iso-ssbg1-v1",
|
|
186
186
|
"sourceSymbols": 32
|
|
187
187
|
}
|
|
188
188
|
}
|
|
@@ -247,7 +247,7 @@
|
|
|
247
247
|
{
|
|
248
248
|
"name": "unknown FEC block profile",
|
|
249
249
|
"valid": false,
|
|
250
|
-
"error_code": "
|
|
250
|
+
"error_code": "track_fec_block_profile_unimplemented",
|
|
251
251
|
"catalog": {
|
|
252
252
|
"version": 1,
|
|
253
253
|
"tracks": [
|
|
@@ -279,6 +279,41 @@
|
|
|
279
279
|
]
|
|
280
280
|
}
|
|
281
281
|
},
|
|
282
|
+
{
|
|
283
|
+
"name": "retired k-padded-v1 block profile",
|
|
284
|
+
"valid": false,
|
|
285
|
+
"error_code": "track_fec_block_profile_unimplemented",
|
|
286
|
+
"catalog": {
|
|
287
|
+
"version": 1,
|
|
288
|
+
"tracks": [
|
|
289
|
+
{
|
|
290
|
+
"name": "video",
|
|
291
|
+
"packaging": "mmtp",
|
|
292
|
+
"isLive": true,
|
|
293
|
+
"codec": "avc1.640028",
|
|
294
|
+
"mmtpMode": "mfu",
|
|
295
|
+
"timescale": 90000,
|
|
296
|
+
"groupDurationMs": 4000,
|
|
297
|
+
"groupDurationTicks": 360000,
|
|
298
|
+
"fec": {
|
|
299
|
+
"algorithm": "raptorq",
|
|
300
|
+
"blockProfile": "k-padded-v1",
|
|
301
|
+
"sourceSymbols": 32,
|
|
302
|
+
"repairSymbols": 8,
|
|
303
|
+
"symbolSize": 1320,
|
|
304
|
+
"interleaveDepthMs": 133,
|
|
305
|
+
"repairTrack": "video/repair"
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"name": "video/repair",
|
|
310
|
+
"packaging": "fec-repair",
|
|
311
|
+
"isLive": true,
|
|
312
|
+
"priority": 240
|
|
313
|
+
}
|
|
314
|
+
]
|
|
315
|
+
}
|
|
316
|
+
},
|
|
282
317
|
{
|
|
283
318
|
"name": "ISO ssbg_mode1 block profile",
|
|
284
319
|
"valid": true,
|
|
@@ -316,7 +351,7 @@
|
|
|
316
351
|
{
|
|
317
352
|
"name": "disabled FEC with an unknown block profile",
|
|
318
353
|
"valid": false,
|
|
319
|
-
"error_code": "
|
|
354
|
+
"error_code": "track_fec_block_profile_unimplemented",
|
|
320
355
|
"catalog": {
|
|
321
356
|
"version": 1,
|
|
322
357
|
"tracks": [
|
|
@@ -435,7 +470,7 @@
|
|
|
435
470
|
"groupDurationMs": 1000,
|
|
436
471
|
"fec": {
|
|
437
472
|
"algorithm": "raptorq",
|
|
438
|
-
"blockProfile": "
|
|
473
|
+
"blockProfile": "iso-ssbg1-v1",
|
|
439
474
|
"sourceSymbols": 32,
|
|
440
475
|
"repairSymbols": 8,
|
|
441
476
|
"symbolSize": 1320,
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
# @blockcast/fec-worker
|
|
2
|
-
|
|
3
|
-
A Web Worker wrapper around `@blockcast/mmt-fec` that moves the RaptorQ decode off the main thread. The main-thread client posts source and repair symbols to a dedicated worker via `postMessage` with `Transferable` `ArrayBuffer` ownership transfer, so packet payloads cross the thread boundary with **zero copies**. Decoded / FEC-recovered frames travel back the same way. Critical for IWA / web players where main-thread blocking on FEC decode would cause frame drops at the renderer.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pnpm add @blockcast/fec-worker
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
The package is dual-shaped: the main-thread side (`FecWorkerClient`, types) is the default export; the worker entry is exposed as the `./worker` subpath so consumers can hand its URL to `new Worker(...)` (or to the `FecWorkerClient` constructor, which spawns it for you).
|
|
12
|
-
|
|
13
|
-
## Quick start
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import { FecWorkerClient, type FecTrackConfig } from "@blockcast/fec-worker"
|
|
17
|
-
|
|
18
|
-
// Worker URL resolved against your bundler. ?worker / new URL() / import.meta —
|
|
19
|
-
// any pattern that gives you a module-Worker URL works.
|
|
20
|
-
const workerUrl = new URL("./fec-worker-entry.js", import.meta.url)
|
|
21
|
-
|
|
22
|
-
const client = new FecWorkerClient(workerUrl)
|
|
23
|
-
|
|
24
|
-
client.onFrame((data, meta) => {
|
|
25
|
-
// data is an ArrayBuffer transferred from the worker (zero-copy).
|
|
26
|
-
// meta tells you whether this frame was recovered via FEC and (if ALTA is
|
|
27
|
-
// configured) whether its source-packet trailer verified.
|
|
28
|
-
decoder.decode(data) // hand off to WebCodecs / MSE
|
|
29
|
-
})
|
|
30
|
-
client.onSnapshot((stats) => fecPanel.render(stats))
|
|
31
|
-
client.onError((msg) => console.error("[fec]", msg))
|
|
32
|
-
|
|
33
|
-
// Configure with a pre-compiled mmt-wasm Module from your loader's importmap.
|
|
34
|
-
const config: FecTrackConfig = {
|
|
35
|
-
codec: "avc1.64001f",
|
|
36
|
-
trackName: "video/base",
|
|
37
|
-
trackType: "video",
|
|
38
|
-
resolution: { w: 1920, h: 1080 },
|
|
39
|
-
framerate: 30,
|
|
40
|
-
algorithm: "raptor",
|
|
41
|
-
blockProfile: "k-padded-v1", // catalog fec.blockProfile: required, never defaulted
|
|
42
|
-
k: 32, // under "iso-ssbg1-v1", the maximum SSB_length
|
|
43
|
-
repairCount: 8,
|
|
44
|
-
symbolSize: 1312,
|
|
45
|
-
interleaveDepth: 30,
|
|
46
|
-
interleaveMs: 1000, // 30 frames @ 30 fps
|
|
47
|
-
deliveryWindowMs: 2000, // computeFecDeliveryWindowMs(...) from the catalog
|
|
48
|
-
fecMode: "subframe",
|
|
49
|
-
altaEnabled: false,
|
|
50
|
-
relayBlockSigEnabled: false,
|
|
51
|
-
}
|
|
52
|
-
client.configure(config, mmtWasmModule)
|
|
53
|
-
|
|
54
|
-
// Feed packets as they arrive from transport. ArrayBuffers are transferred —
|
|
55
|
-
// caller MUST NOT touch `data` after the call.
|
|
56
|
-
client.feedSource(ssId, packetBuffer, captureTs)
|
|
57
|
-
client.feedRepair(ssStart, ssbLength, rsId, repairBuffer, captureTs)
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
`FecWorkerClient` accepts either a `URL` (it spawns the worker for you with `{ type: "module" }`) or a pre-created `Worker` instance (used in tests for constructor injection).
|
|
61
|
-
|
|
62
|
-
## Why a Worker
|
|
63
|
-
|
|
64
|
-
A 1080p30 stream with `K=32, P=8, symbolSize=1312` produces ~1 RaptorQ source-block decode every second per track. Decode time is amortized across SIMD lanes inside the WASM, but the *worst-case* block — one with the maximum recoverable loss pattern — can spike past 16 ms. Run that on the main thread and you've blown a frame; the renderer drops, the user sees a stutter, and CMCD reports a pacing violation.
|
|
65
|
-
|
|
66
|
-
Pushing the decode into a dedicated Worker keeps the main thread free for input handling, MSE buffer maintenance, and frame pacing. The same module compiled into both contexts decodes identically; what changes is who's blocked when a worst-case block hits.
|
|
67
|
-
|
|
68
|
-
This is the **Worker-per-track FEC pipeline** architectural decision tracked in the parent monorepo as a v2.0 milestone (`pim-multicast-gateway/.planning/MILESTONES.md` — "Worker-per-track FEC pipeline with zero-copy ArrayBuffer transfers"). Each track (base / delta / repair / audio) runs in its own Worker, so a stall on one track's decode never starves the others.
|
|
69
|
-
|
|
70
|
-
## Architecture
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
Main thread │ FEC Worker (per track)
|
|
74
|
-
│
|
|
75
|
-
transport packet │
|
|
76
|
-
│ │
|
|
77
|
-
▼ │
|
|
78
|
-
FecWorkerClient.feedSource(...) │
|
|
79
|
-
│ │
|
|
80
|
-
│ postMessage(cmd, [data, ...]) │
|
|
81
|
-
│ ─ data: ArrayBuffer (transferred, neutered on sender)
|
|
82
|
-
│ ─ wasmModule: WebAssembly.Module (structured-cloned)
|
|
83
|
-
├──────────────────────────────────►│ self.onmessage
|
|
84
|
-
│ │ │
|
|
85
|
-
│ │ ▼
|
|
86
|
-
│ │ WasmFecDecoder.add_source(...)
|
|
87
|
-
│ │ │
|
|
88
|
-
│ │ ▼ (recovered or pass-through)
|
|
89
|
-
│ │ postMessage({type:"frame", data}, [data])
|
|
90
|
-
│◄──────────────────────────────────┤
|
|
91
|
-
│ │
|
|
92
|
-
▼ │
|
|
93
|
-
FecWorkerClient.onFrame(data, meta) │
|
|
94
|
-
│ │
|
|
95
|
-
▼ │
|
|
96
|
-
WebCodecs / MSE │
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Buffers cross the boundary via the `Transferable` list. After `postMessage`, the sender's `ArrayBuffer` is detached — touching it throws. This is the contract that makes zero-copy safe: there is no aliased view that could be mutated mid-decode.
|
|
100
|
-
|
|
101
|
-
`WebAssembly.Module` is structured-cloneable (not transferable) and is *cloned* (cheap — the underlying compiled module is shared across realms). The ALTA public key, on the other hand, is a regular `ArrayBuffer` and *is* transferred.
|
|
102
|
-
|
|
103
|
-
Errors that escape the worker's `try/catch` (in either the sync command path or the async configure path) are emitted as `{type: "error", message}` events rather than thrown — the main thread surfaces them through `onError`.
|
|
104
|
-
|
|
105
|
-
## Message protocol
|
|
106
|
-
|
|
107
|
-
All messages are typed as discriminated unions in `fec-worker-types.ts`. Both the worker and the client import the same definitions, so adding a message variant is a single-file change that the compiler enforces on both sides.
|
|
108
|
-
|
|
109
|
-
### Inbound — `FecWorkerCommand` (main → worker)
|
|
110
|
-
|
|
111
|
-
| `type` | Payload | Transferred |
|
|
112
|
-
|--------|---------|-------------|
|
|
113
|
-
| `configure` | `config: FecTrackConfig`, `wasmModule: WebAssembly.Module`, `altaPublicKey?: ArrayBuffer`, `altaWasmModule?: WebAssembly.Module` | `altaPublicKey` only — WASM modules are structured-cloned |
|
|
114
|
-
| `feedSource` | `ssId: number`, `data: ArrayBuffer`, `ts: number`, optional `altaAuth: ArrayBuffer` + `altaPayloadEnd: number` | `data` and `altaAuth` |
|
|
115
|
-
| `feedRepair` | `ssStart: number`, `ssbLength: number`, `rsId: number`, `data: ArrayBuffer`, `ts: number` | `data` |
|
|
116
|
-
| `relayBlockSig` | `sbn: number`, `sig: ArrayBuffer`, `hash: ArrayBuffer` | `sig`, `hash` |
|
|
117
|
-
| `cleanup` | `sbns: number[]` (all timed-out blocks covered by this coalesced barrier) | none |
|
|
118
|
-
| `subscribeBlockUpdates` | — (send only after `capabilities` lists it) | none |
|
|
119
|
-
| `dispose` | — | none |
|
|
120
|
-
|
|
121
|
-
`feedSource` carries the **flat 32-bit Source Symbol ID** from the MMTP Source FEC Payload ID (ISO 23008-1 §C.5.2). The WASM decoder derives `SBN = floor(ssId / K)` and `ESI = ssId % K` internally — do not pre-compute these.
|
|
122
|
-
|
|
123
|
-
`feedRepair` carries the wire-level Repair FEC Payload ID fields directly (ISO 23008-1 §C.5.3): `ssStart` is the SS_ID of the first source symbol in the block (`SBN * configured K`), `ssbLength` is the authored source-symbol count in `1..configured K`, and `rsId` is the repair index within the block. The decoder's block geometry and repair ESI use the configured K; K is never inferred from repair traffic.
|
|
124
|
-
|
|
125
|
-
### Outbound — `FecWorkerEvent` (worker → main)
|
|
126
|
-
|
|
127
|
-
| `type` | Payload | Transferred back |
|
|
128
|
-
|--------|---------|------------------|
|
|
129
|
-
| `frame` | `data: ArrayBuffer`, `meta: FrameMeta` | `data` |
|
|
130
|
-
| `snapshot` | `stats: FecTrackStats` | none (structured clone) |
|
|
131
|
-
| `capabilities` | `commands: FecWorkerOptionalCommand[]` (after `configure`) | none |
|
|
132
|
-
| `blockUpdate` | `block: FecBlockSnapshot` (only after `subscribeBlockUpdates`) | none |
|
|
133
|
-
| `cleanupComplete` | `sbns: number[]` | none |
|
|
134
|
-
| `error` | `message: string` | none |
|
|
135
|
-
|
|
136
|
-
The Worker posts `blockUpdate` only to a client that sent `subscribeBlockUpdates`: each one is a structured clone and a page-thread task, and the snapshot already counts every transition. `FecWorkerClient` subscribes when `onBlockUpdate` is registered and the Worker has announced the command. A Worker that predates the command posts `blockUpdate` unasked and is never sent it (BLO-36599).
|
|
137
|
-
|
|
138
|
-
`FrameMeta` carries `recovered: boolean` (this frame came out of the FEC decode, not the direct path), `sbn: number`, and `altaVerified: boolean | null` (signature outcome, or `null` when ALTA is not configured / verification is pending).
|
|
139
|
-
|
|
140
|
-
## Lifecycle
|
|
141
|
-
|
|
142
|
-
```
|
|
143
|
-
new FecWorkerClient(url)
|
|
144
|
-
│ worker spawned with { type: "module" }
|
|
145
|
-
▼
|
|
146
|
-
client.configure(config, wasmModule [, altaPublicKey, altaWasmModule])
|
|
147
|
-
│ worker initSyncs WASM, instantiates MmtFecDecoder(interleaveDepth, blockProfile),
|
|
148
|
-
│ refuses a decoder whose get_block_profile() differs,
|
|
149
|
-
│ immediately configures exact catalog K/T (no decoder defaults),
|
|
150
|
-
│ derives pendingVerifyCap = ceil(D × 1.5) and TTL = ceil(K × interleaveMs × 1.5)
|
|
151
|
-
│ from catalog values, throws if any of K / D / interleaveMs ≤ 0,
|
|
152
|
-
│ starts the 200 ms snapshot timer, emits initial snapshot
|
|
153
|
-
▼
|
|
154
|
-
client.feedSource(...) / feedRepair(...) ◄── steady state
|
|
155
|
-
│ every transferred ArrayBuffer detaches on the main thread
|
|
156
|
-
│ decoded / recovered frames flow back as {type:"frame"}
|
|
157
|
-
│ every 200 ms a {type:"snapshot"} carries FecTrackStats
|
|
158
|
-
▼
|
|
159
|
-
client.cleanup(sbn) ◄── per-block inactivity deadline
|
|
160
|
-
│ coalesces queued SBNs behind one worker queue-drain barrier
|
|
161
|
-
│ evicts blocks relative to max(sbns) − D × 3
|
|
162
|
-
│ retires exactly those SBNs via WASM cleanup_blocks_detailed(); a lost
|
|
163
|
-
│ block is never answered with a synthesised frame (sinks hold the last
|
|
164
|
-
│ good frame, per @blockcast/mmt-container conceal-timeline)
|
|
165
|
-
│ acknowledges every SBN in {type:"cleanupComplete", sbns}
|
|
166
|
-
│ any block still in "collecting" at eviction time is counted as failed
|
|
167
|
-
▼
|
|
168
|
-
client.dispose()
|
|
169
|
-
sends {type:"dispose"}, terminates worker. WASM decoder and ALTA
|
|
170
|
-
verifier are explicitly free()'d before terminate so their linear
|
|
171
|
-
memory is released (FinalizationRegistry would not run between
|
|
172
|
-
dispose and terminate). Idempotent.
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Backpressure
|
|
176
|
-
|
|
177
|
-
`postMessage` is fire-and-forget at the JS level — there is no built-in flow control. If the main thread can't drain `frame` events fast enough, the worker's outbound queue grows. The remedy is upstream of this package: pace your input (`feedSource` / `feedRepair`) against actual decode capacity by watching the `avgRecoveryMs` / `maxRecoveryMs` fields of each `snapshot`. Spikes in `maxRecoveryMs` past your frame budget are the early signal.
|
|
178
|
-
|
|
179
|
-
## Stats
|
|
180
|
-
|
|
181
|
-
The `snapshot` event delivers a `FecTrackStats` every 200 ms (catalog-derived; not configurable from this layer). Key fields:
|
|
182
|
-
|
|
183
|
-
| Field | Meaning |
|
|
184
|
-
|-------|---------|
|
|
185
|
-
| `sourceSymbols`, `repairSymbols` | Raw ingress counters |
|
|
186
|
-
| `blocksComplete` | Block had all K source symbols without needing repair |
|
|
187
|
-
| `blocksRecovered` | Block was recovered using ≥1 repair symbol |
|
|
188
|
-
| `blocksFailed` | Block aged out before reaching K |
|
|
189
|
-
| `recoveryRate` | `recovered / (recovered + failed)`, 0–100 |
|
|
190
|
-
| `avgRecoveryMs`, `maxRecoveryMs` | Rolling decode latency (capped at 1000 samples) |
|
|
191
|
-
| `liveSbn` | Highest source-block number observed |
|
|
192
|
-
| `repairSymbolSizeMismatch` | Repair symbols rejected before WASM because their byte length did not match `T` |
|
|
193
|
-
| `sourceDroppedRetired` / `sourceDroppedTerminal` / `sourceDroppedDuplicate` | Source symbols dropped before WASM, by **first matching** cause (see below) |
|
|
194
|
-
| `blocks` | Up to `max(D × 3, 24)` recent `FecBlockSnapshot`s for live visualization |
|
|
195
|
-
| `interleaveWindowBlocks` | `D` from config |
|
|
196
|
-
|
|
197
|
-
The three `sourceDropped*` counters split by cause for the same reason the ALTA four-way split exists — so a dashboard can tell the failure modes apart. They are tested in a fixed order, each returning early — `Retired` → `Terminal` → `Duplicate` — so a symbol counts once, under the **first** cause that matches: a symbol that is both past retention and a repeat counts only as `Retired`, and `Terminal` absorbs every post-settle duplicate. A block that settles at K-1 source symbols (BLO-35597 defect 2) is explained by a late symbol past retention (`Retired`), a symbol for a block that had already settled — complete, recovered **or failed** (`Terminal`), or a repeated `(SBN, ESI)` (`Duplicate`). `Retired` and `Terminal` narrow the cause; they do not attribute it. `Duplicate` does: it cannot fire once a block settles — the `Terminal` check returns first, and `markBlockTerminal` retires the block's accepted-ESI set anyway — so a non-zero `Duplicate` is positive evidence that a repeated `(SBN, ESI)` reached the worker while the block was **still collecting** — usually a duplicate packet on the wire, sometimes an SBN/ESI derivation collision. It attributes the **timing**, not the origin. A symbol lost in transit never reaches the worker and increments nothing, so **all three reading zero is not evidence of a publisher defect** — wire loss produces an identical shape. Separate those with `FecBlockSnapshot.ssbLength`: below `k` is a genuinely short authored block, equal to `k` with fewer accepted is loss-or-late, undefined (no repair symbol yet) leaves both open. All three are cumulative across decoder epochs, so they stay comparable against the `sourceSymbols` denominator; only a reset zeroes them.
|
|
198
|
-
|
|
199
|
-
When ALTA is enabled, the snapshot also carries the four-state verification accounting — `altaVerified` (crypto passed), `altaFailed` (tamper-confirmed), `altaPending` (unverifiable, e.g. missing trailer / late-joiner anchor gap), `altaError` (verifier threw — infrastructure flake, not tamper) — plus `altaInitFailed` (true if the ALTA WASM didn't initialize), `altaPendingEvictedCap` / `altaPendingEvictedTtl` (deferred-queue eviction reasons), and a bounded `altaFailedDetails[]` ring with the last ≤16 tamper events. The four-way split exists so ops alerting can distinguish a network problem (`altaPending` rising) from an attack (`altaFailed` rising) from a runtime bug (`altaError` rising).
|
|
200
|
-
|
|
201
|
-
`FecTrackStats` is also the shape consumed downstream by `@blockcast/mmt-container`'s `CmcdProducer` and the diagnostics `fec-panel` — keep it stable when you extend it.
|
|
202
|
-
|
|
203
|
-
## Related packages
|
|
204
|
-
|
|
205
|
-
- **`@blockcast/mmt-fec`** — the wrapped library. Container-agnostic RaptorQ decoder + block manager + reorder buffer. Lives on the main thread when you don't need a Worker; this package is the off-thread variant of the same decoder.
|
|
206
|
-
- **`@blockcast/mmt-container`** — the consumer that wires this Worker into the data path. `FecManager` instantiates one `FecWorkerClient` per track, routes MMTP source/repair payloads in, and pumps recovered frames into the MFU reassembler / fmp4 segmenter.
|
|
207
|
-
- **`@blockcast/mmt-alta-parse`** — ALTA trailer extraction. Used inside the Worker to parse the `[0xF0A1][len][auth]` trailer off recovered source symbols (publisher-stripped trailers don't appear on direct-source packets, which carry the trailer in band).
|
|
208
|
-
|
|
209
|
-
## Testing
|
|
210
|
-
|
|
211
|
-
```bash
|
|
212
|
-
pnpm test # vitest run
|
|
213
|
-
pnpm test:watch # vitest in watch mode
|
|
214
|
-
pnpm typecheck # tsc --noEmit
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
Tests cover:
|
|
218
|
-
- The message-protocol type narrowing (`fec-worker-types.test.ts`)
|
|
219
|
-
- The main-thread client's transfer-list construction, callback dispatch, and dispose idempotence (`fec-worker-client.test.ts`) — the Worker is injected via constructor as a stub so the tests don't need a real WASM build
|
|
220
|
-
|
|
221
|
-
## License
|
|
222
|
-
|
|
223
|
-
Apache-2.0 — see `LICENSE`.
|
|
File without changes
|