@blockcast/mmt-container 0.1.0 → 0.3.0-main.d9354616fdf2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +524 -0
- package/dist/.build-stamp +0 -0
- package/dist/__tests__/test-utils.d.ts +71 -0
- package/dist/__tests__/test-utils.d.ts.map +1 -0
- package/dist/align.d.ts +152 -0
- package/dist/align.d.ts.map +1 -0
- package/dist/align.js +88 -0
- package/dist/align.js.map +7 -0
- package/dist/audio-init-parser.d.ts +66 -0
- package/dist/audio-init-parser.d.ts.map +1 -0
- package/dist/audio-init-parser.js +118 -0
- package/dist/audio-init-parser.js.map +7 -0
- package/dist/audio-ring-buffer.d.ts +50 -0
- package/dist/audio-ring-buffer.d.ts.map +1 -0
- package/dist/audio-ring-buffer.js +80 -0
- package/dist/audio-ring-buffer.js.map +7 -0
- package/dist/authored-timing.d.ts +32 -0
- package/dist/authored-timing.d.ts.map +1 -0
- package/dist/authored-timing.js +32 -0
- package/dist/authored-timing.js.map +7 -0
- package/dist/block-policy.d.ts +314 -0
- package/dist/block-policy.d.ts.map +1 -0
- package/dist/block-policy.js +466 -0
- package/dist/block-policy.js.map +7 -0
- package/dist/browser-runtime.js +26549 -0
- package/dist/browser-runtime.js.map +7 -0
- package/dist/carp-catalog.d.ts +429 -0
- package/dist/carp-catalog.d.ts.map +1 -0
- package/dist/carp-catalog.js +985 -0
- package/dist/carp-catalog.js.map +7 -0
- package/dist/catalog-fec-params.d.ts +275 -0
- package/dist/catalog-fec-params.d.ts.map +1 -0
- package/dist/catalog-fec-params.js +702 -0
- package/dist/catalog-fec-params.js.map +7 -0
- package/dist/catalog-network-source.d.ts +42 -0
- package/dist/catalog-network-source.d.ts.map +1 -0
- package/dist/catalog-network-source.js +47 -0
- package/dist/catalog-network-source.js.map +7 -0
- package/dist/catalog-validator.d.ts +18 -0
- package/dist/catalog-validator.d.ts.map +1 -0
- package/dist/catalog-validator.js +7747 -0
- package/dist/catalog-validator.js.map +7 -0
- package/dist/cmaf-block-assembler.d.ts +285 -0
- package/dist/cmaf-block-assembler.d.ts.map +1 -0
- package/dist/cmaf-block-assembler.js +1966 -0
- package/dist/cmaf-block-assembler.js.map +7 -0
- package/dist/cmaf-group-batcher.d.ts +38 -0
- package/dist/cmaf-group-batcher.d.ts.map +1 -0
- package/dist/cmaf-group-batcher.js +176 -0
- package/dist/cmaf-group-batcher.js.map +7 -0
- package/dist/cmcd-producer.d.ts +104 -0
- package/dist/cmcd-producer.d.ts.map +1 -0
- package/dist/cmcd-producer.js +183 -0
- package/dist/cmcd-producer.js.map +7 -0
- package/dist/codec-utils.d.ts +384 -0
- package/dist/codec-utils.d.ts.map +1 -0
- package/dist/codec-utils.js +1546 -0
- package/dist/codec-utils.js.map +7 -0
- package/dist/conceal-timeline.d.ts +146 -0
- package/dist/conceal-timeline.d.ts.map +1 -0
- package/dist/conceal-timeline.js +137 -0
- package/dist/conceal-timeline.js.map +7 -0
- package/dist/delivery-gap.d.ts +75 -0
- package/dist/delivery-gap.d.ts.map +1 -0
- package/dist/delivery-gap.js +88 -0
- package/dist/delivery-gap.js.map +7 -0
- package/dist/duplicate-ledger.d.ts +197 -0
- package/dist/duplicate-ledger.d.ts.map +1 -0
- package/dist/duplicate-ledger.js +226 -0
- package/dist/duplicate-ledger.js.map +7 -0
- package/dist/fec-codec.d.ts +32 -0
- package/dist/fec-codec.d.ts.map +1 -0
- package/dist/fec-codec.js +47 -0
- package/dist/fec-codec.js.map +7 -0
- package/dist/fec-manager.d.ts +583 -0
- package/dist/fec-manager.d.ts.map +1 -0
- package/dist/fec-manager.js +3899 -0
- package/dist/fec-manager.js.map +7 -0
- package/dist/fec-starvation-detector.d.ts +59 -0
- package/dist/fec-starvation-detector.d.ts.map +1 -0
- package/dist/fec-starvation-detector.js +60 -0
- package/dist/fec-starvation-detector.js.map +7 -0
- package/dist/fec-state.d.ts +131 -0
- package/dist/fec-state.d.ts.map +1 -0
- package/dist/fec-state.js +87 -0
- package/dist/fec-state.js.map +7 -0
- package/dist/fec-worker-setup.d.ts +94 -0
- package/dist/fec-worker-setup.d.ts.map +1 -0
- package/dist/fec-worker-setup.js +673 -0
- package/dist/fec-worker-setup.js.map +7 -0
- package/dist/fmp4-completion.d.ts +30 -0
- package/dist/fmp4-completion.d.ts.map +1 -0
- package/dist/fmp4-completion.js +21 -0
- package/dist/fmp4-completion.js.map +7 -0
- package/dist/fmp4-reader.d.ts +37 -0
- package/dist/fmp4-reader.d.ts.map +1 -0
- package/dist/fmp4-reader.js +100 -0
- package/dist/fmp4-reader.js.map +7 -0
- package/dist/index.d.ts +44 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +460 -14
- package/dist/index.js.map +7 -1
- package/dist/iso-block-locator.d.ts +118 -0
- package/dist/iso-block-locator.d.ts.map +1 -0
- package/dist/iso-block-locator.js +289 -0
- package/dist/iso-block-locator.js.map +7 -0
- package/dist/iso-bmff-timing.d.ts +78 -0
- package/dist/iso-bmff-timing.d.ts.map +1 -0
- package/dist/iso-bmff-timing.js +593 -0
- package/dist/iso-bmff-timing.js.map +7 -0
- package/dist/loc.d.ts +70 -75
- package/dist/loc.d.ts.map +1 -1
- package/dist/loc.js +106 -192
- package/dist/loc.js.map +7 -1
- package/dist/manifest-auth-plan.d.ts +30 -0
- package/dist/manifest-auth-plan.d.ts.map +1 -0
- package/dist/manifest-auth-plan.js +1266 -0
- package/dist/manifest-auth-plan.js.map +7 -0
- package/dist/media-router.d.ts +262 -0
- package/dist/media-router.d.ts.map +1 -0
- package/dist/media-router.js +584 -0
- package/dist/media-router.js.map +7 -0
- package/dist/mfu-reassembler.d.ts +313 -9
- package/dist/mfu-reassembler.d.ts.map +1 -1
- package/dist/mfu-reassembler.js +3051 -285
- package/dist/mfu-reassembler.js.map +7 -1
- package/dist/mfu-reassembly-policy.d.ts +24 -0
- package/dist/mfu-reassembly-policy.d.ts.map +1 -0
- package/dist/mfu-reassembly-policy.js +99 -0
- package/dist/mfu-reassembly-policy.js.map +7 -0
- package/dist/mmtp-container-parser.d.ts +568 -0
- package/dist/mmtp-container-parser.d.ts.map +1 -0
- package/dist/mmtp-container-parser.js +6580 -0
- package/dist/mmtp-container-parser.js.map +7 -0
- package/dist/mmtp-container-parser.no-modules.js +9616 -0
- package/dist/mmtp-container-parser.no-modules.js.map +7 -0
- package/dist/mmtp-decode-pipeline.d.ts +138 -0
- package/dist/mmtp-decode-pipeline.d.ts.map +1 -0
- package/dist/mmtp-decode-pipeline.js +6814 -0
- package/dist/mmtp-decode-pipeline.js.map +7 -0
- package/dist/mmtp-router.d.ts +679 -0
- package/dist/mmtp-router.d.ts.map +1 -0
- package/dist/mmtp-router.js +11278 -0
- package/dist/mmtp-router.js.map +7 -0
- package/dist/mmtp-to-cmaf.d.ts +187 -0
- package/dist/mmtp-to-cmaf.d.ts.map +1 -0
- package/dist/mmtp-to-cmaf.js +716 -0
- package/dist/mmtp-to-cmaf.js.map +7 -0
- package/dist/multicast-auth-catalog.d.ts +115 -0
- package/dist/multicast-auth-catalog.d.ts.map +1 -0
- package/dist/multicast-auth-catalog.js +202 -0
- package/dist/multicast-auth-catalog.js.map +7 -0
- package/dist/multicast-input.d.ts +141 -0
- package/dist/multicast-input.d.ts.map +1 -0
- package/dist/multicast-input.js +390 -0
- package/dist/multicast-input.js.map +7 -0
- package/dist/multicast-manager.d.ts +669 -0
- package/dist/multicast-manager.d.ts.map +1 -0
- package/dist/multicast-manager.js +19101 -0
- package/dist/multicast-manager.js.map +7 -0
- package/dist/multicast-transport.d.ts +271 -0
- package/dist/multicast-transport.d.ts.map +1 -0
- package/dist/multicast-transport.js +2264 -0
- package/dist/multicast-transport.js.map +7 -0
- package/dist/multicast-unwrap.d.ts +57 -0
- package/dist/multicast-unwrap.d.ts.map +1 -0
- package/dist/multicast-unwrap.js +418 -0
- package/dist/multicast-unwrap.js.map +7 -0
- package/dist/no-modules.d.ts +10 -0
- package/dist/no-modules.d.ts.map +1 -0
- package/dist/no-modules.js +9491 -0
- package/dist/no-modules.js.map +7 -0
- package/dist/phase14-catalog-override.d.ts +126 -0
- package/dist/phase14-catalog-override.d.ts.map +1 -0
- package/dist/phase14-catalog-override.js +155 -0
- package/dist/phase14-catalog-override.js.map +7 -0
- package/dist/repair-fetch.d.ts +270 -0
- package/dist/repair-fetch.d.ts.map +1 -0
- package/dist/repair-fetch.js +381 -0
- package/dist/repair-fetch.js.map +7 -0
- package/dist/repair-layers.d.ts +158 -0
- package/dist/repair-layers.d.ts.map +1 -0
- package/dist/repair-layers.js +344 -0
- package/dist/repair-layers.js.map +7 -0
- package/dist/sample-combiner.d.ts +212 -0
- package/dist/sample-combiner.d.ts.map +1 -0
- package/dist/sample-combiner.js +595 -0
- package/dist/sample-combiner.js.map +7 -0
- package/dist/signaling.d.ts +29 -0
- package/dist/signaling.d.ts.map +1 -0
- package/dist/signaling.js +572 -0
- package/dist/signaling.js.map +7 -0
- package/dist/source-auth.d.ts +2 -0
- package/dist/source-auth.d.ts.map +1 -0
- package/dist/source-auth.js +1209 -0
- package/dist/source-auth.js.map +7 -0
- package/dist/switching-set-alignment.d.ts +61 -0
- package/dist/switching-set-alignment.d.ts.map +1 -0
- package/dist/switching-set-alignment.js +70 -0
- package/dist/switching-set-alignment.js.map +7 -0
- package/dist/timestamp-codec.d.ts +34 -0
- package/dist/timestamp-codec.d.ts.map +1 -0
- package/dist/timestamp-codec.js +473 -0
- package/dist/timestamp-codec.js.map +7 -0
- package/dist/track-pipeline-setup.d.ts +83 -0
- package/dist/track-pipeline-setup.d.ts.map +1 -0
- package/dist/track-pipeline-setup.js +291 -0
- package/dist/track-pipeline-setup.js.map +7 -0
- package/dist/track-pipeline.d.ts +121 -0
- package/dist/track-pipeline.d.ts.map +1 -0
- package/dist/track-pipeline.js +209 -0
- package/dist/track-pipeline.js.map +7 -0
- package/dist/track-session.d.ts +414 -0
- package/dist/track-session.d.ts.map +1 -0
- package/dist/track-session.js +754 -0
- package/dist/track-session.js.map +7 -0
- package/dist/transport-pool.d.ts +69 -0
- package/dist/transport-pool.d.ts.map +1 -0
- package/dist/transport-pool.js +74 -0
- package/dist/transport-pool.js.map +7 -0
- package/dist/wasm-mfu-reassembler.d.ts +97 -0
- package/dist/wasm-mfu-reassembler.d.ts.map +1 -0
- package/dist/wasm-mfu-reassembler.js +2133 -0
- package/dist/wasm-mfu-reassembler.js.map +7 -0
- package/dist/wasm-mmtp-container-parser.d.ts +10 -0
- package/dist/wasm-mmtp-container-parser.d.ts.map +1 -0
- package/dist/wasm-mmtp-container-parser.js +6834 -0
- package/dist/wasm-mmtp-container-parser.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/README.md +223 -0
- package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts +38 -0
- package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/block-order.js +78 -0
- package/node_modules/@blockcast/fec-worker/dist/block-order.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +93 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +346 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +380 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +11 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +14 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +859 -0
- package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts +10 -0
- package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/index.js +8 -0
- package/node_modules/@blockcast/fec-worker/dist/index.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +20 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +370 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +7 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +104 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +181 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +194 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +62 -0
- package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +9 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +1 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.js +13 -0
- package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +1 -0
- package/node_modules/@blockcast/fec-worker/package.json +59 -0
- package/node_modules/@blockcast/fec-worker/src/block-order.ts +93 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +392 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +399 -0
- package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +1502 -0
- package/node_modules/@blockcast/fec-worker/src/index.ts +35 -0
- package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +589 -0
- package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +222 -0
- package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +209 -0
- package/node_modules/@blockcast/fec-worker/src/transfer.ts +12 -0
- package/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
- package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
- package/node_modules/@blockcast/mmt-base/README.md +134 -0
- package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
- package/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
- package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
- package/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
- package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
- package/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
- package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
- package/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
- package/node_modules/@blockcast/mmt-base/package.json +49 -0
- package/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
- package/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
- package/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
- package/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
- package/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
- package/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
- package/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
- package/node_modules/@blockcast/mmt-fec/README.md +271 -0
- package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +82 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +296 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +106 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +288 -0
- package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +46 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +96 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +33 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +57 -0
- package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +205 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +240 -0
- package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +28 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.js +28 -0
- package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +20 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +28 -0
- package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +258 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.js +382 -0
- package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +41 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +81 -0
- package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +82 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +170 -0
- package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +134 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +49 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
- package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
- package/node_modules/@blockcast/mmt-fec/package.json +79 -0
- package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +371 -0
- package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +439 -0
- package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +127 -0
- package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +68 -0
- package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +310 -0
- package/node_modules/@blockcast/mmt-fec/src/index.ts +94 -0
- package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +34 -0
- package/node_modules/@blockcast/mmt-fec/src/oti.ts +463 -0
- package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +101 -0
- package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +195 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +28 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +128 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +4 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +4 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +37 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +179 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +99 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +492 -0
- package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +1 -0
- package/node_modules/@blockcast/mmt-manifest-verify/package.json +45 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +171 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +3 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +230 -0
- package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +669 -0
- package/node_modules/@noble/hashes/LICENSE +21 -0
- package/node_modules/@noble/hashes/README.md +521 -0
- package/node_modules/@noble/hashes/_assert.d.ts +17 -0
- package/node_modules/@noble/hashes/_assert.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_assert.js +18 -0
- package/node_modules/@noble/hashes/_assert.js.map +1 -0
- package/node_modules/@noble/hashes/_blake.d.ts +14 -0
- package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_blake.js +50 -0
- package/node_modules/@noble/hashes/_blake.js.map +1 -0
- package/node_modules/@noble/hashes/_md.d.ts +51 -0
- package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_md.js +162 -0
- package/node_modules/@noble/hashes/_md.js.map +1 -0
- package/node_modules/@noble/hashes/_u64.d.ts +55 -0
- package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_u64.js +90 -0
- package/node_modules/@noble/hashes/_u64.js.map +1 -0
- package/node_modules/@noble/hashes/argon2.d.ts +32 -0
- package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/argon2.js +401 -0
- package/node_modules/@noble/hashes/argon2.js.map +1 -0
- package/node_modules/@noble/hashes/blake1.d.ts +106 -0
- package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake1.js +459 -0
- package/node_modules/@noble/hashes/blake1.js.map +1 -0
- package/node_modules/@noble/hashes/blake2.d.ts +116 -0
- package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2.js +420 -0
- package/node_modules/@noble/hashes/blake2.js.map +1 -0
- package/node_modules/@noble/hashes/blake2b.d.ts +11 -0
- package/node_modules/@noble/hashes/blake2b.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2b.js +14 -0
- package/node_modules/@noble/hashes/blake2b.js.map +1 -0
- package/node_modules/@noble/hashes/blake2s.d.ts +20 -0
- package/node_modules/@noble/hashes/blake2s.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2s.js +24 -0
- package/node_modules/@noble/hashes/blake2s.js.map +1 -0
- package/node_modules/@noble/hashes/blake3.d.ts +54 -0
- package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake3.js +255 -0
- package/node_modules/@noble/hashes/blake3.js.map +1 -0
- package/node_modules/@noble/hashes/crypto.d.ts +2 -0
- package/node_modules/@noble/hashes/crypto.d.ts.map +1 -0
- package/node_modules/@noble/hashes/crypto.js +5 -0
- package/node_modules/@noble/hashes/crypto.js.map +1 -0
- package/node_modules/@noble/hashes/cryptoNode.d.ts +2 -0
- package/node_modules/@noble/hashes/cryptoNode.d.ts.map +1 -0
- package/node_modules/@noble/hashes/cryptoNode.js +18 -0
- package/node_modules/@noble/hashes/cryptoNode.js.map +1 -0
- package/node_modules/@noble/hashes/eskdf.d.ts +47 -0
- package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/eskdf.js +166 -0
- package/node_modules/@noble/hashes/eskdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_assert.d.ts +17 -0
- package/node_modules/@noble/hashes/esm/_assert.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_assert.js +15 -0
- package/node_modules/@noble/hashes/esm/_assert.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_blake.d.ts +14 -0
- package/node_modules/@noble/hashes/esm/_blake.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_blake.js +45 -0
- package/node_modules/@noble/hashes/esm/_blake.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_md.d.ts +51 -0
- package/node_modules/@noble/hashes/esm/_md.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_md.js +155 -0
- package/node_modules/@noble/hashes/esm/_md.js.map +1 -0
- package/node_modules/@noble/hashes/esm/_u64.d.ts +55 -0
- package/node_modules/@noble/hashes/esm/_u64.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/_u64.js +67 -0
- package/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
- package/node_modules/@noble/hashes/esm/argon2.d.ts +32 -0
- package/node_modules/@noble/hashes/esm/argon2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/argon2.js +392 -0
- package/node_modules/@noble/hashes/esm/argon2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake1.d.ts +106 -0
- package/node_modules/@noble/hashes/esm/blake1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake1.js +452 -0
- package/node_modules/@noble/hashes/esm/blake1.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2.d.ts +116 -0
- package/node_modules/@noble/hashes/esm/blake2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2.js +413 -0
- package/node_modules/@noble/hashes/esm/blake2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2b.d.ts +11 -0
- package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2b.js +11 -0
- package/node_modules/@noble/hashes/esm/blake2b.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2s.d.ts +20 -0
- package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake2s.js +21 -0
- package/node_modules/@noble/hashes/esm/blake2s.js.map +1 -0
- package/node_modules/@noble/hashes/esm/blake3.d.ts +54 -0
- package/node_modules/@noble/hashes/esm/blake3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/blake3.js +251 -0
- package/node_modules/@noble/hashes/esm/blake3.js.map +1 -0
- package/node_modules/@noble/hashes/esm/crypto.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/crypto.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/crypto.js +2 -0
- package/node_modules/@noble/hashes/esm/crypto.js.map +1 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.js +15 -0
- package/node_modules/@noble/hashes/esm/cryptoNode.js.map +1 -0
- package/node_modules/@noble/hashes/esm/eskdf.d.ts +47 -0
- package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/eskdf.js +160 -0
- package/node_modules/@noble/hashes/esm/eskdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/hkdf.d.ts +36 -0
- package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/hkdf.js +82 -0
- package/node_modules/@noble/hashes/esm/hkdf.js.map +1 -0
- package/node_modules/@noble/hashes/esm/hmac.d.ts +35 -0
- package/node_modules/@noble/hashes/esm/hmac.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/hmac.js +86 -0
- package/node_modules/@noble/hashes/esm/hmac.js.map +1 -0
- package/node_modules/@noble/hashes/esm/index.d.ts +2 -0
- package/node_modules/@noble/hashes/esm/index.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/index.js +33 -0
- package/node_modules/@noble/hashes/esm/index.js.map +1 -0
- package/node_modules/@noble/hashes/esm/legacy.d.ts +71 -0
- package/node_modules/@noble/hashes/esm/legacy.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/legacy.js +281 -0
- package/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
- package/node_modules/@noble/hashes/esm/package.json +10 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +23 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.js +97 -0
- package/node_modules/@noble/hashes/esm/pbkdf2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts +13 -0
- package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/ripemd160.js +13 -0
- package/node_modules/@noble/hashes/esm/ripemd160.js.map +1 -0
- package/node_modules/@noble/hashes/esm/scrypt.d.ts +34 -0
- package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/scrypt.js +228 -0
- package/node_modules/@noble/hashes/esm/scrypt.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha1.d.ts +11 -0
- package/node_modules/@noble/hashes/esm/sha1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha1.js +11 -0
- package/node_modules/@noble/hashes/esm/sha1.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha2.d.ts +159 -0
- package/node_modules/@noble/hashes/esm/sha2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha2.js +375 -0
- package/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha256.d.ts +20 -0
- package/node_modules/@noble/hashes/esm/sha256.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha256.js +20 -0
- package/node_modules/@noble/hashes/esm/sha256.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +142 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.js +393 -0
- package/node_modules/@noble/hashes/esm/sha3-addons.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3.d.ts +53 -0
- package/node_modules/@noble/hashes/esm/sha3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha3.js +234 -0
- package/node_modules/@noble/hashes/esm/sha3.js.map +1 -0
- package/node_modules/@noble/hashes/esm/sha512.d.ts +26 -0
- package/node_modules/@noble/hashes/esm/sha512.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/sha512.js +26 -0
- package/node_modules/@noble/hashes/esm/sha512.js.map +1 -0
- package/node_modules/@noble/hashes/esm/utils.d.ts +161 -0
- package/node_modules/@noble/hashes/esm/utils.d.ts.map +1 -0
- package/node_modules/@noble/hashes/esm/utils.js +281 -0
- package/node_modules/@noble/hashes/esm/utils.js.map +1 -0
- package/node_modules/@noble/hashes/hkdf.d.ts +36 -0
- package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hkdf.js +88 -0
- package/node_modules/@noble/hashes/hkdf.js.map +1 -0
- package/node_modules/@noble/hashes/hmac.d.ts +35 -0
- package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hmac.js +91 -0
- package/node_modules/@noble/hashes/hmac.js.map +1 -0
- package/node_modules/@noble/hashes/index.d.ts +1 -0
- package/node_modules/@noble/hashes/index.d.ts.map +1 -0
- package/node_modules/@noble/hashes/index.js +33 -0
- package/node_modules/@noble/hashes/index.js.map +1 -0
- package/node_modules/@noble/hashes/legacy.d.ts +71 -0
- package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
- package/node_modules/@noble/hashes/legacy.js +287 -0
- package/node_modules/@noble/hashes/legacy.js.map +1 -0
- package/node_modules/@noble/hashes/package.json +266 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts +23 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/pbkdf2.js +101 -0
- package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
- package/node_modules/@noble/hashes/ripemd160.d.ts +13 -0
- package/node_modules/@noble/hashes/ripemd160.d.ts.map +1 -0
- package/node_modules/@noble/hashes/ripemd160.js +16 -0
- package/node_modules/@noble/hashes/ripemd160.js.map +1 -0
- package/node_modules/@noble/hashes/scrypt.d.ts +34 -0
- package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
- package/node_modules/@noble/hashes/scrypt.js +232 -0
- package/node_modules/@noble/hashes/scrypt.js.map +1 -0
- package/node_modules/@noble/hashes/sha1.d.ts +11 -0
- package/node_modules/@noble/hashes/sha1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha1.js +14 -0
- package/node_modules/@noble/hashes/sha1.js.map +1 -0
- package/node_modules/@noble/hashes/sha2.d.ts +159 -0
- package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha2.js +384 -0
- package/node_modules/@noble/hashes/sha2.js.map +1 -0
- package/node_modules/@noble/hashes/sha256.d.ts +20 -0
- package/node_modules/@noble/hashes/sha256.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha256.js +23 -0
- package/node_modules/@noble/hashes/sha256.js.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts +142 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.js +402 -0
- package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
- package/node_modules/@noble/hashes/sha3.d.ts +53 -0
- package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3.js +239 -0
- package/node_modules/@noble/hashes/sha3.js.map +1 -0
- package/node_modules/@noble/hashes/sha512.d.ts +26 -0
- package/node_modules/@noble/hashes/sha512.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha512.js +29 -0
- package/node_modules/@noble/hashes/sha512.js.map +1 -0
- package/node_modules/@noble/hashes/src/_assert.ts +22 -0
- package/node_modules/@noble/hashes/src/_blake.ts +50 -0
- package/node_modules/@noble/hashes/src/_md.ts +176 -0
- package/node_modules/@noble/hashes/src/_u64.ts +91 -0
- package/node_modules/@noble/hashes/src/argon2.ts +497 -0
- package/node_modules/@noble/hashes/src/blake1.ts +534 -0
- package/node_modules/@noble/hashes/src/blake2.ts +486 -0
- package/node_modules/@noble/hashes/src/blake2b.ts +10 -0
- package/node_modules/@noble/hashes/src/blake2s.ts +20 -0
- package/node_modules/@noble/hashes/src/blake3.ts +272 -0
- package/node_modules/@noble/hashes/src/crypto.ts +9 -0
- package/node_modules/@noble/hashes/src/cryptoNode.ts +15 -0
- package/node_modules/@noble/hashes/src/eskdf.ts +187 -0
- package/node_modules/@noble/hashes/src/hkdf.ts +88 -0
- package/node_modules/@noble/hashes/src/hmac.ts +94 -0
- package/node_modules/@noble/hashes/src/index.ts +31 -0
- package/node_modules/@noble/hashes/src/legacy.ts +293 -0
- package/node_modules/@noble/hashes/src/pbkdf2.ts +122 -0
- package/node_modules/@noble/hashes/src/ripemd160.ts +12 -0
- package/node_modules/@noble/hashes/src/scrypt.ts +257 -0
- package/node_modules/@noble/hashes/src/sha1.ts +10 -0
- package/node_modules/@noble/hashes/src/sha2.ts +402 -0
- package/node_modules/@noble/hashes/src/sha256.ts +24 -0
- package/node_modules/@noble/hashes/src/sha3-addons.ts +499 -0
- package/node_modules/@noble/hashes/src/sha3.ts +258 -0
- package/node_modules/@noble/hashes/src/sha512.ts +34 -0
- package/node_modules/@noble/hashes/src/utils.ts +395 -0
- package/node_modules/@noble/hashes/utils.d.ts +161 -0
- package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
- package/node_modules/@noble/hashes/utils.js +313 -0
- package/node_modules/@noble/hashes/utils.js.map +1 -0
- package/package.json +179 -8
- package/schemas/catalog.schema.json +357 -0
- package/src/align.ts +239 -0
- package/src/audio-init-parser.ts +189 -0
- package/src/audio-ring-buffer.ts +120 -0
- package/src/authored-timing.ts +63 -0
- package/src/block-policy.ts +903 -0
- package/src/carp-catalog.ts +1065 -0
- package/src/catalog-fec-params.ts +729 -0
- package/src/catalog-network-source.ts +74 -0
- package/src/catalog-validator.ts +34 -0
- package/src/cmaf-block-assembler.ts +1255 -0
- package/src/cmaf-group-batcher.ts +104 -0
- package/src/cmcd-producer.ts +329 -0
- package/src/codec-utils.ts +1984 -0
- package/src/conceal-timeline.ts +293 -0
- package/src/delivery-gap.ts +147 -0
- package/src/duplicate-ledger.ts +372 -0
- package/src/fec-codec.ts +61 -0
- package/src/fec-manager.ts +4298 -0
- package/src/fec-starvation-detector.ts +128 -0
- package/src/fec-state.ts +219 -0
- package/src/fec-worker-setup.ts +283 -0
- package/src/fmp4-completion.ts +47 -0
- package/src/fmp4-reader.ts +112 -0
- package/src/index.ts +590 -21
- package/src/iso-block-locator.ts +329 -0
- package/src/iso-bmff-timing.ts +813 -0
- package/src/loc.ts +128 -154
- package/src/manifest-auth-plan.ts +107 -0
- package/src/media-router.ts +841 -0
- package/src/mfu-reassembler.ts +3480 -155
- package/src/mfu-reassembly-policy.ts +134 -0
- package/src/mmtp-container-parser.ts +2380 -0
- package/src/mmtp-decode-pipeline.ts +406 -0
- package/src/mmtp-router.ts +4860 -0
- package/src/mmtp-to-cmaf.ts +977 -0
- package/src/multicast-auth-catalog.ts +340 -0
- package/src/multicast-input.ts +793 -0
- package/src/multicast-manager.ts +2783 -0
- package/src/multicast-transport.ts +1058 -0
- package/src/multicast-unwrap.ts +132 -0
- package/src/no-modules.ts +21 -0
- package/src/phase14-catalog-override.ts +336 -0
- package/src/repair-fetch.ts +772 -0
- package/src/repair-layers.ts +533 -0
- package/src/sample-combiner.ts +938 -0
- package/src/signaling.ts +78 -0
- package/src/source-auth.ts +1 -0
- package/src/switching-set-alignment.ts +109 -0
- package/src/timestamp-codec.ts +265 -0
- package/src/track-pipeline-setup.ts +205 -0
- package/src/track-pipeline.ts +332 -0
- package/src/track-session.ts +1010 -0
- package/src/transport-pool.ts +128 -0
- package/src/wasm-mfu-reassembler.ts +405 -0
- package/src/wasm-mmtp-container-parser.ts +23 -0
- package/test-vectors/align.json +199 -0
- package/test-vectors/catalog/README.md +106 -0
- package/test-vectors/catalog/negative/archive-origin-with-path.json +33 -0
- package/test-vectors/catalog/negative/archive-unknown-field.json +34 -0
- package/test-vectors/catalog/negative/fec-block-profile-missing.json +51 -0
- package/test-vectors/catalog/negative/fec-block-profile-unknown.json +52 -0
- package/test-vectors/catalog/negative/fec-enhancement-repair-removed.json +28 -0
- package/test-vectors/catalog/negative/fec-repair-layer-geometry.json +33 -0
- package/test-vectors/catalog/negative/fec-repair-layer-missing-symbols.json +31 -0
- package/test-vectors/catalog/negative/fec-repair-multiple-depends.json +32 -0
- package/test-vectors/catalog/negative/fec-repair-overlay-with-layer.json +34 -0
- package/test-vectors/catalog/negative/fec-repair-priority-out-of-band.json +24 -0
- package/test-vectors/catalog/negative/fec-repair-source-symbols-without-scope.json +33 -0
- package/test-vectors/catalog/negative/legacy-selection-params.json +15 -0
- package/test-vectors/catalog/negative/media-track-repair-layer.json +16 -0
- package/test-vectors/catalog/negative/missing-mmtp-fields.json +12 -0
- package/test-vectors/catalog/negative/multicast-auth-padded-key.json +37 -0
- package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +53 -0
- package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +37 -0
- package/test-vectors/catalog/negative/multicast-endpoint-missing-protocol-and-source.json +24 -0
- package/test-vectors/catalog/negative/multicast-network-source-empty.json +44 -0
- package/test-vectors/catalog/negative/multicast-packet-id-signaling.json +26 -0
- package/test-vectors/catalog/negative/network-source-object.json +25 -0
- package/test-vectors/catalog/negative/raptorq-source-symbols-over-max.json +24 -0
- package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +27 -0
- package/test-vectors/catalog/negative/repair-track-legacy-shape.json +19 -0
- package/test-vectors/catalog/negative/track-role-empty.json +16 -0
- package/test-vectors/catalog/negative/track-role-non-string.json +16 -0
- package/test-vectors/catalog/positive/archive-origin.json +34 -0
- package/test-vectors/catalog/positive/fec-iso-ssbg1.json +52 -0
- package/test-vectors/catalog/positive/fec-layered-repair.json +106 -0
- package/test-vectors/catalog/positive/fec-multicast.json +52 -0
- package/test-vectors/catalog/positive/flat-av.json +30 -0
- package/test-vectors/catalog/positive/multicast-auth-rotation.json +55 -0
- package/test-vectors/catalog/positive/multicast-native-ssm-no-network-source.json +43 -0
- package/test-vectors/catalog/positive/ticks-and-mixed-timescales.json +39 -0
- package/test-vectors/catalog/positive/track-role.json +49 -0
- package/test-vectors/catalog/releases/moqcast-native-v16-v1/catalog.json +65 -0
- package/test-vectors/catalog/releases/moqcast-native-v16-v1.archive.sha256 +1 -0
- package/test-vectors/catalog-multicast-auth-v1.json +26 -0
- package/test-vectors/catalog-validation.json +732 -0
- package/test-vectors/catalog-validator-public-api.mjs +25 -0
- package/test-vectors/generate-source-auth-fixture.mjs +114 -0
- package/test-vectors/hevc-x265-repeat-headers-v1.json +40 -0
- package/test-vectors/source-auth-v1.json +61 -0
- package/test-vectors/source-contiguity-v1.json +131 -0
- package/test-vectors/subsample-placement-v1.json +230 -0
- package/dist/mmtp.d.ts +0 -73
- package/dist/mmtp.d.ts.map +0 -1
- package/dist/mmtp.js +0 -210
- package/dist/mmtp.js.map +0 -1
- package/src/mmtp.ts +0 -277
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/codec-utils.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * H.264/AVC and H.265/HEVC codec utilities for MMTP container format conversion.\n *\n * Shared between moq-lib (hang-mmt-fec) and moqtail players.\n * Handles AVCC\u2194Annex-B conversion, SPS/PPS extraction, fallback avcC generation,\n * HEVC keyframe (IRAP) detection, HEVC codec strings and hvcC records, and MMTP\n * timestamp conversion. The video codec family is always selected from the\n * catalog codec string ({@link videoSampleEntryFromCodecString}), never sniffed.\n *\n * @packageDocumentation\n */\n\n// \u2500\u2500\u2500 Public Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Result of extracting a video codec configuration record from an fMP4 init segment. */\nexport interface AvcCInfo {\n codec: string\n description: Uint8Array\n}\n\n/** Result of extracting AAC AudioSpecificConfig from an fMP4 init segment. */\nexport interface AacAscInfo {\n /** Codec string like \"mp4a.40.2\" (AAC-LC). Derived from AOT in ASC[0] >> 3. */\n codec: string\n /** AudioSpecificConfig bytes \u2014 what AudioDecoder.configure({description}) needs for raw AAC. */\n description: Uint8Array\n}\n\n/** SPS and PPS NAL units extracted from an avcC record. */\nexport interface SpsPps {\n sps: Uint8Array\n pps: Uint8Array\n}\n\n/** Options for fallback avcC generation. */\nexport interface FallbackAvcCOptions {\n /** Codec string like \"avc1.640033\". Profile/constraint/level parsed from hex triplet. */\n codec?: string\n /** Coded width in pixels. Used in SPS pic_width_in_mbs. */\n width?: number\n /** Coded height in pixels. Used in SPS pic_height_in_map_units. */\n height?: number\n}\n\n// \u2500\u2500\u2500 Public Functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Extract the codec configuration record (avcC/hvcC/av1C/vpcC) from\n * an fMP4 init segment (moov box).\n * MMTP FT=0 packets contain a complete fMP4: moov > trak > mdia > minf > stbl > stsd > sample entry > codec config.\n *\n * Walks every trak and returns the first supported video sample entry. This\n * handles both per-track CMSF init segments and multiplexed ftyp+moov blobs\n * where the audio trak may appear before video.\n */\nexport function extractAvcCFromInitSegment(data: Uint8Array): AvcCInfo | undefined {\n if (!hasIsoBmffMagic(data)) return undefined\n\n for (const stsd of findTrackStsdBoxes(data)) {\n const info = extractVideoConfigFromStsd(data, stsd)\n if (info) return info\n }\n\n return undefined\n}\n\nfunction extractVideoConfigFromStsd(data: Uint8Array, stsd: { o: number; sz: number }): AvcCInfo | undefined {\n let s = stsd.o + 16\n const e = stsd.o + stsd.sz\n\n // H.264: avc1 VisualSampleEntry \u2192 avcC.\n const avc1 = findBox(data, s, e, 'avc1')\n if (avc1 && avc1.sz >= 86) {\n const avcC = findBox(data, avc1.o + 86, avc1.o + avc1.sz, 'avcC')\n if (avcC && avcC.sz >= 12) {\n const d = data.subarray(avcC.o + 8, avcC.o + avcC.sz)\n const codec = `avc1.${hex2(d[1])}${hex2(d[2])}${hex2(d[3])}`\n return { codec, description: d }\n }\n }\n // HEVC: hvc1/hev1 VisualSampleEntry \u2192 hvcC. Same +86 child-box offset as\n // avc1 (identical VisualSampleEntry layout). Without this branch, HEVC\n // ftyp+moov inits yield no descriptor, so the WebCodecs path configures the\n // VideoDecoder with no `description` and the first length-prefixed hvc1\n // keyframe decode() throws DataError (\"must fill out the description field\"),\n // which the player's MoQ pump catch swallows \u2192 video track silently 0-fps\n // (BLO-8054).\n // The codec string's first element is the sample entry actually present\n // (ISO/IEC 14496-15 Annex E.3), so an hev1 entry yields \"hev1.*\".\n for (const sampleEntry of ['hvc1', 'hev1'] as const) {\n const hvc = findBox(data, s, e, sampleEntry)\n if (!hvc || hvc.sz < 86) continue\n const hvcC = findBox(data, hvc.o + 86, hvc.o + hvc.sz, 'hvcC')\n // HEVCDecoderConfigurationRecord is \u226523 bytes (+8 box header).\n if (hvcC && hvcC.sz >= 8 + 23) {\n const d = data.subarray(hvcC.o + 8, hvcC.o + hvcC.sz)\n return { codec: hevcCodecStringFromHvcC(d, sampleEntry), description: d }\n }\n }\n // AV1: av01 VisualSampleEntry -> av1C. Real FFmpeg MMTP inits can carry an\n // empty av1C box (size=8) while still providing the authoritative sample\n // entry/codec signal. Return an empty description for that shape so callers\n // can open their FT=0 gate without passing a zero-byte WebCodecs description.\n const av01 = findBox(data, s, e, 'av01')\n if (av01 && av01.sz >= 86) {\n const av1C = findBox(data, av01.o + 86, av01.o + av01.sz, 'av1C')\n if (av1C && av1C.sz >= 8) {\n const d = data.subarray(av1C.o + 8, av1C.o + av1C.sz)\n return { codec: codecStringFromAv1C(d), description: d }\n }\n }\n // VP9: vp09 VisualSampleEntry -> vpcC. Some encoders omit the VP codec record\n // payload; use the sample entry as readiness evidence and fall back to a\n // conservative vp09 codec string in that case.\n const vp09 = findBox(data, s, e, 'vp09')\n if (vp09 && vp09.sz >= 86) {\n const vpcC = findBox(data, vp09.o + 86, vp09.o + vp09.sz, 'vpcC')\n if (vpcC && vpcC.sz >= 8) {\n const d = data.subarray(vpcC.o + 8, vpcC.o + vpcC.sz)\n return { codec: codecStringFromVpcC(d), description: d }\n }\n }\n return undefined\n}\n\n/**\n * Generate a minimal avcC (AVCDecoderConfigurationRecord) from codec parameters.\n * Parses \"avc1.XXYYZZ\" \u2192 profile_idc=0xXX, constraint_flags=0xYY, level_idc=0xZZ.\n * Width/height are encoded in the SPS; if not provided, they're inferred from the\n * H.264 level's max frame size (e.g. level 4.2 \u2192 2048x1088).\n * Used when late MoQ subscribers miss the FT=0 init segment (moov/avcC).\n */\nexport function generateFallbackAvcC(options?: FallbackAvcCOptions | string): Uint8Array {\n const opts: FallbackAvcCOptions = typeof options === 'string' ? { codec: options } : (options ?? {})\n\n let profile = 0x64\n let constraint = 0x00\n let level = 0x2a\n\n if (opts.codec) {\n const match = opts.codec.match(/^avc[13]\\.([0-9a-fA-F]{6})$/)\n if (match) {\n profile = Number.parseInt(match[1].substring(0, 2), 16)\n constraint = Number.parseInt(match[1].substring(2, 4), 16)\n level = Number.parseInt(match[1].substring(4, 6), 16)\n }\n }\n\n const { width, height } = resolveResolution(opts.width, opts.height, level)\n const sps = buildMinimalSps(profile, constraint, level, width, height)\n const pps = buildMinimalPps(profile)\n\n const avcC = new Uint8Array(5 + 1 + 2 + sps.length + 1 + 2 + pps.length)\n let w = 0\n avcC[w++] = 0x01\n avcC[w++] = profile\n avcC[w++] = constraint\n avcC[w++] = level\n avcC[w++] = 0xff\n avcC[w++] = 0xe1\n avcC[w++] = (sps.length >> 8) & 0xff\n avcC[w++] = sps.length & 0xff\n avcC.set(sps, w)\n w += sps.length\n avcC[w++] = 0x01\n avcC[w++] = (pps.length >> 8) & 0xff\n avcC[w++] = pps.length & 0xff\n avcC.set(pps, w)\n return avcC\n}\n\n/**\n * Extract raw SPS and PPS NAL unit bytes from an avcC (AVCDecoderConfigurationRecord).\n * Returns the first SPS and first PPS found.\n */\nexport function extractSpsPpsFromAvcC(avcC: Uint8Array): SpsPps | undefined {\n if (avcC.length < 8) return undefined\n const numSPS = avcC[5] & 0x1f\n let offset = 6\n let sps: Uint8Array | undefined\n for (let i = 0; i < numSPS && offset + 2 <= avcC.length; i++) {\n const spsLen = (avcC[offset] << 8) | avcC[offset + 1]\n offset += 2\n if (offset + spsLen <= avcC.length) {\n if (!sps) sps = avcC.subarray(offset, offset + spsLen)\n offset += spsLen\n }\n }\n let pps: Uint8Array | undefined\n if (offset < avcC.length) {\n const numPPS = avcC[offset] & 0x1f\n offset++\n for (let i = 0; i < numPPS && offset + 2 <= avcC.length; i++) {\n const ppsLen = (avcC[offset] << 8) | avcC[offset + 1]\n offset += 2\n if (offset + ppsLen <= avcC.length) {\n if (!pps) pps = avcC.subarray(offset, offset + ppsLen)\n offset += ppsLen\n }\n }\n }\n return sps && pps ? { sps, pps } : undefined\n}\n\n/**\n * Convert AVCC (4-byte NAL length prefixed) to Annex-B (start code prefixed).\n * Prepends SPS/PPS NALs before keyframes.\n */\nexport function avccToAnnexB(avccData: Uint8Array, isKeyframe: boolean, spsPps: SpsPps): Uint8Array {\n let offset = 0\n let totalNalSize = 0\n let nalCount = 0\n while (offset + 4 <= avccData.length) {\n const nalLen =\n (avccData[offset] << 24) |\n (avccData[offset + 1] << 16) |\n (avccData[offset + 2] << 8) |\n avccData[offset + 3]\n offset += 4\n if (nalLen <= 0 || offset + nalLen > avccData.length) break\n totalNalSize += nalLen\n nalCount++\n offset += nalLen\n }\n if (nalCount === 0) return avccData\n\n let outSize = nalCount * 4 + totalNalSize\n if (isKeyframe) {\n outSize += 4 + spsPps.sps.length + 4 + spsPps.pps.length\n }\n const out = new Uint8Array(outSize)\n let w = 0\n\n if (isKeyframe) {\n out[w++] = 0; out[w++] = 0; out[w++] = 0; out[w++] = 1\n out.set(spsPps.sps, w); w += spsPps.sps.length\n out[w++] = 0; out[w++] = 0; out[w++] = 0; out[w++] = 1\n out.set(spsPps.pps, w); w += spsPps.pps.length\n }\n\n offset = 0\n while (offset + 4 <= avccData.length) {\n const nalLen =\n (avccData[offset] << 24) |\n (avccData[offset + 1] << 16) |\n (avccData[offset + 2] << 8) |\n avccData[offset + 3]\n offset += 4\n if (nalLen <= 0 || offset + nalLen > avccData.length) break\n out[w++] = 0; out[w++] = 0; out[w++] = 0; out[w++] = 1\n out.set(avccData.subarray(offset, offset + nalLen), w)\n w += nalLen\n offset += nalLen\n }\n return out\n}\n\n/**\n * Build an avcC record by parsing Annex-B data to extract SPS (NAL type 7) and PPS (NAL type 8).\n * Returns the avcC record, or null if SPS/PPS not found.\n */\nexport function extractCodecDescriptionFromAnnexB(data: Uint8Array): Uint8Array | null {\n const nalUnits: Array<{ type: number; data: Uint8Array }> = []\n let i = 0\n while (i < data.length - 4) {\n if (data[i] === 0 && data[i + 1] === 0) {\n let nalStart = 0\n if (data[i + 2] === 1) {\n nalStart = i + 3\n } else if (data[i + 2] === 0 && data[i + 3] === 1) {\n nalStart = i + 4\n }\n if (nalStart > 0 && nalStart < data.length) {\n let nalEnd = data.length\n for (let j = nalStart; j < data.length - 3; j++) {\n if (data[j] === 0 && data[j + 1] === 0 &&\n (data[j + 2] === 1 || (data[j + 2] === 0 && data[j + 3] === 1))) {\n nalEnd = j\n break\n }\n }\n const nalType = data[nalStart] & 0x1f\n nalUnits.push({ type: nalType, data: data.slice(nalStart, nalEnd) })\n i = nalEnd\n continue\n }\n }\n i++\n }\n\n const sps = nalUnits.find(n => n.type === 7)\n const pps = nalUnits.find(n => n.type === 8)\n if (!sps || !pps) return null\n\n const avcCLength = 6 + 2 + sps.data.length + 1 + 2 + pps.data.length\n const avcC = new Uint8Array(avcCLength)\n let offset = 0\n avcC[offset++] = 1\n avcC[offset++] = sps.data[1]\n avcC[offset++] = sps.data[2]\n avcC[offset++] = sps.data[3]\n avcC[offset++] = 0xff\n avcC[offset++] = 0xe1\n avcC[offset++] = (sps.data.length >> 8) & 0xff\n avcC[offset++] = sps.data.length & 0xff\n avcC.set(sps.data, offset); offset += sps.data.length\n avcC[offset++] = 1\n avcC[offset++] = (pps.data.length >> 8) & 0xff\n avcC[offset++] = pps.data.length & 0xff\n avcC.set(pps.data, offset)\n return avcC\n}\n\n/**\n * Derive codec string from avcC record (e.g. \"avc1.640033\").\n */\nexport function codecStringFromAvcC(avcC: Uint8Array): string {\n if (avcC.length < 4) return 'avc1.640033'\n return `avc1.${hex2(avcC[1])}${hex2(avcC[2])}${hex2(avcC[3])}`\n}\n\n/** VPS/SPS/PPS NAL units extracted from an HEVC keyframe (raw NAL bytes, no start code/length prefix). */\nexport interface HevcParameterSets {\n vps?: Uint8Array\n sps?: Uint8Array\n pps?: Uint8Array\n}\n\n/** True for HEVC/H.265 codec strings (hev1.* / hvc1.*). */\nexport function isHevcCodec(codec: string): boolean {\n return codec.startsWith('hev1') || codec.startsWith('hvc1')\n}\n\n/** Video sample entries this package decodes (ISO/IEC 14496-15 5.4.2, 8.4.1). */\nexport type VideoSampleEntry = 'avc1' | 'avc3' | 'hev1' | 'hvc1'\n\n/** Video codec family of a sample entry. */\nexport type VideoCodecFamily = 'avc' | 'hevc'\n\n/**\n * Select the video sample entry named by a catalog codec string's first\n * element (RFC 6381 \u00A73.3). The match is exact and case-sensitive; any other\n * string, including an empty one, throws. There is no default family and the\n * bitstream is never sniffed.\n */\nexport function videoSampleEntryFromCodecString(codec: string): VideoSampleEntry {\n const fourCc = codec.split('.')[0]\n if (fourCc === 'avc1' || fourCc === 'avc3' || fourCc === 'hev1' || fourCc === 'hvc1') return fourCc\n throw new Error(`Unsupported video codec family in codec string ${JSON.stringify(codec)}`)\n}\n\n/** Codec family of a sample entry. */\nexport function videoCodecFamily(sampleEntry: VideoSampleEntry): VideoCodecFamily {\n return sampleEntry === 'avc1' || sampleEntry === 'avc3' ? 'avc' : 'hevc'\n}\n\n/**\n * HEVC `nal_unit_type` codes (ITU-T H.265 Table 7-1). The HEVC NAL unit header\n * is two bytes (H.265 \u00A77.3.1.2): forbidden_zero_bit u(1) | nal_unit_type u(6) |\n * nuh_layer_id u(6) | nuh_temporal_id_plus1 u(3).\n */\nexport const HEVC_NAL_UNIT_TYPE = {\n TRAIL_R: 1,\n /** First IRAP type. */\n BLA_W_LP: 16,\n IDR_W_RADL: 19,\n IDR_N_LP: 20,\n CRA_NUT: 21,\n /** Last IRAP type (reserved IRAP VCL). */\n RSV_IRAP_VCL23: 23,\n /** Last VCL type; 32..=63 are non-VCL. */\n LAST_VCL: 31,\n VPS_NUT: 32,\n SPS_NUT: 33,\n PPS_NUT: 34,\n AUD_NUT: 35,\n PREFIX_SEI_NUT: 39,\n SUFFIX_SEI_NUT: 40,\n} as const\n\n/** Bytes in the HEVC NAL unit header (H.265 \u00A77.3.1.2). */\nexport const HEVC_NAL_HEADER_LENGTH = 2\n\n/**\n * Highest `bitDepth{Luma,Chroma}Minus8` an `hvcC` can carry: both are u(3)\n * (ISO/IEC 14496-15 \u00A78.3.3.1.2). H.265 allows the SPS fields up to 8.\n */\nconst HVCC_MAX_BIT_DEPTH_MINUS8 = 7\n\n/** HEVC `nal_unit_type` from the first NAL header byte: (byte >> 1) & 0x3f. */\nexport function hevcNalUnitType(nal: Uint8Array): number {\n return (nal[0]! >> 1) & 0x3f\n}\n\n/**\n * True for an IRAP picture's `nal_unit_type`: BLA_W_LP..=RSV_IRAP_VCL23\n * (16..=23, H.265 Table 7-1 / \u00A77.4.2.2), including the reserved IRAP types 22\n * and 23. An IRAP picture is the HEVC keyframe.\n */\nexport function isHevcIrapNalUnitType(nalUnitType: number): boolean {\n return nalUnitType >= HEVC_NAL_UNIT_TYPE.BLA_W_LP && nalUnitType <= HEVC_NAL_UNIT_TYPE.RSV_IRAP_VCL23\n}\n\n/** Internal alias kept for the existing helpers below. */\nfunction hevcNalType(nal: Uint8Array): number {\n return hevcNalUnitType(nal)\n}\n\n/**\n * Remove H.26x emulation-prevention bytes from a NAL unit so fixed-position\n * fields (e.g. HEVC profile_tier_level) can be read by byte offset.\n *\n * H.265 \u00A77.3.1.1 / \u00A77.4.2: every 0x03 that follows two zero bytes inside a NAL\n * unit is an emulation_prevention_three_byte and is discarded, including one\n * that ends the NAL unit (the cabac_zero_words case).\n */\nexport function removeEmulationPrevention(rbsp: Uint8Array): Uint8Array {\n const out: number[] = []\n let zeros = 0\n for (let i = 0; i < rbsp.length; i++) {\n const b = rbsp[i]!\n if (zeros >= 2 && b === 0x03) {\n zeros = 0\n continue\n }\n out.push(b)\n zeros = b === 0 ? zeros + 1 : 0\n }\n return Uint8Array.from(out)\n}\n\n/**\n * Fields of an HEVC SPS (H.265 \u00A77.3.2.2.1) needed for the codec string and the\n * hvcC record. `profileCompatibilityFlags` holds the 32 flags in bitstream\n * order (flag 0 is the most significant bit); `constraintIndicatorFlags` holds\n * the 48 bits from general_progressive_source_flag onward.\n */\nexport interface HevcSpsInfo {\n profileSpace: number\n tierFlag: boolean\n profileIdc: number\n profileCompatibilityFlags: number\n constraintIndicatorFlags: Uint8Array\n levelIdc: number\n maxSubLayersMinus1: number\n temporalIdNestingFlag: boolean\n seqParameterSetId: number\n chromaFormatIdc: number\n picWidthInLumaSamples: number\n picHeightInLumaSamples: number\n bitDepthLumaMinus8: number\n bitDepthChromaMinus8: number\n}\n\n/** MSB-first RBSP bit reader (H.265 \u00A77.2 read_bits, \u00A79.2 ue(v)). */\nclass RbspReader {\n #bit = 0\n constructor(private readonly data: Uint8Array) {}\n\n bits(count: number): number {\n if (this.#bit + count > this.data.length * 8) throw new Error('HEVC SPS: RBSP truncated')\n let value = 0\n for (let i = 0; i < count; i++, this.#bit++) {\n value = value * 2 + ((this.data[this.#bit >> 3]! >> (7 - (this.#bit & 7))) & 1)\n }\n return value\n }\n\n skip(count: number): void {\n if (this.#bit + count > this.data.length * 8) throw new Error('HEVC SPS: RBSP truncated')\n this.#bit += count\n }\n\n ue(): number {\n let leadingZeros = 0\n while (this.bits(1) === 0) {\n if (++leadingZeros > 31) throw new Error('HEVC SPS: ue(v) exceeds 32 bits')\n }\n return leadingZeros === 0 ? 0 : 2 ** leadingZeros - 1 + this.bits(leadingZeros)\n }\n}\n\n/**\n * Parse the leading fields of an HEVC SPS NAL unit (2-byte header included, no\n * start code). Emulation prevention is removed first. Throws on a non-SPS or\n * non-base-layer NAL unit, truncation, or a value outside its H.265 \u00A77.4.3.2.1\n * range: a malformed SPS must not yield a guessed record.\n */\nexport function parseHevcSps(sps: Uint8Array): HevcSpsInfo {\n if (sps.length < HEVC_NAL_HEADER_LENGTH || (sps[0]! & 0x80) !== 0 || (sps[1]! & 0x07) === 0) {\n throw new Error('HEVC SPS: invalid NAL unit header')\n }\n if (hevcNalUnitType(sps) !== HEVC_NAL_UNIT_TYPE.SPS_NUT) throw new Error('HEVC SPS: NAL unit is not an SPS')\n if (((sps[0]! & 0x01) << 5 | sps[1]! >> 3) !== 0) {\n throw new Error('HEVC SPS: not in the base layer (nuh_layer_id != 0)')\n }\n const r = new RbspReader(removeEmulationPrevention(sps).subarray(HEVC_NAL_HEADER_LENGTH))\n r.bits(4) // sps_video_parameter_set_id\n const maxSubLayersMinus1 = r.bits(3)\n if (maxSubLayersMinus1 > 6) throw new Error('HEVC SPS: sps_max_sub_layers_minus1 is greater than 6')\n const temporalIdNestingFlag = r.bits(1) === 1\n // profile_tier_level(1, sps_max_sub_layers_minus1), H.265 \u00A77.3.3.\n const profileSpace = r.bits(2)\n const tierFlag = r.bits(1) === 1\n const profileIdc = r.bits(5)\n const profileCompatibilityFlags = r.bits(32) >>> 0\n const constraintIndicatorFlags = new Uint8Array(6)\n for (let i = 0; i < 6; i++) constraintIndicatorFlags[i] = r.bits(8)\n const levelIdc = r.bits(8)\n const subLayerProfilePresent: boolean[] = []\n const subLayerLevelPresent: boolean[] = []\n for (let i = 0; i < maxSubLayersMinus1; i++) {\n subLayerProfilePresent.push(r.bits(1) === 1)\n subLayerLevelPresent.push(r.bits(1) === 1)\n }\n if (maxSubLayersMinus1 > 0) {\n for (let i = maxSubLayersMinus1; i < 8; i++) r.skip(2) // reserved_zero_2bits\n }\n for (let i = 0; i < maxSubLayersMinus1; i++) {\n if (subLayerProfilePresent[i]) r.skip(88) // sub-layer profile fields\n if (subLayerLevelPresent[i]) r.skip(8) // sub_layer_level_idc\n }\n const seqParameterSetId = r.ue()\n if (seqParameterSetId > 15) throw new Error('HEVC SPS: sps_seq_parameter_set_id is greater than 15')\n const chromaFormatIdc = r.ue()\n if (chromaFormatIdc > 3) throw new Error('HEVC SPS: chroma_format_idc is greater than 3')\n if (chromaFormatIdc === 3) r.skip(1) // separate_colour_plane_flag\n const picWidthInLumaSamples = r.ue()\n const picHeightInLumaSamples = r.ue()\n if (picWidthInLumaSamples === 0 || picHeightInLumaSamples === 0) {\n throw new Error('HEVC SPS: picture dimension is zero')\n }\n if (r.bits(1) === 1) for (let i = 0; i < 4; i++) r.ue() // conformance window offsets\n const bitDepthLumaMinus8 = r.ue()\n const bitDepthChromaMinus8 = r.ue()\n if (bitDepthLumaMinus8 > 8 || bitDepthChromaMinus8 > 8) throw new Error('HEVC SPS: bit depth is greater than 16')\n return {\n profileSpace,\n tierFlag,\n profileIdc,\n profileCompatibilityFlags,\n constraintIndicatorFlags,\n levelIdc,\n maxSubLayersMinus1,\n temporalIdNestingFlag,\n seqParameterSetId,\n chromaFormatIdc,\n picWidthInLumaSamples,\n picHeightInLumaSamples,\n bitDepthLumaMinus8,\n bitDepthChromaMinus8,\n }\n}\n\n/**\n * RFC 6381 codec string of an HEVC stream from its SPS, per ISO/IEC 14496-15\n * Annex E.3 (e.g. \"hev1.1.6.L93.B0\"); the first element is `sampleEntry`.\n */\nexport function hevcCodecStringFromSps(sps: Uint8Array, sampleEntry: 'hev1' | 'hvc1'): string {\n const info = parseHevcSps(sps)\n return formatHevcCodecString(\n sampleEntry,\n info.profileSpace,\n info.tierFlag,\n info.profileIdc,\n info.profileCompatibilityFlags,\n info.constraintIndicatorFlags,\n info.levelIdc,\n )\n}\n\n/**\n * ISO/IEC 14496-15 Annex E.3 codec string: sample entry; profile space\n * (none/A/B/C) + decimal profile_idc; the 32 compatibility flags in reverse bit\n * order as hex without leading zeros; L/H tier + decimal level_idc; each\n * constraint byte as hex, trailing zero bytes omitted. Hex digits are upper\n * case, as in the Annex E.3 examples.\n */\nfunction formatHevcCodecString(\n sampleEntry: 'hev1' | 'hvc1',\n profileSpace: number,\n tierFlag: boolean,\n profileIdc: number,\n profileCompatibilityFlags: number,\n constraintIndicatorFlags: Uint8Array,\n levelIdc: number,\n): string {\n let reversed = 0\n let v = profileCompatibilityFlags >>> 0\n for (let i = 0; i < 32; i++) {\n reversed = ((reversed << 1) | (v & 1)) >>> 0\n v >>>= 1\n }\n let lastNonZero = -1\n for (let i = 0; i < constraintIndicatorFlags.length; i++) if (constraintIndicatorFlags[i] !== 0) lastNonZero = i\n const space = profileSpace === 0 ? '' : String.fromCharCode(64 + profileSpace) // 1\u2192'A', 2\u2192'B', 3\u2192'C'\n let codec = `${sampleEntry}.${space}${profileIdc}.${reversed.toString(16).toUpperCase()}.${tierFlag ? 'H' : 'L'}${levelIdc}`\n for (let i = 0; i <= lastNonZero; i++) codec += `.${constraintIndicatorFlags[i]!.toString(16).toUpperCase()}`\n return codec\n}\n\n/**\n * The NAL units of an HEVC sample, split by its framing: a complete 4-byte\n * length-prefixed sample is read as such, otherwise Annex B. Null when the\n * sample is neither \u2014 there is no third framing to read it as.\n */\nfunction splitHevcSample(data: Uint8Array): { nals: Uint8Array[]; lengthPrefixed: boolean } | null {\n if (isCompleteAvccSample(data)) return { nals: splitAvccNalUnits(data), lengthPrefixed: true }\n if (isAnnexB(data)) return { nals: splitAnnexBNalUnits(data), lengthPrefixed: false }\n return null\n}\n\n/** IRAP classification of split NAL units; undefined when none has a header. */\nfunction hevcNalUnitsContainIrap(nals: Uint8Array[]): boolean | undefined {\n let sawNal = false\n for (const nal of nals) {\n if (nal.length < HEVC_NAL_HEADER_LENGTH) continue\n sawNal = true\n if (isHevcIrapNalUnitType(hevcNalUnitType(nal))) return true\n }\n return sawNal ? false : undefined\n}\n\n/**\n * Classify an HEVC access unit as a keyframe (contains an IRAP slice,\n * {@link isHevcIrapNalUnitType}). Complete 4-byte length-prefixed samples are\n * read as such; otherwise Annex B. Returns undefined when no NAL unit is found\n * \u2014 an unreadable sample, which is not the same as a delta frame.\n */\nexport function classifyHevcKeyframe(data: Uint8Array): boolean | undefined {\n const split = splitHevcSample(data)\n return split === null ? undefined : hevcNalUnitsContainIrap(split.nals)\n}\n\n/**\n * True when an HEVC access unit contains an IRAP slice. Collapses \"unreadable\"\n * into false; a caller that must tell the two apart (anything about to write\n * the sample into an mdat) uses {@link prepareHevcCmafSample} instead.\n */\nexport function detectHevcKeyframe(data: Uint8Array): boolean {\n return classifyHevcKeyframe(data) === true\n}\n\n/** An HEVC sample ready for an fMP4 mdat whose hvcC has lengthSizeMinusOne = 3. */\nexport interface HevcCmafSample {\n /** The access unit contains an IRAP slice ({@link isHevcIrapNalUnitType}). */\n keyframe: boolean\n /** 4-byte length-prefixed NAL units (the input itself when already so). */\n data: Uint8Array\n}\n\n/**\n * Classify and normalize an HEVC sample for an fMP4 mdat from one split of its\n * NAL units. Returns null \u2014 the sample must not be written \u2014 when its framing\n * is neither a complete 4-byte length-prefixed sample nor Annex B, when it\n * holds no NAL unit, or when nothing is left after `hvc1` drops the parameter\n * sets: bytes the hvcC's lengthSizeMinusOne = 3 does not describe would be\n * misparsed by the decoder, and an unreadable sample is not a delta frame.\n * Normalization as in {@link normalizeHevcSampleToLengthPrefixed}.\n */\nexport function prepareHevcCmafSample(data: Uint8Array, sampleEntry: 'hev1' | 'hvc1'): HevcCmafSample | null {\n const split = splitHevcSample(data)\n if (split === null) return null\n const keyframe = hevcNalUnitsContainIrap(split.nals)\n if (keyframe === undefined) return null\n const normalized = hevcNalUnitsToLengthPrefixed(data, split.nals, split.lengthPrefixed, sampleEntry)\n return normalized === null ? null : { keyframe, data: normalized }\n}\n\n/**\n * Normalize an HEVC sample to 4-byte length-prefixed NAL units for an fMP4\n * mdat whose hvcC declares lengthSizeMinusOne = 3. Complete length-prefixed\n * samples pass through; Annex B is converted. For `hvc1` the VPS/SPS/PPS are\n * dropped (ISO/IEC 14496-15 8.4.1.1: they live only in the hvcC); for `hev1`\n * they are kept in-band. Throws when the sample cannot be read\n * ({@link prepareHevcCmafSample} returns null) rather than pass it through.\n */\nexport function normalizeHevcSampleToLengthPrefixed(data: Uint8Array, sampleEntry: 'hev1' | 'hvc1'): Uint8Array {\n const prepared = prepareHevcCmafSample(data, sampleEntry)\n if (prepared === null) {\n throw new Error('HEVC sample is neither 4-byte length-prefixed nor Annex B, or holds no NAL unit to write')\n }\n return prepared.data\n}\n\nfunction hevcNalUnitsToLengthPrefixed(\n data: Uint8Array,\n nals: Uint8Array[],\n lengthPrefixed: boolean,\n sampleEntry: 'hev1' | 'hvc1',\n): Uint8Array | null {\n const kept = sampleEntry === 'hvc1'\n ? nals.filter((nal) => {\n const t = hevcNalUnitType(nal)\n return t !== HEVC_NAL_UNIT_TYPE.VPS_NUT && t !== HEVC_NAL_UNIT_TYPE.SPS_NUT && t !== HEVC_NAL_UNIT_TYPE.PPS_NUT\n })\n : nals\n if (kept.length === 0) return null\n if (lengthPrefixed && kept.length === nals.length) return data\n const out = new Uint8Array(kept.reduce((sum, nal) => sum + 4 + nal.length, 0))\n let w = 0\n for (const nal of kept) {\n w = writeNalLength(out, w, nal.length)\n out.set(nal, w)\n w += nal.length\n }\n return out\n}\n\n/**\n * Split an AVCC/hvcC bitstream (length-prefixed NAL units) into raw NAL byte slices.\n * `lengthSize` is the NAL length prefix width (4 for FFmpeg LOC / fMP4 sample data).\n */\nexport function splitAvccNalUnits(data: Uint8Array, lengthSize = 4): Uint8Array[] {\n const nals: Uint8Array[] = []\n let i = 0\n while (i + lengthSize <= data.length) {\n let len = 0\n for (let k = 0; k < lengthSize; k++) len = (len << 8) | data[i + k]\n i += lengthSize\n if (len <= 0 || i + len > data.length) break\n nals.push(data.subarray(i, i + len))\n i += len\n }\n return nals\n}\n\n/**\n * True when `data` is exactly one or more length-prefixed NAL units.\n *\n * This is intentionally stricter than \"starts with a plausible length\": a\n * H.264 AVCC access unit may begin with bytes `00 00 00 01` when the first\n * NAL is a one-byte AUD. That byte pattern is also an Annex-B start code, so\n * callers must prove the whole buffer is complete AVCC before falling back to\n * Annex-B detection/conversion.\n */\nexport function isCompleteAvccSample(data: Uint8Array, lengthSize = 4): boolean {\n let i = 0\n let count = 0\n while (i + lengthSize <= data.length) {\n let len = 0\n for (let k = 0; k < lengthSize; k++) len = (len << 8) | data[i + k]\n i += lengthSize\n if (len <= 0 || i + len > data.length) return false\n i += len\n count++\n }\n return count > 0 && i === data.length\n}\n\nexport type H264SampleFormat = 'avcc' | 'annexb' | 'raw-nal' | 'unknown'\nexport type H264NalUnitFormat = H264SampleFormat | 'partial-avcc'\n\nexport interface H264AvccSample {\n data: Uint8Array\n format: H264SampleFormat\n}\n\nexport interface H264NalUnitSample {\n nals: Uint8Array[]\n format: H264NalUnitFormat\n}\n\n/**\n * Normalize a H.264 access unit/sample to length-prefixed AVCC for fMP4 mdat\n * payloads. Already-AVCC samples are returned as-is. Annex-B and single raw\n * NAL samples are converted one-way to AVCC at the MSE/fMP4 boundary.\n */\nexport function normalizeH264SampleToAvcc(data: Uint8Array): H264AvccSample {\n if (isCompleteAvccSample(data)) return { data, format: 'avcc' }\n if (isAnnexB(data)) return { data: annexBToAvcc(data), format: 'annexb' }\n if (isLikelyRawH264NalUnit(data)) return { data: rawH264NalToAvcc(data), format: 'raw-nal' }\n return { data, format: 'unknown' }\n}\n\n/**\n * Split a H.264 access unit/sample into NAL units without changing its framing.\n * Use this for routing, keyframe gates, and diagnostics. Conversion to AVCC is\n * reserved for `normalizeH264SampleToAvcc` at the fMP4/MSE boundary.\n */\nexport function splitH264SampleNalUnits(\n data: Uint8Array,\n options: H264KeyframeDetectionOptions = {},\n): H264NalUnitSample {\n if (isCompleteAvccSample(data)) return { nals: splitAvccNalUnits(data), format: 'avcc' }\n if (isAnnexB(data)) return { nals: splitAnnexBNalUnits(data), format: 'annexb' }\n if (options.allowPartialAvcc === true) {\n const partial = splitPartialAvccNalUnits(data)\n if (partial.length > 0) return { nals: partial, format: 'partial-avcc' }\n }\n if (isLikelyRawH264NalUnit(data)) return { nals: [data], format: 'raw-nal' }\n const nals = splitAvccNalUnits(data)\n return { nals, format: nals.length > 0 ? 'avcc' : 'unknown' }\n}\n\n/**\n * Extract HEVC VPS (type 32) / SPS (33) / PPS (34) NAL units from a keyframe access\n * unit. Accepts either Annex-B (start-code delimited) or AVCC/hvcC (length-prefixed)\n * framing \u2014 FFmpeg LOC delivers the latter.\n */\nexport function extractHevcParameterSets(keyframe: Uint8Array): HevcParameterSets {\n const nals = isAnnexB(keyframe) ? splitAnnexBNalUnits(keyframe) : splitAvccNalUnits(keyframe)\n const out: HevcParameterSets = {}\n for (const nal of nals) {\n if (nal.length === 0) continue\n const t = hevcNalType(nal)\n if (t === 32 && !out.vps) out.vps = nal\n else if (t === 33 && !out.sps) out.sps = nal\n else if (t === 34 && !out.pps) out.pps = nal\n }\n return out\n}\n\n/**\n * Build an hvcC (HEVCDecoderConfigurationRecord, ISO/IEC 14496-15 \u00A78.3.3.1) from\n * VPS/SPS/PPS NAL units. Suitable as the `description` for a WebCodecs HEVC\n * VideoDecoderConfig and as the fMP4 `hvcC` box payload.\n *\n * Field sources (\u00A78.3.3.1.2): general profile/tier/level, chromaFormat,\n * bitDepth{Luma,Chroma}Minus8, numTemporalLayers (= sps_max_sub_layers_minus1\n * + 1) and temporalIdNested come from the parsed SPS. min_spatial_segmentation\n * _idc = 0, parallelismType = 0, avgFrameRate = 0 and constantFrameRate = 0\n * are the record's \"no restriction / unknown / unspecified\" encodings (the VUI\n * and PPS fields that could tighten them are not parsed). lengthSizeMinusOne =\n * 3 (4-byte NAL lengths). array_completeness = 0: the record is derived from\n * in-band parameter sets, which is the `hev1` arrangement (\u00A78.4.1.1).\n *\n * Returns null when the SPS or PPS is absent; throws when the SPS is malformed\n * or its bit depth (16) is not representable in the record.\n *\n * WebCodecs REQUIRES a description for length-prefixed HEVC \u2014 unlike H.264, Chrome will\n * not self-configure HEVC from the bitstream (BLO-7764).\n */\nexport function generateHvcCFromParameterSets(sets: HevcParameterSets): Uint8Array | null {\n const { vps, sps, pps } = sets\n if (!sps || !pps) return null\n const info = parseHevcSps(sps)\n // bitDepth{Luma,Chroma}Minus8 are u(3) in the record (\u00A78.3.3.1.2), so 0..7.\n // H.265 also allows 8 (16-bit), which `0xf8 | 8` would write as 0 \u2014 a\n // record declaring 8-bit \u2014 so a 16-bit SPS is refused, not mis-described.\n if (info.bitDepthLumaMinus8 > HVCC_MAX_BIT_DEPTH_MINUS8 || info.bitDepthChromaMinus8 > HVCC_MAX_BIT_DEPTH_MINUS8) {\n throw new Error('HEVC SPS: bit depth of 16 is not representable in an hvcC record')\n }\n const arrays = [\n { type: 32, nal: vps },\n { type: 33, nal: sps },\n { type: 34, nal: pps },\n ].filter((a): a is { type: number; nal: Uint8Array } => a.nal !== undefined)\n\n let size = 23\n for (const a of arrays) size += 5 + a.nal.length\n const h = new Uint8Array(size)\n let o = 0\n h[o++] = 1 // configurationVersion\n h[o++] = (info.profileSpace << 6) | ((info.tierFlag ? 1 : 0) << 5) | info.profileIdc\n h[o++] = (info.profileCompatibilityFlags >>> 24) & 0xff\n h[o++] = (info.profileCompatibilityFlags >>> 16) & 0xff\n h[o++] = (info.profileCompatibilityFlags >>> 8) & 0xff\n h[o++] = info.profileCompatibilityFlags & 0xff\n h.set(info.constraintIndicatorFlags, o); o += 6 // general_constraint_indicator_flags\n h[o++] = info.levelIdc // general_level_idc\n h[o++] = 0xf0; h[o++] = 0x00 // reserved(1111) + min_spatial_segmentation_idc(0)\n h[o++] = 0xfc // reserved(111111) + parallelismType(0)\n h[o++] = 0xfc | info.chromaFormatIdc // reserved(111111) + chromaFormat\n h[o++] = 0xf8 | info.bitDepthLumaMinus8 // reserved(11111) + bitDepthLumaMinus8\n h[o++] = 0xf8 | info.bitDepthChromaMinus8 // reserved(11111) + bitDepthChromaMinus8\n h[o++] = 0x00; h[o++] = 0x00 // avgFrameRate(0 = unspecified)\n // constantFrameRate(0) | numTemporalLayers | temporalIdNested | lengthSizeMinusOne(3)\n h[o++] = ((info.maxSubLayersMinus1 + 1) << 3) | ((info.temporalIdNestingFlag ? 1 : 0) << 2) | 3\n h[o++] = arrays.length // numOfArrays\n for (const a of arrays) {\n h[o++] = a.type & 0x3f // array_completeness(0) + NAL_unit_type\n h[o++] = 0; h[o++] = 1 // numNalus = 1\n h[o++] = (a.nal.length >> 8) & 0xff\n h[o++] = a.nal.length & 0xff\n h.set(a.nal, o); o += a.nal.length\n }\n return h.subarray(0, o)\n}\n\n/**\n * Build an hvcC `description` for a WebCodecs HEVC VideoDecoderConfig directly from a\n * keyframe access unit (Annex-B or length-prefixed). Returns null if VPS/SPS/PPS aren't\n * present in-band. HEVC analogue of {@link extractCodecDescriptionFromAnnexB}.\n */\nexport function extractHevcCodecDescription(keyframe: Uint8Array): Uint8Array | null {\n return generateHvcCFromParameterSets(extractHevcParameterSets(keyframe))\n}\n\n/**\n * Strip non-VCL NAL units (VPS/SPS/PPS/SEI/AUD, type >= 32) from an HEVC access unit,\n * returning only the VCL NAL units (type <= 31) as a 4-byte length-prefixed buffer.\n *\n * Required when decoding `hvc1` with an explicit hvcC `description`: WebCodecs rejects a\n * sample whose data still carries in-band parameter sets (\"Unable to determine size of\n * bitstream buffer\"). Accepts Annex-B or length-prefixed input. Returns the input\n * unchanged if it already contains only VCL NALs (cheap no-op for delta frames).\n */\nexport function hevcVclOnly(data: Uint8Array): Uint8Array {\n const nals = isAnnexB(data) ? splitAnnexBNalUnits(data) : splitAvccNalUnits(data)\n const vcl = nals.filter((n) => n.length > 0 && hevcNalType(n) <= 31)\n if (vcl.length === nals.length && !isAnnexB(data)) return data\n let size = 0\n for (const n of vcl) size += 4 + n.length\n const out = new Uint8Array(size)\n let o = 0\n for (const n of vcl) {\n out[o++] = (n.length >> 24) & 0xff\n out[o++] = (n.length >> 16) & 0xff\n out[o++] = (n.length >> 8) & 0xff\n out[o++] = n.length & 0xff\n out.set(n, o); o += n.length\n }\n return out\n}\n\n/**\n * Check if data starts with an Annex-B start code (00 00 01 or 00 00 00 01).\n */\nexport function isAnnexB(data: Uint8Array): boolean {\n if (data.length >= 4 && data[0] === 0 && data[1] === 0 &&\n (data[2] === 1 || (data[2] === 0 && data[3] === 1))) {\n return true\n }\n return false\n}\n\n/**\n * Find the byte offset of the first Annex-B start code in data.\n * Returns -1 if no start code found.\n */\nexport function findAnnexBStartCode(data: Uint8Array): number {\n for (let i = 0; i < data.length - 3; i++) {\n if (data[i] === 0 && data[i + 1] === 0) {\n if (data[i + 2] === 1) return i\n if (data[i + 2] === 0 && data[i + 3] === 1) return i\n }\n }\n return -1\n}\n\n/**\n * Split Annex-B bitstream into NAL units.\n * Returns array of NAL unit byte slices (without start codes).\n */\nexport function splitAnnexBNalUnits(data: Uint8Array): Uint8Array[] {\n const nalUnits: Uint8Array[] = []\n let i = 0\n while (i < data.length - 3) {\n if (data[i] === 0 && data[i + 1] === 0) {\n let scLen = 0\n if (data[i + 2] === 1) scLen = 3\n else if (data[i + 2] === 0 && i + 3 < data.length && data[i + 3] === 1) scLen = 4\n if (scLen > 0) {\n const nalStart = i + scLen\n let nalEnd = data.length\n for (let j = nalStart + 1; j < data.length - 2; j++) {\n if (data[j] === 0 && data[j + 1] === 0 &&\n (data[j + 2] === 1 || (data[j + 2] === 0 && j + 3 < data.length && data[j + 3] === 1))) {\n nalEnd = j\n break\n }\n }\n if (nalEnd > nalStart) nalUnits.push(data.subarray(nalStart, nalEnd))\n i = nalEnd\n continue\n }\n }\n i++\n }\n return nalUnits\n}\n\n/**\n * Convert Annex-B (start-code delimited) to AVCC (4-byte length prefixed).\n * Optionally prepends SPS/PPS NALs for keyframes.\n */\nexport function annexBToAvcc(data: Uint8Array, spsPps?: SpsPps): Uint8Array {\n const nalUnits = splitAnnexBNalUnits(data)\n if (nalUnits.length === 0) return data\n\n let extraSize = 0\n if (spsPps) {\n extraSize = 4 + spsPps.sps.length + 4 + spsPps.pps.length\n }\n const frameSize = nalUnits.reduce((sum, nal) => sum + 4 + nal.length, 0)\n const output = new Uint8Array(extraSize + frameSize)\n let w = 0\n\n if (spsPps) {\n w = writeNalLength(output, w, spsPps.sps.length)\n output.set(spsPps.sps, w); w += spsPps.sps.length\n w = writeNalLength(output, w, spsPps.pps.length)\n output.set(spsPps.pps, w); w += spsPps.pps.length\n }\n\n for (const nal of nalUnits) {\n w = writeNalLength(output, w, nal.length)\n output.set(nal, w); w += nal.length\n }\n return output\n}\n\nexport interface H264KeyframeDetectionOptions {\n /**\n * Allow classifying a length-prefixed NAL when the declared NAL length runs\n * beyond this buffer. MMTP routing can see only the first packet fragment of\n * a sample, where the NAL header is present but the full NAL is not.\n */\n allowPartialAvcc?: boolean\n}\n\n/**\n * Classify H.264 keyframe status by scanning NAL units. Returns undefined when\n * the payload is not H.264-classifiable. Handles Annex-B and AVCC formats.\n */\nexport function classifyH264Keyframe(\n data: Uint8Array,\n options: H264KeyframeDetectionOptions = {},\n): boolean | undefined {\n const nals = h264NalUnitsForKeyframeDetection(data, options)\n if (nals.length === 0) return undefined\n let sawIntraSlice = false\n let sawNonIntraVcl = false\n let sawNal = false\n for (const nal of nals) {\n sawNal = true\n const nalType = nal[0] !== undefined ? nal[0] & 0x1f : -1\n if (nalType === 5 || nalType === 7) return true\n if (nalType === 1) {\n if (isH264IntraSlice(nal)) sawIntraSlice = true\n else sawNonIntraVcl = true\n }\n }\n if (sawIntraSlice && !sawNonIntraVcl) return true\n return sawNal ? false : undefined\n}\n\n/**\n * Detect H.264 keyframe by scanning for IDR/SPS or intra non-IDR slices.\n * Handles both Annex-B and AVCC formats.\n */\nexport function detectH264Keyframe(\n data: Uint8Array,\n options: H264KeyframeDetectionOptions = {},\n): boolean {\n return classifyH264Keyframe(data, options) === true\n}\n\n/**\n * Convert MMTP timestamp (NTP short format) to monotonic microseconds.\n * Per ISO 23008-1 \u00A79.2.2 / RFC 5905: upper 16 bits = seconds (lower 16\n * of NTP seconds), lower 16 bits = fractional seconds.\n * Returns a monotonically increasing \u00B5s value within an ~18-hour window.\n */\nexport function mmtpTimestampToMicros(rawTs: bigint | number): number {\n // MMTP carries an NTP short timestamp as an unsigned 32-bit integer. Do not\n // use `Number(rawTs) >>> 0` here: bitwise coercion silently turns malformed\n // values such as -1, 2**32, fractions, and strings into plausible timestamps\n // and can poison downstream latency observations.\n const ts = typeof rawTs === 'bigint'\n ? rawTs >= 0n && rawTs <= 0xffff_ffffn\n ? Number(rawTs)\n : undefined\n : Number.isSafeInteger(rawTs) && rawTs >= 0 && rawTs <= 0xffff_ffff\n ? rawTs\n : undefined\n if (ts === undefined) {\n throw new RangeError(`MMTP timestamp must be an unsigned 32-bit integer, got ${String(rawTs)}`)\n }\n if (ts === 0) return 0\n const seconds = ts >>> 16\n const frac = ts & 0xFFFF\n return seconds * 1_000_000 + Math.floor(frac * 1_000_000 / 65536)\n}\n\n/** Validate the CMSF/MMTP catalog initData contract: complete top-level ftyp+moov. */\nexport function isFmp4InitSegment(data: Uint8Array): boolean {\n let offset = 0\n let sawFtyp = false\n let sawMoov = false\n\n while (offset + 8 <= data.byteLength) {\n const view = new DataView(data.buffer, data.byteOffset + offset, data.byteLength - offset)\n let size = view.getUint32(0, false)\n const type = String.fromCharCode(data[offset + 4]!, data[offset + 5]!, data[offset + 6]!, data[offset + 7]!)\n let headerSize = 8\n\n if (size === 1) {\n if (offset + 16 > data.byteLength) return false\n const largeSize = view.getBigUint64(8, false)\n if (largeSize > BigInt(Number.MAX_SAFE_INTEGER)) return false\n size = Number(largeSize)\n headerSize = 16\n } else if (size === 0) {\n size = data.byteLength - offset\n }\n\n if (size < headerSize || offset + size > data.byteLength) return false\n // `mmpu` is the ISO MMT MPU metadata box. It is valid inside an MMTP\n // FT=0 payload but is not an ISO-BMFF initialization box that an MSE\n // SourceBuffer can append as a top-level box.\n if (type === 'mmpu') return false\n if (type === 'ftyp') sawFtyp = true\n if (type === 'moov') {\n if (!sawFtyp) return false\n sawMoov = true\n }\n offset += size\n }\n\n return offset === data.byteLength && sawFtyp && sawMoov\n}\n\n/**\n * Return the fMP4 initialization segment carried by MMTP MPU metadata.\n *\n * ISO MMTP FT=0 metadata may contain an `mmpu` box between the top-level\n * `ftyp` and `moov` boxes (`ftyp + mmpu + moov`). `mmpu` is an MMT metadata\n * box, not an ISO-BMFF initialization box accepted by an MSE SourceBuffer;\n * appending it produces Chromium's `Invalid top-level ISO BMFF box type mmpu`\n * error, most visibly when a rendition switch delivers a fresh FT=0 packet.\n * The returned bytes retain every other top-level box, in wire order, and are\n * only returned when the resulting bytes are a complete `ftyp` + `moov` init.\n * Inputs that are already a valid fMP4 init are returned unchanged.\n */\nexport function normalizeMmtpInitSegment(data: Uint8Array): Uint8Array | undefined {\n if (isFmp4InitSegment(data)) return data\n\n const parts: Uint8Array[] = []\n let offset = 0\n let removedMpu = false\n\n while (offset + 8 <= data.byteLength) {\n const view = new DataView(data.buffer, data.byteOffset + offset, data.byteLength - offset)\n let size = view.getUint32(0, false)\n let headerSize = 8\n if (size === 1) {\n if (offset + 16 > data.byteLength) return undefined\n const largeSize = view.getBigUint64(8, false)\n if (largeSize > BigInt(Number.MAX_SAFE_INTEGER)) return undefined\n size = Number(largeSize)\n headerSize = 16\n } else if (size === 0) {\n size = data.byteLength - offset\n }\n if (size < headerSize || offset + size > data.byteLength) return undefined\n\n const type = String.fromCharCode(\n data[offset + 4]!,\n data[offset + 5]!,\n data[offset + 6]!,\n data[offset + 7]!,\n )\n if (type === 'mmpu') removedMpu = true\n else parts.push(data.subarray(offset, offset + size))\n offset += size\n }\n\n if (!removedMpu || offset !== data.byteLength) return undefined\n const normalized = new Uint8Array(parts.reduce((total, part) => total + part.byteLength, 0))\n let writeOffset = 0\n for (const part of parts) {\n normalized.set(part, writeOffset)\n writeOffset += part.byteLength\n }\n return isFmp4InitSegment(normalized) ? normalized : undefined\n}\n\n// \u2500\u2500\u2500 Internal Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction hasIsoBmffMagic(data: Uint8Array): boolean {\n for (let i = 0; i + 8 <= data.length && i < 32; i += 4) {\n const tag = String.fromCharCode(data[i + 4], data[i + 5], data[i + 6], data[i + 7])\n if (tag === 'ftyp' || tag === 'moov') return true\n }\n return false\n}\n\nfunction findTrackStsdBoxes(data: Uint8Array): Array<{ o: number; sz: number }> {\n const moov = findBox(data, 0, data.length, 'moov')\n if (!moov) return []\n\n const out: Array<{ o: number; sz: number }> = []\n for (const trak of findBoxes(data, moov.o + 8, moov.o + moov.sz, 'trak')) {\n const stsd = findNestedBox(data, trak.o + 8, trak.o + trak.sz, ['mdia', 'minf', 'stbl', 'stsd'])\n if (stsd) out.push(stsd)\n }\n return out\n}\n\nfunction findNestedBox(\n buf: Uint8Array,\n start: number,\n end: number,\n path: string[],\n): { o: number; sz: number } | undefined {\n let s = start\n let e = end\n let current: { o: number; sz: number } | undefined\n for (const type of path) {\n current = findBox(buf, s, e, type)\n if (!current) return undefined\n s = current.o + 8\n e = current.o + current.sz\n }\n return current\n}\n\nfunction findBox(buf: Uint8Array, start: number, end: number, type: string): { o: number; sz: number } | undefined {\n return findBoxes(buf, start, end, type)[0]\n}\n\nfunction findBoxes(buf: Uint8Array, start: number, end: number, type: string): Array<{ o: number; sz: number }> {\n const boxes: Array<{ o: number; sz: number }> = []\n let o = start\n while (o + 8 <= end) {\n let sz = (buf[o] << 24) | (buf[o + 1] << 16) | (buf[o + 2] << 8) | buf[o + 3]\n const t = String.fromCharCode(buf[o + 4], buf[o + 5], buf[o + 6], buf[o + 7])\n if (sz === 0) sz = end - o\n if (sz < 8 || o + sz > end) break\n if (t === type) boxes.push({ o, sz })\n o += sz\n }\n return boxes\n}\n\nfunction writeNalLength(buf: Uint8Array, offset: number, len: number): number {\n buf[offset] = (len >> 24) & 0xff\n buf[offset + 1] = (len >> 16) & 0xff\n buf[offset + 2] = (len >> 8) & 0xff\n buf[offset + 3] = len & 0xff\n return offset + 4\n}\n\nfunction h264NalUnitsForKeyframeDetection(\n data: Uint8Array,\n options: H264KeyframeDetectionOptions,\n): Uint8Array[] {\n return splitH264SampleNalUnits(data, options).nals\n}\n\nfunction splitPartialAvccNalUnits(data: Uint8Array, lengthSize = 4): Uint8Array[] {\n const nals: Uint8Array[] = []\n let i = 0\n while (i + lengthSize < data.length) {\n let len = 0\n for (let k = 0; k < lengthSize; k++) len = (len << 8) | data[i + k]\n i += lengthSize\n if (len <= 0 || i >= data.length) break\n const end = Math.min(i + len, data.length)\n nals.push(data.subarray(i, end))\n if (end < i + len) break\n i = end\n }\n return nals\n}\n\nfunction isLikelyRawH264NalUnit(data: Uint8Array): boolean {\n if (data.length === 0) return false\n const header = data[0]!\n if ((header & 0x80) !== 0) return false\n const nalType = header & 0x1f\n return nalType > 0 && nalType < 24\n}\n\nfunction rawH264NalToAvcc(data: Uint8Array): Uint8Array {\n const out = new Uint8Array(4 + data.length)\n new DataView(out.buffer, out.byteOffset, out.byteLength).setUint32(0, data.length)\n out.set(data, 4)\n return out\n}\n\nfunction isH264IntraSlice(nal: Uint8Array): boolean {\n const sliceType = readH264SliceType(nal)\n return sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9\n}\n\nfunction readH264SliceType(nal: Uint8Array): number | null {\n if (nal.length < 2 || (nal[0]! & 0x1f) !== 1) return null\n const rbsp = removeEmulationPrevention(nal.subarray(1))\n const state = { bitOffset: 0 }\n if (readUnsignedExpGolomb(rbsp, state) === null) return null\n return readUnsignedExpGolomb(rbsp, state)\n}\n\nfunction readUnsignedExpGolomb(data: Uint8Array, state: { bitOffset: number }): number | null {\n let leadingZeroBits = 0\n while (true) {\n const bit = readBit(data, state)\n if (bit === null) return null\n if (bit === 1) break\n leadingZeroBits++\n if (leadingZeroBits > 30) return null\n }\n\n let suffix = 0\n for (let i = 0; i < leadingZeroBits; i++) {\n const bit = readBit(data, state)\n if (bit === null) return null\n suffix = (suffix << 1) | bit\n }\n return (1 << leadingZeroBits) - 1 + suffix\n}\n\nfunction readBit(data: Uint8Array, state: { bitOffset: number }): 0 | 1 | null {\n if (state.bitOffset >= data.length * 8) return null\n const byte = data[state.bitOffset >> 3]!\n const bit = (byte >> (7 - (state.bitOffset & 7))) & 1\n state.bitOffset++\n return bit as 0 | 1\n}\n\nfunction hex2(n: number): string {\n return n.toString(16).padStart(2, '0')\n}\n\nfunction pad2(n: number): string {\n return String(n).padStart(2, '0')\n}\n\nfunction codecStringFromAv1C(av1C: Uint8Array): string {\n if (av1C.length < 4) return 'av01.0.01M.08'\n const profile = (av1C[1]! >>> 5) & 0x07\n const level = av1C[1]! & 0x1f\n const tier = (av1C[2]! & 0x80) !== 0 ? 'H' : 'M'\n let bitDepth = 8\n if ((av1C[2]! & 0x40) !== 0) {\n bitDepth = (av1C[2]! & 0x20) !== 0 ? 12 : 10\n }\n return `av01.${profile}.${pad2(level)}${tier}.${pad2(bitDepth)}`\n}\n\nfunction codecStringFromVpcC(vpcC: Uint8Array): string {\n if (vpcC.length < 3) return 'vp09.00.10.08'\n // ISO/IEC 14496-15 defines vpcC as a FullBox. Some tooling hands callers\n // the VPCodecConfigurationRecord after the 4-byte FullBox header; tolerate\n // both shapes because WebCodecs callers only need a stable RFC 6381 fallback.\n const offset = vpcC.length >= 7 && vpcC[0] <= 1 ? 4 : 0\n if (offset + 2 >= vpcC.length) return 'vp09.00.10.08'\n const profile = vpcC[offset]!\n const level = vpcC[offset + 1]!\n const bitDepth = (vpcC[offset + 2]! >>> 4) || 8\n return `vp09.${pad2(profile)}.${pad2(level)}.${pad2(bitDepth)}`\n}\n\n/**\n * Derive an RFC 6381 HEVC codec string (e.g. \"hvc1.1.6.L93.90\") from the\n * payload of an hvcC box (the HEVCDecoderConfigurationRecord, ISO 14496-15 \u00A78.3.3.1).\n * Only the general_* fields in the fixed 23-byte header are needed:\n * byte 1: general_profile_space(2) | general_tier_flag(1) | general_profile_idc(5)\n * bytes 2-5: general_profile_compatibility_flags (32 bits)\n * bytes 6-11: general_constraint_indicator_flags (48 bits)\n * byte 12: general_level_idc\n */\nfunction hevcCodecStringFromHvcC(c: Uint8Array, sampleEntry: 'hev1' | 'hvc1'): string {\n return formatHevcCodecString(\n sampleEntry,\n (c[1]! >> 6) & 0x3,\n ((c[1]! >> 5) & 0x1) === 1,\n c[1]! & 0x1f,\n ((c[2]! << 24) | (c[3]! << 16) | (c[4]! << 8) | c[5]!) >>> 0,\n c.subarray(6, 12),\n c[12]!,\n )\n}\n\n/** Exp-Golomb bitstream writer for SPS/PPS generation. */\nclass BitWriter {\n buf: number[] = []\n byte = 0\n bit = 7\n\n u(val: number, bits: number) {\n for (let i = bits - 1; i >= 0; i--) {\n this.byte |= ((val >> i) & 1) << this.bit\n if (--this.bit < 0) {\n this.buf.push(this.byte)\n this.byte = 0\n this.bit = 7\n }\n }\n }\n\n ue(val: number) {\n const v = val + 1\n const bits = Math.floor(Math.log2(v)) + 1\n this.u(0, bits - 1)\n this.u(v, bits)\n }\n\n se(val: number) {\n this.ue(val <= 0 ? -val * 2 : val * 2 - 1)\n }\n\n finish(): Uint8Array {\n if (this.bit < 7) {\n this.byte |= 1 << this.bit\n this.buf.push(this.byte)\n }\n return new Uint8Array(this.buf)\n }\n}\n\nfunction resolveResolution(\n explicitW: number | undefined,\n explicitH: number | undefined,\n level: number,\n): { width: number; height: number } {\n if (explicitW && explicitH) return { width: explicitW, height: explicitH }\n\n const levelResolutions: Record<number, [number, number]> = {\n 10: [176, 144], 11: [352, 288], 12: [352, 288], 13: [352, 288],\n 20: [352, 288], 21: [720, 576], 22: [720, 576],\n 30: [1280, 720], 31: [1280, 720], 32: [1280, 1024],\n 40: [1920, 1088], 41: [1920, 1088], 42: [2048, 1088],\n 50: [4096, 2160], 51: [4096, 2160], 52: [4096, 2160],\n }\n\n const [w, h] = levelResolutions[level] ?? [1920, 1088]\n return { width: explicitW ?? w, height: explicitH ?? h }\n}\n\nfunction buildMinimalSps(\n profile: number, constraint: number, level: number,\n width: number, height: number,\n): Uint8Array {\n const widthInMbs = Math.ceil(width / 16)\n const heightInMapUnits = Math.ceil(height / 16)\n\n const w = new BitWriter()\n w.u(0, 1); w.u(3, 2); w.u(7, 5) // NAL header: SPS\n w.u(profile, 8); w.u(constraint, 8); w.u(level, 8)\n w.ue(0) // seq_parameter_set_id\n\n if (profile === 100 || profile === 110 || profile === 122 || profile === 244 || profile === 44) {\n w.ue(1); w.ue(0); w.ue(0) // chroma + bit depth\n w.u(0, 1); w.u(0, 1) // transform bypass + scaling matrix\n }\n\n w.ue(0) // log2_max_frame_num_minus4\n w.ue(2) // pic_order_cnt_type=2\n w.ue(1) // max_num_ref_frames\n w.u(0, 1) // gaps_in_frame_num\n w.ue(widthInMbs - 1)\n w.ue(heightInMapUnits - 1)\n w.u(1, 1) // frame_mbs_only\n w.u(1, 1) // direct_8x8_inference\n\n const cropRight = widthInMbs * 16 - width\n const cropBottom = heightInMapUnits * 16 - height\n if (cropRight > 0 || cropBottom > 0) {\n w.u(1, 1)\n w.ue(0); w.ue(cropRight / 2); w.ue(0); w.ue(cropBottom / 2)\n } else {\n w.u(0, 1)\n }\n\n w.u(0, 1) // vui_parameters_present\n return w.finish()\n}\n\nfunction buildMinimalPps(profile: number): Uint8Array {\n const isHighProfile = profile === 100 || profile === 110 || profile === 122 || profile === 244 || profile === 44\n const w = new BitWriter()\n w.u(0, 1); w.u(3, 2); w.u(8, 5) // NAL header: PPS\n\n w.ue(0); w.ue(0) // pps_id, sps_id\n w.u(isHighProfile ? 1 : 0, 1) // entropy_coding_mode\n w.u(0, 1) // bottom_field_pic_order\n w.ue(0); w.ue(0); w.ue(0) // slice groups, ref_idx defaults\n w.u(0, 1); w.u(0, 2) // weighted_pred\n w.se(0); w.se(0); w.se(0) // qp offsets\n w.u(1, 1); w.u(0, 1); w.u(0, 1) // deblock, constrained_intra, redundant_pic_cnt\n\n if (isHighProfile) {\n w.u(1, 1); w.u(0, 1); w.se(0) // transform_8x8, scaling_matrix, chroma_qp_offset\n }\n\n return w.finish()\n}\n\n// \u2500\u2500\u2500 AAC / ADTS Utilities \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** ISO 14496-3 sampling frequency index lookup. */\nconst ADTS_SAMPLE_RATES = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350] as const\n\n/**\n * Prepend a 7-byte ADTS header to a raw AAC access unit.\n *\n * WebCodecs AudioDecoder configured WITHOUT an AudioSpecificConfig `description`\n * expects ADTS-framed AAC. MMTP carries raw AAC (no ADTS sync), so this wrapper\n * must be applied before calling `AudioDecoder.decode()`.\n */\nexport function wrapAdtsFrame(raw: Uint8Array, sampleRate: number, channels: number): Uint8Array {\n const sri = ADTS_SAMPLE_RATES.indexOf(sampleRate as typeof ADTS_SAMPLE_RATES[number])\n const idx = sri >= 0 ? sri : 3 // default 48 kHz\n const len = 7 + raw.length\n const out = new Uint8Array(len)\n out[0] = 0xFF\n out[1] = 0xF1 // MPEG-4, Layer 0, no CRC\n out[2] = (1 << 6) | (idx << 2) | (channels >> 2) // profile=AAC-LC(1), freq, ch high\n out[3] = ((channels & 3) << 6) | ((len >> 11) & 3)\n out[4] = (len >> 3) & 0xFF\n out[5] = ((len & 7) << 5) | 0x1F\n out[6] = 0xFC\n out.set(raw, 7)\n return out\n}\n\n/**\n * Extract AAC AudioSpecificConfig (ASC) from an fMP4 init segment.\n *\n * Walks moov > trak > mdia > minf > stbl > stsd > mp4a > esds, then descends\n * the MPEG-4 descriptor chain (ES_Descriptor 0x03 > DecoderConfigDescriptor\n * 0x04 > DecoderSpecificInfo 0x05) to return the ASC payload.\n *\n * Sibling of extractAvcCFromInitSegment, used by the same BLO-4830 / CMSF \u00A73.1\n * path: when the catalog initData is the full ftyp+moov, WebCodecs' AudioDecoder\n * needs the raw ASC (~2 bytes for AAC-LC) as `description`, NOT the whole\n * segment. Without this extraction the configure() succeeds but every decode()\n * silently produces zero output (no error fires), exactly the symptom that\n * shows up as \"Audio continuity FAILED: energy unstable CV=1.00\" in the\n * 7-point E2E test (CV=1.00 is the meanEnergy=0 sentinel from audio-fft.mjs).\n *\n * Returns undefined when:\n * - data has no ftyp/moov magic in the first 32 bytes\n * - no mp4a sample entry exists in any trak's stbl\n * - the esds descriptor chain doesn't yield a DecoderSpecificInfo\n * - the ASC payload is shorter than 2 bytes (AOT + sampling-freq nibble)\n *\n * Walks every trak and returns the first AAC sample entry. This mirrors\n * extractAvcCFromInitSegment so multiplexed ftyp+moov init blobs work\n * regardless of track order.\n */\nexport function extractAacAscFromInitSegment(data: Uint8Array): AacAscInfo | undefined {\n if (!hasIsoBmffMagic(data)) return undefined\n\n for (const stsd of findTrackStsdBoxes(data)) {\n const info = extractAacAscFromStsd(data, stsd)\n if (info) return info\n }\n\n return undefined\n}\n\nfunction extractAacAscFromStsd(data: Uint8Array, stsd: { o: number; sz: number }): AacAscInfo | undefined {\n // stsd: 8 box header + 4 version+flags + 4 entry_count = 16 bytes before entries.\n const s = stsd.o + 16\n const e = stsd.o + stsd.sz\n // mp4a AudioSampleEntry minimum length: 8 box header + 28 fixed fields = 36 bytes\n // before any child boxes (esds lives here).\n const mp4a = findBox(data, s, e, 'mp4a')\n if (!mp4a || mp4a.sz < 36) return undefined\n const esds = findBox(data, mp4a.o + 36, mp4a.o + mp4a.sz, 'esds')\n // esds = 8 box header + 4 full-box version+flags = 12 bytes minimum before descriptors.\n if (!esds || esds.sz < 12) return undefined\n const esdsPayload = data.subarray(esds.o + 8, esds.o + esds.sz)\n const asc = extractAudioSpecificConfig(esdsPayload)\n if (!asc || asc.length < 2) return undefined\n // AudioObjectType = top 5 bits of ASC[0]. AAC-LC = 2, HE-AAC = 5, etc.\n const aot = asc[0] >> 3\n return { codec: `mp4a.40.${aot}`, description: asc }\n}\n\n/**\n * Walk an esds descriptor chain to find DecoderSpecificInfo (tag 0x05).\n * Step over fixed-size headers of container descriptors (0x03, 0x04) so the\n * scan continues into their children rather than skipping their full payload.\n *\n * Assumes the ES_Descriptor flags byte is zero (no streamDependence, URL, OCR\n * ES_ID fields). FFmpeg's mov/mp4 muxer emits exactly that for all standard\n * AAC tracks; the assumption is the same one extractAvcCFromInitSegment makes\n * about the avc1 sample entry's reserved fields.\n *\n * Input is the esds box payload AFTER the 8-byte box header; the first 4 bytes\n * (full-box version+flags) are skipped here.\n */\nfunction extractAudioSpecificConfig(esds: Uint8Array): Uint8Array | undefined {\n let offset = 4 // skip esds version+flags\n while (offset < esds.length) {\n const tag = esds[offset++]\n let size = 0\n for (let i = 0; i < 4 && offset < esds.length; i++) {\n const b = esds[offset++]\n size = (size << 7) | (b & 0x7f)\n if ((b & 0x80) === 0) break\n }\n if (tag === 0x05) {\n if (offset + size > esds.length) return undefined\n return esds.subarray(offset, offset + size)\n }\n if (tag === 0x03) {\n offset += 3 // ES_ID (2) + flags (1)\n } else if (tag === 0x04) {\n offset += 13 // OTI (1) + streamType (1) + bufferSizeDB (3) + maxBitrate (4) + avgBitrate (4)\n } else {\n offset += size\n }\n }\n return undefined\n}\n\n// =============================================================================\n// Inline Tests (vitest)\n// =============================================================================\n\nif (import.meta.vitest) {\n const { describe, test, expect } = import.meta.vitest\n\n describe('codec-utils', () => {\n describe('isAnnexB', () => {\n test('4-byte start code', () => {\n expect(isAnnexB(new Uint8Array([0, 0, 0, 1, 0x65]))).toBe(true)\n })\n test('3-byte start code', () => {\n expect(isAnnexB(new Uint8Array([0, 0, 1, 0x65]))).toBe(true)\n })\n test('rejects AVCC', () => {\n expect(isAnnexB(new Uint8Array([0, 0, 0, 10, 0x65]))).toBe(false)\n })\n })\n\n describe('findAnnexBStartCode', () => {\n test('at offset 0', () => {\n expect(findAnnexBStartCode(new Uint8Array([0, 0, 0, 1, 0x65]))).toBe(0)\n })\n test('at offset 5', () => {\n expect(findAnnexBStartCode(new Uint8Array([0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0, 0, 1, 0x65]))).toBe(5)\n })\n test('returns -1 when none', () => {\n expect(findAnnexBStartCode(new Uint8Array([0xAA, 0xBB, 0xCC]))).toBe(-1)\n })\n })\n\n describe('splitAnnexBNalUnits', () => {\n test('splits two NALs', () => {\n const data = new Uint8Array([0, 0, 0, 1, 0x65, 0xAA, 0xBB, 0, 0, 0, 1, 0x41, 0xCC])\n const nals = splitAnnexBNalUnits(data)\n expect(nals.length).toBe(2)\n expect(nals[0]).toEqual(new Uint8Array([0x65, 0xAA, 0xBB]))\n expect(nals[1]).toEqual(new Uint8Array([0x41, 0xCC]))\n })\n test('handles 3-byte start codes', () => {\n const nals = splitAnnexBNalUnits(new Uint8Array([0, 0, 1, 0x67, 0x42, 0, 0, 1, 0x68, 0x01]))\n expect(nals.length).toBe(2)\n })\n })\n\n describe('annexBToAvcc', () => {\n test('converts single NAL', () => {\n const annexB = new Uint8Array([0, 0, 0, 1, 0x41, 0xAA, 0xBB])\n const avcc = annexBToAvcc(annexB)\n expect(avcc[3]).toBe(3) // NAL length\n expect(avcc[4]).toBe(0x41)\n })\n test('prepends SPS/PPS', () => {\n const annexB = new Uint8Array([0, 0, 0, 1, 0x65, 0x01])\n const avcc = annexBToAvcc(annexB, { sps: new Uint8Array([0x67, 0x42]), pps: new Uint8Array([0x68, 0x01]) })\n expect(avcc[3]).toBe(2) // SPS length\n expect(avcc[4]).toBe(0x67)\n })\n })\n\n describe('detectH264Keyframe', () => {\n test('IDR in Annex-B', () => {\n expect(detectH264Keyframe(new Uint8Array([0, 0, 0, 1, 0x65]))).toBe(true)\n })\n test('SPS in Annex-B', () => {\n expect(detectH264Keyframe(new Uint8Array([0, 0, 0, 1, 0x67]))).toBe(true)\n })\n test('IDR in AVCC', () => {\n expect(detectH264Keyframe(new Uint8Array([0, 0, 0, 5, 0x65, 1, 2, 3, 4]))).toBe(true)\n })\n test('IDR after AVCC AUD', () => {\n expect(detectH264Keyframe(new Uint8Array([\n 0, 0, 0, 1, 0x09,\n 0, 0, 0, 2, 0x65, 0xaa,\n ]))).toBe(true)\n })\n test('non-IDR AVC I-slice in AVCC', () => {\n expect(detectH264Keyframe(new Uint8Array([\n 0, 0, 0, 2, 0x41, 0x88,\n ]))).toBe(true)\n })\n test('raw H.264 IDR NAL', () => {\n expect(detectH264Keyframe(new Uint8Array([0x65, 0x88, 0x84]))).toBe(true)\n })\n test('raw H.264 non-IDR I-slice NAL', () => {\n expect(detectH264Keyframe(new Uint8Array([0x41, 0x88]))).toBe(true)\n })\n test('classifies partial length-prefixed IDR only when requested', () => {\n const partial = new Uint8Array([0, 0, 0x20, 0, 0x65])\n expect(classifyH264Keyframe(partial)).toBeUndefined()\n expect(classifyH264Keyframe(partial, { allowPartialAvcc: true })).toBe(true)\n })\n test('rejects P-frame', () => {\n expect(detectH264Keyframe(new Uint8Array([0, 0, 0, 1, 0x41]))).toBe(false)\n })\n test('rejects AVCC sample with only non-IDR slices', () => {\n expect(detectH264Keyframe(new Uint8Array([\n 0, 0, 0, 2, 0x41, 0xc0,\n 0, 0, 0, 2, 0x41, 0xc0,\n ]))).toBe(false)\n })\n })\n\n describe('avccToAnnexB', () => {\n test('converts with SPS/PPS on keyframe', () => {\n const avcc = new Uint8Array([0, 0, 0, 3, 0x65, 0xAA, 0xBB])\n const spsPps: SpsPps = { sps: new Uint8Array([0x67, 0x42]), pps: new Uint8Array([0x68, 0x01]) }\n const annexB = avccToAnnexB(avcc, true, spsPps)\n expect(annexB[3]).toBe(1) // start code\n expect(annexB[4]).toBe(0x67) // SPS\n })\n })\n\n describe('codecStringFromAvcC', () => {\n test('derives avc1.64002a', () => {\n expect(codecStringFromAvcC(new Uint8Array([1, 100, 0, 42]))).toBe('avc1.64002a')\n })\n })\n\n describe('extractAacAscFromInitSegment', () => {\n // Build a minimal valid ftyp+moov containing one mp4a sample entry whose\n // esds carries the supplied AudioSpecificConfig. The walker only needs\n // the box hierarchy moov > trak > mdia > minf > stbl > stsd > mp4a > esds;\n // mvhd/tkhd/mdhd/hdlr/smhd/dinf/stts/stsc/stsz/stco are spec-required for\n // a truly valid init but the extractor never reads them, so we omit them\n // to keep the fixture tight (~150 bytes vs ~500). FFmpeg's real output\n // includes them; the production path passes through `findBox` exactly\n // the same way.\n function buildMinimalAacInit(asc: Uint8Array): Uint8Array {\n const box = (type: string, payload: Uint8Array): Uint8Array => {\n const sz = 8 + payload.length\n const out = new Uint8Array(sz)\n out[0] = (sz >>> 24) & 0xff\n out[1] = (sz >>> 16) & 0xff\n out[2] = (sz >>> 8) & 0xff\n out[3] = sz & 0xff\n out[4] = type.charCodeAt(0); out[5] = type.charCodeAt(1)\n out[6] = type.charCodeAt(2); out[7] = type.charCodeAt(3)\n out.set(payload, 8)\n return out\n }\n const concat = (...arrs: Uint8Array[]): Uint8Array => {\n const total = arrs.reduce((n, a) => n + a.length, 0)\n const out = new Uint8Array(total)\n let off = 0\n for (const a of arrs) { out.set(a, off); off += a.length }\n return out\n }\n // ftyp: major_brand=iso5, minor=0x200, compat=iso5,iso6\n const ftyp = box('ftyp', new Uint8Array([\n 0x69, 0x73, 0x6f, 0x35, // 'iso5'\n 0x00, 0x00, 0x02, 0x00, // minor 0x200\n 0x69, 0x73, 0x6f, 0x35, // 'iso5'\n 0x69, 0x73, 0x6f, 0x36, // 'iso6'\n ]))\n\n // ESDescriptor (0x03) > DecoderConfigDescriptor (0x04) > DecoderSpecificInfo (0x05) > ASC.\n // Use 1-byte BER sizes (all payloads < 128).\n const dsi = new Uint8Array(2 + asc.length)\n dsi[0] = 0x05; dsi[1] = asc.length\n dsi.set(asc, 2)\n // DCD = 13 fixed bytes + DSI: OTI=0x40 (AAC), streamType=0x05<<2|0x01 (audio, upStream=0)\n const dcd = new Uint8Array(2 + 13 + dsi.length)\n dcd[0] = 0x04; dcd[1] = 13 + dsi.length\n dcd[2] = 0x40 // objectTypeIndication: Audio ISO/IEC 14496-3\n dcd[3] = (0x05 << 2) | 1 // streamType=AudioStream(5), upStream=0, reserved=1\n // bufferSizeDB(3) + maxBitrate(4) + avgBitrate(4) all zero is fine for the walker.\n dcd.set(dsi, 15)\n // ESDescriptor: ES_ID=0, flags=0, then DCD\n const esd = new Uint8Array(2 + 3 + dcd.length)\n esd[0] = 0x03; esd[1] = 3 + dcd.length\n // ES_ID(2) + flags(1) all zero\n esd.set(dcd, 5)\n // esds box = full-box (4-byte version+flags) + ES_Descriptor chain\n const esdsPayload = new Uint8Array(4 + esd.length)\n esdsPayload.set(esd, 4)\n const esds = box('esds', esdsPayload)\n\n // mp4a sample entry: 6 reserved + 2 dref_idx + 8 reserved + 2 channels + 2 samplesize +\n // 2 pre_defined + 2 reserved + 4 samplerate(48000<<16) = 28 bytes,\n // then esds child.\n const mp4aFixed = new Uint8Array(28)\n mp4aFixed[7] = 0x01 // data_reference_index = 1\n mp4aFixed[16] = 0x00; mp4aFixed[17] = 0x01 // channelcount = 1\n mp4aFixed[18] = 0x00; mp4aFixed[19] = 0x10 // samplesize = 16\n // samplerate at offset 24-27 (top 16 bits = sampleRate). 48000 = 0xBB80.\n mp4aFixed[24] = 0xBB; mp4aFixed[25] = 0x80\n const mp4a = box('mp4a', concat(mp4aFixed, esds))\n\n // stsd: 4 ver+flags + 4 entry_count(=1) + entries\n const stsdPayload = new Uint8Array(8 + mp4a.length)\n stsdPayload[7] = 0x01 // entry_count = 1\n stsdPayload.set(mp4a, 8)\n const stsd = box('stsd', stsdPayload)\n\n const stbl = box('stbl', stsd)\n const minf = box('minf', stbl)\n const mdia = box('mdia', minf)\n const trak = box('trak', mdia)\n const moov = box('moov', trak)\n\n return concat(ftyp, moov)\n }\n\n test('extracts AAC-LC mono 48k ASC and derives codec', () => {\n // AOT=2 (00010), samplingFrequencyIndex=3 (0011, 48000Hz), channelConfig=1 (0001),\n // GA: frameLengthFlag=0, dependsOnCoreCoder=0, extensionFlag=0 \u2192 0x11 0x88.\n const asc = new Uint8Array([0x11, 0x88])\n const init = buildMinimalAacInit(asc)\n const result = extractAacAscFromInitSegment(init)\n expect(result).toBeDefined()\n expect(result!.codec).toBe('mp4a.40.2')\n expect(Array.from(result!.description)).toEqual([0x11, 0x88])\n })\n\n test('derives AOT 5 (HE-AAC) from ASC[0] >> 3', () => {\n // AOT=5 (00101), rest don't matter for codec derivation.\n const asc = new Uint8Array([0x29, 0x88]) // 00101 001 1000 1000\n const init = buildMinimalAacInit(asc)\n expect(extractAacAscFromInitSegment(init)?.codec).toBe('mp4a.40.5')\n })\n\n test('rejects data without ftyp/moov magic', () => {\n expect(extractAacAscFromInitSegment(new Uint8Array(64))).toBeUndefined()\n })\n\n test('rejects ftyp+moov with no audio (no mp4a sample entry)', () => {\n // ftyp + moov with empty trak chain \u2014 no stsd, let alone mp4a.\n const ftyp = new Uint8Array([\n 0, 0, 0, 24, 0x66, 0x74, 0x79, 0x70,\n 0x69, 0x73, 0x6f, 0x35, 0, 0, 2, 0,\n 0x69, 0x73, 0x6f, 0x35, 0x69, 0x73, 0x6f, 0x36,\n ])\n const moov = new Uint8Array([0, 0, 0, 8, 0x6d, 0x6f, 0x6f, 0x76]) // empty moov\n const cat = new Uint8Array(ftyp.length + moov.length)\n cat.set(ftyp); cat.set(moov, ftyp.length)\n expect(extractAacAscFromInitSegment(cat)).toBeUndefined()\n })\n })\n\n describe('hevc', () => {\n // Minimal HEVC NAL units: header byte0 = (type << 1). VPS=32(0x40), SPS=33(0x42), PPS=34(0x44).\n // Real x265 repeat-headers=1 parameter sets (the cast encoder profile); the\n // SPS carries emulation-prevention bytes inside profile_tier_level. See\n // test-vectors/hevc-x265-repeat-headers-v1.json for the full access units.\n const vps = new Uint8Array([\n 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x90, 0x00, 0x00,\n 0x03, 0x00, 0x00, 0x03, 0x00, 0x3c, 0x92, 0x80, 0x90,\n ])\n const sps = new Uint8Array([\n 0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, 0x00, 0x90, 0x00, 0x00, 0x03, 0x00, 0x00,\n 0x03, 0x00, 0x3c, 0xa0, 0x0a, 0x08, 0x0f, 0x16, 0x59, 0x2a, 0x49, 0x32, 0xbc, 0x05, 0xa0,\n 0x20, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x03, 0x03, 0xc1,\n ])\n const pps = new Uint8Array([0x44, 0x01, 0xc1, 0x72, 0xb4, 0x62, 0x40])\n const idr = new Uint8Array([0x26, 0x01, 0xaf, 0x06]) // type 19 (IDR_W_RADL)\n const lp = (...nals: Uint8Array[]) => {\n const parts: number[] = []\n for (const n of nals) { parts.push((n.length >> 24) & 0xff, (n.length >> 16) & 0xff, (n.length >> 8) & 0xff, n.length & 0xff, ...n) }\n return Uint8Array.from(parts)\n }\n\n test('isHevcCodec', () => {\n expect(isHevcCodec('hev1.1.6.L93.B0')).toBe(true)\n expect(isHevcCodec('hvc1.1.6.L93.B0')).toBe(true)\n expect(isHevcCodec('avc1.640033')).toBe(false)\n })\n\n test('removeEmulationPrevention strips 0x03', () => {\n expect(Array.from(removeEmulationPrevention(new Uint8Array([0, 0, 0x03, 1])))).toEqual([0, 0, 1])\n expect(Array.from(removeEmulationPrevention(new Uint8Array([0xaa, 0xbb])))).toEqual([0xaa, 0xbb])\n })\n\n test('splitAvccNalUnits splits length-prefixed NALs', () => {\n const nals = splitAvccNalUnits(lp(vps, sps))\n expect(nals.length).toBe(2)\n expect(nals[0]).toEqual(vps)\n expect(nals[1]).toEqual(sps)\n })\n\n test('isCompleteAvccSample accepts complete length-prefixed NAL samples', () => {\n expect(isCompleteAvccSample(lp(new Uint8Array([0x09]), idr))).toBe(true)\n })\n\n test('isCompleteAvccSample rejects Annex-B start-code samples', () => {\n expect(isCompleteAvccSample(new Uint8Array([0, 0, 0, 1, 0x65, 0xaa]))).toBe(false)\n })\n\n test('isCompleteAvccSample rejects truncated length-prefixed samples', () => {\n expect(isCompleteAvccSample(new Uint8Array([0, 0, 0, 4, 0x65, 0xaa]))).toBe(false)\n })\n\n test('normalizeH264SampleToAvcc leaves complete AVCC samples unchanged', () => {\n const avcc = lp(new Uint8Array([0x09]), idr)\n const normalized = normalizeH264SampleToAvcc(avcc)\n expect(normalized.format).toBe('avcc')\n expect(normalized.data).toBe(avcc)\n })\n\n test('normalizeH264SampleToAvcc converts a single raw H.264 NAL to AVCC', () => {\n const raw = new Uint8Array([0x65, 0x88, 0x84])\n const normalized = normalizeH264SampleToAvcc(raw)\n expect(normalized.format).toBe('raw-nal')\n expect(normalized.data).toEqual(new Uint8Array([0, 0, 0, 3, 0x65, 0x88, 0x84]))\n })\n\n test('splitH264SampleNalUnits exposes Annex-B NALs without AVCC conversion', () => {\n const annexB = new Uint8Array([0, 0, 0, 1, 0x65, 0x88, 0x84])\n const sample = splitH264SampleNalUnits(annexB)\n expect(sample.format).toBe('annexb')\n expect(sample.nals).toHaveLength(1)\n expect(sample.nals[0]).toEqual(new Uint8Array([0x65, 0x88, 0x84]))\n })\n\n test('splitH264SampleNalUnits exposes single raw H.264 NALs without wrapping', () => {\n const raw = new Uint8Array([0x65, 0x88, 0x84])\n const sample = splitH264SampleNalUnits(raw)\n expect(sample.format).toBe('raw-nal')\n expect(sample.nals).toEqual([raw])\n })\n\n test('splitH264SampleNalUnits can expose partial AVCC NAL headers', () => {\n const partial = new Uint8Array([0, 0, 0, 5, 0x65, 0x88])\n const sample = splitH264SampleNalUnits(partial, { allowPartialAvcc: true })\n expect(sample.format).toBe('partial-avcc')\n expect(sample.nals).toHaveLength(1)\n expect(sample.nals[0]).toEqual(new Uint8Array([0x65, 0x88]))\n })\n\n test('extractHevcParameterSets finds VPS/SPS/PPS (length-prefixed)', () => {\n const sets = extractHevcParameterSets(lp(vps, sps, pps, idr))\n expect(sets.vps).toEqual(vps)\n expect(sets.sps).toEqual(sps)\n expect(sets.pps).toEqual(pps)\n })\n\n test('extractHevcParameterSets finds VPS/SPS/PPS (Annex-B)', () => {\n const sc = new Uint8Array([0, 0, 0, 1])\n const annexb = Uint8Array.from([...sc, ...vps, ...sc, ...sps, ...sc, ...pps, ...sc, ...idr])\n const sets = extractHevcParameterSets(annexb)\n expect(sets.vps).toEqual(vps)\n expect(sets.sps).toEqual(sps)\n expect(sets.pps).toEqual(pps)\n })\n\n test('generateHvcCFromParameterSets builds a valid hvcC', () => {\n const hvcc = generateHvcCFromParameterSets({ vps, sps, pps })!\n expect(hvcc).not.toBeNull()\n expect(hvcc[0]).toBe(1) // configurationVersion\n expect(hvcc[1]).toBe(sps[3]) // general profile_tier_level byte 0 copied from SPS[3]\n expect(hvcc[22]).toBe(3) // numOfArrays (VPS+SPS+PPS)\n // first array entry: NAL_unit_type 32 (VPS), numNalus 1\n expect(hvcc[23] & 0x3f).toBe(32)\n expect((hvcc[24] << 8) | hvcc[25]).toBe(1)\n })\n\n test('generateHvcCFromParameterSets returns null without SPS/PPS', () => {\n expect(generateHvcCFromParameterSets({ vps })).toBeNull()\n })\n\n test('extractHevcCodecDescription end-to-end from keyframe', () => {\n const desc = extractHevcCodecDescription(lp(vps, sps, pps, idr))\n expect(desc).not.toBeNull()\n expect(desc![0]).toBe(1)\n })\n\n test('hevcVclOnly strips parameter-set NALs, keeps VCL', () => {\n const stripped = hevcVclOnly(lp(vps, sps, pps, idr))\n const nals = splitAvccNalUnits(stripped)\n expect(nals.length).toBe(1) // only the IDR VCL NAL remains\n expect(nals[0]).toEqual(idr)\n })\n\n test('hevcVclOnly is a no-op for VCL-only length-prefixed input', () => {\n const vclOnly = lp(idr)\n expect(hevcVclOnly(vclOnly)).toBe(vclOnly)\n })\n })\n })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sink-side concealment helpers for the keyframe-protected FEC policy.
|
|
3
|
+
*
|
|
4
|
+
* Concealment is hold-last-good-frame. No bitstream is ever synthesised:
|
|
5
|
+
* a generated "fill" picture is codec-specific, resets the reference chain
|
|
6
|
+
* (an IDR) or is not a picture at all, and every later delta would decode
|
|
7
|
+
* against it until the next RAP. Instead the sink keeps presenting the last
|
|
8
|
+
* good frame, sized exactly from authored timestamps, until media resumes.
|
|
9
|
+
*
|
|
10
|
+
* - {@link videoConcealModeForCodec} says whether a video decoder can be fed
|
|
11
|
+
* straight through a delta gap (H.264 conceals missing references itself)
|
|
12
|
+
* or must hold until the next RAP.
|
|
13
|
+
* - {@link HoldLastTimeline} gives MSE sinks gapless per-sample durations.
|
|
14
|
+
* - {@link AudioGapConcealer} sizes audio concealment exactly: repeat the last
|
|
15
|
+
* good access unit (MSE) or insert PCM silence (WebCodecs).
|
|
16
|
+
*/
|
|
17
|
+
import type { FrameGapDecision } from './block-policy.js';
|
|
18
|
+
/**
|
|
19
|
+
* `feed-through`: keep feeding deltas after a delta-only gap; the decoder
|
|
20
|
+
* conceals missing references and the canvas keeps the last frame.
|
|
21
|
+
* `hold-to-rap`: drop non-RAP frames until the next RAP (no queue flush, no
|
|
22
|
+
* A/V sync reset).
|
|
23
|
+
*/
|
|
24
|
+
export type VideoConcealMode = 'feed-through' | 'hold-to-rap';
|
|
25
|
+
/**
|
|
26
|
+
* AVC decoders conceal a missing reference and resynchronise on their own;
|
|
27
|
+
* HEVC, AV1 and VP9 decoders error or freeze on a broken reference chain.
|
|
28
|
+
* Any codec not known to conceal is held to the next RAP (fail-closed).
|
|
29
|
+
*/
|
|
30
|
+
export declare function videoConcealModeForCodec(codec: string): VideoConcealMode;
|
|
31
|
+
/** One video sample in its media timescale. */
|
|
32
|
+
export interface TimelineSample<T> {
|
|
33
|
+
readonly payload: T;
|
|
34
|
+
readonly dts: bigint;
|
|
35
|
+
readonly pts: bigint;
|
|
36
|
+
/** Authored duration in media ticks. */
|
|
37
|
+
readonly duration: number;
|
|
38
|
+
/** Codec-aware RAP. */
|
|
39
|
+
readonly keyframe: boolean;
|
|
40
|
+
readonly mpu?: number;
|
|
41
|
+
/** Decision attached by libmmt to the first frame released after a gap. */
|
|
42
|
+
readonly gapBefore?: FrameGapDecision;
|
|
43
|
+
}
|
|
44
|
+
/** A sample ready to append, with an explicit per-sample duration. */
|
|
45
|
+
export interface TimelineEmit<T> {
|
|
46
|
+
readonly payload: T;
|
|
47
|
+
readonly dts: bigint;
|
|
48
|
+
readonly pts: bigint;
|
|
49
|
+
readonly duration: number;
|
|
50
|
+
readonly keyframe: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface HoldLastTimelineOptions {
|
|
53
|
+
readonly concealMode: VideoConcealMode;
|
|
54
|
+
}
|
|
55
|
+
export interface HoldLastTimelineStats {
|
|
56
|
+
/** Non-RAP frames dropped while waiting for a RAP. */
|
|
57
|
+
droppedFrames: number;
|
|
58
|
+
/** Held frames whose duration was extended over a gap. */
|
|
59
|
+
extendedHolds: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Holds one video sample back so its duration can run to the next emitted
|
|
63
|
+
* sample's dts. That costs exactly one frame of MSE latency (1000/framerate
|
|
64
|
+
* ms, from the catalog) and buys a gapless hold-last without synthesising a
|
|
65
|
+
* bitstream: a gap simply lengthens the last good frame.
|
|
66
|
+
*
|
|
67
|
+
* On a stall, or on any conceal under `hold-to-rap` except a RAP arriving
|
|
68
|
+
* right after the gap, frames are dropped until the next RAP and the held
|
|
69
|
+
* frame stays held until that RAP arrives, then runs exactly to its dts. The
|
|
70
|
+
* element waits on the held frame for the length of the outage, but the
|
|
71
|
+
* buffer never gets a hole, however many RAPs the outage took. Once the
|
|
72
|
+
* stream shows composition offsets (dts ≠ pts), samples pass straight
|
|
73
|
+
* through with their authored durations and MSE starves until the RAP is
|
|
74
|
+
* appended — the one documented case where the element also waits on audio.
|
|
75
|
+
*/
|
|
76
|
+
export declare class HoldLastTimeline<T> {
|
|
77
|
+
#private;
|
|
78
|
+
constructor(options: HoldLastTimelineOptions);
|
|
79
|
+
get stats(): Readonly<HoldLastTimelineStats>;
|
|
80
|
+
push(sample: TimelineSample<T>): TimelineEmit<T>[];
|
|
81
|
+
/** Release the held sample with its authored duration (end of stream). */
|
|
82
|
+
flush(): TimelineEmit<T>[];
|
|
83
|
+
/** Drop all state for a new epoch. */
|
|
84
|
+
reset(): void;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* One audio access unit on its track's authored clock: the ISO-BMFF media
|
|
88
|
+
* timescale the `audio-gap` decision was computed in (`decideGap`, from
|
|
89
|
+
* `AuthoredTiming`). An AAC AU is exactly 1024 ticks there. Never pass values
|
|
90
|
+
* rescaled to another timescale: 1024 samples at 48 kHz is 21333.33... µs,
|
|
91
|
+
* which no integer tick count can hold.
|
|
92
|
+
*/
|
|
93
|
+
export interface AudioAccessUnit<T> {
|
|
94
|
+
readonly payload: T;
|
|
95
|
+
/** Authored presentation time in media ticks (`AuthoredTiming.presentationTime`). */
|
|
96
|
+
readonly pts: bigint;
|
|
97
|
+
/** Authored duration in media ticks (`AuthoredTiming.durationTicks`): a positive safe integer. */
|
|
98
|
+
readonly duration: number;
|
|
99
|
+
}
|
|
100
|
+
export interface AudioGapConcealerStats {
|
|
101
|
+
/**
|
|
102
|
+
* Access units `note()` refused because their duration was not a positive
|
|
103
|
+
* safe integer: not media ticks, so the AU cannot size a gap. The concealer
|
|
104
|
+
* then holds no good AU and the next gap re-anchors. Non-zero means a caller
|
|
105
|
+
* noted a rescaled value (e.g. microseconds) instead of authored ticks.
|
|
106
|
+
*/
|
|
107
|
+
rejectedUnits: number;
|
|
108
|
+
}
|
|
109
|
+
export type AudioGapPlan<T> = {
|
|
110
|
+
readonly kind: 'none';
|
|
111
|
+
} | {
|
|
112
|
+
readonly kind: 'conceal';
|
|
113
|
+
/**
|
|
114
|
+
* MSE: the last good AU repeated into each missing slot. Empty when no
|
|
115
|
+
* good AU has been seen yet; an AAC access unit is not portable across
|
|
116
|
+
* AudioSpecificConfigs, so none is ever synthesised.
|
|
117
|
+
*/
|
|
118
|
+
readonly repeat: AudioAccessUnit<T>[];
|
|
119
|
+
/** WebCodecs: exactly this much PCM silence, in media ticks. */
|
|
120
|
+
readonly silenceTicks: bigint;
|
|
121
|
+
} | {
|
|
122
|
+
/** The gap is not a whole number of AUs: re-anchor at `pts`. */
|
|
123
|
+
readonly kind: 're-anchor';
|
|
124
|
+
readonly pts: bigint;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Sizes an audio gap from the libmmt gap decision. Audio never touches video
|
|
128
|
+
* state: every plan is local to the audio sink.
|
|
129
|
+
*/
|
|
130
|
+
export declare class AudioGapConcealer<T> {
|
|
131
|
+
#private;
|
|
132
|
+
get stats(): Readonly<AudioGapConcealerStats>;
|
|
133
|
+
/**
|
|
134
|
+
* Record a good access unit as it is emitted. An AU whose duration is not
|
|
135
|
+
* whole media ticks is refused and counted (`stats.rejectedUnits`), and the
|
|
136
|
+
* concealer forgets its previous AU: that one no longer precedes the gap, so
|
|
137
|
+
* sizing from it would misplace every slot. Refusing here keeps `plan()`
|
|
138
|
+
* total, so a bad AU never throws out of the packet path.
|
|
139
|
+
*/
|
|
140
|
+
note(au: AudioAccessUnit<T>): void;
|
|
141
|
+
plan(decision: FrameGapDecision | undefined, next: {
|
|
142
|
+
readonly pts: bigint;
|
|
143
|
+
}): AudioGapPlan<T>;
|
|
144
|
+
reset(): void;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=conceal-timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conceal-timeline.d.ts","sourceRoot":"","sources":["../src/conceal-timeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAIzD;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG,aAAa,CAAA;AAE7D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAIxE;AAID,+CAA+C;AAC/C,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,uBAAuB;IACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAA;CACtC;AAED,sEAAsE;AACtE,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAA;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAA;IACrB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAA;CACtB;AAID;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gBAAgB,CAAC,CAAC;;gBAOjB,OAAO,EAAE,uBAAuB;IAI5C,IAAI,KAAK,IAAI,QAAQ,CAAC,qBAAqB,CAAC,CAE3C;IAED,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE;IAsBlD,0EAA0E;IAC1E,KAAK,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE;IAI1B,sCAAsC;IACtC,KAAK,IAAI,IAAI;CAkDd;AAID;;;;;;GAMG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,qFAAqF;IACrF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,kGAAkG;IAClG,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,IACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAA;IACrC,gEAAgE;IAChE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAC9B,GACD;IACE,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,CAAA;AAEL;;;GAGG;AACH,qBAAa,iBAAiB,CAAC,CAAC;;IAI9B,IAAI,KAAK,IAAI,QAAQ,CAAC,sBAAsB,CAAC,CAE5C;IAED;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI;IASlC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,SAAS,EAAE,IAAI,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,YAAY,CAAC,CAAC,CAAC;IA2B7F,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// src/conceal-timeline.ts
|
|
2
|
+
function videoConcealModeForCodec(codec) {
|
|
3
|
+
const lower = codec.toLowerCase();
|
|
4
|
+
if (lower.startsWith("avc1") || lower.startsWith("avc3")) return "feed-through";
|
|
5
|
+
return "hold-to-rap";
|
|
6
|
+
}
|
|
7
|
+
var U32_MAX = 0xffffffffn;
|
|
8
|
+
var HoldLastTimeline = class {
|
|
9
|
+
#concealMode;
|
|
10
|
+
#held = null;
|
|
11
|
+
#dropping = false;
|
|
12
|
+
#compositionOffsets = false;
|
|
13
|
+
#stats = { droppedFrames: 0, extendedHolds: 0 };
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.#concealMode = options.concealMode;
|
|
16
|
+
}
|
|
17
|
+
get stats() {
|
|
18
|
+
return { ...this.#stats };
|
|
19
|
+
}
|
|
20
|
+
push(sample) {
|
|
21
|
+
if (sample.dts !== sample.pts) this.#compositionOffsets = true;
|
|
22
|
+
if (this.#dropping) {
|
|
23
|
+
if (!sample.keyframe) {
|
|
24
|
+
this.#stats.droppedFrames++;
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
this.#dropping = false;
|
|
28
|
+
return this.#accept(sample);
|
|
29
|
+
}
|
|
30
|
+
if (this.#dropsUntilRap(sample)) {
|
|
31
|
+
this.#dropping = true;
|
|
32
|
+
this.#stats.droppedFrames++;
|
|
33
|
+
return this.#compositionOffsets ? this.#releaseHeld() : [];
|
|
34
|
+
}
|
|
35
|
+
return this.#accept(sample);
|
|
36
|
+
}
|
|
37
|
+
/** Release the held sample with its authored duration (end of stream). */
|
|
38
|
+
flush() {
|
|
39
|
+
return this.#releaseHeld();
|
|
40
|
+
}
|
|
41
|
+
/** Drop all state for a new epoch. */
|
|
42
|
+
reset() {
|
|
43
|
+
this.#held = null;
|
|
44
|
+
this.#dropping = false;
|
|
45
|
+
this.#compositionOffsets = false;
|
|
46
|
+
}
|
|
47
|
+
#accept(sample) {
|
|
48
|
+
if (this.#compositionOffsets) {
|
|
49
|
+
const out2 = this.#releaseHeld();
|
|
50
|
+
out2.push(this.#emit(sample, sample.duration));
|
|
51
|
+
return out2;
|
|
52
|
+
}
|
|
53
|
+
const out = [];
|
|
54
|
+
const held = this.#held;
|
|
55
|
+
if (held) out.push(this.#emit(held, this.#durationTo(held, sample.dts)));
|
|
56
|
+
this.#held = sample;
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
#dropsUntilRap(sample) {
|
|
60
|
+
const gap = sample.gapBefore;
|
|
61
|
+
if (!gap || gap.trackKind !== "video" || sample.keyframe) return false;
|
|
62
|
+
if (gap.action === "stall") return true;
|
|
63
|
+
return this.#concealMode === "hold-to-rap" && gap.reason !== "rap-next";
|
|
64
|
+
}
|
|
65
|
+
#durationTo(held, target) {
|
|
66
|
+
if (target <= held.dts) return held.duration;
|
|
67
|
+
const span = target - held.dts;
|
|
68
|
+
if (span > U32_MAX) return held.duration;
|
|
69
|
+
const duration = Number(span);
|
|
70
|
+
if (duration !== held.duration) this.#stats.extendedHolds++;
|
|
71
|
+
return duration;
|
|
72
|
+
}
|
|
73
|
+
#releaseHeld() {
|
|
74
|
+
const held = this.#held;
|
|
75
|
+
this.#held = null;
|
|
76
|
+
return held ? [this.#emit(held, held.duration)] : [];
|
|
77
|
+
}
|
|
78
|
+
#emit(sample, duration) {
|
|
79
|
+
return {
|
|
80
|
+
payload: sample.payload,
|
|
81
|
+
dts: sample.dts,
|
|
82
|
+
pts: sample.pts,
|
|
83
|
+
duration,
|
|
84
|
+
keyframe: sample.keyframe
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var AudioGapConcealer = class {
|
|
89
|
+
#last = null;
|
|
90
|
+
#stats = { rejectedUnits: 0 };
|
|
91
|
+
get stats() {
|
|
92
|
+
return { ...this.#stats };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Record a good access unit as it is emitted. An AU whose duration is not
|
|
96
|
+
* whole media ticks is refused and counted (`stats.rejectedUnits`), and the
|
|
97
|
+
* concealer forgets its previous AU: that one no longer precedes the gap, so
|
|
98
|
+
* sizing from it would misplace every slot. Refusing here keeps `plan()`
|
|
99
|
+
* total, so a bad AU never throws out of the packet path.
|
|
100
|
+
*/
|
|
101
|
+
note(au) {
|
|
102
|
+
if (!Number.isSafeInteger(au.duration) || au.duration <= 0) {
|
|
103
|
+
this.#stats.rejectedUnits++;
|
|
104
|
+
this.#last = null;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.#last = au;
|
|
108
|
+
}
|
|
109
|
+
plan(decision, next) {
|
|
110
|
+
if (!decision || decision.trackKind !== "audio") return { kind: "none" };
|
|
111
|
+
const missing = decision.missingFrames;
|
|
112
|
+
if (decision.reason !== "audio-gap" || missing === null || !Number.isSafeInteger(missing) || missing <= 0) {
|
|
113
|
+
return { kind: "re-anchor", pts: next.pts };
|
|
114
|
+
}
|
|
115
|
+
const last = this.#last;
|
|
116
|
+
if (last === null) return { kind: "re-anchor", pts: next.pts };
|
|
117
|
+
const duration = BigInt(last.duration);
|
|
118
|
+
const repeat = [];
|
|
119
|
+
for (let slot = 1; slot <= missing; slot++) {
|
|
120
|
+
repeat.push({
|
|
121
|
+
payload: last.payload,
|
|
122
|
+
pts: last.pts + BigInt(slot) * duration,
|
|
123
|
+
duration: last.duration
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return { kind: "conceal", repeat, silenceTicks: BigInt(missing) * duration };
|
|
127
|
+
}
|
|
128
|
+
reset() {
|
|
129
|
+
this.#last = null;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
export {
|
|
133
|
+
AudioGapConcealer,
|
|
134
|
+
HoldLastTimeline,
|
|
135
|
+
videoConcealModeForCodec
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=conceal-timeline.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/conceal-timeline.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Sink-side concealment helpers for the keyframe-protected FEC policy.\n *\n * Concealment is hold-last-good-frame. No bitstream is ever synthesised:\n * a generated \"fill\" picture is codec-specific, resets the reference chain\n * (an IDR) or is not a picture at all, and every later delta would decode\n * against it until the next RAP. Instead the sink keeps presenting the last\n * good frame, sized exactly from authored timestamps, until media resumes.\n *\n * - {@link videoConcealModeForCodec} says whether a video decoder can be fed\n * straight through a delta gap (H.264 conceals missing references itself)\n * or must hold until the next RAP.\n * - {@link HoldLastTimeline} gives MSE sinks gapless per-sample durations.\n * - {@link AudioGapConcealer} sizes audio concealment exactly: repeat the last\n * good access unit (MSE) or insert PCM silence (WebCodecs).\n */\n\nimport type { FrameGapDecision } from './block-policy.js'\n\n// \u2500\u2500\u2500 Video conceal mode \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * `feed-through`: keep feeding deltas after a delta-only gap; the decoder\n * conceals missing references and the canvas keeps the last frame.\n * `hold-to-rap`: drop non-RAP frames until the next RAP (no queue flush, no\n * A/V sync reset).\n */\nexport type VideoConcealMode = 'feed-through' | 'hold-to-rap'\n\n/**\n * AVC decoders conceal a missing reference and resynchronise on their own;\n * HEVC, AV1 and VP9 decoders error or freeze on a broken reference chain.\n * Any codec not known to conceal is held to the next RAP (fail-closed).\n */\nexport function videoConcealModeForCodec(codec: string): VideoConcealMode {\n const lower = codec.toLowerCase()\n if (lower.startsWith('avc1') || lower.startsWith('avc3')) return 'feed-through'\n return 'hold-to-rap'\n}\n\n// \u2500\u2500\u2500 HoldLastTimeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** One video sample in its media timescale. */\nexport interface TimelineSample<T> {\n readonly payload: T\n readonly dts: bigint\n readonly pts: bigint\n /** Authored duration in media ticks. */\n readonly duration: number\n /** Codec-aware RAP. */\n readonly keyframe: boolean\n readonly mpu?: number\n /** Decision attached by libmmt to the first frame released after a gap. */\n readonly gapBefore?: FrameGapDecision\n}\n\n/** A sample ready to append, with an explicit per-sample duration. */\nexport interface TimelineEmit<T> {\n readonly payload: T\n readonly dts: bigint\n readonly pts: bigint\n readonly duration: number\n readonly keyframe: boolean\n}\n\nexport interface HoldLastTimelineOptions {\n readonly concealMode: VideoConcealMode\n}\n\nexport interface HoldLastTimelineStats {\n /** Non-RAP frames dropped while waiting for a RAP. */\n droppedFrames: number\n /** Held frames whose duration was extended over a gap. */\n extendedHolds: number\n}\n\nconst U32_MAX = 0xffff_ffffn\n\n/**\n * Holds one video sample back so its duration can run to the next emitted\n * sample's dts. That costs exactly one frame of MSE latency (1000/framerate\n * ms, from the catalog) and buys a gapless hold-last without synthesising a\n * bitstream: a gap simply lengthens the last good frame.\n *\n * On a stall, or on any conceal under `hold-to-rap` except a RAP arriving\n * right after the gap, frames are dropped until the next RAP and the held\n * frame stays held until that RAP arrives, then runs exactly to its dts. The\n * element waits on the held frame for the length of the outage, but the\n * buffer never gets a hole, however many RAPs the outage took. Once the\n * stream shows composition offsets (dts \u2260 pts), samples pass straight\n * through with their authored durations and MSE starves until the RAP is\n * appended \u2014 the one documented case where the element also waits on audio.\n */\nexport class HoldLastTimeline<T> {\n readonly #concealMode: VideoConcealMode\n #held: TimelineSample<T> | null = null\n #dropping = false\n #compositionOffsets = false\n readonly #stats: HoldLastTimelineStats = { droppedFrames: 0, extendedHolds: 0 }\n\n constructor(options: HoldLastTimelineOptions) {\n this.#concealMode = options.concealMode\n }\n\n get stats(): Readonly<HoldLastTimelineStats> {\n return { ...this.#stats }\n }\n\n push(sample: TimelineSample<T>): TimelineEmit<T>[] {\n if (sample.dts !== sample.pts) this.#compositionOffsets = true\n\n if (this.#dropping) {\n if (!sample.keyframe) {\n this.#stats.droppedFrames++\n return []\n }\n this.#dropping = false\n return this.#accept(sample)\n }\n\n if (this.#dropsUntilRap(sample)) {\n this.#dropping = true\n this.#stats.droppedFrames++\n // The held frame stays held: the RAP's #accept sizes it exactly.\n return this.#compositionOffsets ? this.#releaseHeld() : []\n }\n\n return this.#accept(sample)\n }\n\n /** Release the held sample with its authored duration (end of stream). */\n flush(): TimelineEmit<T>[] {\n return this.#releaseHeld()\n }\n\n /** Drop all state for a new epoch. */\n reset(): void {\n this.#held = null\n this.#dropping = false\n this.#compositionOffsets = false\n }\n\n #accept(sample: TimelineSample<T>): TimelineEmit<T>[] {\n if (this.#compositionOffsets) {\n const out = this.#releaseHeld()\n out.push(this.#emit(sample, sample.duration))\n return out\n }\n const out: TimelineEmit<T>[] = []\n const held = this.#held\n if (held) out.push(this.#emit(held, this.#durationTo(held, sample.dts)))\n this.#held = sample\n return out\n }\n\n #dropsUntilRap(sample: TimelineSample<T>): boolean {\n const gap = sample.gapBefore\n if (!gap || gap.trackKind !== 'video' || sample.keyframe) return false\n if (gap.action === 'stall') return true\n return this.#concealMode === 'hold-to-rap' && gap.reason !== 'rap-next'\n }\n\n #durationTo(held: TimelineSample<T>, target: bigint): number {\n if (target <= held.dts) return held.duration\n const span = target - held.dts\n if (span > U32_MAX) return held.duration\n const duration = Number(span)\n if (duration !== held.duration) this.#stats.extendedHolds++\n return duration\n }\n\n #releaseHeld(): TimelineEmit<T>[] {\n const held = this.#held\n this.#held = null\n return held ? [this.#emit(held, held.duration)] : []\n }\n\n #emit(sample: TimelineSample<T>, duration: number): TimelineEmit<T> {\n return {\n payload: sample.payload,\n dts: sample.dts,\n pts: sample.pts,\n duration,\n keyframe: sample.keyframe,\n }\n }\n}\n\n// \u2500\u2500\u2500 AudioGapConcealer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * One audio access unit on its track's authored clock: the ISO-BMFF media\n * timescale the `audio-gap` decision was computed in (`decideGap`, from\n * `AuthoredTiming`). An AAC AU is exactly 1024 ticks there. Never pass values\n * rescaled to another timescale: 1024 samples at 48 kHz is 21333.33... \u00B5s,\n * which no integer tick count can hold.\n */\nexport interface AudioAccessUnit<T> {\n readonly payload: T\n /** Authored presentation time in media ticks (`AuthoredTiming.presentationTime`). */\n readonly pts: bigint\n /** Authored duration in media ticks (`AuthoredTiming.durationTicks`): a positive safe integer. */\n readonly duration: number\n}\n\nexport interface AudioGapConcealerStats {\n /**\n * Access units `note()` refused because their duration was not a positive\n * safe integer: not media ticks, so the AU cannot size a gap. The concealer\n * then holds no good AU and the next gap re-anchors. Non-zero means a caller\n * noted a rescaled value (e.g. microseconds) instead of authored ticks.\n */\n rejectedUnits: number\n}\n\nexport type AudioGapPlan<T> =\n | { readonly kind: 'none' }\n | {\n readonly kind: 'conceal'\n /**\n * MSE: the last good AU repeated into each missing slot. Empty when no\n * good AU has been seen yet; an AAC access unit is not portable across\n * AudioSpecificConfigs, so none is ever synthesised.\n */\n readonly repeat: AudioAccessUnit<T>[]\n /** WebCodecs: exactly this much PCM silence, in media ticks. */\n readonly silenceTicks: bigint\n }\n | {\n /** The gap is not a whole number of AUs: re-anchor at `pts`. */\n readonly kind: 're-anchor'\n readonly pts: bigint\n }\n\n/**\n * Sizes an audio gap from the libmmt gap decision. Audio never touches video\n * state: every plan is local to the audio sink.\n */\nexport class AudioGapConcealer<T> {\n #last: AudioAccessUnit<T> | null = null\n readonly #stats: AudioGapConcealerStats = { rejectedUnits: 0 }\n\n get stats(): Readonly<AudioGapConcealerStats> {\n return { ...this.#stats }\n }\n\n /**\n * Record a good access unit as it is emitted. An AU whose duration is not\n * whole media ticks is refused and counted (`stats.rejectedUnits`), and the\n * concealer forgets its previous AU: that one no longer precedes the gap, so\n * sizing from it would misplace every slot. Refusing here keeps `plan()`\n * total, so a bad AU never throws out of the packet path.\n */\n note(au: AudioAccessUnit<T>): void {\n if (!Number.isSafeInteger(au.duration) || au.duration <= 0) {\n this.#stats.rejectedUnits++\n this.#last = null\n return\n }\n this.#last = au\n }\n\n plan(decision: FrameGapDecision | undefined, next: { readonly pts: bigint }): AudioGapPlan<T> {\n if (!decision || decision.trackKind !== 'audio') return { kind: 'none' }\n const missing = decision.missingFrames\n if (\n decision.reason !== 'audio-gap' ||\n missing === null ||\n !Number.isSafeInteger(missing) ||\n missing <= 0\n ) {\n return { kind: 're-anchor', pts: next.pts }\n }\n const last = this.#last\n // Exact sizing needs the preceding AU's duration; a sink that has not\n // emitted one yet has nothing to hold and simply starts at the next AU.\n if (last === null) return { kind: 're-anchor', pts: next.pts }\n const duration = BigInt(last.duration)\n const repeat: AudioAccessUnit<T>[] = []\n for (let slot = 1; slot <= missing; slot++) {\n repeat.push({\n payload: last.payload,\n pts: last.pts + BigInt(slot) * duration,\n duration: last.duration,\n })\n }\n return { kind: 'conceal', repeat, silenceTicks: BigInt(missing) * duration }\n }\n\n reset(): void {\n this.#last = null\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["out"]
|
|
7
|
+
}
|