@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
|
@@ -1,892 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MMTP_EXT_TYPE_ALTA_AUTH as _LEAF_MMTP_EXT_TYPE_ALTA_AUTH,
|
|
3
|
-
MMTP_EXT_TRAILER_HEADER_SIZE as _LEAF_MMTP_EXT_TRAILER_HEADER_SIZE,
|
|
4
|
-
extractAltaTrailer as _leafExtractAltaTrailer,
|
|
5
|
-
type AltaTrailer as _LeafAltaTrailer,
|
|
6
|
-
} from '@blockcast/mmt-alta-parse'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @mmt/container - MMTP Parser
|
|
10
|
-
*
|
|
11
|
-
* MMTP (MMT Protocol) packet parser based on ISO/IEC 23008-1:2023 Section 9.2
|
|
12
|
-
*
|
|
13
|
-
* MMTP header format (12 bytes):
|
|
14
|
-
* - Byte 0: V(2) | C(1) | FEC_type(2) | r(1) | X(1) | R(1)
|
|
15
|
-
* - Byte 1: reserved(2) | packet_type(6)
|
|
16
|
-
* - Bytes 2-3: packet_id (big-endian)
|
|
17
|
-
* - Bytes 4-7: timestamp (big-endian, 32-bit)
|
|
18
|
-
* - Bytes 8-11: sequence_number (big-endian)
|
|
19
|
-
*
|
|
20
|
-
* FEC_type values:
|
|
21
|
-
* - 0: No FEC / source packet
|
|
22
|
-
* - 1: FEC mode 0 (source with FEC payload ID)
|
|
23
|
-
* - 2: FEC repair packet mode 0
|
|
24
|
-
* - 3: FEC repair packet mode 1
|
|
25
|
-
*
|
|
26
|
-
* @packageDocumentation
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
export interface MMTPHeader {
|
|
30
|
-
version: number
|
|
31
|
-
/** Packet type: 0x00=MPU, 0x02=Signaling, 0x03=Repair */
|
|
32
|
-
packetType: number
|
|
33
|
-
packetId: number
|
|
34
|
-
timestamp: bigint
|
|
35
|
-
sequenceNumber: number
|
|
36
|
-
payloadLength: number
|
|
37
|
-
fecType: number
|
|
38
|
-
/** C flag: header carries a 32-bit packet_counter. */
|
|
39
|
-
packetCounterFlag: boolean
|
|
40
|
-
packetCounter?: number
|
|
41
|
-
/** X flag: header carries an extension header and value. */
|
|
42
|
-
extensionFlag: boolean
|
|
43
|
-
extension?: { type: number; data: Uint8Array }
|
|
44
|
-
/** Byte offset at which the MMTP payload begins. */
|
|
45
|
-
headerLength: number
|
|
46
|
-
/** Random Access Point flag - indicates keyframe (ISO 23008-1, byte 0 bit 0) */
|
|
47
|
-
rapFlag: boolean
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface MPUHeader {
|
|
51
|
-
mpuSequenceNumber: number
|
|
52
|
-
fragmentationIndicator: number // FI: 0=complete, 1=first, 2=middle, 3=last
|
|
53
|
-
/** 8-bit MPU fragment_counter from byte 3. */
|
|
54
|
-
fragmentCounter: number
|
|
55
|
-
/** T flag: 1=timed media (14-byte MFU DU header), 0=non-timed (4-byte header) */
|
|
56
|
-
timedFlag: number
|
|
57
|
-
/** A flag: aggregated MPU payload. This strict profile requires A=0. */
|
|
58
|
-
aggregationFlag: boolean
|
|
59
|
-
/** MPU payload_length (bytes 0-1): bytes after the length field, including
|
|
60
|
-
* the remaining six MPU-header bytes and all data-unit bytes. */
|
|
61
|
-
payloadLength: number
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface MFUDuHeader {
|
|
65
|
-
movieFragmentSequenceNumber: number
|
|
66
|
-
sampleNumber: number
|
|
67
|
-
offset: number
|
|
68
|
-
priority: number
|
|
69
|
-
dependencyCounter: number
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface MMTPPacket {
|
|
73
|
-
header: MMTPHeader
|
|
74
|
-
payload: Uint8Array
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export const MMTP_HEADER_SIZE = 12
|
|
78
|
-
export const MPU_HEADER_SIZE = 8
|
|
79
|
-
export const MFU_DU_HEADER_SIZE_TIMED = 14 // T=1: timed media (video/audio samples)
|
|
80
|
-
export const MFU_DU_HEADER_SIZE_NONTIMED = 4 // T=0: non-timed media (item_id only)
|
|
81
|
-
|
|
82
|
-
const MPU_LENGTH_FIELD_SIZE = 2
|
|
83
|
-
const MPU_HEADER_REMAINDER_SIZE = MPU_HEADER_SIZE - MPU_LENGTH_FIELD_SIZE
|
|
84
|
-
const SOURCE_FEC_PAYLOAD_ID_SIZE = 4
|
|
85
|
-
|
|
86
|
-
// MMTP Packet Types (ISO/IEC 23008-1:2023 Section 9.2.2)
|
|
87
|
-
export const PACKET_TYPE_MPU = 0x00
|
|
88
|
-
export const PACKET_TYPE_SIGNALING = 0x02
|
|
89
|
-
export const PACKET_TYPE_REPAIR = 0x03
|
|
90
|
-
|
|
91
|
-
// AL-FEC Signaling Message ID (ISO/IEC 23008-1:2023 Amendment 1:2025)
|
|
92
|
-
export const ALFEC_MESSAGE_ID = 0x0203
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* MMTP `packet_id` of the signaling flow, which carries PACKET_TYPE_SIGNALING
|
|
96
|
-
* packets such as the AL-FEC message (ALFEC_MESSAGE_ID). The FFmpeg `moq_mmt`
|
|
97
|
-
* muxer sends that message on this packet_id into the same multicast group as
|
|
98
|
-
* the media, and moqcast-draft (PR #44) makes advertising it for a track a
|
|
99
|
-
* MUST NOT. A track's packet_id is therefore 1..MMTP_PACKET_ID_MAX.
|
|
100
|
-
*/
|
|
101
|
-
export const MMTP_SIGNALING_PACKET_ID = 0
|
|
102
|
-
|
|
103
|
-
/** Largest value of the 16-bit MMTP `packet_id` header field. */
|
|
104
|
-
export const MMTP_PACKET_ID_MAX = 0xffff
|
|
105
|
-
|
|
106
|
-
// FEC Code IDs
|
|
107
|
-
export const FEC_CODE_XOR = 1
|
|
108
|
-
export const FEC_CODE_RAPTORQ = 2
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Parse MMTP header from buffer
|
|
112
|
-
*/
|
|
113
|
-
export function parseMMTPHeader(buffer: Uint8Array): MMTPHeader {
|
|
114
|
-
if (buffer.length < MMTP_HEADER_SIZE) {
|
|
115
|
-
throw new Error(`MMTP packet too small: ${buffer.length} bytes`)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
|
|
119
|
-
|
|
120
|
-
const version = (buffer[0]! >> 6) & 0x03
|
|
121
|
-
if (version !== 0) {
|
|
122
|
-
throw new Error(`Unsupported MMTP version: ${version}`)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Extract FEC type from byte 0, bits 3-4
|
|
126
|
-
const fecType = (buffer[0]! >> 3) & 0x03
|
|
127
|
-
const packetCounterFlag = (buffer[0]! & 0x20) !== 0
|
|
128
|
-
const extensionFlag = (buffer[0]! & 0x02) !== 0
|
|
129
|
-
|
|
130
|
-
// Extract RAP flag from byte 0, bit 0 (R bit - Random Access Point)
|
|
131
|
-
const rapFlag = (buffer[0]! & 0x01) === 1
|
|
132
|
-
|
|
133
|
-
// ISO/IEC 23008-1:2023 Figure 8 (V=0) places reserved(2) before
|
|
134
|
-
// packet_type(6), so packet_type occupies the low six bits of byte 1.
|
|
135
|
-
const packetType = buffer[1]! & 0x3F
|
|
136
|
-
|
|
137
|
-
let offset = 2
|
|
138
|
-
|
|
139
|
-
// Packet ID (2 bytes, big-endian)
|
|
140
|
-
const packetId = view.getUint16(offset, false)
|
|
141
|
-
offset += 2
|
|
142
|
-
|
|
143
|
-
// Timestamp (4 bytes, big-endian)
|
|
144
|
-
const timestamp = BigInt(view.getUint32(offset, false))
|
|
145
|
-
offset += 4
|
|
146
|
-
|
|
147
|
-
// Sequence number (4 bytes, big-endian)
|
|
148
|
-
const sequenceNumber = view.getUint32(offset, false)
|
|
149
|
-
offset += 4
|
|
150
|
-
|
|
151
|
-
let packetCounter: number | undefined
|
|
152
|
-
if (packetCounterFlag) {
|
|
153
|
-
if (offset + 4 > buffer.length) throw new Error('MMTP packet truncated in packet_counter')
|
|
154
|
-
packetCounter = view.getUint32(offset, false)
|
|
155
|
-
offset += 4
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
let extension: { type: number; data: Uint8Array } | undefined
|
|
159
|
-
if (extensionFlag) {
|
|
160
|
-
if (offset + 4 > buffer.length) throw new Error('MMTP packet truncated in header extension')
|
|
161
|
-
const type = view.getUint16(offset, false)
|
|
162
|
-
const length = view.getUint16(offset + 2, false)
|
|
163
|
-
offset += 4
|
|
164
|
-
if (offset + length > buffer.length) throw new Error('MMTP packet truncated in header extension value')
|
|
165
|
-
extension = { type, data: buffer.subarray(offset, offset + length) }
|
|
166
|
-
offset += length
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return {
|
|
170
|
-
version,
|
|
171
|
-
packetType,
|
|
172
|
-
packetId,
|
|
173
|
-
timestamp,
|
|
174
|
-
sequenceNumber,
|
|
175
|
-
payloadLength: buffer.length - offset,
|
|
176
|
-
fecType,
|
|
177
|
-
packetCounterFlag,
|
|
178
|
-
packetCounter,
|
|
179
|
-
extensionFlag,
|
|
180
|
-
extension,
|
|
181
|
-
headerLength: offset,
|
|
182
|
-
rapFlag,
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* The MMTP `packet_id` of `buffer`, or null exactly when parseMMTPHeader would
|
|
188
|
-
* throw for it (short buffer, V != 0, truncated packet_counter or header
|
|
189
|
-
* extension).
|
|
190
|
-
*
|
|
191
|
-
* This is the per-packet filter a receiver runs before any other work, so it
|
|
192
|
-
* builds no header object, DataView or BigInt timestamp (BLO-36599). Use
|
|
193
|
-
* parseMMTPHeader when any other header field is needed.
|
|
194
|
-
*/
|
|
195
|
-
export function readMMTPPacketId(buffer: Uint8Array): number | null {
|
|
196
|
-
if (buffer.length < MMTP_HEADER_SIZE) return null
|
|
197
|
-
const flags = buffer[0]!
|
|
198
|
-
if (((flags >> 6) & 0x03) !== 0) return null
|
|
199
|
-
let offset = MMTP_HEADER_SIZE
|
|
200
|
-
if ((flags & 0x20) !== 0) {
|
|
201
|
-
if (offset + 4 > buffer.length) return null
|
|
202
|
-
offset += 4
|
|
203
|
-
}
|
|
204
|
-
if ((flags & 0x02) !== 0) {
|
|
205
|
-
if (offset + 4 > buffer.length) return null
|
|
206
|
-
const length = (buffer[offset + 2]! << 8) | buffer[offset + 3]!
|
|
207
|
-
if (offset + 4 + length > buffer.length) return null
|
|
208
|
-
}
|
|
209
|
-
return (buffer[2]! << 8) | buffer[3]!
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Unwrap MMTP packet to extract payload
|
|
214
|
-
*/
|
|
215
|
-
export function unwrapMMTP(buffer: Uint8Array): MMTPPacket {
|
|
216
|
-
const header = parseMMTPHeader(buffer)
|
|
217
|
-
const payload = buffer.subarray(header.headerLength)
|
|
218
|
-
|
|
219
|
-
return { header, payload }
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Parse MPU header from payload
|
|
224
|
-
* ISO/IEC 23008-1:2023 Section 9.2.3.3
|
|
225
|
-
*
|
|
226
|
-
* MPU Header format (8 bytes) as written by FFmpeg/libmmt:
|
|
227
|
-
* - Bytes 0-1: payload_length (16 bits, big-endian)
|
|
228
|
-
* - Byte 2: FT(4) | T(1) | FI(2) | A(1)
|
|
229
|
-
* - Byte 3: fragment_counter (8 bits)
|
|
230
|
-
* - Bytes 4-7: MPU_sequence_number (32 bits, big-endian)
|
|
231
|
-
*/
|
|
232
|
-
export function parseMPUHeader(payload: Uint8Array): MPUHeader {
|
|
233
|
-
if (payload.length < MPU_HEADER_SIZE) {
|
|
234
|
-
throw new Error(`Payload too small for MPU header: ${payload.length} bytes`)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength)
|
|
238
|
-
|
|
239
|
-
// Bytes 0-1: payload_length (16 bits, big-endian)
|
|
240
|
-
const payloadLength = view.getUint16(0, false)
|
|
241
|
-
|
|
242
|
-
// Byte 2: FT(4) | T(1) | FI(2) | A(1)
|
|
243
|
-
const flagsByte = payload[2]!
|
|
244
|
-
const timedFlag = (flagsByte >> 3) & 0x01
|
|
245
|
-
const fragmentationIndicator = (flagsByte >> 1) & 0x03
|
|
246
|
-
const aggregationFlag = (flagsByte & 0x01) !== 0
|
|
247
|
-
|
|
248
|
-
// Byte 3: fragment_counter (8 bits). The high bit is part of the counter in
|
|
249
|
-
// the current libmmt/FFmpeg writer ABI.
|
|
250
|
-
const fragmentCounter = payload[3]!
|
|
251
|
-
|
|
252
|
-
// Bytes 4-7: MPU_sequence_number (32 bits, big-endian)
|
|
253
|
-
const mpuSequenceNumber = view.getUint32(4, false)
|
|
254
|
-
|
|
255
|
-
return {
|
|
256
|
-
mpuSequenceNumber,
|
|
257
|
-
fragmentationIndicator,
|
|
258
|
-
fragmentCounter,
|
|
259
|
-
timedFlag,
|
|
260
|
-
aggregationFlag,
|
|
261
|
-
payloadLength,
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
export function parseTimedMfuDuHeader(payload: Uint8Array, offset: number): MFUDuHeader | null {
|
|
266
|
-
if (offset < 0 || offset + MFU_DU_HEADER_SIZE_TIMED > payload.length) return null
|
|
267
|
-
const view = new DataView(payload.buffer, payload.byteOffset + offset, MFU_DU_HEADER_SIZE_TIMED)
|
|
268
|
-
return {
|
|
269
|
-
movieFragmentSequenceNumber: view.getUint32(0, false),
|
|
270
|
-
sampleNumber: view.getUint32(4, false),
|
|
271
|
-
offset: view.getUint32(8, false),
|
|
272
|
-
priority: payload[offset + 12]!,
|
|
273
|
-
dependencyCounter: payload[offset + 13]!,
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Why `extractMFUPayload` refused a packet.
|
|
279
|
-
*
|
|
280
|
-
* These identifiers are part of the public contract: callers surface them in
|
|
281
|
-
* diagnostics, so renaming one is a breaking change.
|
|
282
|
-
*/
|
|
283
|
-
export type MFURejectionGate =
|
|
284
|
-
| 'packet-shorter-than-mmtp-plus-mpu-header'
|
|
285
|
-
| 'mmtp-header-unparseable'
|
|
286
|
-
| 'not-an-mpu-packet'
|
|
287
|
-
| 'payload-shorter-than-mpu-header'
|
|
288
|
-
| 'aggregation-flag-set'
|
|
289
|
-
| 'mpu-payload-length-below-header-remainder'
|
|
290
|
-
| 'mpu-declared-end-exceeds-payload'
|
|
291
|
-
| 'mfu-offset-at-or-past-declared-end'
|
|
292
|
-
| 'source-fec-payload-id-width-mismatch'
|
|
293
|
-
| 'declared-trailers-unresolved'
|
|
294
|
-
|
|
295
|
-
export interface MFURejection {
|
|
296
|
-
gate: MFURejectionGate
|
|
297
|
-
/** Human-readable detail, including the byte arithmetic that decided it. */
|
|
298
|
-
detail: string
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
interface MfuPayloadLayout {
|
|
302
|
-
hasMfuDuHeader: boolean
|
|
303
|
-
mfuOffset: number
|
|
304
|
-
dataEnd: number
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
function resolveMfuPayloadLayout(
|
|
308
|
-
mpu: MPUHeader,
|
|
309
|
-
fragmentType: number,
|
|
310
|
-
payload: Uint8Array,
|
|
311
|
-
): { layout: MfuPayloadLayout } | { rejection: MFURejection } {
|
|
312
|
-
if (mpu.payloadLength < MPU_HEADER_REMAINDER_SIZE) {
|
|
313
|
-
return {
|
|
314
|
-
rejection: {
|
|
315
|
-
gate: 'mpu-payload-length-below-header-remainder',
|
|
316
|
-
detail: `payload_length=${mpu.payloadLength} < ${MPU_HEADER_REMAINDER_SIZE}`,
|
|
317
|
-
},
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// ISO/IEC 23008-1 defines payload_length from immediately after its own
|
|
322
|
-
// two-byte field. It therefore includes the remaining six MPU-header bytes.
|
|
323
|
-
const declaredEnd = MPU_LENGTH_FIELD_SIZE + mpu.payloadLength
|
|
324
|
-
if (declaredEnd > payload.length) {
|
|
325
|
-
return {
|
|
326
|
-
rejection: {
|
|
327
|
-
gate: 'mpu-declared-end-exceeds-payload',
|
|
328
|
-
detail:
|
|
329
|
-
`payload_length=${mpu.payloadLength} implies end=${declaredEnd}, ` +
|
|
330
|
-
`payload is ${payload.length} bytes`,
|
|
331
|
-
},
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
const hasHeader = fragmentType === 2 && mpu.fragmentationIndicator <= 1
|
|
336
|
-
const mfuHeaderSize = mpu.timedFlag ? MFU_DU_HEADER_SIZE_TIMED : MFU_DU_HEADER_SIZE_NONTIMED
|
|
337
|
-
const mfuOffset = MPU_HEADER_SIZE + (hasHeader ? mfuHeaderSize : 0)
|
|
338
|
-
if (mfuOffset >= declaredEnd) {
|
|
339
|
-
return {
|
|
340
|
-
rejection: {
|
|
341
|
-
gate: 'mfu-offset-at-or-past-declared-end',
|
|
342
|
-
detail: `mfuOffset=${mfuOffset} >= declaredEnd=${declaredEnd}`,
|
|
343
|
-
},
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return {
|
|
348
|
-
layout: {
|
|
349
|
-
hasMfuDuHeader: hasHeader,
|
|
350
|
-
mfuOffset,
|
|
351
|
-
dataEnd: declaredEnd,
|
|
352
|
-
},
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
function isEmptyOrExactAltaTrailer(payload: Uint8Array, start: number, end: number): boolean {
|
|
357
|
-
if (start === end) return true
|
|
358
|
-
if (start < 0 || end > payload.length || start + _LEAF_MMTP_EXT_TRAILER_HEADER_SIZE > end) {
|
|
359
|
-
return false
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
const view = new DataView(
|
|
363
|
-
payload.buffer,
|
|
364
|
-
payload.byteOffset + start,
|
|
365
|
-
end - start,
|
|
366
|
-
)
|
|
367
|
-
if (view.getUint16(0, false) !== _LEAF_MMTP_EXT_TYPE_ALTA_AUTH) return false
|
|
368
|
-
|
|
369
|
-
const authLength = view.getUint16(2, false)
|
|
370
|
-
return start + _LEAF_MMTP_EXT_TRAILER_HEADER_SIZE + authLength === end
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
interface DeclaredTrailerLayout {
|
|
374
|
-
hasFecId: boolean
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function resolveDeclaredTrailers(
|
|
378
|
-
payload: Uint8Array,
|
|
379
|
-
declaredEnd: number,
|
|
380
|
-
fecType: number,
|
|
381
|
-
options?: { skipFecId?: boolean },
|
|
382
|
-
): DeclaredTrailerLayout | null {
|
|
383
|
-
if (declaredEnd > payload.length) return null
|
|
384
|
-
|
|
385
|
-
if (options?.skipFecId) {
|
|
386
|
-
return isEmptyOrExactAltaTrailer(payload, declaredEnd, payload.length)
|
|
387
|
-
? { hasFecId: false }
|
|
388
|
-
: null
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (fecType === 1) {
|
|
392
|
-
const fecStart = payload.length - SOURCE_FEC_PAYLOAD_ID_SIZE
|
|
393
|
-
if (fecStart < declaredEnd || !isEmptyOrExactAltaTrailer(payload, declaredEnd, fecStart)) {
|
|
394
|
-
return null
|
|
395
|
-
}
|
|
396
|
-
return { hasFecId: true }
|
|
397
|
-
}
|
|
398
|
-
if (fecType !== 0) return null
|
|
399
|
-
|
|
400
|
-
if (isEmptyOrExactAltaTrailer(payload, declaredEnd, payload.length)) {
|
|
401
|
-
return { hasFecId: false }
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
return null
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Extract NAL unit payload from MMTP packet
|
|
409
|
-
*/
|
|
410
|
-
export function extractNALUnit(mmtpPacket: Uint8Array): Uint8Array {
|
|
411
|
-
const extraction = extractMFUPayload(mmtpPacket)
|
|
412
|
-
if (!extraction) throw new Error('Malformed MMTP MPU payload')
|
|
413
|
-
return extraction.data
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
/** Result of extracting MFU payload from an MMTP packet */
|
|
417
|
-
export interface MFUExtraction {
|
|
418
|
-
/** MMTP header fields */
|
|
419
|
-
header: MMTPHeader
|
|
420
|
-
/** MPU header fields */
|
|
421
|
-
mpu: MPUHeader
|
|
422
|
-
/** Fragment type (FT field, 4 bits): 0=metadata, 2=MFU data */
|
|
423
|
-
fragmentType: number
|
|
424
|
-
/** MFU payload data (video/audio bytes, headers stripped, FEC ID excluded) */
|
|
425
|
-
data: Uint8Array
|
|
426
|
-
/** Parsed timed MFU DU header when present, otherwise null */
|
|
427
|
-
mfuDuHeader: MFUDuHeader | null
|
|
428
|
-
/** Non-timed MFU Item_ID when the 4-byte DU header is present. */
|
|
429
|
-
itemId: number | null
|
|
430
|
-
/** Source FEC Payload ID if present (`FEC_type == 1`), or null */
|
|
431
|
-
fecPayloadId: { ssId: number } | null
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Extract MFU payload from a raw MMTP packet.
|
|
436
|
-
*
|
|
437
|
-
* Handles all the byte arithmetic for:
|
|
438
|
-
* - MMTP header (12 bytes)
|
|
439
|
-
* - MPU sub-header (8 bytes, payloadLength field)
|
|
440
|
-
* - MFU DU header (14 bytes timed / 4 bytes non-timed, only for FI ≤ 1)
|
|
441
|
-
* - Source FEC Payload ID (4 bytes at end, only when `FEC_type == 1`)
|
|
442
|
-
*
|
|
443
|
-
* `payloadLength` is the ISO length-after-field value: six remaining MPU-header
|
|
444
|
-
* bytes, then the MFU DU header when present, then media. ALTA and Source FEC
|
|
445
|
-
* trailers are outside that declared span and must consume the exact suffix.
|
|
446
|
-
*
|
|
447
|
-
* @param mmtpPacket Raw MMTP packet (from multicast or MoQ)
|
|
448
|
-
* @param options.skipFecId When true, do NOT subtract the 4-byte Source FEC Payload ID
|
|
449
|
-
* from the payload boundary, even if fecType >= 1 in the MMTP header. Use this for
|
|
450
|
-
* FEC-recovered symbols where the FEC PID was already stripped before WASM decoding
|
|
451
|
-
* but the fecType bits in byte 0 still reflect the original packet (FEC Type=1 per
|
|
452
|
-
* draft-ramadan-moq-mmt-00 §3.1).
|
|
453
|
-
* @returns Extracted MFU data + metadata, or null if packet is too small
|
|
454
|
-
*/
|
|
455
|
-
interface MfuPlan {
|
|
456
|
-
header: MMTPHeader
|
|
457
|
-
payload: Uint8Array
|
|
458
|
-
mpu: MPUHeader
|
|
459
|
-
fragmentType: number
|
|
460
|
-
layout: MfuPayloadLayout
|
|
461
|
-
trailerLayout: DeclaredTrailerLayout
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Single source of truth for whether a packet yields an MFU payload.
|
|
466
|
-
*
|
|
467
|
-
* `extractMFUPayload` and `explainMFURejection` both delegate here, so the
|
|
468
|
-
* reason reported to operators can never drift from the decision the parser
|
|
469
|
-
* actually made.
|
|
470
|
-
*/
|
|
471
|
-
function planMfuExtraction(
|
|
472
|
-
mmtpPacket: Uint8Array,
|
|
473
|
-
options?: { skipFecId?: boolean },
|
|
474
|
-
parsedHeader?: MMTPHeader,
|
|
475
|
-
): { plan: MfuPlan } | { rejection: MFURejection } {
|
|
476
|
-
if (mmtpPacket.length < MMTP_HEADER_SIZE + MPU_HEADER_SIZE) {
|
|
477
|
-
return {
|
|
478
|
-
rejection: {
|
|
479
|
-
gate: 'packet-shorter-than-mmtp-plus-mpu-header',
|
|
480
|
-
detail: `${mmtpPacket.length} bytes < ${MMTP_HEADER_SIZE + MPU_HEADER_SIZE}`,
|
|
481
|
-
},
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
let header: MMTPHeader
|
|
486
|
-
if (parsedHeader) {
|
|
487
|
-
header = parsedHeader
|
|
488
|
-
} else {
|
|
489
|
-
try {
|
|
490
|
-
header = parseMMTPHeader(mmtpPacket)
|
|
491
|
-
} catch (error) {
|
|
492
|
-
return {
|
|
493
|
-
rejection: {
|
|
494
|
-
gate: 'mmtp-header-unparseable',
|
|
495
|
-
detail: error instanceof Error ? error.message : String(error),
|
|
496
|
-
},
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
if (header.packetType !== PACKET_TYPE_MPU) {
|
|
501
|
-
return {
|
|
502
|
-
rejection: {
|
|
503
|
-
gate: 'not-an-mpu-packet',
|
|
504
|
-
detail: `packetType=0x${header.packetType.toString(16).padStart(2, '0')}`,
|
|
505
|
-
},
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
const payload = mmtpPacket.subarray(header.headerLength)
|
|
510
|
-
if (payload.length < MPU_HEADER_SIZE) {
|
|
511
|
-
return {
|
|
512
|
-
rejection: {
|
|
513
|
-
gate: 'payload-shorter-than-mpu-header',
|
|
514
|
-
detail: `${payload.length} bytes < ${MPU_HEADER_SIZE}`,
|
|
515
|
-
},
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
const mpu = parseMPUHeader(payload)
|
|
520
|
-
if (mpu.aggregationFlag) {
|
|
521
|
-
return {
|
|
522
|
-
rejection: { gate: 'aggregation-flag-set', detail: 'strict profile requires A=0' },
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
// Fragment type from byte 2 upper nibble (not returned by parseMPUHeader)
|
|
527
|
-
const fragmentType = (payload[2]! >> 4) & 0x0f
|
|
528
|
-
|
|
529
|
-
const layoutResult = resolveMfuPayloadLayout(mpu, fragmentType, payload)
|
|
530
|
-
if ('rejection' in layoutResult) return layoutResult
|
|
531
|
-
const { layout } = layoutResult
|
|
532
|
-
|
|
533
|
-
const trailerLayout = resolveDeclaredTrailers(
|
|
534
|
-
payload,
|
|
535
|
-
layout.dataEnd,
|
|
536
|
-
header.fecType,
|
|
537
|
-
options,
|
|
538
|
-
)
|
|
539
|
-
if (!trailerLayout) {
|
|
540
|
-
// The most common cause is a producer whose Source FEC Payload ID width
|
|
541
|
-
// disagrees with ISO/IEC 23008-1 §C.5.2. Name that explicitly rather than
|
|
542
|
-
// leaving operators to infer it from a generic trailer error.
|
|
543
|
-
if (!options?.skipFecId && header.fecType === 1) {
|
|
544
|
-
const observed = payload.length - layout.dataEnd
|
|
545
|
-
if (observed !== SOURCE_FEC_PAYLOAD_ID_SIZE) {
|
|
546
|
-
return {
|
|
547
|
-
rejection: {
|
|
548
|
-
gate: 'source-fec-payload-id-width-mismatch',
|
|
549
|
-
detail:
|
|
550
|
-
`producer wrote a ${observed}-byte Source FEC Payload ID, ` +
|
|
551
|
-
`ISO/IEC 23008-1 §C.5.2 requires ${SOURCE_FEC_PAYLOAD_ID_SIZE} ` +
|
|
552
|
-
`(payload=${payload.length}, declaredEnd=${layout.dataEnd})`,
|
|
553
|
-
},
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
return {
|
|
558
|
-
rejection: {
|
|
559
|
-
gate: 'declared-trailers-unresolved',
|
|
560
|
-
detail:
|
|
561
|
-
`trailer bytes [${layout.dataEnd}, ${payload.length}) are neither empty ` +
|
|
562
|
-
`nor an exact ALTA trailer (fecType=${header.fecType})`,
|
|
563
|
-
},
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
return { plan: { header, payload, mpu, fragmentType, layout, trailerLayout } }
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/**
|
|
571
|
-
* Report why `extractMFUPayload` would refuse this packet, or null if it would
|
|
572
|
-
* accept it.
|
|
573
|
-
*
|
|
574
|
-
* `extractMFUPayload` returns bare `null` on ten distinct conditions, which
|
|
575
|
-
* makes a producer/consumer framing disagreement indistinguishable from a
|
|
576
|
-
* publisher that never started — both render as silence. Use this wherever
|
|
577
|
-
* that distinction matters: diagnostics, contract tests, and operator-facing
|
|
578
|
-
* logs.
|
|
579
|
-
*/
|
|
580
|
-
export function explainMFURejection(
|
|
581
|
-
mmtpPacket: Uint8Array,
|
|
582
|
-
options?: { skipFecId?: boolean },
|
|
583
|
-
): MFURejection | null {
|
|
584
|
-
const result = planMfuExtraction(mmtpPacket, options)
|
|
585
|
-
return 'rejection' in result ? result.rejection : null
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
export function extractMFUPayload(
|
|
589
|
-
mmtpPacket: Uint8Array,
|
|
590
|
-
options?: { skipFecId?: boolean },
|
|
591
|
-
): MFUExtraction | null {
|
|
592
|
-
return extractPlannedMfu(mmtpPacket, planMfuExtraction(mmtpPacket, options))
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
/**
|
|
596
|
-
* extractMFUPayload for a caller that already holds this packet's parsed MMTP
|
|
597
|
-
* header, so the header is not parsed a second time (BLO-36599).
|
|
598
|
-
*
|
|
599
|
-
* `header` must be `parseMMTPHeader(mmtpPacket)` of this same packet; the
|
|
600
|
-
* result is then identical to `extractMFUPayload(mmtpPacket, options)`.
|
|
601
|
-
*/
|
|
602
|
-
export function extractMFUPayloadWithHeader(
|
|
603
|
-
mmtpPacket: Uint8Array,
|
|
604
|
-
header: MMTPHeader,
|
|
605
|
-
options?: { skipFecId?: boolean },
|
|
606
|
-
): MFUExtraction | null {
|
|
607
|
-
return extractPlannedMfu(mmtpPacket, planMfuExtraction(mmtpPacket, options, header))
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
function extractPlannedMfu(
|
|
611
|
-
mmtpPacket: Uint8Array,
|
|
612
|
-
result: { plan: MfuPlan } | { rejection: MFURejection },
|
|
613
|
-
): MFUExtraction | null {
|
|
614
|
-
if ('rejection' in result) return null
|
|
615
|
-
const { header, payload, mpu, fragmentType, layout, trailerLayout } = result.plan
|
|
616
|
-
|
|
617
|
-
const mfuDuHeaderPresent = layout.hasMfuDuHeader
|
|
618
|
-
const mfuOffset = layout.mfuOffset
|
|
619
|
-
const dataEnd = layout.dataEnd
|
|
620
|
-
|
|
621
|
-
const mfuDuHeader =
|
|
622
|
-
mfuDuHeaderPresent && mpu.timedFlag === 1
|
|
623
|
-
? parseTimedMfuDuHeader(payload, MPU_HEADER_SIZE)
|
|
624
|
-
: null
|
|
625
|
-
const itemId =
|
|
626
|
-
mfuDuHeaderPresent && mpu.timedFlag === 0
|
|
627
|
-
? new DataView(payload.buffer, payload.byteOffset + MPU_HEADER_SIZE, 4).getUint32(0, false)
|
|
628
|
-
: null
|
|
629
|
-
|
|
630
|
-
const data = payload.subarray(mfuOffset, dataEnd)
|
|
631
|
-
|
|
632
|
-
const fecPayloadId = trailerLayout.hasFecId
|
|
633
|
-
? {
|
|
634
|
-
ssId: new DataView(
|
|
635
|
-
mmtpPacket.buffer,
|
|
636
|
-
mmtpPacket.byteOffset + mmtpPacket.length - SOURCE_FEC_PAYLOAD_ID_SIZE,
|
|
637
|
-
SOURCE_FEC_PAYLOAD_ID_SIZE,
|
|
638
|
-
).getUint32(0, false),
|
|
639
|
-
}
|
|
640
|
-
: null
|
|
641
|
-
|
|
642
|
-
return { header, mpu, fragmentType, data, mfuDuHeader, itemId, fecPayloadId }
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
/**
|
|
646
|
-
* Extract timestamp from MMTP packet
|
|
647
|
-
*/
|
|
648
|
-
export function extractTimestamp(mmtpPacket: Uint8Array): bigint {
|
|
649
|
-
const { header } = unwrapMMTP(mmtpPacket)
|
|
650
|
-
return header.timestamp
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
/**
|
|
654
|
-
* Check if MMTP packet is an FEC repair packet
|
|
655
|
-
* FEC_type 2 and 3 are repair packets
|
|
656
|
-
*/
|
|
657
|
-
export function isFecRepairPacket(mmtpPacket: Uint8Array): boolean {
|
|
658
|
-
if (mmtpPacket.length < 1) return false
|
|
659
|
-
const fecType = (mmtpPacket[0]! >> 3) & 0x03
|
|
660
|
-
return fecType >= 2
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
/**
|
|
664
|
-
* Extract Source FEC Payload ID (SS_ID) from the last 4 bytes of an MMTP
|
|
665
|
-
* source packet per ISO/IEC 23008-1:2023 Section C.5.2 Figure C.10.
|
|
666
|
-
*
|
|
667
|
-
* SS_ID is a flat 32-bit monotonic counter (incremented by 1 per packet
|
|
668
|
-
* for ssbg_mode0 and ssbg_mode1). Block membership and ESI use the
|
|
669
|
-
* configured K; repair SS_Start identifies the first SS_ID of the block and
|
|
670
|
-
* SSB_length records the authored source-symbol count:
|
|
671
|
-
* SBN = floor(SS_ID / K), ESI = SS_ID % K
|
|
672
|
-
* SS_Start = SBN * K (first SS_ID of the block)
|
|
673
|
-
*
|
|
674
|
-
* This matches FFmpeg moqenc_mmt.c, the drafts (draft-ramadan-moq-fec §6.2),
|
|
675
|
-
* and ATSC A/331 §8.1.2.5 which defers to ISO 23008-1 Annex C.
|
|
676
|
-
*/
|
|
677
|
-
export function extractFecPayloadId(mmtpPacket: Uint8Array): { ssId: number } | null {
|
|
678
|
-
const header = parseHeaderForSourceFecId(mmtpPacket)
|
|
679
|
-
return header ? sourceFecPayloadIdOf(mmtpPacket, header) : null
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
/**
|
|
683
|
-
* Return true when FEC_type=1 and the exact suffix after the ISO-declared MPU
|
|
684
|
-
* payload contains a four-byte Source FEC Payload ID.
|
|
685
|
-
*/
|
|
686
|
-
export function hasSourceFecPayloadId(mmtpPacket: Uint8Array): boolean {
|
|
687
|
-
const header = parseHeaderForSourceFecId(mmtpPacket)
|
|
688
|
-
return header !== null && sourceFecPayloadIdOf(mmtpPacket, header) !== null
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
function parseHeaderForSourceFecId(mmtpPacket: Uint8Array): MMTPHeader | null {
|
|
692
|
-
if (mmtpPacket.length < MMTP_HEADER_SIZE + MPU_HEADER_SIZE) return null
|
|
693
|
-
try {
|
|
694
|
-
return parseMMTPHeader(mmtpPacket)
|
|
695
|
-
} catch {
|
|
696
|
-
return null
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
/**
|
|
701
|
-
* The Source FEC Payload ID of a packet whose MMTP header the caller already
|
|
702
|
-
* parsed, or null when the packet carries none: present only when FEC_type=1
|
|
703
|
-
* and the exact suffix after the ISO-declared MPU payload holds the four-byte
|
|
704
|
-
* ID (ISO/IEC 23008-1 §C.5.2). Same answer as extractFecPayloadId, without a
|
|
705
|
-
* second header parse (BLO-36599).
|
|
706
|
-
*
|
|
707
|
-
* `header` must be `parseMMTPHeader(mmtpPacket)` of this same packet.
|
|
708
|
-
*/
|
|
709
|
-
export function sourceFecPayloadIdOf(
|
|
710
|
-
mmtpPacket: Uint8Array,
|
|
711
|
-
header: MMTPHeader,
|
|
712
|
-
): { ssId: number } | null {
|
|
713
|
-
if (mmtpPacket.length < MMTP_HEADER_SIZE + MPU_HEADER_SIZE) return null
|
|
714
|
-
if (header.packetType !== PACKET_TYPE_MPU) return null
|
|
715
|
-
|
|
716
|
-
const payload = mmtpPacket.subarray(header.headerLength)
|
|
717
|
-
if (payload.length < MPU_HEADER_SIZE) return null
|
|
718
|
-
const payloadLength = (payload[0]! << 8) | payload[1]!
|
|
719
|
-
if (payloadLength < MPU_HEADER_REMAINDER_SIZE) return null
|
|
720
|
-
const declaredEnd = MPU_LENGTH_FIELD_SIZE + payloadLength
|
|
721
|
-
if (!resolveDeclaredTrailers(payload, declaredEnd, header.fecType)?.hasFecId) return null
|
|
722
|
-
|
|
723
|
-
// Flat 4-byte SS_ID: encoder writes block_id * K + symbol_id
|
|
724
|
-
const off = mmtpPacket.length - SOURCE_FEC_PAYLOAD_ID_SIZE
|
|
725
|
-
return {
|
|
726
|
-
ssId:
|
|
727
|
-
((mmtpPacket[off]! << 24) |
|
|
728
|
-
(mmtpPacket[off + 1]! << 16) |
|
|
729
|
-
(mmtpPacket[off + 2]! << 8) |
|
|
730
|
-
mmtpPacket[off + 3]!) >>>
|
|
731
|
-
0,
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
/**
|
|
736
|
-
* MMTP header-extension ext_type assigned to the detached ALTA authenticator
|
|
737
|
-
* trailer (Path 2 / 08-07). Carried in an `[ext_type][ext_length][auth]`
|
|
738
|
-
* block appended after the MPU's declared payload bytes, before the 4-byte
|
|
739
|
-
* Source FEC Payload ID. MMTP X-bit stays 0 — non-ALTA MMTP receivers treat
|
|
740
|
-
* the trailer as bytes past `payload_length` and skip it (per ISO 23008-1
|
|
741
|
-
* §9.2.2 "may be discarded without impacting correct processing").
|
|
742
|
-
*/
|
|
743
|
-
// Re-export the ALTA trailer helper from the zero-dep leaf package. The leaf
|
|
744
|
-
// owns the implementation so container and FEC consumers share one parser
|
|
745
|
-
// without creating a package cycle.
|
|
746
|
-
export const MMTP_EXT_TYPE_ALTA_AUTH = _LEAF_MMTP_EXT_TYPE_ALTA_AUTH
|
|
747
|
-
export const MMTP_EXT_TRAILER_HEADER_SIZE = _LEAF_MMTP_EXT_TRAILER_HEADER_SIZE
|
|
748
|
-
export type AltaTrailer = _LeafAltaTrailer
|
|
749
|
-
export const extractAltaTrailer = _leafExtractAltaTrailer
|
|
750
|
-
|
|
751
|
-
/** Size of Repair FEC Payload ID per ISO/IEC 23008-1 Section C.5.3 */
|
|
752
|
-
export const REPAIR_FEC_PID_SIZE = 13
|
|
753
|
-
|
|
754
|
-
/**
|
|
755
|
-
* Parse the 13-byte Repair FEC Payload ID after the complete dynamic MMTP header.
|
|
756
|
-
* `parsedHeader`, when given, must be `parseMMTPHeader(mmtpPacket)` of this
|
|
757
|
-
* same packet; it spares the second header parse (BLO-36599).
|
|
758
|
-
*/
|
|
759
|
-
function readRepairFecPayloadIdFields(mmtpPacket: Uint8Array, parsedHeader?: MMTPHeader): {
|
|
760
|
-
packetId: number; ssStart: number; rsbLength: number; rsId: number; ssbLength: number; dataOffset: number
|
|
761
|
-
} | null {
|
|
762
|
-
let header: MMTPHeader
|
|
763
|
-
if (parsedHeader) {
|
|
764
|
-
header = parsedHeader
|
|
765
|
-
} else {
|
|
766
|
-
try {
|
|
767
|
-
header = parseMMTPHeader(mmtpPacket)
|
|
768
|
-
} catch {
|
|
769
|
-
return null
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
if (header.packetType !== PACKET_TYPE_REPAIR || header.fecType !== 2) return null
|
|
773
|
-
|
|
774
|
-
const off = header.headerLength
|
|
775
|
-
if (mmtpPacket.length < off + REPAIR_FEC_PID_SIZE) return null
|
|
776
|
-
const ssStart =
|
|
777
|
-
((mmtpPacket[off]! << 24) |
|
|
778
|
-
(mmtpPacket[off + 1]! << 16) |
|
|
779
|
-
(mmtpPacket[off + 2]! << 8) |
|
|
780
|
-
mmtpPacket[off + 3]!) >>>
|
|
781
|
-
0 // 32 bits
|
|
782
|
-
const rsbLength = (mmtpPacket[off + 4]! << 16) | (mmtpPacket[off + 5]! << 8) | mmtpPacket[off + 6]! // 24 bits
|
|
783
|
-
const rsId = (mmtpPacket[off + 7]! << 16) | (mmtpPacket[off + 8]! << 8) | mmtpPacket[off + 9]! // 24 bits
|
|
784
|
-
const ssbLength = (mmtpPacket[off + 10]! << 16) | (mmtpPacket[off + 11]! << 8) | mmtpPacket[off + 12]! // 24 bits
|
|
785
|
-
return {
|
|
786
|
-
packetId: header.packetId,
|
|
787
|
-
ssStart,
|
|
788
|
-
rsbLength,
|
|
789
|
-
rsId,
|
|
790
|
-
ssbLength,
|
|
791
|
-
dataOffset: off + REPAIR_FEC_PID_SIZE,
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
/**
|
|
796
|
-
* Extract Repair FEC Payload ID from a raw-multicast MMTP repair packet.
|
|
797
|
-
* Per ISO/IEC 23008-1:2023 Section C.5.3 (ssbg_mode0, one-stage, no FFSRP_TS):
|
|
798
|
-
* [MMTP header][SS_Start:4][RSB_length:3][RS_ID:3][SSB_length:3][repair data]
|
|
799
|
-
* OTI is delivered via AL-FEC signaling message (Table C.3), not per-packet.
|
|
800
|
-
*
|
|
801
|
-
* Byte 1 is reserved(2)|packet_type(6) for V=0, so repair type 0x03 is 0x03.
|
|
802
|
-
* Pre-migration high-bits bytes (0x0c) are rejected — no compatibility decode.
|
|
803
|
-
*/
|
|
804
|
-
export function extractRepairFecPayloadId(mmtpPacket: Uint8Array): {
|
|
805
|
-
ssStart: number; rsbLength: number; rsId: number; ssbLength: number
|
|
806
|
-
} | null {
|
|
807
|
-
const fields = readRepairFecPayloadIdFields(mmtpPacket)
|
|
808
|
-
if (!fields) return null
|
|
809
|
-
return {
|
|
810
|
-
ssStart: fields.ssStart,
|
|
811
|
-
rsbLength: fields.rsbLength,
|
|
812
|
-
rsId: fields.rsId,
|
|
813
|
-
ssbLength: fields.ssbLength,
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
/** Parsed MoQ repair frame per ISO/IEC 23008-1 Section C.4.3 + C.5.3 */
|
|
818
|
-
export interface MoqRepairFrame {
|
|
819
|
-
/** MMTP packetId (1=video, 2=audio) — for routing to correct FEC decoder */
|
|
820
|
-
packetId: number
|
|
821
|
-
/** SS_Start (32 bits): SS_ID of first source symbol in block */
|
|
822
|
-
ssStart: number
|
|
823
|
-
/** RSB_length (24 bits): number of repair symbols (P) */
|
|
824
|
-
rsbLength: number
|
|
825
|
-
/** RS_ID (24 bits): repair symbol index (0-based) */
|
|
826
|
-
rsId: number
|
|
827
|
-
/** SSB_length (24 bits): authored source-symbol count (1..=configured K) */
|
|
828
|
-
ssbLength: number
|
|
829
|
-
/** Repair symbol data after the dynamic MMTP header and 13-byte FEC payload ID. */
|
|
830
|
-
symbolData: Uint8Array
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
/**
|
|
834
|
-
* Parse a MoQ repair frame (ISO/IEC 23008-1 Annex C format).
|
|
835
|
-
*
|
|
836
|
-
* Wire format per ISO 23008-1 §C.4.3 + §C.5.3:
|
|
837
|
-
* MMTP Header: fixed 12 bytes plus C/X optional fields
|
|
838
|
-
* then SS_Start (4 bytes) → block identifier
|
|
839
|
-
* then RSB_length (3 bytes) → P
|
|
840
|
-
* then RS_ID (3 bytes) → ESI = K + RS_ID
|
|
841
|
-
* then SSB_length (3 bytes) → authored source-symbol count (1..=K)
|
|
842
|
-
* then Repair Symbol Data (T bytes)
|
|
843
|
-
*
|
|
844
|
-
* @param frame - Raw MoQ repair frame bytes
|
|
845
|
-
* @returns Parsed frame or null if invalid
|
|
846
|
-
*/
|
|
847
|
-
export function parseMoqRepairFrame(frame: Uint8Array): MoqRepairFrame | null {
|
|
848
|
-
return moqRepairFrameFrom(frame, readRepairFecPayloadIdFields(frame))
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
/**
|
|
852
|
-
* parseMoqRepairFrame for a caller that already holds this frame's parsed MMTP
|
|
853
|
-
* header, so the header is not parsed a second time (BLO-36599). The router's
|
|
854
|
-
* multicast repair branch uses it: one repair packet in every K + P otherwise
|
|
855
|
-
* paid two header parses.
|
|
856
|
-
*
|
|
857
|
-
* `header` must be `parseMMTPHeader(frame)` of this same frame; the result is
|
|
858
|
-
* then identical to `parseMoqRepairFrame(frame)`.
|
|
859
|
-
*/
|
|
860
|
-
export function parseMoqRepairFrameWithHeader(
|
|
861
|
-
frame: Uint8Array,
|
|
862
|
-
header: MMTPHeader,
|
|
863
|
-
): MoqRepairFrame | null {
|
|
864
|
-
return moqRepairFrameFrom(frame, readRepairFecPayloadIdFields(frame, header))
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
function moqRepairFrameFrom(
|
|
868
|
-
frame: Uint8Array,
|
|
869
|
-
repairId: ReturnType<typeof readRepairFecPayloadIdFields>,
|
|
870
|
-
): MoqRepairFrame | null {
|
|
871
|
-
if (!repairId) return null
|
|
872
|
-
|
|
873
|
-
const symbolData = frame.subarray(repairId.dataOffset)
|
|
874
|
-
if (
|
|
875
|
-
repairId.rsbLength === 0 ||
|
|
876
|
-
repairId.ssbLength === 0 ||
|
|
877
|
-
repairId.rsId >= repairId.rsbLength ||
|
|
878
|
-
symbolData.length === 0
|
|
879
|
-
) return null
|
|
880
|
-
|
|
881
|
-
return {
|
|
882
|
-
packetId: repairId.packetId,
|
|
883
|
-
ssStart: repairId.ssStart,
|
|
884
|
-
rsbLength: repairId.rsbLength,
|
|
885
|
-
rsId: repairId.rsId,
|
|
886
|
-
ssbLength: repairId.ssbLength,
|
|
887
|
-
symbolData,
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
// The signalling-message parsers (9.3.4.2 payload header, AL-FEC message,
|
|
892
|
-
// PA/MPT) live in ./signalling.ts.
|