@blockcast/mmt-container 0.3.0 → 0.4.0-main.71d61b2a53f2
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 +33 -16
- package/dist/browser-runtime.js +14743 -14412
- package/dist/browser-runtime.js.map +4 -4
- package/dist/carp-catalog.d.ts +24 -19
- package/dist/carp-catalog.d.ts.map +1 -1
- package/dist/carp-catalog.js +29 -14
- package/dist/carp-catalog.js.map +4 -4
- 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 +60 -23
- package/dist/catalog-fec-params.js.map +4 -4
- package/dist/catalog-network-source.js +1 -7
- package/dist/catalog-network-source.js.map +4 -4
- 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/cmcd-producer.d.ts.map +1 -1
- package/dist/cmcd-producer.js +0 -4
- package/dist/cmcd-producer.js.map +2 -2
- package/dist/delivery-catalog.d.ts +124 -0
- package/dist/delivery-catalog.d.ts.map +1 -0
- package/dist/delivery-catalog.js +1857 -0
- package/dist/delivery-catalog.js.map +7 -0
- 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 +36 -30
- package/dist/fec-manager.d.ts.map +1 -1
- package/dist/fec-manager.js +303 -293
- package/dist/fec-manager.js.map +4 -4
- package/dist/fec-state.d.ts +19 -31
- package/dist/fec-state.d.ts.map +1 -1
- package/dist/fec-state.js +4 -10
- package/dist/fec-state.js.map +4 -4
- package/dist/fec-worker-setup.d.ts +18 -14
- package/dist/fec-worker-setup.d.ts.map +1 -1
- package/dist/fec-worker-setup.js +81 -96
- package/dist/fec-worker-setup.js.map +4 -4
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -0
- package/dist/index.js.map +2 -2
- package/dist/iso-block-locator.js +1 -7
- package/dist/iso-block-locator.js.map +4 -4
- 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 +24 -30
- package/dist/mfu-reassembler.js.map +4 -4
- package/dist/mmtp-container-parser.d.ts +6 -11
- package/dist/mmtp-container-parser.d.ts.map +1 -1
- package/dist/mmtp-container-parser.js +56 -97
- package/dist/mmtp-container-parser.js.map +4 -4
- package/dist/mmtp-container-parser.no-modules.js +78 -105
- package/dist/mmtp-container-parser.no-modules.js.map +4 -4
- package/dist/mmtp-decode-pipeline.js +56 -97
- package/dist/mmtp-decode-pipeline.js.map +4 -4
- package/dist/mmtp-router.d.ts +37 -26
- package/dist/mmtp-router.d.ts.map +1 -1
- package/dist/mmtp-router.js +162 -313
- package/dist/mmtp-router.js.map +4 -4
- package/dist/multicast-input.js +1 -7
- package/dist/multicast-input.js.map +4 -4
- package/dist/multicast-manager.d.ts +34 -6
- package/dist/multicast-manager.d.ts.map +1 -1
- package/dist/multicast-manager.js +709 -658
- 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 +44 -26
- package/dist/multicast-transport.js.map +4 -4
- package/dist/multicast-unwrap.js +29 -35
- package/dist/multicast-unwrap.js.map +4 -4
- package/dist/no-modules.js +77 -104
- package/dist/no-modules.js.map +4 -4
- package/dist/repair-fetch.d.ts +30 -19
- package/dist/repair-fetch.d.ts.map +1 -1
- package/dist/repair-fetch.js +33 -24
- package/dist/repair-fetch.js.map +4 -4
- package/dist/repair-layers.d.ts +18 -7
- package/dist/repair-layers.d.ts.map +1 -1
- package/dist/repair-layers.js +12 -10
- package/dist/repair-layers.js.map +4 -4
- package/dist/signaling.js +2 -11
- package/dist/signaling.js.map +4 -4
- package/dist/timestamp-codec.js +24 -30
- package/dist/timestamp-codec.js.map +4 -4
- 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 +1 -7
- package/dist/wasm-mfu-reassembler.js.map +4 -4
- package/dist/wasm-mmtp-container-parser.js +56 -97
- package/dist/wasm-mmtp-container-parser.js.map +4 -4
- package/package.json +7 -14
- package/schemas/catalog.schema.json +3 -3
- package/src/carp-catalog.ts +46 -24
- package/src/catalog-fec-params.ts +173 -64
- package/src/cmaf-block-assembler.ts +1 -4
- package/src/cmcd-producer.ts +0 -6
- package/src/delivery-catalog.ts +498 -0
- package/src/delta-fallback-config.ts +72 -0
- package/src/fec-manager.ts +414 -334
- package/src/fec-state.ts +20 -32
- package/src/fec-worker-setup.ts +109 -90
- package/src/index.ts +32 -0
- package/src/media-router.ts +59 -21
- package/src/mmtp-container-parser.ts +27 -18
- package/src/mmtp-router.ts +146 -313
- package/src/multicast-manager.ts +184 -83
- 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 +37 -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-endpoint-relay-address.json +39 -0
- 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-amt-manual-relay.json +38 -0
- 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/test-vectors/delivery-catalog/README.md +11 -0
- package/test-vectors/delivery-catalog/negative/missing-block-profile.json +58 -0
- package/test-vectors/delivery-catalog/negative/packet-id-signaling.json +59 -0
- package/test-vectors/delivery-catalog/negative/retired-k-padded-block-profile.json +59 -0
- package/test-vectors/delivery-catalog/positive/dash.json +56 -0
- package/test-vectors/delivery-catalog/positive/mmtp-source-only.json +43 -0
- 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
package/dist/fec-manager.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
// src/track-session.ts
|
|
2
2
|
import { fecBlockBudgetMs } from "@blockcast/mmt-fec";
|
|
3
3
|
function computeFecDeliveryWindowMs(config) {
|
|
4
|
-
const fecInterleaveMs = config.interleaveDepthMs;
|
|
5
4
|
const fecK = config.sourceSymbols;
|
|
6
|
-
if (!Number.isFinite(
|
|
5
|
+
if (!Number.isFinite(fecK) || fecK <= 0) {
|
|
7
6
|
throw new Error(
|
|
8
|
-
`[TrackSession]
|
|
7
|
+
`[TrackSession] fecK=${fecK}. Derive a positive FEC source-symbol count from the stream catalog.`
|
|
9
8
|
);
|
|
10
9
|
}
|
|
11
|
-
|
|
10
|
+
return fecSpanDeliveryWindowMs(config.interleaveDepthMs, config.jitterBufferMs);
|
|
11
|
+
}
|
|
12
|
+
function fecSpanDeliveryWindowMs(interleaveDepthMs, jitterBufferMs) {
|
|
13
|
+
if (!Number.isFinite(interleaveDepthMs) || interleaveDepthMs <= 0) {
|
|
12
14
|
throw new Error(
|
|
13
|
-
`[TrackSession]
|
|
15
|
+
`[TrackSession] fecInterleaveMs=${interleaveDepthMs}. Derive a positive FEC interleave window from the stream catalog.`
|
|
14
16
|
);
|
|
15
17
|
}
|
|
16
|
-
if (
|
|
17
|
-
return fecBlockBudgetMs(
|
|
18
|
+
if (jitterBufferMs === void 0) return Math.ceil(interleaveDepthMs);
|
|
19
|
+
return fecBlockBudgetMs(interleaveDepthMs, jitterBufferMs);
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
// src/delivery-gap.ts
|
|
@@ -106,19 +108,16 @@ var DeliveryGapEstimator = class {
|
|
|
106
108
|
import {
|
|
107
109
|
deriveFecInterleaveDepth as deriveFecInterleaveDepth2,
|
|
108
110
|
deriveFecRetentionBlocks,
|
|
109
|
-
tryDeriveFecRetentionBlocks
|
|
111
|
+
tryDeriveFecRetentionBlocks,
|
|
112
|
+
LOCAL_FEC_RETENTION_BLOCKS,
|
|
113
|
+
LOCAL_FEC_TIMEOUT_MS
|
|
110
114
|
} from "@blockcast/mmt-fec";
|
|
111
115
|
|
|
112
|
-
// ../mmt-
|
|
116
|
+
// ../mmt-base/dist/mmtp.js
|
|
113
117
|
var MPU_HEADER_SIZE = 8;
|
|
114
118
|
var MPU_LENGTH_FIELD_SIZE = 2;
|
|
115
119
|
var MPU_HEADER_REMAINDER_SIZE = MPU_HEADER_SIZE - MPU_LENGTH_FIELD_SIZE;
|
|
116
120
|
|
|
117
|
-
// ../mmt-base/dist/mmtp.js
|
|
118
|
-
var MPU_HEADER_SIZE2 = 8;
|
|
119
|
-
var MPU_LENGTH_FIELD_SIZE2 = 2;
|
|
120
|
-
var MPU_HEADER_REMAINDER_SIZE2 = MPU_HEADER_SIZE2 - MPU_LENGTH_FIELD_SIZE2;
|
|
121
|
-
|
|
122
121
|
// ../mmt-base/dist/ntp-short.js
|
|
123
122
|
var NTP_SHORT_BITS = 32;
|
|
124
123
|
var NTP_SHORT_MODULUS = 2 ** NTP_SHORT_BITS;
|
|
@@ -146,49 +145,21 @@ function serial32Precedes(a, b) {
|
|
|
146
145
|
const distance = serial32Distance(a, b);
|
|
147
146
|
return distance !== 0 && distance < SERIAL32_HALF;
|
|
148
147
|
}
|
|
149
|
-
function kStrideBlockStart(sbn, k) {
|
|
150
|
-
assertUint32(sbn, "sbn");
|
|
151
|
-
if (!Number.isInteger(k) || k < 1 || k >= SERIAL32_HALF) {
|
|
152
|
-
throw new RangeError(`k must be a positive integer below 2^31 (got ${k})`);
|
|
153
|
-
}
|
|
154
|
-
const high = Math.floor(sbn / 65536);
|
|
155
|
-
const low = sbn % 65536;
|
|
156
|
-
return (high * k % SERIAL32_SPAN * 65536 + low * k) % SERIAL32_SPAN;
|
|
157
|
-
}
|
|
158
|
-
function kStrideBlockPrecedes(a, b, k) {
|
|
159
|
-
return serial32Precedes(kStrideBlockStart(a, k), kStrideBlockStart(b, k));
|
|
160
|
-
}
|
|
161
|
-
function kStrideBlocksBehind(a, b, k) {
|
|
162
|
-
const from = kStrideBlockStart(a, k);
|
|
163
|
-
const to = kStrideBlockStart(b, k);
|
|
164
|
-
if (!serial32Precedes(from, to))
|
|
165
|
-
return 0;
|
|
166
|
-
return Math.ceil(serial32Distance(from, to) / k);
|
|
167
|
-
}
|
|
168
|
-
function isKStrideBlock(sbn, k) {
|
|
169
|
-
return Number.isInteger(sbn) && sbn >= 0 && sbn < SERIAL32_SPAN && Number.isInteger(k) && k >= 1 && k < SERIAL32_HALF;
|
|
170
|
-
}
|
|
171
|
-
function kStrideNextBlock(sbn, k) {
|
|
172
|
-
assertUint32(sbn, "sbn");
|
|
173
|
-
kStrideBlockStart(sbn, k);
|
|
174
|
-
return (sbn + 1) * k >= SERIAL32_SPAN ? 0 : sbn + 1;
|
|
175
|
-
}
|
|
176
148
|
|
|
177
149
|
// ../mmt-base/dist/fec-block-profile.js
|
|
178
150
|
var FEC_BLOCK_PROFILES = Object.freeze([
|
|
179
|
-
"k-padded-v1",
|
|
180
151
|
"iso-ssbg1-v1"
|
|
181
152
|
]);
|
|
182
153
|
function isFecBlockProfile(value) {
|
|
183
|
-
return value === "
|
|
154
|
+
return value === "iso-ssbg1-v1";
|
|
184
155
|
}
|
|
185
156
|
function parseFecBlockProfile(value, where) {
|
|
186
157
|
if (isFecBlockProfile(value))
|
|
187
158
|
return value;
|
|
188
159
|
if (value === void 0) {
|
|
189
|
-
throw new Error(`${where} is required: name the FEC block profile ("
|
|
160
|
+
throw new Error(`${where} is required: name the FEC block profile ("iso-ssbg1-v1")`);
|
|
190
161
|
}
|
|
191
|
-
throw new Error(`${where} must be "
|
|
162
|
+
throw new Error(`${where} must be "iso-ssbg1-v1" (got ${JSON.stringify(value)})`);
|
|
192
163
|
}
|
|
193
164
|
var SSBG1_LENGTH_FIELD_BYTES = 2;
|
|
194
165
|
function ssbg1MaxPacketLength(symbolSize) {
|
|
@@ -441,7 +412,7 @@ var IsoBlockLocator = class _IsoBlockLocator {
|
|
|
441
412
|
};
|
|
442
413
|
|
|
443
414
|
// src/fec-state.ts
|
|
444
|
-
var MIN_INTERLEAVE_DEPTH_MS =
|
|
415
|
+
var MIN_INTERLEAVE_DEPTH_MS = 1;
|
|
445
416
|
var FEC_INACTIVE_REASONS = Object.freeze([
|
|
446
417
|
"no-catalog-fec",
|
|
447
418
|
"reliable-moq",
|
|
@@ -836,7 +807,6 @@ var FECManager = class _FECManager {
|
|
|
836
807
|
constructor() {
|
|
837
808
|
// Per-track WASM RaptorQ decoders, keyed by physical stream identity.
|
|
838
809
|
this.#fecDecoders = /* @__PURE__ */ new Map();
|
|
839
|
-
/** @deprecated Use setFecDecoder(packetId, ...). Backwards-compat shim. */
|
|
840
810
|
// Per-track Worker-backed FEC decoders, keyed by physical stream identity.
|
|
841
811
|
// Worker-backed tracks use async decode — recovered frames arrive via onFrame callback,
|
|
842
812
|
// not synchronous return from feedSourceSymbol/feedRepairSymbol.
|
|
@@ -851,10 +821,9 @@ var FECManager = class _FECManager {
|
|
|
851
821
|
// source/repair symbols do not split across two RaptorQ states.
|
|
852
822
|
this.#syncDecoderBlockOwners = /* @__PURE__ */ new Map();
|
|
853
823
|
this.#decoderBlockOwners = /* @__PURE__ */ new WeakMap();
|
|
854
|
-
this.#fecK = 4;
|
|
855
824
|
this.#fecSymbolSize = 0;
|
|
856
|
-
this.#fecTimeoutMs =
|
|
857
|
-
// default
|
|
825
|
+
this.#fecTimeoutMs = LOCAL_FEC_TIMEOUT_MS;
|
|
826
|
+
// local default; refined by setFramerate() when fps known
|
|
858
827
|
this.#trackConfigs = /* @__PURE__ */ new Map();
|
|
859
828
|
this.#fecStats = newFecCounters();
|
|
860
829
|
this.#fecTrackStats = /* @__PURE__ */ new Map();
|
|
@@ -894,10 +863,10 @@ var FECManager = class _FECManager {
|
|
|
894
863
|
this.#blockSourceEsis = /* @__PURE__ */ new Map();
|
|
895
864
|
// Authored SSB_length per block (ISO/IEC 23008-1 §C.5.3), learned from the
|
|
896
865
|
// first repair symbol. The FFmpeg moq_mmt publisher closes a block every D
|
|
897
|
-
// media units, usually before it holds K symbols
|
|
898
|
-
//
|
|
899
|
-
// SSB_length
|
|
900
|
-
//
|
|
866
|
+
// media units, usually before it holds K symbols; under iso-ssbg1-v1
|
|
867
|
+
// (ssbg_mode1) that block is K' = SSB_length symbols, its repair ESIs start
|
|
868
|
+
// at SSB_length, and K is only the maximum. Such a block is clean at
|
|
869
|
+
// SSB_length source arrivals and recoverable from SSB_length received
|
|
901
870
|
// symbols; waiting for K fails every one of them.
|
|
902
871
|
this.#blockAuthoredLengths = /* @__PURE__ */ new Map();
|
|
903
872
|
this.#ssbLengthConflictCount = 0;
|
|
@@ -1014,14 +983,16 @@ var FECManager = class _FECManager {
|
|
|
1014
983
|
this.#resolvedBlockClasses = /* @__PURE__ */ new Map();
|
|
1015
984
|
// Blocks already reported through onBlockRepaired (once per block).
|
|
1016
985
|
this.#repairedBlocks = /* @__PURE__ */ new Set();
|
|
1017
|
-
// Blocks created
|
|
986
|
+
// Blocks created before any symbol of theirs was tracked: the repair-less
|
|
987
|
+
// spans placeIsoRepair materializes (onBlockVanished).
|
|
1018
988
|
this.#materializedBlocks = /* @__PURE__ */ new Set();
|
|
1019
989
|
// packetIds whose ordered-relay horizon became underivable and fell back to
|
|
1020
990
|
// the datagram deadline. Bounds the warn in #derivableOrderedHorizon to once
|
|
1021
991
|
// per stream. Not only throws: the ordinary out-of-range case is detected by
|
|
1022
992
|
// arithmetic and never throws at all.
|
|
1023
993
|
this.#orderedHorizonWarnedFor = /* @__PURE__ */ new Set();
|
|
1024
|
-
//
|
|
994
|
+
// Newest block start (SS_Start) seen per stream and when: the frontier for
|
|
995
|
+
// source-discontinuity detection and isoSpanResolution.
|
|
1025
996
|
this.#highestSbn = /* @__PURE__ */ new Map();
|
|
1026
997
|
// iso-ssbg1-v1 block location per stream (streamKey). A source belongs to a
|
|
1027
998
|
// block only once a repair symbol stated the block's (SS_Start, SSB_length).
|
|
@@ -1115,7 +1086,10 @@ var FECManager = class _FECManager {
|
|
|
1115
1086
|
#releasedWorkerClients;
|
|
1116
1087
|
#syncDecoderBlockOwners;
|
|
1117
1088
|
#decoderBlockOwners;
|
|
1118
|
-
|
|
1089
|
+
// The stream-global K a configure() call stated, reported as fecStats.k.
|
|
1090
|
+
// It never resolves a packetId: a packetId has only its own track config
|
|
1091
|
+
// (BLO-45953), and K does not feed the delivery-window math.
|
|
1092
|
+
#streamK;
|
|
1119
1093
|
#fecSymbolSize;
|
|
1120
1094
|
#fecTimeoutMs;
|
|
1121
1095
|
#trackConfigs;
|
|
@@ -1277,7 +1251,8 @@ var FECManager = class _FECManager {
|
|
|
1277
1251
|
this.#completedBlocks.add(key);
|
|
1278
1252
|
if (clean) this.#cleanlyCompletedBlocks.add(key);
|
|
1279
1253
|
this.#indexBlockKey(key, sbn, packetId);
|
|
1280
|
-
const
|
|
1254
|
+
const config = this.#trackConfig(packetId);
|
|
1255
|
+
const expiresAtMs = nowMs + config.interleaveDepthMs + 2 * this.#blockLifetimeMs(config);
|
|
1281
1256
|
this.#terminalExpiryMs.set(key, expiresAtMs);
|
|
1282
1257
|
let queue = this.#terminalQueues.get(packetId);
|
|
1283
1258
|
if (!queue) {
|
|
@@ -1313,8 +1288,9 @@ var FECManager = class _FECManager {
|
|
|
1313
1288
|
* retention the Worker and the WASM decoder are configured with, because it
|
|
1314
1289
|
* comes from the same function they do (`deriveFecRetentionBlocks`, over the
|
|
1315
1290
|
* block's delivery window and its span). The decoder retires every block
|
|
1316
|
-
* more than this many
|
|
1317
|
-
*
|
|
1291
|
+
* more than this many blocks behind the newest SS_Start it saw, counted
|
|
1292
|
+
* from below by `isoBlocksBehindLowerBound` (`cleanup_by_ss_start`), so
|
|
1293
|
+
* settling earlier than this would decide a block the decoder would still
|
|
1318
1294
|
* have recovered.
|
|
1319
1295
|
*
|
|
1320
1296
|
* This used to call `deriveFecInterleaveDepth`, which returns D -- MEDIA
|
|
@@ -1327,6 +1303,14 @@ var FECManager = class _FECManager {
|
|
|
1327
1303
|
* derivation; do not re-derive a horizon at either call site.
|
|
1328
1304
|
*/
|
|
1329
1305
|
#orderedHorizonBlocksFor(packetId, config) {
|
|
1306
|
+
if (config.interleaveDepthMs === 0) {
|
|
1307
|
+
if (Number.isFinite(config.timeoutMs) && config.timeoutMs > 0) {
|
|
1308
|
+
return LOCAL_FEC_RETENTION_BLOCKS;
|
|
1309
|
+
}
|
|
1310
|
+
throw new Error(
|
|
1311
|
+
`[FECManager] packetId=${packetId}: local FEC cleanup requires a positive timeout (got ${config.timeoutMs})`
|
|
1312
|
+
);
|
|
1313
|
+
}
|
|
1330
1314
|
if (!_FECManager.#hasOrderedGeometry(config)) {
|
|
1331
1315
|
throw new Error(
|
|
1332
1316
|
`[FECManager] packetId=${packetId}: ordered-relay settlement derives the decoder's interleave horizon from the catalog interleaveDepthMs (>= ${MIN_INTERLEAVE_DEPTH_MS}ms), the media-unit rate and the block delivery window; got interleaveDepthMs=${config.interleaveDepthMs} fps=${String(config.fps)} timeoutMs=${config.timeoutMs}.`
|
|
@@ -1340,7 +1324,7 @@ var FECManager = class _FECManager {
|
|
|
1340
1324
|
* two can never disagree about which streams settle by stream order.
|
|
1341
1325
|
*/
|
|
1342
1326
|
static #hasOrderedGeometry(config) {
|
|
1343
|
-
return config
|
|
1327
|
+
return _FECManager.#hasCatalogTiming(config) && // `fps` is no longer an input to the horizon, but it still gates WHICH
|
|
1344
1328
|
// streams settle by stream order at all: a track with no usable
|
|
1345
1329
|
// media-unit rate fell back to datagram semantics before this and must
|
|
1346
1330
|
// keep doing so. Removing this widens ordered-relay settlement to streams
|
|
@@ -1380,6 +1364,9 @@ var FECManager = class _FECManager {
|
|
|
1380
1364
|
* argument: narrower IS the failing direction.
|
|
1381
1365
|
*/
|
|
1382
1366
|
#derivableOrderedHorizon(config, packetId) {
|
|
1367
|
+
if (config.interleaveDepthMs === 0) {
|
|
1368
|
+
return Number.isFinite(config.timeoutMs) && config.timeoutMs > 0 ? LOCAL_FEC_RETENTION_BLOCKS : void 0;
|
|
1369
|
+
}
|
|
1383
1370
|
if (!_FECManager.#hasOrderedGeometry(config)) return void 0;
|
|
1384
1371
|
try {
|
|
1385
1372
|
const blocks = tryDeriveFecRetentionBlocks(config.timeoutMs, config.interleaveDepthMs);
|
|
@@ -1412,19 +1399,20 @@ var FECManager = class _FECManager {
|
|
|
1412
1399
|
/**
|
|
1413
1400
|
* The stream's interleave horizon, or undefined when its geometry cannot
|
|
1414
1401
|
* define one. Two different streams reach that case, with different causes:
|
|
1415
|
-
* a packetId that was never configured,
|
|
1416
|
-
*
|
|
1402
|
+
* a packetId that was never configured, which has no geometry at all
|
|
1403
|
+
* (explicitly configured tracks are refused an underivable geometry
|
|
1417
1404
|
* at config time — #upsertTrackConfig, setMulticastSymbolDelivery); or a
|
|
1418
1405
|
* configured track whose timeoutMs was later widened past the 255-block
|
|
1419
1406
|
* ceiling without re-validating, which #derivableOrderedHorizon catches
|
|
1420
1407
|
* rather than throwing from the packet-feed path. Either way the stream
|
|
1421
|
-
* keeps datagram semantics instead of throwing.
|
|
1408
|
+
* keeps datagram semantics instead of throwing. A track's configuration can
|
|
1422
1409
|
* also change under a stream that already holds blocks, so a caller cannot
|
|
1423
1410
|
* assume a horizon that was defined when a block was held is still defined
|
|
1424
1411
|
* (see #advanceOrderedFrontier).
|
|
1425
1412
|
*/
|
|
1426
1413
|
#orderedHorizonBlocks(packetId) {
|
|
1427
|
-
|
|
1414
|
+
const config = this.#trackConfigs.get(packetId);
|
|
1415
|
+
return config === void 0 ? void 0 : this.#derivableOrderedHorizon(config, packetId);
|
|
1428
1416
|
}
|
|
1429
1417
|
/** True while a block of an ordered-relay stream can still receive symbols. */
|
|
1430
1418
|
#withinOrderedHorizon(key) {
|
|
@@ -1458,7 +1446,7 @@ var FECManager = class _FECManager {
|
|
|
1458
1446
|
*/
|
|
1459
1447
|
#advanceOrderedFrontier(streamKey, sbn, packetId, catalogTrackName) {
|
|
1460
1448
|
const previous = this.#orderedFrontiers.get(streamKey);
|
|
1461
|
-
const frontier = previous === void 0 || this.#blockPrecedes(previous, sbn
|
|
1449
|
+
const frontier = previous === void 0 || this.#blockPrecedes(previous, sbn) ? sbn : previous;
|
|
1462
1450
|
if (frontier !== previous) this.#orderedFrontiers.set(streamKey, frontier);
|
|
1463
1451
|
const pending = this.#orderedPendingBlocks.get(streamKey);
|
|
1464
1452
|
if (!pending) return;
|
|
@@ -1493,7 +1481,7 @@ var FECManager = class _FECManager {
|
|
|
1493
1481
|
if (this.#completedBlocks.has(key) || this.#pendingWorkerCleanups.has(key) || this.#repairRequestedBlocks.has(key)) return;
|
|
1494
1482
|
const authoredLength = this.#blockAuthoredLengths.get(key);
|
|
1495
1483
|
const received = (this.#blockSourceCounts.get(key) ?? 0) + (this.#blockRepairRsIds.get(key)?.size ?? 0);
|
|
1496
|
-
if (this.onRepairNeeded && (authoredLength === void 0 || received < authoredLength)) {
|
|
1484
|
+
if (this.#hasCatalogTimingForPacket(packetId) && this.onRepairNeeded && (authoredLength === void 0 || received < authoredLength)) {
|
|
1497
1485
|
this.#requestRepair(sbn, packetId, catalogTrackName, true);
|
|
1498
1486
|
return;
|
|
1499
1487
|
}
|
|
@@ -1649,7 +1637,7 @@ var FECManager = class _FECManager {
|
|
|
1649
1637
|
}
|
|
1650
1638
|
#requestRepair(sbn, packetId, catalogTrackName, settledByOrder = false) {
|
|
1651
1639
|
const key = this.#blockKey(sbn, packetId, catalogTrackName);
|
|
1652
|
-
if (this.#completedBlocks.has(key) || !this.onRepairNeeded || this.#repairRequestedBlocks.has(key)) return;
|
|
1640
|
+
if (this.#completedBlocks.has(key) || !this.#hasCatalogTimingForPacket(packetId) || !this.onRepairNeeded || this.#repairRequestedBlocks.has(key)) return;
|
|
1653
1641
|
const deadline = this.#repairDeadlines.get(key);
|
|
1654
1642
|
if (deadline?.handle != null) clearTimeout(deadline.handle);
|
|
1655
1643
|
this.#repairDeadlines.set(key, null);
|
|
@@ -1729,6 +1717,7 @@ var FECManager = class _FECManager {
|
|
|
1729
1717
|
}
|
|
1730
1718
|
/** A block's live class without creating classifier state for the stream. */
|
|
1731
1719
|
#peekClass(sbn, packetId, catalogTrackName) {
|
|
1720
|
+
if (!this.#hasCatalogTimingForPacket(packetId)) return "unknown";
|
|
1732
1721
|
const classifier = this.#classifiers.get(this.#streamKey(packetId, catalogTrackName));
|
|
1733
1722
|
if (classifier) return classifier.classOf(sbn);
|
|
1734
1723
|
return this.#geometryFor(packetId, catalogTrackName).trackKind === "audio" ? "audio" : "unknown";
|
|
@@ -1750,8 +1739,8 @@ var FECManager = class _FECManager {
|
|
|
1750
1739
|
// Deliberately one block tighter than deriveFecRetentionBlocks over the same
|
|
1751
1740
|
// inputs (that function's `+ 1`). Different question: the retention horizon
|
|
1752
1741
|
// asks how long the decoder still ACCEPTS symbols for a block, this asks how
|
|
1753
|
-
//
|
|
1754
|
-
// #noteSbnSeen).
|
|
1742
|
+
// many blocks a stream can live behind (or ahead of) its frontier before a
|
|
1743
|
+
// source symbol there is a discontinuity rather than loss (see #noteSbnSeen).
|
|
1755
1744
|
// The extra block of retention is slack for a block still being fed; a block
|
|
1756
1745
|
// nothing has been heard from does not get it. Not the units defect — but it
|
|
1757
1746
|
// is the next place the two can drift, so change both or neither.
|
|
@@ -1760,27 +1749,28 @@ var FECManager = class _FECManager {
|
|
|
1760
1749
|
return Math.ceil(config.timeoutMs / config.interleaveDepthMs);
|
|
1761
1750
|
}
|
|
1762
1751
|
/**
|
|
1763
|
-
* Record that a symbol for block `sbn`
|
|
1764
|
-
*
|
|
1752
|
+
* Record that a symbol for block `sbn` (the block's SS_Start) arrived and
|
|
1753
|
+
* advance the stream's frontier, the newest block start seen.
|
|
1765
1754
|
*
|
|
1766
|
-
*
|
|
1767
|
-
*
|
|
1768
|
-
*
|
|
1769
|
-
*
|
|
1770
|
-
*
|
|
1771
|
-
* its last symbol, is a source discontinuity, not loss. A repair symbol can
|
|
1772
|
-
* only advance the frontier: a D-28 fetch legitimately answers for an old
|
|
1773
|
-
* block, so it never signals a discontinuity.
|
|
1755
|
+
* A SOURCE symbol whose block goes back further than one live window, or
|
|
1756
|
+
* jumps further than the stream could have produced since its last symbol,
|
|
1757
|
+
* is a source discontinuity, not loss. A repair symbol can only advance the
|
|
1758
|
+
* frontier: a D-28 fetch legitimately answers for an old block, so it never
|
|
1759
|
+
* signals a discontinuity.
|
|
1774
1760
|
*
|
|
1775
1761
|
* The producer closes a block at its Dth media-unit boundary OR when K
|
|
1776
|
-
* source symbols filled it, so one interleave span can start several
|
|
1777
|
-
*
|
|
1778
|
-
*
|
|
1779
|
-
*
|
|
1780
|
-
*
|
|
1781
|
-
*
|
|
1782
|
-
*
|
|
1783
|
-
*
|
|
1762
|
+
* source symbols filled it, so one interleave span can start several blocks
|
|
1763
|
+
* (every large keyframe does). What bounds a forward jump is therefore
|
|
1764
|
+
* packet evidence, not a block rate: SS_ID advances by one per FEC source
|
|
1765
|
+
* packet (ISO/IEC 23008-1 C.5.2) and the MMTP packet_sequence_number by one
|
|
1766
|
+
* per packet of the packet_id, so with both source symbols'
|
|
1767
|
+
* packet_sequence_number a block start can move at most the packets sent
|
|
1768
|
+
* between them plus the anchor's own offset into its block (< K). Without
|
|
1769
|
+
* it, only the D-close rate is known.
|
|
1770
|
+
*
|
|
1771
|
+
* Vanished blocks are not enumerated here: their starts are unknown until a
|
|
1772
|
+
* repair states them. The SS_IDs between two stated blocks become one
|
|
1773
|
+
* repair-less span when the later block's repair arrives (placeIsoRepair).
|
|
1784
1774
|
*/
|
|
1785
1775
|
#noteSbnSeen(sbn, packetId, catalogTrackName, symbol, packetSequenceNumber) {
|
|
1786
1776
|
const streamKey = this.#streamKey(packetId, catalogTrackName);
|
|
@@ -1789,7 +1779,7 @@ var FECManager = class _FECManager {
|
|
|
1789
1779
|
const anchor = this.#sourceAnchors.get(streamKey);
|
|
1790
1780
|
const psn = symbol === "source" && packetSequenceNumber !== void 0 && Number.isSafeInteger(packetSequenceNumber) && packetSequenceNumber >= 0 && packetSequenceNumber <= 4294967295 ? packetSequenceNumber : void 0;
|
|
1791
1781
|
const anchorHere = () => {
|
|
1792
|
-
if (psn !== void 0 && (anchor === void 0 || !this.#blockPrecedes(sbn, anchor.sbn
|
|
1782
|
+
if (psn !== void 0 && (anchor === void 0 || !this.#blockPrecedes(sbn, anchor.sbn))) {
|
|
1793
1783
|
this.#sourceAnchors.set(streamKey, { sbn, psn, atMs: now });
|
|
1794
1784
|
}
|
|
1795
1785
|
};
|
|
@@ -1805,9 +1795,9 @@ var FECManager = class _FECManager {
|
|
|
1805
1795
|
anchorHere();
|
|
1806
1796
|
return;
|
|
1807
1797
|
}
|
|
1808
|
-
const config = this.#
|
|
1798
|
+
const config = this.#trackConfig(packetId);
|
|
1809
1799
|
const window = this.#liveWindowBlocks(config);
|
|
1810
|
-
if (!this.#blockPrecedes(previous.sbn, sbn
|
|
1800
|
+
if (!this.#blockPrecedes(previous.sbn, sbn)) {
|
|
1811
1801
|
if (symbol === "source" && window !== null && this.#blocksBehind(sbn, previous.sbn, packetId) > window) {
|
|
1812
1802
|
discontinuity();
|
|
1813
1803
|
return;
|
|
@@ -1818,15 +1808,9 @@ var FECManager = class _FECManager {
|
|
|
1818
1808
|
const missing = this.#blocksBehind(previous.sbn, sbn, packetId) - 1;
|
|
1819
1809
|
let plausible = true;
|
|
1820
1810
|
if (window !== null) {
|
|
1821
|
-
if (
|
|
1811
|
+
if (psn !== void 0 && anchor !== void 0 && this.#blockPrecedes(anchor.sbn, sbn) && psn !== anchor.psn) {
|
|
1822
1812
|
const sent = psn - anchor.psn >>> 0;
|
|
1823
1813
|
plausible = sent <= 2147483647 && serial32Distance(anchor.sbn, sbn) <= sent + config.k;
|
|
1824
|
-
} else if (psn !== void 0 && anchor !== void 0 && this.#blockPrecedes(anchor.sbn, sbn, packetId) && psn !== anchor.psn) {
|
|
1825
|
-
const sent = psn - anchor.psn >>> 0;
|
|
1826
|
-
const between = this.#blocksBehind(anchor.sbn, sbn, packetId) - 1;
|
|
1827
|
-
const dCloses = window + Math.ceil((now - anchor.atMs) / config.interleaveDepthMs);
|
|
1828
|
-
const kCloses = config.k > 0 ? Math.ceil(sent / config.k) : sent;
|
|
1829
|
-
plausible = sent <= 2147483647 && between <= sent - 1 && between <= dCloses + kCloses;
|
|
1830
1814
|
} else {
|
|
1831
1815
|
plausible = missing <= window + Math.ceil((now - previous.atMs) / config.interleaveDepthMs);
|
|
1832
1816
|
}
|
|
@@ -1838,48 +1822,31 @@ var FECManager = class _FECManager {
|
|
|
1838
1822
|
}
|
|
1839
1823
|
this.#highestSbn.set(streamKey, { sbn, atMs: now });
|
|
1840
1824
|
anchorHere();
|
|
1841
|
-
if (this.#isIso(packetId)) return;
|
|
1842
|
-
if (missing <= 0 || window === null) return;
|
|
1843
|
-
let vanished = previous.sbn;
|
|
1844
|
-
for (let i = 0; i < missing; i++) {
|
|
1845
|
-
vanished = this.#nextBlock(vanished, packetId);
|
|
1846
|
-
this.#materializeBlock(
|
|
1847
|
-
vanished,
|
|
1848
|
-
packetId,
|
|
1849
|
-
catalogTrackName,
|
|
1850
|
-
this.#blocksBehind(vanished, sbn, packetId) <= window
|
|
1851
|
-
);
|
|
1852
|
-
}
|
|
1853
1825
|
}
|
|
1854
1826
|
/*
|
|
1855
|
-
* Block order for one stream (BLO-35597 iso:5).
|
|
1856
|
-
* number (ISO/IEC 23008-1 C.5.2), so
|
|
1857
|
-
*
|
|
1858
|
-
*
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
#blockPrecedes(a, b, packetId) {
|
|
1863
|
-
if (this.#isIso(packetId)) return serial32Precedes(a, b);
|
|
1864
|
-
const k = this.kForPacket(packetId);
|
|
1865
|
-
return isKStrideBlock(a, k) && isKStrideBlock(b, k) ? kStrideBlockPrecedes(a, b, k) : a < b;
|
|
1866
|
-
}
|
|
1867
|
-
/** Blocks `a` lies behind `b` (0 when it does not precede it). */
|
|
1868
|
-
#blocksBehind(a, b, packetId) {
|
|
1869
|
-
if (this.#isIso(packetId)) return isoBlocksBehindLowerBound(a, b, this.kForPacket(packetId));
|
|
1870
|
-
const k = this.kForPacket(packetId);
|
|
1871
|
-
return isKStrideBlock(a, k) && isKStrideBlock(b, k) ? kStrideBlocksBehind(a, b, k) : Math.max(0, b - a);
|
|
1827
|
+
* Block order for one stream (BLO-35597 iso:5). A block is keyed by its
|
|
1828
|
+
* SS_Start and SS_ID is a 32-bit serial number (ISO/IEC 23008-1 C.5.2), so
|
|
1829
|
+
* blocks are ordered by RFC 1982 comparison of their starts. Only configured
|
|
1830
|
+
* streams hold blocks: every entry point refuses an unconfigured packetId.
|
|
1831
|
+
*/
|
|
1832
|
+
#blockPrecedes(a, b) {
|
|
1833
|
+
return serial32Precedes(a, b);
|
|
1872
1834
|
}
|
|
1873
|
-
/**
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1835
|
+
/**
|
|
1836
|
+
* Blocks `a` lies behind `b` (0 when it does not precede it). Blocks vary
|
|
1837
|
+
* in length (K' = SSB_length <= K), so only a lower bound is known: the one
|
|
1838
|
+
* metric the decoder and the worker retire by too.
|
|
1839
|
+
*/
|
|
1840
|
+
#blocksBehind(a, b, packetId) {
|
|
1841
|
+
return isoBlocksBehindLowerBound(a, b, this.#trackConfig(packetId).k);
|
|
1877
1842
|
}
|
|
1878
1843
|
#materializeBlock(sbn, packetId, catalogTrackName, repairable) {
|
|
1879
1844
|
const key = this.#blockKey(sbn, packetId, catalogTrackName);
|
|
1880
1845
|
if (this.#blockResolutionFor(key) !== "untracked") return;
|
|
1881
1846
|
this.#materializedBlocks.add(key);
|
|
1882
|
-
this.#
|
|
1847
|
+
if (this.#hasCatalogTimingForPacket(packetId)) {
|
|
1848
|
+
this.#classifierFor(packetId, catalogTrackName).touch(sbn);
|
|
1849
|
+
}
|
|
1883
1850
|
this.onBlockVanished?.(sbn, packetId, catalogTrackName);
|
|
1884
1851
|
if (repairable) {
|
|
1885
1852
|
this.noteBlockActivity(sbn, packetId, catalogTrackName, true);
|
|
@@ -1918,21 +1885,39 @@ var FECManager = class _FECManager {
|
|
|
1918
1885
|
});
|
|
1919
1886
|
if (this.#lifecycleTrace.length > 64) this.#lifecycleTrace.splice(0, 32);
|
|
1920
1887
|
}
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1888
|
+
/**
|
|
1889
|
+
* A configured packetId's track config. There is no manager-wide default
|
|
1890
|
+
* (BLO-45953): an unconfigured packetId does no FEC work, so every caller
|
|
1891
|
+
* here is reached only behind a configuration gate and this throw marks a
|
|
1892
|
+
* broken invariant, never a packet-path outcome.
|
|
1893
|
+
*/
|
|
1894
|
+
#trackConfig(packetId) {
|
|
1895
|
+
const config = this.#trackConfigs.get(packetId);
|
|
1896
|
+
if (config === void 0) {
|
|
1897
|
+
throw new Error(
|
|
1898
|
+
`[FECManager] packetId=${packetId} was never configured; configure the track from its catalog (configureTrack/setFecWorker/setFecDecoder) first`
|
|
1899
|
+
);
|
|
1900
|
+
}
|
|
1901
|
+
return config;
|
|
1929
1902
|
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1903
|
+
/**
|
|
1904
|
+
* Whether this track has the catalog's elapsed-time FEC policy. A zero span
|
|
1905
|
+
* is a deliberate no-deadline signal; it still leaves the wire geometry
|
|
1906
|
+
* usable for in-band decode, but it cannot drive classification, repair
|
|
1907
|
+
* fetches or layer adaptation.
|
|
1908
|
+
*/
|
|
1909
|
+
static #hasCatalogTiming(config) {
|
|
1910
|
+
return Number.isSafeInteger(config.interleaveDepthMs) && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS;
|
|
1911
|
+
}
|
|
1912
|
+
#hasCatalogTimingForPacket(packetId) {
|
|
1913
|
+
const config = this.#trackConfigs.get(packetId);
|
|
1914
|
+
return config !== void 0 && _FECManager.#hasCatalogTiming(config);
|
|
1932
1915
|
}
|
|
1933
1916
|
#computeTimeout(config) {
|
|
1934
|
-
if (config.timeoutMs && config.timeoutMs > 0)
|
|
1935
|
-
|
|
1917
|
+
if (typeof config.timeoutMs === "number" && Number.isFinite(config.timeoutMs) && config.timeoutMs > 0) {
|
|
1918
|
+
return config.timeoutMs;
|
|
1919
|
+
}
|
|
1920
|
+
if (Number.isSafeInteger(config.interleaveDepthMs) && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
|
|
1936
1921
|
return Math.max(
|
|
1937
1922
|
this.#fecTimeoutMs,
|
|
1938
1923
|
computeFecDeliveryWindowMs({
|
|
@@ -1957,14 +1942,17 @@ var FECManager = class _FECManager {
|
|
|
1957
1942
|
*/
|
|
1958
1943
|
#refreshDeliveryGapWindow() {
|
|
1959
1944
|
let windowMs;
|
|
1960
|
-
const consider = (geometry) => {
|
|
1945
|
+
const consider = (geometry, packetId) => {
|
|
1946
|
+
if (!this.#hasCatalogTimingForPacket(packetId)) return;
|
|
1961
1947
|
if (geometry?.trackKind !== "video" || geometry.mode !== "classifying") return;
|
|
1962
1948
|
const { ticks, timescale } = geometry.keyframeInterval;
|
|
1963
1949
|
const ms = ticks / timescale * 1e3;
|
|
1964
1950
|
if (Number.isFinite(ms) && ms > 0 && (windowMs === void 0 || ms > windowMs)) windowMs = ms;
|
|
1965
1951
|
};
|
|
1966
|
-
for (const geometry of this.#streamGeometries
|
|
1967
|
-
|
|
1952
|
+
for (const [streamKey, geometry] of this.#streamGeometries) {
|
|
1953
|
+
consider(geometry, this.#parseStreamKey(streamKey).packetId);
|
|
1954
|
+
}
|
|
1955
|
+
for (const [packetId, config] of this.#trackConfigs) consider(config.geometry, packetId);
|
|
1968
1956
|
this.#deliveryGaps.setWindowMs(windowMs);
|
|
1969
1957
|
}
|
|
1970
1958
|
/**
|
|
@@ -1992,6 +1980,7 @@ var FECManager = class _FECManager {
|
|
|
1992
1980
|
return Math.max(config.timeoutMs, Math.ceil(config.interleaveDepthMs + gapMs));
|
|
1993
1981
|
}
|
|
1994
1982
|
#repairDeadlineMs(config, waitMs = this.#multicastWaitMs(config)) {
|
|
1983
|
+
if (!_FECManager.#hasCatalogTiming(config)) return waitMs;
|
|
1995
1984
|
const halfFailBoundMs = Math.ceil(waitMs / 2);
|
|
1996
1985
|
if (config.k > 0 && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS && config.fps !== void 0 && Number.isFinite(config.fps) && config.fps > 0) {
|
|
1997
1986
|
const mediaUnitMs = 1e3 / config.fps;
|
|
@@ -2006,10 +1995,12 @@ var FECManager = class _FECManager {
|
|
|
2006
1995
|
}
|
|
2007
1996
|
/**
|
|
2008
1997
|
* One block lifetime: the inactivity fail bound plus the D-28 repair grace,
|
|
2009
|
-
* at the widest wait the catalog allows (#maxMulticastWaitMs).
|
|
2010
|
-
*
|
|
2011
|
-
*
|
|
2012
|
-
*
|
|
1998
|
+
* at the widest wait the catalog allows (#maxMulticastWaitMs). For a track
|
|
1999
|
+
* without a catalog span this is receiver-local cleanup time only; no repair
|
|
2000
|
+
* grace is added. Everything derived from it (terminal retention, the
|
|
2001
|
+
* release gate's hold ceiling, the duplicate ledgers, the owed-cleanup
|
|
2002
|
+
* bound) is compared across time, so it must not follow the live
|
|
2003
|
+
* measurement.
|
|
2013
2004
|
*/
|
|
2014
2005
|
#blockLifetimeMs(config) {
|
|
2015
2006
|
const waitMs = this.#maxMulticastWaitMs(config);
|
|
@@ -2025,6 +2016,7 @@ var FECManager = class _FECManager {
|
|
|
2025
2016
|
return Math.min(waitMs + this.#repairGraceMs(config, waitMs), this.#blockLifetimeMs(config));
|
|
2026
2017
|
}
|
|
2027
2018
|
#repairGraceMs(config, waitMs) {
|
|
2019
|
+
if (!_FECManager.#hasCatalogTiming(config)) return 0;
|
|
2028
2020
|
return Math.max(1, waitMs - this.#repairDeadlineMs(config, waitMs));
|
|
2029
2021
|
}
|
|
2030
2022
|
#armBlockTimeout(sbn, packetId, catalogTrackName, delayMs) {
|
|
@@ -2111,51 +2103,72 @@ var FECManager = class _FECManager {
|
|
|
2111
2103
|
* stream; every other field stays per packetId.
|
|
2112
2104
|
*/
|
|
2113
2105
|
#upsertTrackConfig(packetId, config, catalogTrackName) {
|
|
2114
|
-
const
|
|
2106
|
+
const previousTrack = this.#trackConfigs.get(packetId);
|
|
2107
|
+
const k = config.k ?? previousTrack?.k;
|
|
2108
|
+
if (k === void 0 || !Number.isSafeInteger(k) || k <= 0) {
|
|
2109
|
+
throw new Error(
|
|
2110
|
+
`[FECManager] packetId=${packetId}: fec.k=${String(k)} must be a positive integer; configure the track from its catalog`
|
|
2111
|
+
);
|
|
2112
|
+
}
|
|
2113
|
+
const previous = previousTrack ?? {};
|
|
2115
2114
|
const streamScopedGeometry = catalogTrackName !== void 0 && config.geometry !== void 0 ? config.geometry : void 0;
|
|
2116
2115
|
if (streamScopedGeometry !== void 0) {
|
|
2117
2116
|
const { geometry: _streamGeometry, ...packetLevel } = config;
|
|
2118
2117
|
config = packetLevel;
|
|
2119
2118
|
}
|
|
2120
2119
|
const timingChanged = config.k !== void 0 || config.interleaveDepthMs !== void 0 || config.fps !== void 0;
|
|
2120
|
+
if (config.timeoutMs !== void 0 && (!Number.isFinite(config.timeoutMs) || config.timeoutMs < 0)) {
|
|
2121
|
+
throw new Error(
|
|
2122
|
+
`[FECManager] packetId=${packetId}: timeoutMs=${config.timeoutMs} must be a finite non-negative cleanup budget`
|
|
2123
|
+
);
|
|
2124
|
+
}
|
|
2121
2125
|
if (config.blockProfile !== void 0) {
|
|
2122
2126
|
parseFecBlockProfile(config.blockProfile, `packetId=${packetId} fec.blockProfile`);
|
|
2123
2127
|
}
|
|
2124
2128
|
const blockProfile = config.blockProfile ?? previous.blockProfile;
|
|
2125
2129
|
if (blockProfile === void 0) {
|
|
2126
2130
|
throw new Error(
|
|
2127
|
-
`[FECManager] packetId=${packetId}: fec.blockProfile is required ("
|
|
2131
|
+
`[FECManager] packetId=${packetId}: fec.blockProfile is required ("iso-ssbg1-v1"); configure the track from its catalog`
|
|
2128
2132
|
);
|
|
2129
2133
|
}
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
);
|
|
2136
|
-
}
|
|
2134
|
+
const ownInterleaveDepthMs = config.interleaveDepthMs ?? previousTrack?.interleaveDepthMs ?? 0;
|
|
2135
|
+
if (!Number.isSafeInteger(ownInterleaveDepthMs) || ownInterleaveDepthMs !== 0 && ownInterleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) {
|
|
2136
|
+
throw new Error(
|
|
2137
|
+
`[FECManager] packetId=${packetId}: fec.interleaveDepthMs must be absent, 0, or a finite value >= ${MIN_INTERLEAVE_DEPTH_MS} ms (got ${String(ownInterleaveDepthMs)})`
|
|
2138
|
+
);
|
|
2137
2139
|
}
|
|
2140
|
+
const hasCatalogTiming = _FECManager.#hasCatalogTiming({ interleaveDepthMs: ownInterleaveDepthMs });
|
|
2138
2141
|
const next = {
|
|
2139
2142
|
blockProfile,
|
|
2140
|
-
k
|
|
2141
|
-
symbolSize: config.symbolSize != null && config.symbolSize > 0 ? config.symbolSize :
|
|
2142
|
-
interleaveDepthMs:
|
|
2143
|
-
fps: config.fps ?? previous.fps,
|
|
2144
|
-
timeoutMs: config.timeoutMs ?? (timingChanged ? 0 : previous.timeoutMs),
|
|
2143
|
+
k,
|
|
2144
|
+
symbolSize: config.symbolSize != null && config.symbolSize > 0 ? config.symbolSize : previousTrack?.symbolSize ?? 0,
|
|
2145
|
+
interleaveDepthMs: ownInterleaveDepthMs,
|
|
2146
|
+
fps: config.fps ?? previous.fps ?? this.#fecFps,
|
|
2147
|
+
timeoutMs: config.timeoutMs ?? (timingChanged ? 0 : previous.timeoutMs ?? 0),
|
|
2145
2148
|
...(config.trackKind ?? previous.trackKind) === void 0 ? {} : { trackKind: config.trackKind ?? previous.trackKind },
|
|
2146
2149
|
...(config.codec ?? previous.codec) === void 0 ? {} : { codec: config.codec ?? previous.codec },
|
|
2147
2150
|
...(config.geometry ?? previous.geometry) === void 0 ? {} : { geometry: config.geometry ?? previous.geometry }
|
|
2148
2151
|
};
|
|
2149
|
-
|
|
2152
|
+
if (!hasCatalogTiming) {
|
|
2153
|
+
next.timeoutMs = config.timeoutMs !== void 0 && config.timeoutMs > 0 ? config.timeoutMs : previousTrack !== void 0 && previousTrack.interleaveDepthMs === 0 ? previousTrack.timeoutMs : LOCAL_FEC_TIMEOUT_MS;
|
|
2154
|
+
} else {
|
|
2155
|
+
next.timeoutMs = this.#computeTimeout(next);
|
|
2156
|
+
}
|
|
2150
2157
|
if (this.#multicastSymbolDelivery === "ordered-relay") {
|
|
2151
2158
|
this.#orderedHorizonBlocksFor(packetId, next);
|
|
2152
2159
|
}
|
|
2153
|
-
|
|
2160
|
+
const timingPolicyChanged = _FECManager.#hasCatalogTiming({ interleaveDepthMs: previous.interleaveDepthMs ?? 0 }) !== hasCatalogTiming;
|
|
2161
|
+
if (timingPolicyChanged && !hasCatalogTiming) {
|
|
2162
|
+
for (const key of [...this.#repairDeadlines.keys()]) {
|
|
2163
|
+
if (this.#belongsToPacket(key, packetId)) this.#clearRepairDeadline(key);
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
if (previous.blockProfile !== void 0 && previous.k !== next.k) {
|
|
2154
2167
|
this.#dropIsoLocators(packetId);
|
|
2155
2168
|
}
|
|
2156
2169
|
this.#trackConfigs.set(packetId, next);
|
|
2157
2170
|
this.#refreshDeliveryGapWindow();
|
|
2158
|
-
let policyChanged = config.geometry !== void 0 && JSON.stringify(config.geometry) !== JSON.stringify(previous.geometry) || config.trackKind !== void 0 && config.trackKind !== previous.trackKind;
|
|
2171
|
+
let policyChanged = timingPolicyChanged || config.geometry !== void 0 && JSON.stringify(config.geometry) !== JSON.stringify(previous.geometry) || config.trackKind !== void 0 && config.trackKind !== previous.trackKind;
|
|
2159
2172
|
if (streamScopedGeometry !== void 0) {
|
|
2160
2173
|
const streamKey = this.#streamKey(packetId, catalogTrackName);
|
|
2161
2174
|
if (JSON.stringify(streamScopedGeometry) !== JSON.stringify(this.#streamGeometries.get(streamKey))) {
|
|
@@ -2170,20 +2183,14 @@ var FECManager = class _FECManager {
|
|
|
2170
2183
|
if (!this.#belongsToPacket(key, packetId)) continue;
|
|
2171
2184
|
const stream = this.#parseStreamKey(key);
|
|
2172
2185
|
const geometry = this.#geometryFor(stream.packetId, stream.catalogTrackName);
|
|
2173
|
-
if (JSON.stringify(geometry) === JSON.stringify(classifier.geometry)) continue;
|
|
2186
|
+
if (hasCatalogTiming && JSON.stringify(geometry) === JSON.stringify(classifier.geometry)) continue;
|
|
2174
2187
|
this.#classifiers.delete(key);
|
|
2188
|
+
if (!hasCatalogTiming) continue;
|
|
2175
2189
|
this.#applyClassifierChanges(stream.packetId, stream.catalogTrackName, classifier.retire());
|
|
2176
2190
|
}
|
|
2177
2191
|
}
|
|
2178
2192
|
return next;
|
|
2179
2193
|
}
|
|
2180
|
-
#normalizeSymbolData(packetId, data) {
|
|
2181
|
-
const symbolSize = this.symbolSizeForPacket(packetId);
|
|
2182
|
-
if (symbolSize <= 0 || data.byteLength === symbolSize) return data;
|
|
2183
|
-
const normalized = new Uint8Array(symbolSize);
|
|
2184
|
-
normalized.set(data.subarray(0, symbolSize));
|
|
2185
|
-
return normalized;
|
|
2186
|
-
}
|
|
2187
2194
|
#blockKeysFor(sbn, packetId, catalogTrackName) {
|
|
2188
2195
|
if (packetId != null && catalogTrackName !== void 0) {
|
|
2189
2196
|
return [this.#blockKey(sbn, packetId, catalogTrackName)];
|
|
@@ -2244,7 +2251,7 @@ var FECManager = class _FECManager {
|
|
|
2244
2251
|
...stats,
|
|
2245
2252
|
packetId,
|
|
2246
2253
|
blocksComplete: trackTotal,
|
|
2247
|
-
k: this.#
|
|
2254
|
+
k: this.#trackConfigs.get(packetId)?.k,
|
|
2248
2255
|
recoveryRate: trackAffected > 0 ? stats.blocksRecovered / trackAffected * 100 : 100,
|
|
2249
2256
|
packetLossRate: trackTotal > 0 ? trackAffected / trackTotal * 100 : 0
|
|
2250
2257
|
};
|
|
@@ -2256,7 +2263,7 @@ var FECManager = class _FECManager {
|
|
|
2256
2263
|
(block) => block.multicastSymbols > 0 && block.moqSymbols > 0
|
|
2257
2264
|
).length,
|
|
2258
2265
|
recentBlockPathCounts: Array.from(this.#blockPathCounts.values()).slice(-24),
|
|
2259
|
-
k: this.#
|
|
2266
|
+
k: this.#streamK,
|
|
2260
2267
|
// True recovery rate: of blocks that HAD loss, how many were recovered?
|
|
2261
2268
|
recoveryRate: affected > 0 ? s.blocksRecovered / affected * 100 : 100,
|
|
2262
2269
|
packetLossRate: total > 0 ? affected / total * 100 : 0,
|
|
@@ -2269,7 +2276,6 @@ var FECManager = class _FECManager {
|
|
|
2269
2276
|
},
|
|
2270
2277
|
blocks: stats.blocks.map((block) => ({ ...block })),
|
|
2271
2278
|
decoder: stats.decoder ? { ...stats.decoder } : void 0,
|
|
2272
|
-
altaFailedDetails: stats.altaFailedDetails?.map((detail) => ({ ...detail })),
|
|
2273
2279
|
packetId
|
|
2274
2280
|
})),
|
|
2275
2281
|
repairSymbolSizeMismatches: this.#repairSymbolSizeMismatchCount,
|
|
@@ -2551,15 +2557,20 @@ var FECManager = class _FECManager {
|
|
|
2551
2557
|
}
|
|
2552
2558
|
}
|
|
2553
2559
|
}
|
|
2554
|
-
/**
|
|
2560
|
+
/**
|
|
2561
|
+
* Record a transport symbol and reject later duplicates of the same
|
|
2562
|
+
* packetId/SBN/ESI. `sbn` is the block's SS_Start. A packetId with no
|
|
2563
|
+
* configured block profile has no block geometry: its symbol is refused
|
|
2564
|
+
* (false) and no block state is created for it.
|
|
2565
|
+
*/
|
|
2555
2566
|
feedSymbolFromSource(packetId, sbn, esi, _data, source, catalogTrackName) {
|
|
2567
|
+
if (!this.#hasBlockProfile(packetId)) return false;
|
|
2556
2568
|
const blockKey = this.#blockKey(sbn, packetId, catalogTrackName);
|
|
2557
2569
|
const streamKey = this.#streamKey(packetId, catalogTrackName);
|
|
2558
2570
|
if (source === "multicast" && this.#multicastSymbolDelivery === "ordered-relay") {
|
|
2559
2571
|
this.#advanceOrderedFrontier(streamKey, sbn, packetId, catalogTrackName);
|
|
2560
2572
|
}
|
|
2561
|
-
const
|
|
2562
|
-
const sourceSymbols = this.#isIso(packetId) ? this.#isoLocatorFor(packetId, catalogTrackName).blockAt(sbn)?.length ?? k : k;
|
|
2573
|
+
const sourceSymbols = this.#isoLocatorFor(packetId, catalogTrackName).blockAt(sbn)?.length ?? this.#trackConfig(packetId).k;
|
|
2563
2574
|
const isSourceSymbol = esi >= 0 && esi < sourceSymbols;
|
|
2564
2575
|
const isStartupPartial = this.#startupPartialBlocks.has(blockKey);
|
|
2565
2576
|
const isReadyMulticastRepair = this.#startupRequireRepairReady && source === "multicast" && !isSourceSymbol && this.#startupRepairReadyPackets.has(streamKey);
|
|
@@ -2677,14 +2688,14 @@ var FECManager = class _FECManager {
|
|
|
2677
2688
|
for (const [key] of this.#activeBlocks) {
|
|
2678
2689
|
const { packetId, sbn } = this.#parseBlockKey(key);
|
|
2679
2690
|
const count = this.#blockSourceCounts.get(key) ?? 0;
|
|
2680
|
-
const k = this.#blockAuthoredLengths.get(key) ?? this
|
|
2691
|
+
const k = this.#blockAuthoredLengths.get(key) ?? this.#trackConfig(packetId).k;
|
|
2681
2692
|
blocks.push({ sbn, packetId, state: "collecting", sourceCount: count, k, progress: k > 0 ? Math.min(count / k, 1) : 0 });
|
|
2682
2693
|
}
|
|
2683
2694
|
const completed = [...this.#completedBlocks].slice(-16);
|
|
2684
2695
|
for (const key of completed) {
|
|
2685
2696
|
const { packetId, sbn } = this.#parseBlockKey(key);
|
|
2686
2697
|
if (!this.#activeBlocks.has(key)) {
|
|
2687
|
-
const k = this
|
|
2698
|
+
const k = this.#trackConfig(packetId).k;
|
|
2688
2699
|
blocks.push({ sbn, packetId, state: "complete", sourceCount: k, k, progress: 1 });
|
|
2689
2700
|
}
|
|
2690
2701
|
}
|
|
@@ -2695,25 +2706,23 @@ var FECManager = class _FECManager {
|
|
|
2695
2706
|
get wasmDecoder() {
|
|
2696
2707
|
return this.#fecDecoders.values().next().value?.client ?? null;
|
|
2697
2708
|
}
|
|
2698
|
-
|
|
2699
|
-
return this.#fecK;
|
|
2700
|
-
}
|
|
2709
|
+
/** A configured packetId's K; undefined for an unconfigured one (no FEC work). */
|
|
2701
2710
|
kForPacket(packetId) {
|
|
2702
|
-
return this.#
|
|
2711
|
+
return this.#trackConfigs.get(packetId)?.k;
|
|
2703
2712
|
}
|
|
2704
2713
|
/** FEC symbol size in bytes. */
|
|
2705
2714
|
get symbolSize() {
|
|
2706
2715
|
return this.#fecSymbolSize;
|
|
2707
2716
|
}
|
|
2708
2717
|
symbolSizeForPacket(packetId) {
|
|
2709
|
-
return this.#
|
|
2718
|
+
return this.#trackConfigs.get(packetId)?.symbolSize;
|
|
2710
2719
|
}
|
|
2711
2720
|
/** FEC block span in milliseconds (0 = no interleaving). */
|
|
2712
2721
|
get interleaveDepthMs() {
|
|
2713
2722
|
return this.#fecInterleaveDepthMs;
|
|
2714
2723
|
}
|
|
2715
2724
|
interleaveDepthMsForPacket(packetId) {
|
|
2716
|
-
return this.#
|
|
2725
|
+
return this.#trackConfigs.get(packetId)?.interleaveDepthMs;
|
|
2717
2726
|
}
|
|
2718
2727
|
/**
|
|
2719
2728
|
* Record one multicast MMTP packet arrival (every packet of the leg, FEC
|
|
@@ -2731,7 +2740,8 @@ var FECManager = class _FECManager {
|
|
|
2731
2740
|
* plus the larger of the catalog tolerance and the measured delivery gap.
|
|
2732
2741
|
*/
|
|
2733
2742
|
timeoutMsForPacket(packetId) {
|
|
2734
|
-
|
|
2743
|
+
const config = this.#trackConfigs.get(packetId);
|
|
2744
|
+
return config === void 0 ? void 0 : this.#multicastWaitMs(config);
|
|
2735
2745
|
}
|
|
2736
2746
|
/**
|
|
2737
2747
|
* Largest multicast delivery gap measured over the current window (ms), and
|
|
@@ -2787,27 +2797,31 @@ var FECManager = class _FECManager {
|
|
|
2787
2797
|
}
|
|
2788
2798
|
/** Resolved per-track D-28 repair request deadline in milliseconds. */
|
|
2789
2799
|
repairDeadlineMsForPacket(packetId) {
|
|
2790
|
-
|
|
2800
|
+
const config = this.#trackConfigs.get(packetId);
|
|
2801
|
+
return config === void 0 ? void 0 : this.#repairDeadlineMs(config);
|
|
2791
2802
|
}
|
|
2792
2803
|
/**
|
|
2793
2804
|
* One block lifetime: the longest a block stays open after its last symbol
|
|
2794
2805
|
* (inactivity fail bound plus D-28 repair grace).
|
|
2795
2806
|
*/
|
|
2796
2807
|
blockLifetimeMsForPacket(packetId) {
|
|
2797
|
-
|
|
2808
|
+
const config = this.#trackConfigs.get(packetId);
|
|
2809
|
+
return config === void 0 ? void 0 : this.#blockLifetimeMs(config);
|
|
2798
2810
|
}
|
|
2799
2811
|
/**
|
|
2800
2812
|
* How long a terminal (clean, recovered or failed) block stays authoritative,
|
|
2801
2813
|
* for late symbols and for the in-order release gate. It is also the gate's
|
|
2802
2814
|
* hold ceiling (MmtpRouter's holdLimitMs): a retired block reads back as
|
|
2803
2815
|
* untracked, which the gate counts as lost, so no frame may still be waiting
|
|
2804
|
-
* on a block that can retire.
|
|
2805
|
-
*
|
|
2806
|
-
*
|
|
2807
|
-
*
|
|
2816
|
+
* on a block that can retire. With a positive catalog span the window is one
|
|
2817
|
+
* interleave depth for a gap's last block to finish arriving, one block
|
|
2818
|
+
* lifetime to fail it, and one more for an owed Worker cleanup. With an
|
|
2819
|
+
* absent/zero span it is a receiver-local cleanup bound only; it creates no
|
|
2820
|
+
* catalog FEC deadline.
|
|
2808
2821
|
*/
|
|
2809
2822
|
terminalRetentionMsForPacket(packetId) {
|
|
2810
|
-
const config = this.#
|
|
2823
|
+
const config = this.#trackConfigs.get(packetId);
|
|
2824
|
+
if (config === void 0) return void 0;
|
|
2811
2825
|
return config.interleaveDepthMs + 2 * this.#blockLifetimeMs(config);
|
|
2812
2826
|
}
|
|
2813
2827
|
/** Remaining fetch budget for a specific repair-requested block. */
|
|
@@ -2818,7 +2832,8 @@ var FECManager = class _FECManager {
|
|
|
2818
2832
|
if (deadlineMs !== void 0) {
|
|
2819
2833
|
return Math.max(1, Math.ceil(deadlineMs - performance.now()));
|
|
2820
2834
|
}
|
|
2821
|
-
const trackConfig = this.#
|
|
2835
|
+
const trackConfig = this.#trackConfigs.get(packetId);
|
|
2836
|
+
if (trackConfig === void 0) return void 0;
|
|
2822
2837
|
return Math.max(1, trackConfig.timeoutMs - this.#repairDeadlineMs(trackConfig));
|
|
2823
2838
|
}
|
|
2824
2839
|
/** True once configureTrack/setFecDecoder/setFecWorker configured this packetId. */
|
|
@@ -2829,14 +2844,19 @@ var FECManager = class _FECManager {
|
|
|
2829
2844
|
blockProfileForPacket(packetId) {
|
|
2830
2845
|
return this.#trackConfigs.get(packetId)?.blockProfile;
|
|
2831
2846
|
}
|
|
2832
|
-
|
|
2833
|
-
|
|
2847
|
+
/**
|
|
2848
|
+
* Whether a packetId has a configured block geometry. iso-ssbg1-v1 is the
|
|
2849
|
+
* only profile, so every configured track has it; a packetId never
|
|
2850
|
+
* configured (or released) has none and gets no FEC block tracking.
|
|
2851
|
+
*/
|
|
2852
|
+
#hasBlockProfile(packetId) {
|
|
2853
|
+
return this.#trackConfigs.get(packetId)?.blockProfile !== void 0;
|
|
2834
2854
|
}
|
|
2835
2855
|
#isoLocatorFor(packetId, catalogTrackName) {
|
|
2836
2856
|
const streamKey = this.#streamKey(packetId, catalogTrackName);
|
|
2837
2857
|
let locator = this.#isoLocators.get(streamKey);
|
|
2838
2858
|
if (!locator) {
|
|
2839
|
-
locator = new IsoBlockLocator(this
|
|
2859
|
+
locator = new IsoBlockLocator(this.#trackConfig(packetId).k, this.#isoRetentionBlocks(packetId));
|
|
2840
2860
|
this.#isoLocators.set(streamKey, locator);
|
|
2841
2861
|
}
|
|
2842
2862
|
return locator;
|
|
@@ -2867,12 +2887,14 @@ var FECManager = class _FECManager {
|
|
|
2867
2887
|
*/
|
|
2868
2888
|
#isoRetentionBlocks(packetId) {
|
|
2869
2889
|
const config = this.#trackConfigs.get(packetId);
|
|
2870
|
-
if (config?.blockProfile
|
|
2890
|
+
if (config?.blockProfile === void 0) {
|
|
2871
2891
|
throw new Error(
|
|
2872
|
-
`[FECManager] packetId=${packetId} has no iso-ssbg1-v1 block
|
|
2892
|
+
`[FECManager] packetId=${packetId} has no configured iso-ssbg1-v1 block profile`
|
|
2873
2893
|
);
|
|
2874
2894
|
}
|
|
2875
|
-
|
|
2895
|
+
if (!_FECManager.#hasCatalogTiming(config)) return LOCAL_FEC_RETENTION_BLOCKS;
|
|
2896
|
+
const terminalRetentionMs = config.interleaveDepthMs + 2 * this.#blockLifetimeMs(config);
|
|
2897
|
+
const blocks = Math.ceil(terminalRetentionMs / config.interleaveDepthMs) + 1;
|
|
2876
2898
|
if (!Number.isSafeInteger(blocks) || blocks <= 0) {
|
|
2877
2899
|
throw new Error(`[FECManager] packetId=${packetId} iso-ssbg1-v1 retention of ${blocks} blocks is not derivable`);
|
|
2878
2900
|
}
|
|
@@ -2880,7 +2902,8 @@ var FECManager = class _FECManager {
|
|
|
2880
2902
|
}
|
|
2881
2903
|
/** Whether an iso-ssbg1-v1 protected packet fits one ssbg_mode1 symbol (len + 2 <= T). */
|
|
2882
2904
|
isoSourceFits(packetId, packetLength) {
|
|
2883
|
-
|
|
2905
|
+
const symbolSize = this.#trackConfigs.get(packetId)?.symbolSize;
|
|
2906
|
+
return symbolSize !== void 0 && ssbg1FitsSymbol(packetLength, symbolSize);
|
|
2884
2907
|
}
|
|
2885
2908
|
/**
|
|
2886
2909
|
* Locate an iso-ssbg1-v1 source by range membership in a block a repair
|
|
@@ -2941,11 +2964,11 @@ var FECManager = class _FECManager {
|
|
|
2941
2964
|
* that could hold them is pending or not yet stated by a repair, else the
|
|
2942
2965
|
* starts of the blocks that failed or vanished.
|
|
2943
2966
|
*
|
|
2944
|
-
* `untracked` reads
|
|
2945
|
-
*
|
|
2946
|
-
*
|
|
2947
|
-
*
|
|
2948
|
-
* an SS_Start
|
|
2967
|
+
* `untracked` reads as the release gate reads it (MmtpRouter
|
|
2968
|
+
* #createFecReleaseGate): a block holding either released frame's SS_ID
|
|
2969
|
+
* (`fromSsId` or `toSsId`) delivered that frame, so untracked there means it
|
|
2970
|
+
* resolved and retired; a block starting after the stream's frontier
|
|
2971
|
+
* (`highestSbn`, an SS_Start) may still be heard from; a block at or behind the
|
|
2949
2972
|
* frontier that no symbol of this manager ever reached vanished, and its
|
|
2950
2973
|
* media is lost.
|
|
2951
2974
|
*/
|
|
@@ -3013,6 +3036,7 @@ var FECManager = class _FECManager {
|
|
|
3013
3036
|
}
|
|
3014
3037
|
/** Current classifier mode of a stream. */
|
|
3015
3038
|
classifierModeFor(packetId, catalogTrackName) {
|
|
3039
|
+
if (!this.#hasCatalogTimingForPacket(packetId)) return { mode: "all-protected", reason: null };
|
|
3016
3040
|
const classifier = this.#classifierFor(packetId, catalogTrackName);
|
|
3017
3041
|
return { mode: classifier.mode, reason: classifier.reason };
|
|
3018
3042
|
}
|
|
@@ -3022,10 +3046,12 @@ var FECManager = class _FECManager {
|
|
|
3022
3046
|
* it does not. A stream with no classifier yet has shown nothing against it.
|
|
3023
3047
|
*/
|
|
3024
3048
|
mpuBoundsRapsFor(packetId, catalogTrackName) {
|
|
3049
|
+
if (!this.#hasCatalogTimingForPacket(packetId)) return false;
|
|
3025
3050
|
return this.#classifiers.get(this.#streamKey(packetId, catalogTrackName))?.mpuBoundsRaps ?? true;
|
|
3026
3051
|
}
|
|
3027
3052
|
/** A block's class now, or frozen at its resolution. */
|
|
3028
3053
|
blockClassFor(sbn, packetId, catalogTrackName) {
|
|
3054
|
+
if (!this.#hasCatalogTimingForPacket(packetId)) return "unknown";
|
|
3029
3055
|
const frozen = this.#resolvedBlockClasses.get(this.#blockKey(sbn, packetId, catalogTrackName));
|
|
3030
3056
|
if (frozen !== void 0) return frozen;
|
|
3031
3057
|
return this.#peekClass(sbn, packetId, catalogTrackName);
|
|
@@ -3047,7 +3073,7 @@ var FECManager = class _FECManager {
|
|
|
3047
3073
|
* invariant (consecutive MPUs exactly one keyframe interval apart).
|
|
3048
3074
|
*/
|
|
3049
3075
|
noteReleasedRap(packetId, catalogTrackName, mpu, presentationTime, mediaTimescale) {
|
|
3050
|
-
if (!this.#trackConfigs.has(packetId)) return;
|
|
3076
|
+
if (!this.#trackConfigs.has(packetId) || !this.#hasCatalogTimingForPacket(packetId)) return;
|
|
3051
3077
|
this.#applyClassifierChanges(
|
|
3052
3078
|
packetId,
|
|
3053
3079
|
catalogTrackName,
|
|
@@ -3063,27 +3089,34 @@ var FECManager = class _FECManager {
|
|
|
3063
3089
|
// -----------------------------------------------------------------------
|
|
3064
3090
|
/** Configure FEC parameters. */
|
|
3065
3091
|
configure(config) {
|
|
3066
|
-
if (config.
|
|
3092
|
+
if (config.interleaveDepthMs != null && (!Number.isSafeInteger(config.interleaveDepthMs) || config.interleaveDepthMs < 0)) {
|
|
3093
|
+
throw new Error(
|
|
3094
|
+
`[FECManager] interleaveDepthMs=${config.interleaveDepthMs} must be a non-negative safe integer in milliseconds`
|
|
3095
|
+
);
|
|
3096
|
+
}
|
|
3097
|
+
if (config.timeoutMs != null && (!Number.isFinite(config.timeoutMs) || config.timeoutMs < 0)) {
|
|
3098
|
+
throw new Error(
|
|
3099
|
+
`[FECManager] timeoutMs=${config.timeoutMs} must be a finite non-negative cleanup budget`
|
|
3100
|
+
);
|
|
3101
|
+
}
|
|
3102
|
+
if (config.k != null && (!Number.isSafeInteger(config.k) || config.k <= 0)) {
|
|
3103
|
+
throw new Error(`[FECManager] k=${config.k} must be a positive integer`);
|
|
3104
|
+
}
|
|
3105
|
+
if (config.k != null) this.#streamK = config.k;
|
|
3067
3106
|
if (config.symbolSize != null && config.symbolSize > 0) this.#fecSymbolSize = config.symbolSize;
|
|
3068
3107
|
if (config.interleaveDepthMs != null) this.#fecInterleaveDepthMs = config.interleaveDepthMs;
|
|
3069
3108
|
if (config.fps != null && Number.isFinite(config.fps) && config.fps > 0) {
|
|
3070
3109
|
this.#fecFps = config.fps;
|
|
3071
3110
|
}
|
|
3072
|
-
if (config.interleaveDepthMs != null && config.interleaveDepthMs > 0 && config.interleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) {
|
|
3073
|
-
console.warn(`[FECManager] interleaveDepthMs=${config.interleaveDepthMs} looks like frame count, not milliseconds (\xA75.1 requires ms). Expected range: ${MIN_INTERLEAVE_DEPTH_MS}-10000ms.`);
|
|
3074
|
-
}
|
|
3075
3111
|
if (config.timeoutMs != null && config.timeoutMs > 0) {
|
|
3076
3112
|
this.#fecTimeoutMs = config.timeoutMs;
|
|
3077
|
-
} else if (config.interleaveDepthMs
|
|
3078
|
-
this.#fecTimeoutMs =
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
symbolSize: this.#fecSymbolSize,
|
|
3082
|
-
mediaUnitsPerSecond: config.fps
|
|
3083
|
-
});
|
|
3113
|
+
} else if (config.interleaveDepthMs === 0) {
|
|
3114
|
+
this.#fecTimeoutMs = LOCAL_FEC_TIMEOUT_MS;
|
|
3115
|
+
} else if (config.interleaveDepthMs != null && Number.isSafeInteger(config.interleaveDepthMs) && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
|
|
3116
|
+
this.#fecTimeoutMs = fecSpanDeliveryWindowMs(config.interleaveDepthMs);
|
|
3084
3117
|
}
|
|
3085
3118
|
for (const [packetId, track] of this.#trackConfigs) {
|
|
3086
|
-
if (track.timeoutMs < this.#fecTimeoutMs) {
|
|
3119
|
+
if (_FECManager.#hasCatalogTiming(track) && track.timeoutMs < this.#fecTimeoutMs) {
|
|
3087
3120
|
this.#trackConfigs.set(packetId, { ...track, timeoutMs: this.#fecTimeoutMs });
|
|
3088
3121
|
}
|
|
3089
3122
|
}
|
|
@@ -3142,7 +3175,7 @@ var FECManager = class _FECManager {
|
|
|
3142
3175
|
);
|
|
3143
3176
|
}
|
|
3144
3177
|
if (config) this.#upsertTrackConfig(packetId, config, catalogTrackName);
|
|
3145
|
-
const workerK = this.#
|
|
3178
|
+
const workerK = this.#trackConfig(packetId).k;
|
|
3146
3179
|
this.#workerClients.set(streamKey, client);
|
|
3147
3180
|
this.#releasedWorkerClients.delete(client);
|
|
3148
3181
|
client.onFrame((data, meta) => {
|
|
@@ -3322,7 +3355,7 @@ var FECManager = class _FECManager {
|
|
|
3322
3355
|
return;
|
|
3323
3356
|
}
|
|
3324
3357
|
this.#settleOwedCleanup(key, "cleanup-ack-timeout");
|
|
3325
|
-
}, Math.ceil(this.#liveBlockLifetimeMs(this.#
|
|
3358
|
+
}, Math.ceil(this.#liveBlockLifetimeMs(this.#trackConfig(packetId))))
|
|
3326
3359
|
};
|
|
3327
3360
|
this.#pendingWorkerCleanupBounds.set(key, bound);
|
|
3328
3361
|
}
|
|
@@ -3363,16 +3396,11 @@ var FECManager = class _FECManager {
|
|
|
3363
3396
|
if (this.#fpsDetected || fps <= 0) return;
|
|
3364
3397
|
this.#fpsDetected = true;
|
|
3365
3398
|
this.#fecFps = fps;
|
|
3366
|
-
if (this.#fecInterleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
|
|
3367
|
-
this.#fecTimeoutMs =
|
|
3368
|
-
interleaveDepthMs: this.#fecInterleaveDepthMs,
|
|
3369
|
-
sourceSymbols: this.#fecK,
|
|
3370
|
-
symbolSize: this.#fecSymbolSize,
|
|
3371
|
-
mediaUnitsPerSecond: fps
|
|
3372
|
-
});
|
|
3399
|
+
if (Number.isSafeInteger(this.#fecInterleaveDepthMs) && this.#fecInterleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
|
|
3400
|
+
this.#fecTimeoutMs = fecSpanDeliveryWindowMs(this.#fecInterleaveDepthMs);
|
|
3373
3401
|
}
|
|
3374
3402
|
for (const [packetId, config] of this.#trackConfigs) {
|
|
3375
|
-
if (config.fps !== void 0 || config.interleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) continue;
|
|
3403
|
+
if (config.fps !== void 0 || !Number.isSafeInteger(config.interleaveDepthMs) || config.interleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) continue;
|
|
3376
3404
|
this.#trackConfigs.set(packetId, {
|
|
3377
3405
|
...config,
|
|
3378
3406
|
fps,
|
|
@@ -3401,51 +3429,33 @@ var FECManager = class _FECManager {
|
|
|
3401
3429
|
* Caller is responsible for routing recovered data and updating
|
|
3402
3430
|
* block completion state via `markBlockCompleted()`.
|
|
3403
3431
|
*/
|
|
3404
|
-
feedSourceSymbol(packetId, ssId, symbolData,
|
|
3432
|
+
feedSourceSymbol(packetId, ssId, symbolData, catalogTrackName) {
|
|
3405
3433
|
this.#fecStats.sourcePackets++;
|
|
3406
3434
|
this.#statsForPacket(packetId).sourcePackets++;
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
this.#isoSourceOversizeCount++;
|
|
3420
|
-
return null;
|
|
3421
|
-
}
|
|
3422
|
-
sbn = located.block.start;
|
|
3423
|
-
fecData = symbolData;
|
|
3424
|
-
} else {
|
|
3425
|
-
fecData = this.#normalizeSymbolData(packetId, symbolData);
|
|
3426
|
-
sbn = Math.floor(ssId / this.kForPacket(packetId));
|
|
3435
|
+
if (!this.#hasBlockProfile(packetId)) return null;
|
|
3436
|
+
const locator = this.#isoLocatorFor(packetId, catalogTrackName);
|
|
3437
|
+
const located = locator.locate(ssId);
|
|
3438
|
+
if (located === null) {
|
|
3439
|
+
throw new Error(
|
|
3440
|
+
`[FECManager] iso-ssbg1-v1 source SS_ID=${ssId} (packetId=${packetId}) has no stated block; hold it until a repair places it (placeIsoRepair)`
|
|
3441
|
+
);
|
|
3442
|
+
}
|
|
3443
|
+
locator.observe(ssId);
|
|
3444
|
+
if (!ssbg1FitsSymbol(symbolData.byteLength, this.#trackConfig(packetId).symbolSize)) {
|
|
3445
|
+
this.#isoSourceOversizeCount++;
|
|
3446
|
+
return null;
|
|
3427
3447
|
}
|
|
3448
|
+
const sbn = located.block.start;
|
|
3428
3449
|
const blockKey = this.#blockKey(sbn, packetId, catalogTrackName);
|
|
3429
3450
|
const syncBlockOwner = this.#syncDecoderBlockOwners.get(blockKey);
|
|
3430
3451
|
const workerClient = this.#routableWorkerForPacket(packetId, catalogTrackName);
|
|
3431
3452
|
if (workerClient && !syncBlockOwner) {
|
|
3432
3453
|
if (!this.#claimDecoderBlock(workerClient, sbn, catalogTrackName)) return null;
|
|
3433
|
-
const buf =
|
|
3434
|
-
|
|
3435
|
-
|
|
3454
|
+
const buf = symbolData.buffer.slice(
|
|
3455
|
+
symbolData.byteOffset,
|
|
3456
|
+
symbolData.byteOffset + symbolData.byteLength
|
|
3436
3457
|
);
|
|
3437
|
-
|
|
3438
|
-
const authBuf = alta.auth.buffer.slice(
|
|
3439
|
-
alta.auth.byteOffset,
|
|
3440
|
-
alta.auth.byteOffset + alta.auth.byteLength
|
|
3441
|
-
);
|
|
3442
|
-
workerClient.feedSource(ssId, buf, performance.now(), {
|
|
3443
|
-
auth: authBuf,
|
|
3444
|
-
payloadEnd: alta.payloadEnd
|
|
3445
|
-
});
|
|
3446
|
-
} else {
|
|
3447
|
-
workerClient.feedSource(ssId, buf, performance.now());
|
|
3448
|
-
}
|
|
3458
|
+
workerClient.feedSource(ssId, buf, performance.now());
|
|
3449
3459
|
return null;
|
|
3450
3460
|
}
|
|
3451
3461
|
const entry = this.#decoderForPacket(packetId, catalogTrackName);
|
|
@@ -3455,7 +3465,7 @@ var FECManager = class _FECManager {
|
|
|
3455
3465
|
this.#syncDecoderBlockOwners.set(blockKey, client);
|
|
3456
3466
|
let recovered = null;
|
|
3457
3467
|
try {
|
|
3458
|
-
recovered = client.add_source(ssId,
|
|
3468
|
+
recovered = client.add_source(ssId, symbolData, performance.now());
|
|
3459
3469
|
} catch {
|
|
3460
3470
|
}
|
|
3461
3471
|
this.#retireIsoUnplaced(client, packetId, catalogTrackName);
|
|
@@ -3474,7 +3484,8 @@ var FECManager = class _FECManager {
|
|
|
3474
3484
|
feedRepairSymbol(packetId, ssStart, ssbLength, rsId, repairData, catalogTrackName) {
|
|
3475
3485
|
this.#fecStats.repairPackets++;
|
|
3476
3486
|
this.#statsForPacket(packetId).repairPackets++;
|
|
3477
|
-
|
|
3487
|
+
if (!this.#hasBlockProfile(packetId)) return null;
|
|
3488
|
+
const symbolSize = this.#trackConfig(packetId).symbolSize;
|
|
3478
3489
|
if (symbolSize > 0 && repairData.byteLength !== symbolSize) {
|
|
3479
3490
|
this.#repairSymbolSizeMismatchCount++;
|
|
3480
3491
|
if (this.#repairSymbolSizeMismatchCount <= 5 || this.#repairSymbolSizeMismatchCount % 100 === 0) {
|
|
@@ -3485,18 +3496,12 @@ var FECManager = class _FECManager {
|
|
|
3485
3496
|
return null;
|
|
3486
3497
|
}
|
|
3487
3498
|
const fecData = repairData;
|
|
3488
|
-
const k = this
|
|
3489
|
-
|
|
3490
|
-
if (
|
|
3491
|
-
|
|
3492
|
-
if (ssbLength <= 0 || ssbLength > k || block === void 0 || block.span || block.length !== ssbLength) {
|
|
3493
|
-
return null;
|
|
3494
|
-
}
|
|
3495
|
-
sbn = ssStart;
|
|
3496
|
-
} else {
|
|
3497
|
-
if (ssbLength <= 0 || ssbLength > k || ssStart % k !== 0) return null;
|
|
3498
|
-
sbn = Math.floor(ssStart / k);
|
|
3499
|
+
const k = this.#trackConfig(packetId).k;
|
|
3500
|
+
const block = this.#isoLocatorFor(packetId, catalogTrackName).blockAt(ssStart);
|
|
3501
|
+
if (ssbLength <= 0 || ssbLength > k || block === void 0 || block.span || block.length !== ssbLength) {
|
|
3502
|
+
return null;
|
|
3499
3503
|
}
|
|
3504
|
+
const sbn = ssStart;
|
|
3500
3505
|
this.#noteSbnSeen(sbn, packetId, catalogTrackName, "repair");
|
|
3501
3506
|
this.noteBlockActivity(sbn, packetId, catalogTrackName);
|
|
3502
3507
|
const blockKey = this.#blockKey(sbn, packetId, catalogTrackName);
|
|
@@ -3534,8 +3539,9 @@ var FECManager = class _FECManager {
|
|
|
3534
3539
|
* Record a block's authored SSB_length from a repair symbol. Returns false,
|
|
3535
3540
|
* leaving the block unchanged, when the symbol contradicts the block: a
|
|
3536
3541
|
* different SSB_length than an earlier repair symbol declared is dropped,
|
|
3537
|
-
* and an SSB_length that places an already-received source ESI
|
|
3538
|
-
*
|
|
3542
|
+
* and an SSB_length that places an already-received source ESI at or past
|
|
3543
|
+
* the block's end fails the block, since its geometry can no longer be
|
|
3544
|
+
* trusted.
|
|
3539
3545
|
*/
|
|
3540
3546
|
#noteAuthoredLength(blockKey, sbn, packetId, ssbLength, catalogTrackName) {
|
|
3541
3547
|
const known = this.#blockAuthoredLengths.get(blockKey);
|
|
@@ -3602,7 +3608,7 @@ var FECManager = class _FECManager {
|
|
|
3602
3608
|
* a sweep tied to expiry alone would never run there.
|
|
3603
3609
|
*/
|
|
3604
3610
|
#retireIsoUnplaced(decoder, packetId, catalogTrackName) {
|
|
3605
|
-
if (!this.#
|
|
3611
|
+
if (!this.#hasBlockProfile(packetId)) return;
|
|
3606
3612
|
const newest = this.#isoLocators.get(this.#streamKey(packetId, catalogTrackName))?.newest;
|
|
3607
3613
|
if (newest === void 0) return;
|
|
3608
3614
|
try {
|
|
@@ -3647,11 +3653,13 @@ var FECManager = class _FECManager {
|
|
|
3647
3653
|
this.#failBlock(sbn, packetId, catalogTrackName);
|
|
3648
3654
|
return;
|
|
3649
3655
|
}
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3656
|
+
if (_FECManager.#hasCatalogTiming(trackConfig)) {
|
|
3657
|
+
this.#applyClassifierChanges(
|
|
3658
|
+
packetId,
|
|
3659
|
+
catalogTrackName,
|
|
3660
|
+
this.#classifierFor(packetId, catalogTrackName).observe(sbn, evidence)
|
|
3661
|
+
);
|
|
3662
|
+
}
|
|
3655
3663
|
const count = (this.#blockSourceCounts.get(key) ?? 0) + 1;
|
|
3656
3664
|
this.#blockSourceCounts.set(key, count);
|
|
3657
3665
|
if (count === 1) this.#indexBlockKey(key, sbn, packetId);
|
|
@@ -3695,6 +3703,7 @@ var FECManager = class _FECManager {
|
|
|
3695
3703
|
}
|
|
3696
3704
|
/** Refresh deadlines after accepted block activity. */
|
|
3697
3705
|
noteBlockActivity(sbn, packetId, catalogTrackName, sourceProgress = false) {
|
|
3706
|
+
if (!this.#trackConfigs.has(packetId)) return;
|
|
3698
3707
|
const key = this.#blockKey(sbn, packetId, catalogTrackName);
|
|
3699
3708
|
if (this.#completedBlocks.has(key)) return;
|
|
3700
3709
|
if (this.#pendingWorkerCleanups.has(key)) return;
|
|
@@ -3704,13 +3713,13 @@ var FECManager = class _FECManager {
|
|
|
3704
3713
|
this.#holdForOrderedSettlement(key, sbn, packetId, catalogTrackName);
|
|
3705
3714
|
return;
|
|
3706
3715
|
}
|
|
3707
|
-
const trackConfig = this.#
|
|
3716
|
+
const trackConfig = this.#trackConfig(packetId);
|
|
3708
3717
|
const timeoutMs = this.#multicastWaitMs(trackConfig);
|
|
3709
3718
|
if (!(timeoutMs > 0)) {
|
|
3710
3719
|
throw new Error(`[FECManager] packetId=${packetId} has no positive fail bound (timeoutMs=${timeoutMs})`);
|
|
3711
3720
|
}
|
|
3712
3721
|
const repairDeadline = this.#repairDeadlines.get(key);
|
|
3713
|
-
if (this.onRepairNeeded && !repairRequested && (repairDeadline === void 0 || sourceProgress)) {
|
|
3722
|
+
if (this.#hasCatalogTimingForPacket(packetId) && this.onRepairNeeded && !repairRequested && (repairDeadline === void 0 || sourceProgress)) {
|
|
3714
3723
|
this.#armRepairDeadline(
|
|
3715
3724
|
key,
|
|
3716
3725
|
sbn,
|
|
@@ -3780,6 +3789,7 @@ var FECManager = class _FECManager {
|
|
|
3780
3789
|
}
|
|
3781
3790
|
/** Mark a block as completed externally (e.g., after routing recovered data). */
|
|
3782
3791
|
markBlockCompleted(sbn, packetId, catalogTrackName) {
|
|
3792
|
+
if (packetId != null && !this.#trackConfigs.has(packetId)) return;
|
|
3783
3793
|
for (const key of this.#blockKeysFor(sbn, packetId, catalogTrackName)) {
|
|
3784
3794
|
this.#resolveCompleted(key);
|
|
3785
3795
|
}
|