@blockcast/mmt-container 0.1.0-main.0399efef1f07
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 +432 -0
- package/dist/.build-stamp +0 -0
- package/dist/__tests__/test-utils.d.ts +71 -0
- package/dist/__tests__/test-utils.d.ts.map +1 -0
- package/dist/align.d.ts +152 -0
- package/dist/align.d.ts.map +1 -0
- package/dist/align.js +88 -0
- package/dist/align.js.map +7 -0
- package/dist/audio-init-parser.d.ts +66 -0
- package/dist/audio-init-parser.d.ts.map +1 -0
- package/dist/audio-init-parser.js +118 -0
- package/dist/audio-init-parser.js.map +7 -0
- package/dist/audio-ring-buffer.d.ts +50 -0
- package/dist/audio-ring-buffer.d.ts.map +1 -0
- package/dist/audio-ring-buffer.js +93 -0
- package/dist/audio-ring-buffer.js.map +7 -0
- package/dist/authored-timing.d.ts +32 -0
- package/dist/authored-timing.d.ts.map +1 -0
- package/dist/authored-timing.js +32 -0
- package/dist/authored-timing.js.map +7 -0
- package/dist/browser-runtime.js +20087 -0
- package/dist/browser-runtime.js.map +7 -0
- package/dist/carp-catalog.d.ts +318 -0
- package/dist/carp-catalog.d.ts.map +1 -0
- package/dist/carp-catalog.js +873 -0
- package/dist/carp-catalog.js.map +7 -0
- package/dist/catalog-fec-params.d.ts +202 -0
- package/dist/catalog-fec-params.d.ts.map +1 -0
- package/dist/catalog-fec-params.js +568 -0
- package/dist/catalog-fec-params.js.map +7 -0
- package/dist/catalog-network-source.d.ts +19 -0
- package/dist/catalog-network-source.d.ts.map +1 -0
- package/dist/catalog-network-source.js +22 -0
- package/dist/catalog-network-source.js.map +7 -0
- package/dist/catalog-validator.d.ts +18 -0
- package/dist/catalog-validator.d.ts.map +1 -0
- package/dist/catalog-validator.js +7747 -0
- package/dist/catalog-validator.js.map +7 -0
- package/dist/cmaf-block-assembler.d.ts +217 -0
- package/dist/cmaf-block-assembler.d.ts.map +1 -0
- package/dist/cmaf-block-assembler.js +1769 -0
- package/dist/cmaf-block-assembler.js.map +7 -0
- package/dist/cmaf-group-batcher.d.ts +38 -0
- package/dist/cmaf-group-batcher.d.ts.map +1 -0
- package/dist/cmaf-group-batcher.js +195 -0
- package/dist/cmaf-group-batcher.js.map +7 -0
- package/dist/cmcd-producer.d.ts +104 -0
- package/dist/cmcd-producer.d.ts.map +1 -0
- package/dist/cmcd-producer.js +207 -0
- package/dist/cmcd-producer.js.map +7 -0
- package/dist/codec-utils.d.ts +248 -0
- package/dist/codec-utils.d.ts.map +1 -0
- package/dist/codec-utils.js +1268 -0
- package/dist/codec-utils.js.map +7 -0
- package/dist/fec-codec.d.ts +32 -0
- package/dist/fec-codec.d.ts.map +1 -0
- package/dist/fec-codec.js +47 -0
- package/dist/fec-codec.js.map +7 -0
- package/dist/fec-manager.d.ts +307 -0
- package/dist/fec-manager.d.ts.map +1 -0
- package/dist/fec-manager.js +1530 -0
- package/dist/fec-manager.js.map +7 -0
- package/dist/fec-starvation-detector.d.ts +59 -0
- package/dist/fec-starvation-detector.d.ts.map +1 -0
- package/dist/fec-starvation-detector.js +75 -0
- package/dist/fec-starvation-detector.js.map +7 -0
- package/dist/fec-worker-setup.d.ts +88 -0
- package/dist/fec-worker-setup.d.ts.map +1 -0
- package/dist/fec-worker-setup.js +614 -0
- package/dist/fec-worker-setup.js.map +7 -0
- package/dist/fmp4-completion.d.ts +30 -0
- package/dist/fmp4-completion.d.ts.map +1 -0
- package/dist/fmp4-completion.js +21 -0
- package/dist/fmp4-completion.js.map +7 -0
- package/dist/fmp4-reader.d.ts +37 -0
- package/dist/fmp4-reader.d.ts.map +1 -0
- package/dist/fmp4-reader.js +100 -0
- package/dist/fmp4-reader.js.map +7 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +380 -0
- package/dist/index.js.map +7 -0
- package/dist/iso-bmff-timing.d.ts +78 -0
- package/dist/iso-bmff-timing.d.ts.map +1 -0
- package/dist/iso-bmff-timing.js +618 -0
- package/dist/iso-bmff-timing.js.map +7 -0
- package/dist/loc.d.ts +68 -0
- package/dist/loc.d.ts.map +1 -0
- package/dist/loc.js +143 -0
- package/dist/loc.js.map +7 -0
- package/dist/manifest-auth-plan.d.ts +30 -0
- package/dist/manifest-auth-plan.d.ts.map +1 -0
- package/dist/manifest-auth-plan.js +1285 -0
- package/dist/manifest-auth-plan.js.map +7 -0
- package/dist/media-router.d.ts +251 -0
- package/dist/media-router.d.ts.map +1 -0
- package/dist/media-router.js +624 -0
- package/dist/media-router.js.map +7 -0
- package/dist/mfu-reassembler.d.ts +396 -0
- package/dist/mfu-reassembler.d.ts.map +1 -0
- package/dist/mfu-reassembler.js +3085 -0
- package/dist/mfu-reassembler.js.map +7 -0
- package/dist/mfu-reassembly-policy.d.ts +24 -0
- package/dist/mfu-reassembly-policy.d.ts.map +1 -0
- package/dist/mfu-reassembly-policy.js +99 -0
- package/dist/mfu-reassembly-policy.js.map +7 -0
- package/dist/mmtp-container-parser.d.ts +434 -0
- package/dist/mmtp-container-parser.d.ts.map +1 -0
- package/dist/mmtp-container-parser.js +6164 -0
- package/dist/mmtp-container-parser.js.map +7 -0
- package/dist/mmtp-container-parser.no-modules.js +8999 -0
- package/dist/mmtp-container-parser.no-modules.js.map +7 -0
- package/dist/mmtp-decode-pipeline.d.ts +132 -0
- package/dist/mmtp-decode-pipeline.d.ts.map +1 -0
- package/dist/mmtp-decode-pipeline.js +6413 -0
- package/dist/mmtp-decode-pipeline.js.map +7 -0
- package/dist/mmtp-router.d.ts +390 -0
- package/dist/mmtp-router.d.ts.map +1 -0
- package/dist/mmtp-router.js +9242 -0
- package/dist/mmtp-router.js.map +7 -0
- package/dist/mmtp-to-cmaf.d.ts +181 -0
- package/dist/mmtp-to-cmaf.d.ts.map +1 -0
- package/dist/mmtp-to-cmaf.js +802 -0
- package/dist/mmtp-to-cmaf.js.map +7 -0
- package/dist/multicast-auth-catalog.d.ts +115 -0
- package/dist/multicast-auth-catalog.d.ts.map +1 -0
- package/dist/multicast-auth-catalog.js +202 -0
- package/dist/multicast-auth-catalog.js.map +7 -0
- package/dist/multicast-input.d.ts +107 -0
- package/dist/multicast-input.d.ts.map +1 -0
- package/dist/multicast-input.js +256 -0
- package/dist/multicast-input.js.map +7 -0
- package/dist/multicast-manager.d.ts +369 -0
- package/dist/multicast-manager.d.ts.map +1 -0
- package/dist/multicast-manager.js +13400 -0
- package/dist/multicast-manager.js.map +7 -0
- package/dist/multicast-transport.d.ts +61 -0
- package/dist/multicast-transport.d.ts.map +1 -0
- package/dist/multicast-transport.js +1665 -0
- package/dist/multicast-transport.js.map +7 -0
- package/dist/multicast-unwrap.d.ts +57 -0
- package/dist/multicast-unwrap.d.ts.map +1 -0
- package/dist/multicast-unwrap.js +384 -0
- package/dist/multicast-unwrap.js.map +7 -0
- package/dist/no-modules.d.ts +9 -0
- package/dist/no-modules.d.ts.map +1 -0
- package/dist/no-modules.js +8965 -0
- package/dist/no-modules.js.map +7 -0
- package/dist/phase14-catalog-override.d.ts +126 -0
- package/dist/phase14-catalog-override.d.ts.map +1 -0
- package/dist/phase14-catalog-override.js +155 -0
- package/dist/phase14-catalog-override.js.map +7 -0
- package/dist/repair-fetch.d.ts +58 -0
- package/dist/repair-fetch.d.ts.map +1 -0
- package/dist/repair-fetch.js +127 -0
- package/dist/repair-fetch.js.map +7 -0
- package/dist/repair-layers.d.ts +141 -0
- package/dist/repair-layers.d.ts.map +1 -0
- package/dist/repair-layers.js +303 -0
- package/dist/repair-layers.js.map +7 -0
- package/dist/sample-combiner.d.ts +212 -0
- package/dist/sample-combiner.d.ts.map +1 -0
- package/dist/sample-combiner.js +616 -0
- package/dist/sample-combiner.js.map +7 -0
- package/dist/signaling.d.ts +29 -0
- package/dist/signaling.d.ts.map +1 -0
- package/dist/signaling.js +232 -0
- package/dist/signaling.js.map +7 -0
- package/dist/source-auth.d.ts +2 -0
- package/dist/source-auth.d.ts.map +1 -0
- package/dist/source-auth.js +1238 -0
- package/dist/source-auth.js.map +7 -0
- package/dist/switching-set-alignment.d.ts +61 -0
- package/dist/switching-set-alignment.d.ts.map +1 -0
- package/dist/switching-set-alignment.js +85 -0
- package/dist/switching-set-alignment.js.map +7 -0
- package/dist/timestamp-codec.d.ts +34 -0
- package/dist/timestamp-codec.d.ts.map +1 -0
- package/dist/timestamp-codec.js +456 -0
- package/dist/timestamp-codec.js.map +7 -0
- package/dist/track-pipeline-setup.d.ts +72 -0
- package/dist/track-pipeline-setup.d.ts.map +1 -0
- package/dist/track-pipeline-setup.js +306 -0
- package/dist/track-pipeline-setup.js.map +7 -0
- package/dist/track-pipeline.d.ts +121 -0
- package/dist/track-pipeline.d.ts.map +1 -0
- package/dist/track-pipeline.js +229 -0
- package/dist/track-pipeline.js.map +7 -0
- package/dist/track-session.d.ts +398 -0
- package/dist/track-session.d.ts.map +1 -0
- package/dist/track-session.js +767 -0
- package/dist/track-session.js.map +7 -0
- package/dist/transport-pool.d.ts +69 -0
- package/dist/transport-pool.d.ts.map +1 -0
- package/dist/transport-pool.js +88 -0
- package/dist/transport-pool.js.map +7 -0
- package/dist/wasm-mfu-reassembler.d.ts +92 -0
- package/dist/wasm-mfu-reassembler.d.ts.map +1 -0
- package/dist/wasm-mfu-reassembler.js +2139 -0
- package/dist/wasm-mfu-reassembler.js.map +7 -0
- package/dist/wasm-mmtp-container-parser.d.ts +10 -0
- package/dist/wasm-mmtp-container-parser.d.ts.map +1 -0
- package/dist/wasm-mmtp-container-parser.js +6418 -0
- package/dist/wasm-mmtp-container-parser.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/README.md +213 -0
- package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +87 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +279 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +252 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +11 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +14 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +565 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts +10 -0
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/index.js +8 -0
- package/node_modules/@blockcast/fec-worker/dist/index.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +20 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +349 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +104 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +181 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +179 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +47 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +9 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.js +13 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/package.json +59 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +319 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +268 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +1048 -0
- package/node_modules/@blockcast/fec-worker/src/index.ts +32 -0
- package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +558 -0
- package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +222 -0
- package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +194 -0
- package/node_modules/@blockcast/fec-worker/src/transfer.ts +12 -0
- package/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
- package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
- package/node_modules/@blockcast/mmt-base/README.md +120 -0
- package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts +2 -0
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/index.js +2 -0
- package/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +276 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js +645 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/package.json +49 -0
- package/node_modules/@blockcast/mmt-base/src/index.ts +1 -0
- package/node_modules/@blockcast/mmt-base/src/mmtp.ts +899 -0
- package/node_modules/@blockcast/mmt-fec/README.md +270 -0
- package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +82 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +296 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +72 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +192 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +46 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +96 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +33 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +57 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +185 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +273 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +22 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.js +22 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +20 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +28 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +172 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.js +254 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +41 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +81 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +120 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +2 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +2 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +276 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +645 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +49 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +899 -0
- package/node_modules/@blockcast/mmt-fec/package.json +79 -0
- package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +371 -0
- package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +277 -0
- package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +127 -0
- package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +68 -0
- package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +332 -0
- package/node_modules/@blockcast/mmt-fec/src/index.ts +77 -0
- package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +34 -0
- package/node_modules/@blockcast/mmt-fec/src/oti.ts +317 -0
- package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +101 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +28 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +128 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +4 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +4 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +37 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +179 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +99 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +492 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/package.json +45 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +171 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +3 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +230 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +669 -0
- package/node_modules/@noble/hashes/LICENSE +21 -0
- package/node_modules/@noble/hashes/README.md +521 -0
- package/node_modules/@noble/hashes/_assert.d.ts +17 -0
- package/node_modules/@noble/hashes/_assert.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_assert.js +18 -0
- package/node_modules/@noble/hashes/_assert.js.map +1 -0
- package/node_modules/@noble/hashes/_blake.d.ts +14 -0
- package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_blake.js +50 -0
- package/node_modules/@noble/hashes/_blake.js.map +1 -0
- package/node_modules/@noble/hashes/_md.d.ts +51 -0
- package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_md.js +162 -0
- package/node_modules/@noble/hashes/_md.js.map +1 -0
- package/node_modules/@noble/hashes/_u64.d.ts +55 -0
- package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_u64.js +90 -0
- package/node_modules/@noble/hashes/_u64.js.map +1 -0
- package/node_modules/@noble/hashes/argon2.d.ts +32 -0
- package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/argon2.js +401 -0
- package/node_modules/@noble/hashes/argon2.js.map +1 -0
- package/node_modules/@noble/hashes/blake1.d.ts +106 -0
- package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake1.js +459 -0
- package/node_modules/@noble/hashes/blake1.js.map +1 -0
- package/node_modules/@noble/hashes/blake2.d.ts +116 -0
- package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2.js +420 -0
- package/node_modules/@noble/hashes/blake2.js.map +1 -0
- package/node_modules/@noble/hashes/blake2b.d.ts +11 -0
- package/node_modules/@noble/hashes/blake2b.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2b.js +14 -0
- package/node_modules/@noble/hashes/blake2b.js.map +1 -0
- package/node_modules/@noble/hashes/blake2s.d.ts +20 -0
- package/node_modules/@noble/hashes/blake2s.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2s.js +24 -0
- package/node_modules/@noble/hashes/blake2s.js.map +1 -0
- package/node_modules/@noble/hashes/blake3.d.ts +54 -0
- package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake3.js +255 -0
- package/node_modules/@noble/hashes/blake3.js.map +1 -0
- package/node_modules/@noble/hashes/crypto.d.ts +2 -0
- package/node_modules/@noble/hashes/crypto.d.ts.map +1 -0
- package/node_modules/@noble/hashes/crypto.js +5 -0
- package/node_modules/@noble/hashes/crypto.js.map +1 -0
- package/node_modules/@noble/hashes/cryptoNode.d.ts +2 -0
- package/node_modules/@noble/hashes/cryptoNode.d.ts.map +1 -0
- package/node_modules/@noble/hashes/cryptoNode.js +18 -0
- package/node_modules/@noble/hashes/cryptoNode.js.map +1 -0
- package/node_modules/@noble/hashes/eskdf.d.ts +47 -0
- package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/eskdf.js +166 -0
- package/node_modules/@noble/hashes/eskdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_assert.d.ts +17 -0
- package/node_modules/@noble/hashes/esm/_assert.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_assert.js +15 -0
- package/node_modules/@noble/hashes/esm/_assert.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_blake.d.ts +14 -0
- package/node_modules/@noble/hashes/esm/_blake.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_blake.js +45 -0
- package/node_modules/@noble/hashes/esm/_blake.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_md.d.ts +51 -0
- package/node_modules/@noble/hashes/esm/_md.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_md.js +155 -0
- package/node_modules/@noble/hashes/esm/_md.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_u64.d.ts +55 -0
- package/node_modules/@noble/hashes/esm/_u64.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_u64.js +67 -0
- package/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
- package/node_modules/@noble/hashes/esm/argon2.d.ts +32 -0
- package/node_modules/@noble/hashes/esm/argon2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/argon2.js +392 -0
- package/node_modules/@noble/hashes/esm/argon2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake1.d.ts +106 -0
- package/node_modules/@noble/hashes/esm/blake1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake1.js +452 -0
- package/node_modules/@noble/hashes/esm/blake1.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2.d.ts +116 -0
- package/node_modules/@noble/hashes/esm/blake2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2.js +413 -0
- package/node_modules/@noble/hashes/esm/blake2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2b.d.ts +11 -0
- package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2b.js +11 -0
- package/node_modules/@noble/hashes/esm/blake2b.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2s.d.ts +20 -0
- package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2s.js +21 -0
- package/node_modules/@noble/hashes/esm/blake2s.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake3.d.ts +54 -0
- package/node_modules/@noble/hashes/esm/blake3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake3.js +251 -0
- package/node_modules/@noble/hashes/esm/blake3.js.map +1 -0
- package/node_modules/@noble/hashes/esm/crypto.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/crypto.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/crypto.js +2 -0
- package/node_modules/@noble/hashes/esm/crypto.js.map +1 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.js +15 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.js.map +1 -0
- package/node_modules/@noble/hashes/esm/eskdf.d.ts +47 -0
- package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/eskdf.js +160 -0
- package/node_modules/@noble/hashes/esm/eskdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/hkdf.d.ts +36 -0
- package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/hkdf.js +82 -0
- package/node_modules/@noble/hashes/esm/hkdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/hmac.d.ts +35 -0
- package/node_modules/@noble/hashes/esm/hmac.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/hmac.js +86 -0
- package/node_modules/@noble/hashes/esm/hmac.js.map +1 -0
- package/node_modules/@noble/hashes/esm/index.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/index.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/index.js +33 -0
- package/node_modules/@noble/hashes/esm/index.js.map +1 -0
- package/node_modules/@noble/hashes/esm/legacy.d.ts +71 -0
- package/node_modules/@noble/hashes/esm/legacy.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/legacy.js +281 -0
- package/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
- package/node_modules/@noble/hashes/esm/package.json +10 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +23 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.js +97 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts +13 -0
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/ripemd160.js +13 -0
- package/node_modules/@noble/hashes/esm/ripemd160.js.map +1 -0
- package/node_modules/@noble/hashes/esm/scrypt.d.ts +34 -0
- package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/scrypt.js +228 -0
- package/node_modules/@noble/hashes/esm/scrypt.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha1.d.ts +11 -0
- package/node_modules/@noble/hashes/esm/sha1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha1.js +11 -0
- package/node_modules/@noble/hashes/esm/sha1.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha2.d.ts +159 -0
- package/node_modules/@noble/hashes/esm/sha2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha2.js +375 -0
- package/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha256.d.ts +20 -0
- package/node_modules/@noble/hashes/esm/sha256.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha256.js +20 -0
- package/node_modules/@noble/hashes/esm/sha256.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +142 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.js +393 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3.d.ts +53 -0
- package/node_modules/@noble/hashes/esm/sha3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3.js +234 -0
- package/node_modules/@noble/hashes/esm/sha3.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha512.d.ts +26 -0
- package/node_modules/@noble/hashes/esm/sha512.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha512.js +26 -0
- package/node_modules/@noble/hashes/esm/sha512.js.map +1 -0
- package/node_modules/@noble/hashes/esm/utils.d.ts +161 -0
- package/node_modules/@noble/hashes/esm/utils.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/utils.js +281 -0
- package/node_modules/@noble/hashes/esm/utils.js.map +1 -0
- package/node_modules/@noble/hashes/hkdf.d.ts +36 -0
- package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hkdf.js +88 -0
- package/node_modules/@noble/hashes/hkdf.js.map +1 -0
- package/node_modules/@noble/hashes/hmac.d.ts +35 -0
- package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hmac.js +91 -0
- package/node_modules/@noble/hashes/hmac.js.map +1 -0
- package/node_modules/@noble/hashes/index.d.ts +1 -0
- package/node_modules/@noble/hashes/index.d.ts.map +1 -0
- package/node_modules/@noble/hashes/index.js +33 -0
- package/node_modules/@noble/hashes/index.js.map +1 -0
- package/node_modules/@noble/hashes/legacy.d.ts +71 -0
- package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
- package/node_modules/@noble/hashes/legacy.js +287 -0
- package/node_modules/@noble/hashes/legacy.js.map +1 -0
- package/node_modules/@noble/hashes/package.json +266 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts +23 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/pbkdf2.js +101 -0
- package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
- package/node_modules/@noble/hashes/ripemd160.d.ts +13 -0
- package/node_modules/@noble/hashes/ripemd160.d.ts.map +1 -0
- package/node_modules/@noble/hashes/ripemd160.js +16 -0
- package/node_modules/@noble/hashes/ripemd160.js.map +1 -0
- package/node_modules/@noble/hashes/scrypt.d.ts +34 -0
- package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
- package/node_modules/@noble/hashes/scrypt.js +232 -0
- package/node_modules/@noble/hashes/scrypt.js.map +1 -0
- package/node_modules/@noble/hashes/sha1.d.ts +11 -0
- package/node_modules/@noble/hashes/sha1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha1.js +14 -0
- package/node_modules/@noble/hashes/sha1.js.map +1 -0
- package/node_modules/@noble/hashes/sha2.d.ts +159 -0
- package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha2.js +384 -0
- package/node_modules/@noble/hashes/sha2.js.map +1 -0
- package/node_modules/@noble/hashes/sha256.d.ts +20 -0
- package/node_modules/@noble/hashes/sha256.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha256.js +23 -0
- package/node_modules/@noble/hashes/sha256.js.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts +142 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.js +402 -0
- package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
- package/node_modules/@noble/hashes/sha3.d.ts +53 -0
- package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3.js +239 -0
- package/node_modules/@noble/hashes/sha3.js.map +1 -0
- package/node_modules/@noble/hashes/sha512.d.ts +26 -0
- package/node_modules/@noble/hashes/sha512.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha512.js +29 -0
- package/node_modules/@noble/hashes/sha512.js.map +1 -0
- package/node_modules/@noble/hashes/src/_assert.ts +22 -0
- package/node_modules/@noble/hashes/src/_blake.ts +50 -0
- package/node_modules/@noble/hashes/src/_md.ts +176 -0
- package/node_modules/@noble/hashes/src/_u64.ts +91 -0
- package/node_modules/@noble/hashes/src/argon2.ts +497 -0
- package/node_modules/@noble/hashes/src/blake1.ts +534 -0
- package/node_modules/@noble/hashes/src/blake2.ts +486 -0
- package/node_modules/@noble/hashes/src/blake2b.ts +10 -0
- package/node_modules/@noble/hashes/src/blake2s.ts +20 -0
- package/node_modules/@noble/hashes/src/blake3.ts +272 -0
- package/node_modules/@noble/hashes/src/crypto.ts +9 -0
- package/node_modules/@noble/hashes/src/cryptoNode.ts +15 -0
- package/node_modules/@noble/hashes/src/eskdf.ts +187 -0
- package/node_modules/@noble/hashes/src/hkdf.ts +88 -0
- package/node_modules/@noble/hashes/src/hmac.ts +94 -0
- package/node_modules/@noble/hashes/src/index.ts +31 -0
- package/node_modules/@noble/hashes/src/legacy.ts +293 -0
- package/node_modules/@noble/hashes/src/pbkdf2.ts +122 -0
- package/node_modules/@noble/hashes/src/ripemd160.ts +12 -0
- package/node_modules/@noble/hashes/src/scrypt.ts +257 -0
- package/node_modules/@noble/hashes/src/sha1.ts +10 -0
- package/node_modules/@noble/hashes/src/sha2.ts +402 -0
- package/node_modules/@noble/hashes/src/sha256.ts +24 -0
- package/node_modules/@noble/hashes/src/sha3-addons.ts +499 -0
- package/node_modules/@noble/hashes/src/sha3.ts +258 -0
- package/node_modules/@noble/hashes/src/sha512.ts +34 -0
- package/node_modules/@noble/hashes/src/utils.ts +395 -0
- package/node_modules/@noble/hashes/utils.d.ts +161 -0
- package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
- package/node_modules/@noble/hashes/utils.js +313 -0
- package/node_modules/@noble/hashes/utils.js.map +1 -0
- package/package.json +203 -0
- package/schemas/catalog.schema.json +360 -0
- package/src/align.ts +239 -0
- package/src/audio-init-parser.ts +189 -0
- package/src/audio-ring-buffer.ts +120 -0
- package/src/authored-timing.ts +63 -0
- package/src/carp-catalog.ts +845 -0
- package/src/catalog-fec-params.ts +535 -0
- package/src/catalog-network-source.ts +49 -0
- package/src/catalog-validator.ts +34 -0
- package/src/cmaf-block-assembler.ts +1167 -0
- package/src/cmaf-group-batcher.ts +104 -0
- package/src/cmcd-producer.ts +334 -0
- package/src/codec-utils.ts +1611 -0
- package/src/fec-codec.ts +61 -0
- package/src/fec-manager.ts +2081 -0
- package/src/fec-starvation-detector.ts +128 -0
- package/src/fec-worker-setup.ts +213 -0
- package/src/fmp4-completion.ts +47 -0
- package/src/fmp4-reader.ts +112 -0
- package/src/index.ts +486 -0
- package/src/iso-bmff-timing.ts +813 -0
- package/src/loc.ts +181 -0
- package/src/manifest-auth-plan.ts +107 -0
- package/src/media-router.ts +795 -0
- package/src/mfu-reassembler.ts +3741 -0
- package/src/mfu-reassembly-policy.ts +134 -0
- package/src/mmtp-container-parser.ts +1836 -0
- package/src/mmtp-decode-pipeline.ts +389 -0
- package/src/mmtp-router.ts +3136 -0
- package/src/mmtp-to-cmaf.ts +1024 -0
- package/src/multicast-auth-catalog.ts +340 -0
- package/src/multicast-input.ts +439 -0
- package/src/multicast-manager.ts +1720 -0
- package/src/multicast-transport.ts +321 -0
- package/src/multicast-unwrap.ts +132 -0
- package/src/no-modules.ts +20 -0
- package/src/phase14-catalog-override.ts +336 -0
- package/src/repair-fetch.ts +238 -0
- package/src/repair-layers.ts +490 -0
- package/src/sample-combiner.ts +938 -0
- package/src/signaling.ts +78 -0
- package/src/source-auth.ts +1 -0
- package/src/switching-set-alignment.ts +109 -0
- package/src/timestamp-codec.ts +265 -0
- package/src/track-pipeline-setup.ts +189 -0
- package/src/track-pipeline.ts +332 -0
- package/src/track-session.ts +994 -0
- package/src/transport-pool.ts +128 -0
- package/src/wasm-mfu-reassembler.ts +389 -0
- package/src/wasm-mmtp-container-parser.ts +23 -0
- package/test-vectors/align.json +199 -0
- package/test-vectors/catalog/README.md +40 -0
- package/test-vectors/catalog/negative/fec-enhancement-repair-removed.json +27 -0
- package/test-vectors/catalog/negative/fec-repair-layer-geometry.json +32 -0
- package/test-vectors/catalog/negative/fec-repair-layer-missing-symbols.json +30 -0
- package/test-vectors/catalog/negative/fec-repair-multiple-depends.json +31 -0
- package/test-vectors/catalog/negative/fec-repair-overlay-with-layer.json +33 -0
- package/test-vectors/catalog/negative/fec-repair-priority-out-of-band.json +23 -0
- package/test-vectors/catalog/negative/fec-repair-source-symbols-without-scope.json +32 -0
- package/test-vectors/catalog/negative/legacy-selection-params.json +15 -0
- package/test-vectors/catalog/negative/media-track-repair-layer.json +16 -0
- package/test-vectors/catalog/negative/missing-mmtp-fields.json +12 -0
- package/test-vectors/catalog/negative/multicast-auth-padded-key.json +37 -0
- package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +53 -0
- package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +37 -0
- package/test-vectors/catalog/negative/multicast-endpoint-missing-protocol-and-source.json +24 -0
- package/test-vectors/catalog/negative/network-source-object.json +25 -0
- package/test-vectors/catalog/negative/raptorq-source-symbols-over-max.json +23 -0
- package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +26 -0
- package/test-vectors/catalog/negative/repair-track-legacy-shape.json +19 -0
- package/test-vectors/catalog/negative/track-role-empty.json +16 -0
- package/test-vectors/catalog/negative/track-role-non-string.json +16 -0
- package/test-vectors/catalog/positive/fec-layered-repair.json +104 -0
- package/test-vectors/catalog/positive/fec-multicast.json +51 -0
- package/test-vectors/catalog/positive/flat-av.json +30 -0
- package/test-vectors/catalog/positive/multicast-auth-rotation.json +55 -0
- package/test-vectors/catalog/positive/ticks-and-mixed-timescales.json +39 -0
- package/test-vectors/catalog/positive/track-role.json +49 -0
- package/test-vectors/catalog/releases/moqcast-native-v16-v1/catalog.json +65 -0
- package/test-vectors/catalog/releases/moqcast-native-v16-v1.archive.sha256 +1 -0
- package/test-vectors/catalog-multicast-auth-v1.json +26 -0
- package/test-vectors/catalog-validation.json +148 -0
- package/test-vectors/catalog-validator-public-api.mjs +25 -0
- package/test-vectors/generate-source-auth-fixture.mjs +114 -0
- package/test-vectors/source-auth-v1.json +61 -0
- package/test-vectors/source-contiguity-v1.json +131 -0
- package/test-vectors/subsample-placement-v1.json +230 -0
|
@@ -0,0 +1,873 @@
|
|
|
1
|
+
// src/multicast-auth-catalog.ts
|
|
2
|
+
var RAW_ED25519_KEY_LENGTH = 32;
|
|
3
|
+
var SOURCE_AUTH_SCOPE_LENGTH = 32;
|
|
4
|
+
var BASE64URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
5
|
+
function encodeBase64Url(bytes) {
|
|
6
|
+
let output = "";
|
|
7
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
8
|
+
const b0 = bytes[i];
|
|
9
|
+
const b1 = bytes[i + 1];
|
|
10
|
+
const b2 = bytes[i + 2];
|
|
11
|
+
output += BASE64URL_ALPHABET[b0 >> 2];
|
|
12
|
+
output += BASE64URL_ALPHABET[(b0 & 3) << 4 | (b1 === void 0 ? 0 : b1 >> 4)];
|
|
13
|
+
if (b1 === void 0) break;
|
|
14
|
+
output += BASE64URL_ALPHABET[(b1 & 15) << 2 | (b2 === void 0 ? 0 : b2 >> 6)];
|
|
15
|
+
if (b2 === void 0) break;
|
|
16
|
+
output += BASE64URL_ALPHABET[b2 & 63];
|
|
17
|
+
}
|
|
18
|
+
return output;
|
|
19
|
+
}
|
|
20
|
+
var BASE64URL_DECODE_TABLE = (() => {
|
|
21
|
+
const table = new Int8Array(128).fill(-1);
|
|
22
|
+
for (let i = 0; i < BASE64URL_ALPHABET.length; i++) {
|
|
23
|
+
table[BASE64URL_ALPHABET.charCodeAt(i)] = i;
|
|
24
|
+
}
|
|
25
|
+
return table;
|
|
26
|
+
})();
|
|
27
|
+
function decodeBase64Url(text) {
|
|
28
|
+
if (text.length % 4 === 1) {
|
|
29
|
+
throw new Error(`[multicast-auth-catalog] invalid unpadded base64url length for "${text}"`);
|
|
30
|
+
}
|
|
31
|
+
const bytes = [];
|
|
32
|
+
let buffer = 0;
|
|
33
|
+
let bits = 0;
|
|
34
|
+
for (let i = 0; i < text.length; i++) {
|
|
35
|
+
const code = text.charCodeAt(i);
|
|
36
|
+
const value = code < 128 ? BASE64URL_DECODE_TABLE[code] : -1;
|
|
37
|
+
if (value === void 0 || value < 0) {
|
|
38
|
+
throw new Error(`[multicast-auth-catalog] invalid base64url character in "${text}"`);
|
|
39
|
+
}
|
|
40
|
+
buffer = buffer << 6 | value;
|
|
41
|
+
bits += 6;
|
|
42
|
+
if (bits >= 8) {
|
|
43
|
+
bits -= 8;
|
|
44
|
+
bytes.push(buffer >> bits & 255);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const decoded = Uint8Array.from(bytes);
|
|
48
|
+
if (encodeBase64Url(decoded) !== text) {
|
|
49
|
+
throw new Error(`[multicast-auth-catalog] non-canonical base64url encoding "${text}"`);
|
|
50
|
+
}
|
|
51
|
+
return decoded;
|
|
52
|
+
}
|
|
53
|
+
function decodeAuthScope(authScope) {
|
|
54
|
+
const bytes = decodeBase64Url(authScope);
|
|
55
|
+
if (bytes.byteLength !== SOURCE_AUTH_SCOPE_LENGTH) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`[multicast-auth-catalog] authScope must decode to ${SOURCE_AUTH_SCOPE_LENGTH} raw bytes, got ${bytes.byteLength}`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return bytes;
|
|
61
|
+
}
|
|
62
|
+
function decodeEd25519PublicKey(publicKey) {
|
|
63
|
+
const bytes = decodeBase64Url(publicKey);
|
|
64
|
+
if (bytes.byteLength !== RAW_ED25519_KEY_LENGTH) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`[multicast-auth-catalog] public key must decode to ${RAW_ED25519_KEY_LENGTH} raw bytes, got ${bytes.byteLength}`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return bytes;
|
|
70
|
+
}
|
|
71
|
+
function isNonEmptyString(value) {
|
|
72
|
+
return typeof value === "string" && value.length > 0;
|
|
73
|
+
}
|
|
74
|
+
function isValidAuthScopeField(value) {
|
|
75
|
+
if (!isNonEmptyString(value)) return false;
|
|
76
|
+
try {
|
|
77
|
+
decodeAuthScope(value);
|
|
78
|
+
return true;
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function isValidPublicKeyField(value) {
|
|
84
|
+
if (!isNonEmptyString(value)) return false;
|
|
85
|
+
try {
|
|
86
|
+
decodeEd25519PublicKey(value);
|
|
87
|
+
return true;
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function hasOnlyKeys(object, allowed) {
|
|
93
|
+
const allowedKeys = new Set(allowed);
|
|
94
|
+
return Object.keys(object).every((key) => allowedKeys.has(key));
|
|
95
|
+
}
|
|
96
|
+
function isMulticastAuthTrackConfig(obj) {
|
|
97
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
98
|
+
const o = obj;
|
|
99
|
+
return hasOnlyKeys(o, ["mediaTrack", "manifestTrack", "authScope", "sourceSymbolFormat"]) && isNonEmptyString(o["mediaTrack"]) && isNonEmptyString(o["manifestTrack"]) && o["mediaTrack"] !== o["manifestTrack"] && isValidAuthScopeField(o["authScope"]) && isNonEmptyString(o["sourceSymbolFormat"]);
|
|
100
|
+
}
|
|
101
|
+
var VALID_COMPACTION = /* @__PURE__ */ new Set(["merkle", "none"]);
|
|
102
|
+
var VALID_ENFORCEMENT = /* @__PURE__ */ new Set(["shadow", "enforce"]);
|
|
103
|
+
function hasUniqueMulticastAuthTrackBindings(tracks) {
|
|
104
|
+
const bindings = tracks.flatMap((track) => {
|
|
105
|
+
if (typeof track !== "object" || track === null) return [];
|
|
106
|
+
const value = track;
|
|
107
|
+
if (typeof value["mediaTrack"] !== "string" || typeof value["sourceSymbolFormat"] !== "string") {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
return [JSON.stringify([value["mediaTrack"], value["sourceSymbolFormat"]])];
|
|
111
|
+
});
|
|
112
|
+
return new Set(bindings).size === bindings.length;
|
|
113
|
+
}
|
|
114
|
+
function isMulticastAuthConfig(obj) {
|
|
115
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
116
|
+
const o = obj;
|
|
117
|
+
if (o["scheme"] !== "bc-provenance") return false;
|
|
118
|
+
if (o["hash"] !== "blake3") return false;
|
|
119
|
+
if (o["sig"] !== "ed25519") return false;
|
|
120
|
+
if (!hasOnlyKeys(o, ["scheme", "hash", "sig", "publicKey", "keyId", "previousKey", "compaction", "enforcement", "tracks"])) return false;
|
|
121
|
+
if (!isValidPublicKeyField(o["publicKey"])) return false;
|
|
122
|
+
if (!isNonEmptyString(o["keyId"])) return false;
|
|
123
|
+
if (o["previousKey"] !== void 0 && !isValidPublicKeyField(o["previousKey"])) return false;
|
|
124
|
+
if (o["previousKey"] === o["publicKey"]) return false;
|
|
125
|
+
if (typeof o["compaction"] !== "string" || !VALID_COMPACTION.has(o["compaction"])) return false;
|
|
126
|
+
if (o["enforcement"] !== void 0) {
|
|
127
|
+
if (typeof o["enforcement"] !== "string" || !VALID_ENFORCEMENT.has(o["enforcement"])) return false;
|
|
128
|
+
}
|
|
129
|
+
if (!Array.isArray(o["tracks"]) || o["tracks"].length === 0) return false;
|
|
130
|
+
const tracks = o["tracks"];
|
|
131
|
+
if (!tracks.every((t) => isMulticastAuthTrackConfig(t))) return false;
|
|
132
|
+
const typedTracks = tracks;
|
|
133
|
+
const scopes = typedTracks.map((t) => t.authScope);
|
|
134
|
+
if (new Set(scopes).size !== scopes.length) return false;
|
|
135
|
+
if (!hasUniqueMulticastAuthTrackBindings(typedTracks)) return false;
|
|
136
|
+
const manifestTracks = typedTracks.map((t) => t.manifestTrack);
|
|
137
|
+
if (new Set(manifestTracks).size !== manifestTracks.length) return false;
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
function resolveMulticastAuthMode(playerMode, auth) {
|
|
141
|
+
if (playerMode !== void 0) return playerMode;
|
|
142
|
+
if (auth === void 0) return "off";
|
|
143
|
+
return auth.enforcement ?? "shadow";
|
|
144
|
+
}
|
|
145
|
+
function resolveMulticastAuthCatalog(catalog, playerMode) {
|
|
146
|
+
if (typeof catalog !== "object" || catalog === null || Array.isArray(catalog)) {
|
|
147
|
+
throw new Error("[multicast-auth-catalog] catalog must be an object");
|
|
148
|
+
}
|
|
149
|
+
const root = catalog;
|
|
150
|
+
const rawAuth = root["multicast.auth"];
|
|
151
|
+
if (rawAuth === void 0) {
|
|
152
|
+
if (playerMode === "enforce") {
|
|
153
|
+
throw new Error("[multicast-auth-catalog] player enforce mode requires multicast.auth");
|
|
154
|
+
}
|
|
155
|
+
return void 0;
|
|
156
|
+
}
|
|
157
|
+
if (!isMulticastAuthConfig(rawAuth)) {
|
|
158
|
+
throw new Error("[multicast-auth-catalog] invalid multicast.auth v2 block");
|
|
159
|
+
}
|
|
160
|
+
const rawTracks = root["tracks"];
|
|
161
|
+
if (!Array.isArray(rawTracks)) {
|
|
162
|
+
throw new Error("[multicast-auth-catalog] catalog tracks must be an array");
|
|
163
|
+
}
|
|
164
|
+
const catalogTrackNames = new Set(
|
|
165
|
+
rawTracks.flatMap(
|
|
166
|
+
(track) => typeof track === "object" && track !== null && typeof track["name"] === "string" ? [track["name"]] : []
|
|
167
|
+
)
|
|
168
|
+
);
|
|
169
|
+
for (const track of rawAuth.tracks) {
|
|
170
|
+
if (!catalogTrackNames.has(track.mediaTrack)) {
|
|
171
|
+
throw new Error(`[multicast-auth-catalog] unknown mediaTrack "${track.mediaTrack}"`);
|
|
172
|
+
}
|
|
173
|
+
if (!catalogTrackNames.has(track.manifestTrack)) {
|
|
174
|
+
throw new Error(`[multicast-auth-catalog] unknown manifestTrack "${track.manifestTrack}"`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
keyId: rawAuth.keyId,
|
|
179
|
+
acceptedPublicKeys: [
|
|
180
|
+
decodeEd25519PublicKey(rawAuth.publicKey),
|
|
181
|
+
...rawAuth.previousKey === void 0 ? [] : [decodeEd25519PublicKey(rawAuth.previousKey)]
|
|
182
|
+
],
|
|
183
|
+
mode: resolveMulticastAuthMode(playerMode, rawAuth),
|
|
184
|
+
compaction: rawAuth.compaction,
|
|
185
|
+
tracks: rawAuth.tracks.map((track) => ({
|
|
186
|
+
...track,
|
|
187
|
+
authScope: decodeAuthScope(track.authScope)
|
|
188
|
+
}))
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/repair-layers.ts
|
|
193
|
+
var REPAIR_PRIORITY_MIN = 192;
|
|
194
|
+
var REPAIR_PRIORITY_MAX = 255;
|
|
195
|
+
var DEFAULT_REPAIR_PRIORITY = 240;
|
|
196
|
+
var MAX_RAPTORQ_SOURCE_SYMBOLS = 56403;
|
|
197
|
+
var MAX_REPAIR_SYMBOLS = 16777215;
|
|
198
|
+
var MAX_ENCODING_SYMBOL_ID = 16777215;
|
|
199
|
+
var RepairContractError = class extends Error {
|
|
200
|
+
constructor(code, path, message) {
|
|
201
|
+
super(`[repair-layers:${code}] ${path}: ${message}`);
|
|
202
|
+
this.code = code;
|
|
203
|
+
this.path = path;
|
|
204
|
+
this.name = "RepairContractError";
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
var throwRepairContractError = (code, path, message) => {
|
|
208
|
+
throw new RepairContractError(code, path, message);
|
|
209
|
+
};
|
|
210
|
+
var REPAIR_FIELDS = ["depends", "repairLayer", "repairSymbols", "priority", "scope", "sourceSymbols"];
|
|
211
|
+
var REPAIR_TRACK_GEOMETRY_KEYS = [
|
|
212
|
+
"mmtpMode",
|
|
213
|
+
"timescale",
|
|
214
|
+
"groupDurationMs",
|
|
215
|
+
"groupDurationTicks",
|
|
216
|
+
"keyframeIntervalMs",
|
|
217
|
+
"keyframeIntervalTicks",
|
|
218
|
+
"fec",
|
|
219
|
+
"symbolSize",
|
|
220
|
+
"interleaveDepthMs"
|
|
221
|
+
];
|
|
222
|
+
var REPAIR_TRACK_ONLY_KEYS = ["repairLayer", "repairSymbols", "sourceSymbols", "scope"];
|
|
223
|
+
function rejectRepairTrackGeometry(path, fields, fail) {
|
|
224
|
+
for (const key of REPAIR_TRACK_GEOMETRY_KEYS) {
|
|
225
|
+
if (fields[key] !== void 0) {
|
|
226
|
+
fail(
|
|
227
|
+
"track_repair_geometry",
|
|
228
|
+
`${path}.${key}`,
|
|
229
|
+
"a repair track carries no block geometry; it is shared with the source track's fec object"
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function repairReachability(fecObjects) {
|
|
235
|
+
let declaresFecSource = false;
|
|
236
|
+
const layerZeroNames = /* @__PURE__ */ new Set();
|
|
237
|
+
for (const candidate of fecObjects) {
|
|
238
|
+
if (typeof candidate !== "object" || candidate === null || Array.isArray(candidate)) continue;
|
|
239
|
+
const fec = candidate;
|
|
240
|
+
if (fec["algorithm"] === "none") continue;
|
|
241
|
+
declaresFecSource = true;
|
|
242
|
+
const repairTrack = fec["repairTrack"];
|
|
243
|
+
if (typeof repairTrack === "string" && repairTrack.length > 0) layerZeroNames.add(repairTrack);
|
|
244
|
+
}
|
|
245
|
+
return { declaresFecSource, layerZeroNames };
|
|
246
|
+
}
|
|
247
|
+
function assertRepairTrackReachable(descriptor, reachability, fail) {
|
|
248
|
+
if (dependsTarget(descriptor) !== void 0) return;
|
|
249
|
+
if (reachability.declaresFecSource && !reachability.layerZeroNames.has(descriptor.name)) {
|
|
250
|
+
fail(
|
|
251
|
+
"track_repair_depends",
|
|
252
|
+
`${descriptor.path}.depends`,
|
|
253
|
+
"no source names this repair track in fec.repairTrack and it declares no depends"
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function rejectRepairFieldsOnMediaTrack(path, fields, fail) {
|
|
258
|
+
for (const key of REPAIR_TRACK_ONLY_KEYS) {
|
|
259
|
+
if (fields[key] !== void 0) {
|
|
260
|
+
fail("track_repair_layer", `${path}.${key}`, `${key} is a repair track field`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function describeRepairTrack(name, path, fields) {
|
|
265
|
+
const descriptor = { name, path };
|
|
266
|
+
for (const field of REPAIR_FIELDS) {
|
|
267
|
+
if (field in fields) descriptor[field] = fields[field];
|
|
268
|
+
}
|
|
269
|
+
return descriptor;
|
|
270
|
+
}
|
|
271
|
+
function isSafeInteger(value) {
|
|
272
|
+
return typeof value === "number" && Number.isSafeInteger(value);
|
|
273
|
+
}
|
|
274
|
+
function positiveInteger(value) {
|
|
275
|
+
return isSafeInteger(value) && value > 0;
|
|
276
|
+
}
|
|
277
|
+
function dependsTarget(descriptor) {
|
|
278
|
+
const depends = descriptor.depends;
|
|
279
|
+
return Array.isArray(depends) && depends.length === 1 && typeof depends[0] === "string" && depends[0].length > 0 ? depends[0] : void 0;
|
|
280
|
+
}
|
|
281
|
+
function validateRepairTrackFields(descriptor, fail) {
|
|
282
|
+
const { path } = descriptor;
|
|
283
|
+
if (descriptor.depends !== void 0 && dependsTarget(descriptor) === void 0) {
|
|
284
|
+
fail("track_repair_depends", `${path}.depends`, "must name exactly one source track");
|
|
285
|
+
}
|
|
286
|
+
if (descriptor.repairLayer !== void 0 && (!isSafeInteger(descriptor.repairLayer) || descriptor.repairLayer < 0)) {
|
|
287
|
+
fail("track_repair_layer", `${path}.repairLayer`, "must be a non-negative integer");
|
|
288
|
+
}
|
|
289
|
+
if (descriptor.repairSymbols !== void 0 && (!positiveInteger(descriptor.repairSymbols) || descriptor.repairSymbols > MAX_REPAIR_SYMBOLS)) {
|
|
290
|
+
fail("track_repair_layer", `${path}.repairSymbols`, `must be a positive integer at most ${MAX_REPAIR_SYMBOLS}`);
|
|
291
|
+
}
|
|
292
|
+
if (descriptor.priority !== void 0 && (!isSafeInteger(descriptor.priority) || descriptor.priority < REPAIR_PRIORITY_MIN || descriptor.priority > REPAIR_PRIORITY_MAX)) {
|
|
293
|
+
fail(
|
|
294
|
+
"track_repair_priority",
|
|
295
|
+
`${path}.priority`,
|
|
296
|
+
`must be an integer from ${REPAIR_PRIORITY_MIN} to ${REPAIR_PRIORITY_MAX} (MoQT scale, lower first)`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
if (descriptor.scope !== void 0) {
|
|
300
|
+
if (descriptor.scope !== "keyframe") {
|
|
301
|
+
fail("track_repair_overlay", `${path}.scope`, 'must be "keyframe"');
|
|
302
|
+
}
|
|
303
|
+
if (descriptor.repairLayer !== void 0) {
|
|
304
|
+
fail("track_repair_overlay", `${path}.repairLayer`, "an overlay is a separate FEC instance and carries no repairLayer");
|
|
305
|
+
}
|
|
306
|
+
for (const field of ["depends", "sourceSymbols", "repairSymbols", "priority"]) {
|
|
307
|
+
if (descriptor[field] === void 0) {
|
|
308
|
+
fail("track_repair_overlay", `${path}.${field}`, `an overlay must declare ${field}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (descriptor.sourceSymbols !== void 0) {
|
|
313
|
+
if (descriptor.scope === void 0) {
|
|
314
|
+
fail("track_repair_overlay", `${path}.sourceSymbols`, "only an overlay (scope: keyframe) declares its own sourceSymbols");
|
|
315
|
+
}
|
|
316
|
+
if (!positiveInteger(descriptor.sourceSymbols) || descriptor.sourceSymbols > MAX_RAPTORQ_SOURCE_SYMBOLS) {
|
|
317
|
+
fail(
|
|
318
|
+
"track_fec_bounds",
|
|
319
|
+
`${path}.sourceSymbols`,
|
|
320
|
+
`must be a positive integer at most ${MAX_RAPTORQ_SOURCE_SYMBOLS} (RFC 6330 source block limit)`
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (isSafeInteger(descriptor.repairLayer) && descriptor.repairLayer >= 1) {
|
|
325
|
+
for (const field of ["depends", "repairSymbols", "priority"]) {
|
|
326
|
+
if (descriptor[field] === void 0) {
|
|
327
|
+
fail("track_repair_layer", `${path}.${field}`, `repair layer ${descriptor.repairLayer} must declare ${field}`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function assembleRepairLayers(source, descriptors, fail = throwRepairContractError, options = {}) {
|
|
333
|
+
const layerZeroName = typeof source.repairTrack === "string" && source.repairTrack.length > 0 ? source.repairTrack : void 0;
|
|
334
|
+
const layerZero = layerZeroName === void 0 ? void 0 : descriptors.find((d) => d.name === layerZeroName);
|
|
335
|
+
if (layerZeroName !== void 0 && layerZero === void 0 && options.layerZeroMustBeDeclared) {
|
|
336
|
+
fail("track_repair_track", `${source.path}.repairTrack`, `unknown FEC repair track ${JSON.stringify(layerZeroName)}`);
|
|
337
|
+
}
|
|
338
|
+
const dependents = descriptors.filter((d) => d.name !== layerZeroName && dependsTarget(d) === source.name);
|
|
339
|
+
const k = positiveInteger(source.sourceSymbols) ? source.sourceSymbols : 0;
|
|
340
|
+
if (source.algorithm === "raptorq" && k > MAX_RAPTORQ_SOURCE_SYMBOLS) {
|
|
341
|
+
fail(
|
|
342
|
+
"track_fec_bounds",
|
|
343
|
+
`${source.path}.sourceSymbols`,
|
|
344
|
+
`must be at most ${MAX_RAPTORQ_SOURCE_SYMBOLS} (RFC 6330 source block limit)`
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
if (layerZeroName === void 0) {
|
|
348
|
+
if (dependents.length === 0) return void 0;
|
|
349
|
+
fail(
|
|
350
|
+
"track_repair_layer",
|
|
351
|
+
`${dependents[0].path}.depends`,
|
|
352
|
+
`repair layers of ${JSON.stringify(source.name)} require a layer 0 (fec.repairTrack) on the source`
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
const layered = dependents.length > 0;
|
|
356
|
+
let layerZeroSymbols = 0;
|
|
357
|
+
if (positiveInteger(source.repairSymbols)) {
|
|
358
|
+
layerZeroSymbols = source.repairSymbols;
|
|
359
|
+
} else if (layered) {
|
|
360
|
+
fail("track_fec", `${source.path}.repairSymbols`, "layered or overlay repair needs a positive integer repairSymbols on layer 0");
|
|
361
|
+
}
|
|
362
|
+
if (layered && !positiveInteger(source.sourceSymbols)) {
|
|
363
|
+
fail("track_fec", `${source.path}.sourceSymbols`, "layered or overlay repair needs a positive integer sourceSymbols on the source");
|
|
364
|
+
}
|
|
365
|
+
if (layered && source.algorithm !== "raptorq") {
|
|
366
|
+
fail(
|
|
367
|
+
"track_fec",
|
|
368
|
+
`${source.path}.algorithm`,
|
|
369
|
+
"repair layers and overlays are defined only for raptorq: a block code fixes its codeword length, so symbols of a larger P are not symbols of the code a receiver holding fewer layers decodes"
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
let layerZeroPriority = DEFAULT_REPAIR_PRIORITY;
|
|
373
|
+
if (layerZero !== void 0) {
|
|
374
|
+
if (layerZero.depends !== void 0 && dependsTarget(layerZero) !== source.name) {
|
|
375
|
+
fail(
|
|
376
|
+
"track_repair_depends",
|
|
377
|
+
`${layerZero.path}.depends`,
|
|
378
|
+
`layer 0 of ${JSON.stringify(source.name)} must depend on that source`
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
if (layerZero.repairLayer !== void 0 && layerZero.repairLayer !== 0) {
|
|
382
|
+
fail("track_repair_layer", `${layerZero.path}.repairLayer`, "the track named by fec.repairTrack is layer 0");
|
|
383
|
+
}
|
|
384
|
+
if (layerZero.scope !== void 0) {
|
|
385
|
+
fail("track_repair_overlay", `${layerZero.path}.scope`, "the track named by fec.repairTrack is base layer 0, not an overlay");
|
|
386
|
+
}
|
|
387
|
+
if (layerZero.repairSymbols !== void 0 && layerZero.repairSymbols !== layerZeroSymbols) {
|
|
388
|
+
fail(
|
|
389
|
+
"track_repair_layer",
|
|
390
|
+
`${layerZero.path}.repairSymbols`,
|
|
391
|
+
`must agree with the source's fec.repairSymbols (${layerZeroSymbols})`
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
if (typeof layerZero.priority === "number") layerZeroPriority = layerZero.priority;
|
|
395
|
+
}
|
|
396
|
+
const baseLayers = [
|
|
397
|
+
{ layer: 0, repairTrackName: layerZeroName, repairSymbols: layerZeroSymbols, rsIdOffset: 0, priority: layerZeroPriority }
|
|
398
|
+
];
|
|
399
|
+
const overlays = [];
|
|
400
|
+
for (const d of dependents) {
|
|
401
|
+
if (d.scope === void 0 && d.repairLayer === void 0) {
|
|
402
|
+
fail(
|
|
403
|
+
"track_repair_layer",
|
|
404
|
+
`${d.path}.repairLayer`,
|
|
405
|
+
`a repair track that depends on ${JSON.stringify(source.name)} must declare repairLayer (1..n) or scope: "keyframe"`
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
const layerTracks = dependents.filter((d) => d.scope === void 0).sort((a, b) => a.repairLayer - b.repairLayer);
|
|
410
|
+
for (const d of dependents) {
|
|
411
|
+
if (d.scope !== "keyframe") continue;
|
|
412
|
+
if (overlays.length === 1) {
|
|
413
|
+
fail(
|
|
414
|
+
"track_repair_overlay",
|
|
415
|
+
`${d.path}.scope`,
|
|
416
|
+
`${JSON.stringify(source.name)} already has keyframe overlay ${JSON.stringify(overlays[0].repairTrackName)}: a RAP packet carries exactly two Source FEC Payload IDs (base, then overlay), so one overlay per source`
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
const sourceSymbols = d.sourceSymbols;
|
|
420
|
+
const repairSymbols = d.repairSymbols;
|
|
421
|
+
if (sourceSymbols + repairSymbols - 1 > MAX_ENCODING_SYMBOL_ID) {
|
|
422
|
+
fail(
|
|
423
|
+
"track_fec_bounds",
|
|
424
|
+
`${d.path}.repairSymbols`,
|
|
425
|
+
`overlay sourceSymbols + repairSymbols - 1 exceeds the 24-bit ESI space (${MAX_ENCODING_SYMBOL_ID})`
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
overlays.push({ repairTrackName: d.name, scope: "keyframe", sourceSymbols, repairSymbols, priority: d.priority });
|
|
429
|
+
}
|
|
430
|
+
let offset = layerZeroSymbols;
|
|
431
|
+
let previousPriority = layerZeroPriority;
|
|
432
|
+
layerTracks.forEach((d, i) => {
|
|
433
|
+
const expected = i + 1;
|
|
434
|
+
if (d.repairLayer === 0) {
|
|
435
|
+
fail("track_repair_layer", `${d.path}.repairLayer`, `layer 0 of ${JSON.stringify(source.name)} is ${JSON.stringify(layerZeroName)}, named by fec.repairTrack`);
|
|
436
|
+
}
|
|
437
|
+
if (d.repairLayer !== expected) {
|
|
438
|
+
fail(
|
|
439
|
+
"track_repair_layer",
|
|
440
|
+
`${d.path}.repairLayer`,
|
|
441
|
+
i > 0 && d.repairLayer === layerTracks[i - 1].repairLayer ? `repair layer ${d.repairLayer} is declared twice for ${JSON.stringify(source.name)}` : `repair layers must be contiguous from 1: expected ${expected}, found ${d.repairLayer}`
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
const priority = d.priority;
|
|
445
|
+
if (priority < previousPriority) {
|
|
446
|
+
fail(
|
|
447
|
+
"track_repair_priority",
|
|
448
|
+
`${d.path}.priority`,
|
|
449
|
+
`must be at least ${previousPriority}, the priority of layer ${expected - 1}: priority is monotonic non-decreasing with layer index`
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
previousPriority = priority;
|
|
453
|
+
const repairSymbols = d.repairSymbols;
|
|
454
|
+
baseLayers.push({ layer: expected, repairTrackName: d.name, repairSymbols, rsIdOffset: offset, priority });
|
|
455
|
+
offset += repairSymbols;
|
|
456
|
+
});
|
|
457
|
+
const totalBaseRepairSymbols = offset;
|
|
458
|
+
if (totalBaseRepairSymbols > MAX_REPAIR_SYMBOLS) {
|
|
459
|
+
fail(
|
|
460
|
+
"track_fec_bounds",
|
|
461
|
+
`${layerTracks.length === 0 ? source.path : layerTracks[layerTracks.length - 1].path}.repairSymbols`,
|
|
462
|
+
`total repair symbols across base layers exceeds the 24-bit RS_ID space (${MAX_REPAIR_SYMBOLS})`
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
if (k + totalBaseRepairSymbols - 1 > MAX_ENCODING_SYMBOL_ID) {
|
|
466
|
+
fail(
|
|
467
|
+
"track_fec_bounds",
|
|
468
|
+
`${source.path}.sourceSymbols`,
|
|
469
|
+
`sourceSymbols + total base repair symbols - 1 exceeds the 24-bit ESI space (${MAX_ENCODING_SYMBOL_ID})`
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
return { sourceTrackName: source.name, baseLayers, overlays, totalBaseRepairSymbols };
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// src/carp-catalog.ts
|
|
476
|
+
var VALID_ROLE_SUFFIXES = /* @__PURE__ */ new Set(["base", "delta", "repair"]);
|
|
477
|
+
function parseTrackRole(trackName) {
|
|
478
|
+
if (trackName === "") {
|
|
479
|
+
throw new Error("[carp-catalog] empty track name");
|
|
480
|
+
}
|
|
481
|
+
for (let i = 0; i < trackName.length; i++) {
|
|
482
|
+
const cp = trackName.charCodeAt(i);
|
|
483
|
+
if (cp <= 31 || cp === 127 || cp > 126) {
|
|
484
|
+
throw new Error(
|
|
485
|
+
`[carp-catalog] track name contains non-ASCII or control character (code point 0x${cp.toString(16)}) in "${trackName}"`
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
const lastSlash = trackName.lastIndexOf("/");
|
|
490
|
+
if (lastSlash === -1) {
|
|
491
|
+
return "single";
|
|
492
|
+
}
|
|
493
|
+
const suffix = trackName.slice(lastSlash + 1);
|
|
494
|
+
if (suffix === "") {
|
|
495
|
+
throw new Error(
|
|
496
|
+
`[carp-catalog] empty role suffix in track name "${trackName}"; track names must not end with "/"`
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
if (!VALID_ROLE_SUFFIXES.has(suffix)) {
|
|
500
|
+
throw new Error(
|
|
501
|
+
`[carp-catalog] unknown role suffix "${suffix}" in track name "${trackName}"; expected one of: base, delta, repair`
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
return suffix;
|
|
505
|
+
}
|
|
506
|
+
function hasSwitchingSetRole(names) {
|
|
507
|
+
return names.some((name) => {
|
|
508
|
+
const lastSlash = name.lastIndexOf("/");
|
|
509
|
+
if (lastSlash === -1) return false;
|
|
510
|
+
const suffix = name.slice(lastSlash + 1);
|
|
511
|
+
return suffix === "base" || suffix === "delta";
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
function validateSwitchingSet(trackNames) {
|
|
515
|
+
if (trackNames.length === 0) return { ok: true };
|
|
516
|
+
const roles = trackNames.map(parseTrackRole);
|
|
517
|
+
if (roles.every((r) => r === "single")) {
|
|
518
|
+
return { ok: true };
|
|
519
|
+
}
|
|
520
|
+
const presentRoles = new Set(roles.filter((r) => r !== "single"));
|
|
521
|
+
const required = ["base", "delta", "repair"];
|
|
522
|
+
const missing = required.filter((r) => !presentRoles.has(r));
|
|
523
|
+
if (missing.length > 0) {
|
|
524
|
+
return { ok: false, missing };
|
|
525
|
+
}
|
|
526
|
+
return { ok: true };
|
|
527
|
+
}
|
|
528
|
+
function isFecCatalogConfig(obj) {
|
|
529
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
530
|
+
const o = obj;
|
|
531
|
+
const algorithm = o["algorithm"];
|
|
532
|
+
const symbolSize = o["symbolSize"];
|
|
533
|
+
return typeof algorithm === "string" && (algorithm === "none" || algorithm === "raptorq" || algorithm === "reed-solomon") && typeof o["sourceSymbols"] === "number" && o["sourceSymbols"] >= 1 && typeof o["repairSymbols"] === "number" && o["repairSymbols"] >= 1 && typeof symbolSize === "number" && symbolSize >= 1 && (algorithm !== "raptorq" || symbolSize % 8 === 0) && typeof o["repairTrack"] === "string" && o["repairTrack"].length > 0;
|
|
534
|
+
}
|
|
535
|
+
function isMulticastTrackObject(obj) {
|
|
536
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
537
|
+
const o = obj;
|
|
538
|
+
return typeof o["name"] === "string" && typeof o["packetId"] === "number";
|
|
539
|
+
}
|
|
540
|
+
function isMulticastEndpoint(obj) {
|
|
541
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
542
|
+
const o = obj;
|
|
543
|
+
const protocol = o["protocol"] ?? (typeof o["sourceAddress"] === "string" && o["sourceAddress"].length > 0 ? "ssm" : void 0);
|
|
544
|
+
return typeof protocol === "string" && (protocol === "ssm" || protocol === "asm" || protocol === "amt" || protocol === "atsc3") && typeof o["groupAddress"] === "string" && o["groupAddress"].length > 0 && typeof o["port"] === "number" && o["port"] > 0 && o["port"] <= 65535 && Array.isArray(o["tracks"]) && o["tracks"].every((t) => typeof t === "string" || isMulticastTrackObject(t));
|
|
545
|
+
}
|
|
546
|
+
function isMulticastCatalogConfig(obj) {
|
|
547
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
548
|
+
const o = obj;
|
|
549
|
+
return Array.isArray(o["endpoints"]) && o["endpoints"].every((ep) => isMulticastEndpoint(ep));
|
|
550
|
+
}
|
|
551
|
+
function isTrackTimingConfig(obj) {
|
|
552
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
553
|
+
const o = obj;
|
|
554
|
+
const ms = o["groupDurationMs"];
|
|
555
|
+
const ticks = o["groupDurationTicks"];
|
|
556
|
+
if (ms === void 0 && ticks === void 0) return false;
|
|
557
|
+
if (ms !== void 0 && (typeof ms !== "number" || !Number.isInteger(ms) || ms <= 0)) return false;
|
|
558
|
+
if ("groupDurationTicks" in o) {
|
|
559
|
+
if (ticks === void 0) return ms !== void 0;
|
|
560
|
+
if (typeof ticks !== "number" || !Number.isInteger(ticks) || ticks <= 0) return false;
|
|
561
|
+
}
|
|
562
|
+
return true;
|
|
563
|
+
}
|
|
564
|
+
function resolveGroupDurationMs(timing, timescale) {
|
|
565
|
+
if (!Number.isSafeInteger(timescale) || timescale <= 0) {
|
|
566
|
+
throw new Error(
|
|
567
|
+
`[carp-catalog] resolveGroupDurationMs: timescale must be a positive safe integer Hz, got ${timescale}`
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
if (!isTrackTimingConfig(timing)) {
|
|
571
|
+
throw new Error(
|
|
572
|
+
`[carp-catalog] resolveGroupDurationMs: invalid TrackTimingConfig: ${JSON.stringify(timing)}`
|
|
573
|
+
);
|
|
574
|
+
}
|
|
575
|
+
if (timing.groupDurationTicks === void 0) {
|
|
576
|
+
return timing.groupDurationMs;
|
|
577
|
+
}
|
|
578
|
+
const durationMs = timing.groupDurationTicks / timescale * 1e3;
|
|
579
|
+
if (!Number.isFinite(durationMs) || durationMs <= 0 || durationMs > Number.MAX_SAFE_INTEGER) {
|
|
580
|
+
throw new Error(
|
|
581
|
+
`[carp-catalog] resolveGroupDurationMs: groupDurationTicks=${timing.groupDurationTicks} at timescale=${timescale} cannot be represented as a positive safe millisecond duration`
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
return durationMs;
|
|
585
|
+
}
|
|
586
|
+
var CmsfCatalogValidationError = class extends Error {
|
|
587
|
+
constructor(code, path, message) {
|
|
588
|
+
super(`[cmsf:${code}] ${path}: ${message}`);
|
|
589
|
+
this.code = code;
|
|
590
|
+
this.path = path;
|
|
591
|
+
this.name = "CmsfCatalogValidationError";
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
function catalogError(code, path, message) {
|
|
595
|
+
throw new CmsfCatalogValidationError(code, path, message);
|
|
596
|
+
}
|
|
597
|
+
function validateCmsfMmtpCatalog(value) {
|
|
598
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
599
|
+
catalogError("catalog_object", "$", "catalog must be an object");
|
|
600
|
+
}
|
|
601
|
+
const catalog = value;
|
|
602
|
+
const rawVersion = catalog["version"];
|
|
603
|
+
const normalizedVersion = typeof rawVersion === "string" ? Number.isFinite(Number(rawVersion)) ? Number(rawVersion) : rawVersion.startsWith("draft-ietf-moq-catalogformat") ? 1 : NaN : rawVersion;
|
|
604
|
+
if (!Number.isInteger(normalizedVersion) || normalizedVersion <= 0) {
|
|
605
|
+
catalogError("catalog_version", "$.version", "version must be a positive integer or a recognized format tag");
|
|
606
|
+
}
|
|
607
|
+
catalog["version"] = normalizedVersion;
|
|
608
|
+
if (!Array.isArray(catalog["tracks"])) {
|
|
609
|
+
catalogError("catalog_tracks", "$.tracks", "tracks must be an array");
|
|
610
|
+
}
|
|
611
|
+
const common = typeof catalog["commonTrackFields"] === "object" && catalog["commonTrackFields"] !== null && !Array.isArray(catalog["commonTrackFields"]) ? catalog["commonTrackFields"] : {};
|
|
612
|
+
const tracks = catalog["tracks"];
|
|
613
|
+
const trackRecords = [];
|
|
614
|
+
const effective = (track, field) => track[field] ?? common[field];
|
|
615
|
+
const positiveInteger2 = (input) => Number.isSafeInteger(input) && input > 0;
|
|
616
|
+
const positiveNumber = (input) => typeof input === "number" && Number.isFinite(input) && input > 0;
|
|
617
|
+
for (let index = 0; index < tracks.length; index++) {
|
|
618
|
+
const raw = tracks[index];
|
|
619
|
+
const path = `$.tracks[${index}]`;
|
|
620
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
621
|
+
catalogError("track_object", path, "track must be an object");
|
|
622
|
+
}
|
|
623
|
+
const track = raw;
|
|
624
|
+
const name = track["name"];
|
|
625
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
626
|
+
catalogError("track_name", `${path}.name`, "name must be a non-empty string");
|
|
627
|
+
}
|
|
628
|
+
trackRecords.push(track);
|
|
629
|
+
const packaging = effective(track, "packaging");
|
|
630
|
+
if (typeof packaging !== "string" || packaging.length === 0) {
|
|
631
|
+
catalogError("track_packaging", `${path}.packaging`, "packaging must be a non-empty string");
|
|
632
|
+
}
|
|
633
|
+
const trackHasIsLive = Object.prototype.hasOwnProperty.call(track, "isLive");
|
|
634
|
+
const hasIsLive = trackHasIsLive || Object.prototype.hasOwnProperty.call(common, "isLive");
|
|
635
|
+
const isLive = trackHasIsLive ? track["isLive"] : common["isLive"];
|
|
636
|
+
if (hasIsLive && typeof isLive !== "boolean") {
|
|
637
|
+
catalogError("track_is_live", `${path}.isLive`, "isLive must be a boolean");
|
|
638
|
+
}
|
|
639
|
+
track["isLive"] = isLive ?? true;
|
|
640
|
+
const selectionValue = effective(track, "selectionParams");
|
|
641
|
+
const selection = typeof selectionValue === "object" && selectionValue !== null && !Array.isArray(selectionValue) ? selectionValue : void 0;
|
|
642
|
+
const codec = selection?.["codec"] ?? effective(track, "codec");
|
|
643
|
+
if (packaging !== "timeline" && packaging !== "mediatimeline" && packaging !== "eventtimeline" && packaging !== "fec-repair" && (typeof codec !== "string" || codec.length === 0)) {
|
|
644
|
+
catalogError("track_codec", `${path}.codec`, `codec is required for packaging=${packaging}`);
|
|
645
|
+
}
|
|
646
|
+
const timescale = effective(track, "timescale");
|
|
647
|
+
const groupDurationMs = effective(track, "groupDurationMs");
|
|
648
|
+
const groupDurationTicks = effective(track, "groupDurationTicks");
|
|
649
|
+
const keyframeIntervalMs = effective(track, "keyframeIntervalMs");
|
|
650
|
+
const keyframeIntervalTicks = effective(track, "keyframeIntervalTicks");
|
|
651
|
+
if (groupDurationMs !== void 0 && !positiveInteger2(groupDurationMs)) {
|
|
652
|
+
catalogError("track_group_duration_ms", `${path}.groupDurationMs`, "must be a positive integer");
|
|
653
|
+
}
|
|
654
|
+
if (groupDurationTicks !== void 0 && !positiveInteger2(groupDurationTicks)) {
|
|
655
|
+
catalogError("track_group_duration_ticks", `${path}.groupDurationTicks`, "must be a positive integer");
|
|
656
|
+
}
|
|
657
|
+
if (keyframeIntervalMs !== void 0 && !positiveNumber(keyframeIntervalMs) || keyframeIntervalTicks !== void 0 && !positiveInteger2(keyframeIntervalTicks)) {
|
|
658
|
+
catalogError("track_keyframe_interval", path, "keyframe interval fields must be positive numbers");
|
|
659
|
+
}
|
|
660
|
+
if (packaging === "fec-repair") {
|
|
661
|
+
rejectRepairTrackGeometry(path, track, catalogError);
|
|
662
|
+
validateRepairTrackFields(describeRepairTrack(name, path, track), catalogError);
|
|
663
|
+
} else {
|
|
664
|
+
rejectRepairFieldsOnMediaTrack(path, track, catalogError);
|
|
665
|
+
}
|
|
666
|
+
if (packaging === "mmtp") {
|
|
667
|
+
const mmtpMode = effective(track, "mmtpMode");
|
|
668
|
+
if (mmtpMode !== "mpu" && mmtpMode !== "mfu") {
|
|
669
|
+
catalogError("track_mmtp_mode", `${path}.mmtpMode`, "must be mpu or mfu");
|
|
670
|
+
}
|
|
671
|
+
if (!positiveInteger2(timescale)) {
|
|
672
|
+
catalogError("track_timescale", `${path}.timescale`, "must be a positive integer");
|
|
673
|
+
}
|
|
674
|
+
if (groupDurationMs === void 0 && groupDurationTicks === void 0) {
|
|
675
|
+
catalogError(
|
|
676
|
+
"track_group_duration_ms",
|
|
677
|
+
path,
|
|
678
|
+
"groupDurationMs or groupDurationTicks must be a positive integer"
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
if (groupDurationTicks === void 0 && BigInt(groupDurationMs) * BigInt(timescale) % 1000n !== 0n) {
|
|
682
|
+
catalogError("track_group_duration_exact", `${path}.groupDurationMs`, "does not resolve to an exact integer tick count");
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (track["fec"] !== void 0) {
|
|
686
|
+
const fec = track["fec"];
|
|
687
|
+
if (typeof fec !== "object" || fec === null || Array.isArray(fec)) {
|
|
688
|
+
catalogError("track_fec", `${path}.fec`, "FEC must be an object");
|
|
689
|
+
}
|
|
690
|
+
const config = fec;
|
|
691
|
+
const algorithm = config["algorithm"];
|
|
692
|
+
if (algorithm !== "none" && algorithm !== "raptorq" && algorithm !== "reed-solomon") {
|
|
693
|
+
catalogError("track_fec", `${path}.fec.algorithm`, "algorithm is not supported");
|
|
694
|
+
}
|
|
695
|
+
if ("interleaveDepth" in config || "interleaveMs" in config) {
|
|
696
|
+
catalogError("track_fec", `${path}.fec`, "interleaveDepthMs is the only supported interleave field");
|
|
697
|
+
}
|
|
698
|
+
if ("enhancementRepair" in config) {
|
|
699
|
+
catalogError(
|
|
700
|
+
"track_fec",
|
|
701
|
+
`${path}.fec.enhancementRepair`,
|
|
702
|
+
"repair layers are self-describing fec-repair tracks (depends, repairLayer); fec.enhancementRepair is not supported"
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
if (config["interleaveDepthMs"] !== void 0 && !positiveInteger2(config["interleaveDepthMs"])) {
|
|
706
|
+
catalogError("track_fec", `${path}.fec.interleaveDepthMs`, "must be a positive integer");
|
|
707
|
+
}
|
|
708
|
+
if (algorithm !== "none") {
|
|
709
|
+
for (const field of ["sourceSymbols", "repairSymbols", "symbolSize"]) {
|
|
710
|
+
if (!positiveInteger2(config[field])) {
|
|
711
|
+
catalogError("track_fec", `${path}.fec.${field}`, "must be a positive integer");
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
if (typeof config["repairTrack"] !== "string" || config["repairTrack"].length === 0) {
|
|
715
|
+
catalogError("track_fec", `${path}.fec.repairTrack`, "must be a non-empty string");
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
const repairDescriptors = trackRecords.flatMap(
|
|
721
|
+
(track, index) => effective(track, "packaging") === "fec-repair" ? [describeRepairTrack(track["name"], `$.tracks[${index}]`, track)] : []
|
|
722
|
+
);
|
|
723
|
+
const reachability = repairReachability(
|
|
724
|
+
trackRecords.filter((track) => effective(track, "packaging") !== "fec-repair").map((track) => track["fec"])
|
|
725
|
+
);
|
|
726
|
+
for (const descriptor of repairDescriptors) {
|
|
727
|
+
assertRepairTrackReachable(descriptor, reachability, catalogError);
|
|
728
|
+
const target = dependsTarget(descriptor);
|
|
729
|
+
if (target === void 0) continue;
|
|
730
|
+
const source = trackRecords.find((candidate) => candidate["name"] === target);
|
|
731
|
+
const sourceFec = source?.["fec"];
|
|
732
|
+
if (!source || effective(source, "packaging") !== "mmtp" || !sourceFec || sourceFec["algorithm"] === "none") {
|
|
733
|
+
catalogError(
|
|
734
|
+
"track_repair_depends",
|
|
735
|
+
`${descriptor.path}.depends`,
|
|
736
|
+
`${JSON.stringify(target)} is not an mmtp track with FEC`
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
for (let index = 0; index < trackRecords.length; index++) {
|
|
741
|
+
const track = trackRecords[index];
|
|
742
|
+
const fec = track["fec"];
|
|
743
|
+
if (!fec || fec["algorithm"] === "none") continue;
|
|
744
|
+
assembleRepairLayers(
|
|
745
|
+
{
|
|
746
|
+
name: track["name"],
|
|
747
|
+
path: `$.tracks[${index}].fec`,
|
|
748
|
+
algorithm: fec["algorithm"],
|
|
749
|
+
sourceSymbols: fec["sourceSymbols"],
|
|
750
|
+
repairSymbols: fec["repairSymbols"],
|
|
751
|
+
repairTrack: fec["repairTrack"]
|
|
752
|
+
},
|
|
753
|
+
repairDescriptors,
|
|
754
|
+
catalogError,
|
|
755
|
+
{ layerZeroMustBeDeclared: true }
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
const switchingSets = /* @__PURE__ */ new Map();
|
|
759
|
+
for (let index = 0; index < trackRecords.length; index++) {
|
|
760
|
+
const track = trackRecords[index];
|
|
761
|
+
if (effective(track, "packaging") !== "mmtp") continue;
|
|
762
|
+
const altGroup = effective(track, "altGroup");
|
|
763
|
+
if (!Number.isSafeInteger(altGroup)) continue;
|
|
764
|
+
const timescale = BigInt(effective(track, "timescale"));
|
|
765
|
+
const durationTicks = effective(track, "groupDurationTicks");
|
|
766
|
+
const ticks = durationTicks !== void 0 ? BigInt(durationTicks) : BigInt(effective(track, "groupDurationMs")) * timescale / 1000n;
|
|
767
|
+
const anchor = switchingSets.get(altGroup);
|
|
768
|
+
if (anchor && ticks * anchor.timescale !== anchor.ticks * timescale) {
|
|
769
|
+
catalogError("track_switching_set", `$.tracks[${index}]`, `group duration does not match ${JSON.stringify(anchor.name)} in altGroup ${altGroup}`);
|
|
770
|
+
}
|
|
771
|
+
if (!anchor) switchingSets.set(altGroup, { name: track["name"], ticks, timescale });
|
|
772
|
+
}
|
|
773
|
+
const multicast = catalog["multicast"];
|
|
774
|
+
if (typeof multicast === "object" && multicast !== null && !Array.isArray(multicast)) {
|
|
775
|
+
const endpoints = multicast["endpoints"];
|
|
776
|
+
if (Array.isArray(endpoints)) {
|
|
777
|
+
for (let endpointIndex = 0; endpointIndex < endpoints.length; endpointIndex++) {
|
|
778
|
+
const endpoint = endpoints[endpointIndex];
|
|
779
|
+
if (typeof endpoint !== "object" || endpoint === null || Array.isArray(endpoint)) continue;
|
|
780
|
+
const refs = endpoint["tracks"];
|
|
781
|
+
if (!Array.isArray(refs)) continue;
|
|
782
|
+
const packetIds = /* @__PURE__ */ new Map();
|
|
783
|
+
for (let refIndex = 0; refIndex < refs.length; refIndex++) {
|
|
784
|
+
const ref = refs[refIndex];
|
|
785
|
+
if (typeof ref !== "object" || ref === null || Array.isArray(ref)) continue;
|
|
786
|
+
const trackRef = ref;
|
|
787
|
+
const refPath = `$.multicast.endpoints[${endpointIndex}].tracks[${refIndex}]`;
|
|
788
|
+
const name = trackRef["name"];
|
|
789
|
+
if (typeof name !== "string" || !trackRecords.some((track) => track["name"] === name)) {
|
|
790
|
+
catalogError("multicast_track", `${refPath}.name`, `unknown catalog track ${JSON.stringify(name)}`);
|
|
791
|
+
}
|
|
792
|
+
const packetId = trackRef["packetId"];
|
|
793
|
+
if (!Number.isSafeInteger(packetId) || packetId < 0 || packetId > 65535) {
|
|
794
|
+
catalogError("multicast_packet_id", `${refPath}.packetId`, "packetId must be an integer from 0 to 65535");
|
|
795
|
+
}
|
|
796
|
+
const previous = packetIds.get(packetId);
|
|
797
|
+
if (previous !== void 0) {
|
|
798
|
+
catalogError("multicast_packet_id", `${refPath}.packetId`, `packetId is already assigned to ${JSON.stringify(previous)}`);
|
|
799
|
+
}
|
|
800
|
+
packetIds.set(packetId, name);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
try {
|
|
806
|
+
resolveMulticastAuthCatalog(catalog);
|
|
807
|
+
} catch (error) {
|
|
808
|
+
catalogError(
|
|
809
|
+
"multicast_auth",
|
|
810
|
+
"$.multicast.auth",
|
|
811
|
+
error instanceof Error ? error.message : "invalid multicast.auth v2 block"
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
return catalog;
|
|
815
|
+
}
|
|
816
|
+
function resolveGroupDurationTicks(timing, timescale) {
|
|
817
|
+
if (!Number.isFinite(timescale) || !Number.isInteger(timescale) || timescale <= 0) {
|
|
818
|
+
throw new Error(
|
|
819
|
+
`[carp-catalog] resolveGroupDurationTicks: timescale must be a positive integer Hz, got ${timescale}`
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
if (!isTrackTimingConfig(timing)) {
|
|
823
|
+
throw new Error(
|
|
824
|
+
`[carp-catalog] resolveGroupDurationTicks: invalid TrackTimingConfig: ${JSON.stringify(timing)}`
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
if (timing.groupDurationTicks !== void 0) {
|
|
828
|
+
return timing.groupDurationTicks;
|
|
829
|
+
}
|
|
830
|
+
if (timing.groupDurationMs === void 0) {
|
|
831
|
+
throw new Error(
|
|
832
|
+
"[carp-catalog] resolveGroupDurationTicks: groupDurationMs is required when groupDurationTicks is absent"
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
const product = timing.groupDurationMs * timescale;
|
|
836
|
+
if (product % 1e3 !== 0) {
|
|
837
|
+
throw new Error(
|
|
838
|
+
`[carp-catalog] resolveGroupDurationTicks: groupDurationMs=${timing.groupDurationMs} at timescale=${timescale} produces non-integer ticks (${product / 1e3}); publisher must use groupDurationTicks override (mmt-00 \xA74.4.4)`
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
return product / 1e3;
|
|
842
|
+
}
|
|
843
|
+
function validateSwitchingSetTiming(tracks) {
|
|
844
|
+
if (tracks.length === 0) return { ok: true };
|
|
845
|
+
const ticksByTrack = tracks.map((t) => ({
|
|
846
|
+
name: t.name,
|
|
847
|
+
ticks: resolveGroupDurationTicks(t.timing, t.timescale),
|
|
848
|
+
timescale: t.timescale
|
|
849
|
+
}));
|
|
850
|
+
const expectedTicks = ticksByTrack[0].ticks;
|
|
851
|
+
const expectedTimescale = ticksByTrack[0].timescale;
|
|
852
|
+
const mismatches = ticksByTrack.slice(1).filter(
|
|
853
|
+
(t) => BigInt(t.ticks) * BigInt(expectedTimescale) !== BigInt(expectedTicks) * BigInt(t.timescale)
|
|
854
|
+
).map(({ name, ticks }) => ({ name, ticks }));
|
|
855
|
+
if (mismatches.length === 0) return { ok: true };
|
|
856
|
+
return { ok: false, expectedTicks, mismatches };
|
|
857
|
+
}
|
|
858
|
+
export {
|
|
859
|
+
CmsfCatalogValidationError,
|
|
860
|
+
hasSwitchingSetRole,
|
|
861
|
+
isFecCatalogConfig,
|
|
862
|
+
isMulticastCatalogConfig,
|
|
863
|
+
isMulticastEndpoint,
|
|
864
|
+
isMulticastTrackObject,
|
|
865
|
+
isTrackTimingConfig,
|
|
866
|
+
parseTrackRole,
|
|
867
|
+
resolveGroupDurationMs,
|
|
868
|
+
resolveGroupDurationTicks,
|
|
869
|
+
validateCmsfMmtpCatalog,
|
|
870
|
+
validateSwitchingSet,
|
|
871
|
+
validateSwitchingSetTiming
|
|
872
|
+
};
|
|
873
|
+
//# sourceMappingURL=carp-catalog.js.map
|