@blockcast/mmt-container 0.5.0 → 1.0.0-main.3cb7359ea316

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.
Files changed (136) hide show
  1. package/README.md +21 -16
  2. package/dist/browser-runtime.js +1024 -1078
  3. package/dist/browser-runtime.js.map +4 -4
  4. package/dist/carp-catalog.d.ts +33 -87
  5. package/dist/carp-catalog.d.ts.map +1 -1
  6. package/dist/carp-catalog.js +12 -434
  7. package/dist/carp-catalog.js.map +4 -4
  8. package/dist/catalog-fec-params.d.ts +48 -161
  9. package/dist/catalog-fec-params.d.ts.map +1 -1
  10. package/dist/catalog-fec-params.js +567 -592
  11. package/dist/catalog-fec-params.js.map +4 -4
  12. package/dist/catalog-network-source.js +6 -2
  13. package/dist/catalog-network-source.js.map +3 -3
  14. package/dist/delivery-catalog.js +12 -4
  15. package/dist/delivery-catalog.js.map +4 -4
  16. package/dist/delta-fallback-config.d.ts +21 -26
  17. package/dist/delta-fallback-config.d.ts.map +1 -1
  18. package/dist/delta-fallback-config.js +582 -24
  19. package/dist/delta-fallback-config.js.map +4 -4
  20. package/dist/fec-manager.js +6 -2
  21. package/dist/fec-manager.js.map +3 -3
  22. package/dist/fec-state.d.ts +5 -43
  23. package/dist/fec-state.d.ts.map +1 -1
  24. package/dist/fec-state.js +529 -34
  25. package/dist/fec-state.js.map +4 -4
  26. package/dist/fec-worker-setup.js +6 -2
  27. package/dist/fec-worker-setup.js.map +3 -3
  28. package/dist/held-layer-admission.js +6 -2
  29. package/dist/held-layer-admission.js.map +3 -3
  30. package/dist/index.d.ts +3 -3
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +5 -39
  33. package/dist/index.js.map +2 -2
  34. package/dist/iso-block-locator.js +6 -2
  35. package/dist/iso-block-locator.js.map +3 -3
  36. package/dist/mfu-reassembler.js +6 -2
  37. package/dist/mfu-reassembler.js.map +3 -3
  38. package/dist/mmtp-container-parser.js +6 -2
  39. package/dist/mmtp-container-parser.js.map +3 -3
  40. package/dist/mmtp-container-parser.no-modules.js +551 -452
  41. package/dist/mmtp-container-parser.no-modules.js.map +4 -4
  42. package/dist/mmtp-decode-pipeline.js +6 -2
  43. package/dist/mmtp-decode-pipeline.js.map +3 -3
  44. package/dist/mmtp-fec-session.d.ts +7 -6
  45. package/dist/mmtp-fec-session.d.ts.map +1 -1
  46. package/dist/mmtp-fec-session.js +13 -9
  47. package/dist/mmtp-fec-session.js.map +3 -3
  48. package/dist/mmtp-router.d.ts +7 -16
  49. package/dist/mmtp-router.d.ts.map +1 -1
  50. package/dist/mmtp-router.js +19 -29
  51. package/dist/mmtp-router.js.map +3 -3
  52. package/dist/multicast-auth-catalog.js +7 -3
  53. package/dist/multicast-auth-catalog.js.map +3 -3
  54. package/dist/multicast-input.js +7 -3
  55. package/dist/multicast-input.js.map +3 -3
  56. package/dist/multicast-manager.d.ts +29 -32
  57. package/dist/multicast-manager.d.ts.map +1 -1
  58. package/dist/multicast-manager.js +682 -253
  59. package/dist/multicast-manager.js.map +4 -4
  60. package/dist/multicast-transport.d.ts +23 -2
  61. package/dist/multicast-transport.d.ts.map +1 -1
  62. package/dist/multicast-transport.js +57 -16
  63. package/dist/multicast-transport.js.map +4 -4
  64. package/dist/multicast-unwrap.js +6 -2
  65. package/dist/multicast-unwrap.js.map +3 -3
  66. package/dist/no-modules.js +551 -452
  67. package/dist/no-modules.js.map +4 -4
  68. package/dist/phase14-catalog-override.d.ts +10 -5
  69. package/dist/phase14-catalog-override.d.ts.map +1 -1
  70. package/dist/phase14-catalog-override.js +35 -11
  71. package/dist/phase14-catalog-override.js.map +2 -2
  72. package/dist/repair-fetch.d.ts +3 -1
  73. package/dist/repair-fetch.d.ts.map +1 -1
  74. package/dist/repair-fetch.js +16 -3
  75. package/dist/repair-fetch.js.map +3 -3
  76. package/dist/repair-layers.d.ts +0 -123
  77. package/dist/repair-layers.d.ts.map +1 -1
  78. package/dist/repair-layers.js +1 -349
  79. package/dist/repair-layers.js.map +3 -3
  80. package/dist/signaling.js +6 -2
  81. package/dist/signaling.js.map +3 -3
  82. package/dist/timestamp-codec.js +6 -2
  83. package/dist/timestamp-codec.js.map +3 -3
  84. package/dist/wasm-mfu-reassembler.js +6 -2
  85. package/dist/wasm-mfu-reassembler.js.map +3 -3
  86. package/dist/wasm-mmtp-container-parser.js +6 -2
  87. package/dist/wasm-mmtp-container-parser.js.map +3 -3
  88. package/package.json +9 -5
  89. package/schemas/catalog.schema.json +53 -58
  90. package/src/carp-catalog.ts +39 -229
  91. package/src/catalog-fec-params.ts +130 -493
  92. package/src/delta-fallback-config.ts +63 -50
  93. package/src/fec-state.ts +7 -62
  94. package/src/index.ts +10 -30
  95. package/src/mmtp-fec-session.ts +11 -10
  96. package/src/mmtp-router.ts +14 -29
  97. package/src/multicast-manager.ts +89 -121
  98. package/src/multicast-transport.ts +65 -12
  99. package/src/phase14-catalog-override.ts +67 -16
  100. package/src/repair-fetch.ts +27 -3
  101. package/src/repair-layers.ts +7 -520
  102. package/test-vectors/catalog/README.md +39 -67
  103. package/test-vectors/catalog/fec-01-runtime/README.md +15 -0
  104. package/test-vectors/catalog/{negative/fec-block-profile-retired.json → fec-01-runtime/fec-iso-ssbg1.json} +1 -1
  105. package/test-vectors/catalog/fec-01-runtime/fec-layered-repair.json +106 -0
  106. package/test-vectors/catalog/{negative/fec-block-profile-unknown.json → fec-01-runtime/fec-multicast.json} +2 -1
  107. package/test-vectors/catalog/fec-01-runtime/multicast-native-ssm-no-network-source.json +44 -0
  108. package/test-vectors/catalog/negative/fec-block-profile-missing.json +24 -11
  109. package/test-vectors/catalog/negative/fec-iso-symbol-size-below-floor.json +13 -8
  110. package/test-vectors/catalog/negative/fec-reed-solomon-iso-symbol-size-13.json +13 -8
  111. package/test-vectors/catalog/negative/fec-repair-layer-geometry.json +20 -10
  112. package/test-vectors/catalog/negative/fec-repair-layer-missing-symbols.json +20 -10
  113. package/test-vectors/catalog/negative/fec-repair-overlay-source-symbols-zero.json +25 -17
  114. package/test-vectors/catalog/negative/fec-repair-symbols-zero.json +13 -8
  115. package/test-vectors/catalog/negative/fec-source-symbols-zero.json +13 -8
  116. package/test-vectors/catalog/negative/fec-symbol-size-zero.json +13 -8
  117. package/test-vectors/catalog/negative/raptorq-source-symbols-over-max.json +18 -9
  118. package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +13 -8
  119. package/test-vectors/catalog/positive/fec-algorithm-unimplemented.json +14 -9
  120. package/test-vectors/catalog/positive/fec-iso-ssbg1.json +25 -12
  121. package/test-vectors/catalog/positive/fec-layered-repair.json +79 -35
  122. package/test-vectors/catalog/positive/fec-multicast.json +26 -13
  123. package/test-vectors/catalog/positive/fec-reed-solomon-layered.json +29 -18
  124. package/test-vectors/catalog/positive/multicast-draft01-4-1-example.json +28 -20
  125. package/test-vectors/catalog/positive/multicast-draft01-7-2-6-example.json +14 -10
  126. package/test-vectors/catalog/positive/multicast-native-ssm-no-network-source.json +22 -12
  127. package/test-vectors/catalog/section-codes.json +13 -22
  128. package/test-vectors/catalog-timing.json +2 -2
  129. package/test-vectors/catalog-validation.json +30 -243
  130. package/test-vectors/catalog/negative/fec-enhancement-repair-removed.json +0 -28
  131. package/test-vectors/catalog/negative/fec-reed-solomon-k-plus-p-over-255.json +0 -39
  132. package/test-vectors/catalog/negative/fec-reed-solomon-overlay-over-255.json +0 -40
  133. package/test-vectors/catalog/negative/fec-repair-multiple-depends.json +0 -32
  134. package/test-vectors/catalog/negative/fec-repair-overlay-with-layer.json +0 -34
  135. package/test-vectors/catalog/negative/fec-repair-priority-out-of-band.json +0 -24
  136. package/test-vectors/catalog/negative/fec-repair-source-symbols-without-scope.json +0 -33
@@ -1,4 +1,3 @@
1
- import { type FecBlockProfile } from "@blockcast/mmt-base";
2
1
  /** Lowest MoQT-scale priority a repair track may declare. */
3
2
  export declare const REPAIR_PRIORITY_MIN = 192;
4
3
  /** Highest MoQT-scale priority a repair track may declare. */
@@ -13,69 +12,6 @@ export declare const MAX_REPAIR_SYMBOLS = 16777215;
13
12
  export declare const MAX_ENCODING_SYMBOL_ID = 16777215;
14
13
  /** Reed-Solomon block bound: K + P <= 255 (draft-ramadan-moq-fec-01 4.5, 6.3.4 rule 12). */
15
14
  export declare const MAX_REED_SOLOMON_BLOCK_SYMBOLS = 255;
16
- export type RepairContractCode = "track_fec" | "track_repair_track" | "track_repair_depends" | "track_repair_layer" | "track_repair_priority" | "track_repair_overlay" | "track_repair_geometry" | "track_fec_bounds" | "track_fec_block_profile" | "track_fec_block_profile_unimplemented";
17
- /** Reports one contract violation and never returns. */
18
- export type RepairContractFail = (code: RepairContractCode, path: string, message: string) => never;
19
- export declare class RepairContractError extends Error {
20
- readonly code: RepairContractCode;
21
- readonly path: string;
22
- constructor(code: RepairContractCode, path: string, message: string);
23
- }
24
- export declare const throwRepairContractError: RepairContractFail;
25
- /**
26
- * Read one catalog `fec.blockProfile` (BLO-35597, ISO/IEC 23008-1 Annex C):
27
- * the one rule both catalog dialects, the CMSF validator and the per-track
28
- * resolver apply.
29
- *
30
- * draft-ramadan-moq-fec §5.1 defines exactly one profile, `iso-ssbg1-v1`, and
31
- * it is the only one this library implements. A `fec` block that declares an
32
- * FEC instance (any `algorithm` other than `"none"`) MUST name it; a block
33
- * declaring no FEC instance may omit the token (returns undefined), but a token
34
- * it does carry must be implemented. Failures are reported at `path`:
35
- *
36
- * - `track_fec_block_profile_unimplemented`: a non-empty string that names no
37
- * implemented profile. The retired Blockcast-private `k-padded-v1` is one
38
- * such token; a near-miss such as `"iso-ssbg1"` is another, never
39
- * normalized.
40
- * - `track_fec_block_profile`: no token on a declared FEC instance, or a value
41
- * that is not a non-empty string.
42
- *
43
- * The token is never defaulted and never inferred from the wire. A receiver
44
- * treats either failure as "FEC unavailable" for that track alone (it consumes
45
- * the source without FEC and joins none of its repair tracks); a conformance
46
- * validator rejects the catalog.
47
- *
48
- * @param path JSON path of the `blockProfile` field, for the error.
49
- */
50
- export declare function readFecBlockProfile(value: unknown, path: string, declaresFecInstance: true, fail: RepairContractFail): FecBlockProfile;
51
- export declare function readFecBlockProfile(value: unknown, path: string, declaresFecInstance: boolean, fail: RepairContractFail): FecBlockProfile | undefined;
52
- /** The self-describing fields of one repair track entry, in either dialect. */
53
- export type RepairTrackDescriptor = {
54
- /** Track (MSF) or rendition (hang) name. */
55
- name: string;
56
- /** JSON path of the entry, for error reporting. */
57
- path: string;
58
- depends?: unknown;
59
- repairLayer?: unknown;
60
- repairSymbols?: unknown;
61
- priority?: unknown;
62
- scope?: unknown;
63
- sourceSymbols?: unknown;
64
- };
65
- /** The source track's `fec` object as the layer contract reads it. */
66
- export type RepairSourceGeometry = {
67
- /** Source track or rendition name. */
68
- name: string;
69
- /** JSON path of the `fec` object, for error reporting. */
70
- path: string;
71
- algorithm?: unknown;
72
- /** K. */
73
- sourceSymbols?: unknown;
74
- /** P_0. */
75
- repairSymbols?: unknown;
76
- /** Layer 0 track name. */
77
- repairTrack?: unknown;
78
- };
79
15
  /** A resolved base repair layer with its derived RS_ID range. */
80
16
  export type RepairLayerParams = {
81
17
  /** Layer index; 0 is the track named by the source's `fec.repairTrack`. */
@@ -109,63 +45,4 @@ export type RepairLayersResolution = {
109
45
  /** Sum of P over base layers: the wire RSB_length on every base layer packet. */
110
46
  totalBaseRepairSymbols: number;
111
47
  };
112
- /** Track-level block geometry keys a repair track must not carry (§6.3 rule 8): geometry is the source's. */
113
- export declare const REPAIR_TRACK_GEOMETRY_KEYS: readonly ["mmtpMode", "timescale", "groupDurationMs", "groupDurationTicks", "keyframeIntervalMs", "keyframeIntervalTicks", "fec", "symbolSize", "interleaveDepthMs"];
114
- /** Self-describing repair fields that only a repair track or repair rendition may carry. */
115
- export declare const REPAIR_TRACK_ONLY_KEYS: readonly ["repairLayer", "repairSymbols", "sourceSymbols", "scope"];
116
- /** Rule 8: a repair track (MSF) or repair rendition (hang) carries no block geometry. */
117
- export declare function rejectRepairTrackGeometry(path: string, fields: Record<string, unknown>, fail: RepairContractFail): void;
118
- /** Which repair tracks a catalog can reach, for rule 9 (no orphan repair track). */
119
- export type RepairReachability = {
120
- /** True once any track or rendition carries `fec` with an algorithm other than `none`. */
121
- declaresFecSource: boolean;
122
- /** Every non-empty `fec.repairTrack` a FEC source names: the layer-0 tracks. */
123
- layerZeroNames: ReadonlySet<string>;
124
- };
125
- /**
126
- * Derive rule 9's inputs from the raw `fec` objects of every media track (MSF,
127
- * packaging other than `fec-repair`) or media rendition (hang) in a catalog.
128
- * Callers must not pass repair tracks: rule 8 forbids `fec` on them, and a
129
- * repair track that carried one would otherwise name itself as its own
130
- * layer 0 and slip past rule 9. One derivation for the validator and both
131
- * resolver dialects, so an empty-string pointer or an `algorithm: "none"`
132
- * source is read the same way everywhere.
133
- */
134
- export declare function repairReachability(fecObjects: Iterable<unknown>): RepairReachability;
135
- /**
136
- * Rule 9: once a catalog declares a FEC source, a repair track that declares no
137
- * `depends` must be some source's layer 0. A catalog with no FEC source may
138
- * still carry a naming-era repair track that nothing joins.
139
- */
140
- export declare function assertRepairTrackReachable(descriptor: RepairTrackDescriptor, reachability: RepairReachability, fail: RepairContractFail): void;
141
- /** A media track (MSF) or media rendition (hang) carries no repair-track fields. */
142
- export declare function rejectRepairFieldsOnMediaTrack(path: string, fields: Record<string, unknown>, fail: RepairContractFail): void;
143
- /** Pick the self-describing repair fields out of a raw track or rendition record. */
144
- export declare function describeRepairTrack(name: string, path: string, fields: Record<string, unknown>): RepairTrackDescriptor;
145
- /** The single source a repair track names in `depends`, once its shape has been validated. */
146
- export declare function dependsTarget(descriptor: RepairTrackDescriptor): string | undefined;
147
- /**
148
- * Validate the shape of one repair track's self-describing fields, independent
149
- * of any source. Cross-track rules (layer 0 agreement, contiguity, priority
150
- * order, bounds) live in `assembleRepairLayers`.
151
- */
152
- export declare function validateRepairTrackFields(descriptor: RepairTrackDescriptor, fail: RepairContractFail): void;
153
- /**
154
- * Resolve the base layers and overlays of one source track and derive each
155
- * base layer's RS_ID offset. Fails closed on every §6.3 rule violation through
156
- * `fail`, which receives the code and the JSON path of the offending field.
157
- *
158
- * `descriptors` are every repair track (or repair rendition) in the catalog,
159
- * already shape-checked by `validateRepairTrackFields`. Returns undefined when
160
- * the source names no layer 0 and nothing depends on it.
161
- */
162
- export type AssembleRepairLayersOptions = {
163
- /**
164
- * MSF: `fec.repairTrack` must name one of `descriptors` (a `fec-repair`
165
- * track), so a dangling pointer fails closed with `track_repair_track`.
166
- * hang: layer 0 lives outside `repair.renditions`, so leave this unset.
167
- */
168
- layerZeroMustBeDeclared?: boolean;
169
- };
170
- export declare function assembleRepairLayers(source: RepairSourceGeometry, descriptors: readonly RepairTrackDescriptor[], fail?: RepairContractFail, options?: AssembleRepairLayersOptions): RepairLayersResolution | undefined;
171
48
  //# sourceMappingURL=repair-layers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repair-layers.d.ts","sourceRoot":"","sources":["../src/repair-layers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"repair-layers.d.ts","sourceRoot":"","sources":["../src/repair-layers.ts"],"names":[],"mappings":"AASA,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,8DAA8D;AAC9D,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,2DAA2D;AAC3D,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,2FAA2F;AAC3F,eAAO,MAAM,0BAA0B,QAAQ,CAAC;AAChD,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAC3C,iEAAiE;AACjE,eAAO,MAAM,sBAAsB,WAAW,CAAC;AAC/C,4FAA4F;AAC5F,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD,iEAAiE;AACjE,MAAM,MAAM,iBAAiB,GAAG;IAC/B,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oFAAoF;AACpF,MAAM,MAAM,mBAAmB,GAAG;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC;IAClB,yDAAyD;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,aAAa,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACzC,iFAAiF;IACjF,8EAA8E;IAC9E,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACzC,iFAAiF;IACjF,sBAAsB,EAAE,MAAM,CAAC;CAC/B,CAAC"}
@@ -1,32 +1,3 @@
1
- // ../mmt-base/dist/mmtp.js
2
- var MPU_HEADER_SIZE = 8;
3
- var MPU_LENGTH_FIELD_SIZE = 2;
4
- var MPU_HEADER_REMAINDER_SIZE = MPU_HEADER_SIZE - MPU_LENGTH_FIELD_SIZE;
5
-
6
- // ../mmt-base/dist/ntp-short.js
7
- var NTP_SHORT_BITS = 32;
8
- var NTP_SHORT_MODULUS = 2 ** NTP_SHORT_BITS;
9
- var NTP_SHORT_HALF_RANGE = 2 ** (NTP_SHORT_BITS - 1);
10
-
11
- // ../mmt-base/dist/fec-block-profile.js
12
- var FEC_BLOCK_PROFILES = Object.freeze([
13
- "iso-ssbg1-v1"
14
- ]);
15
- function isFecBlockProfile(value) {
16
- return value === "iso-ssbg1-v1";
17
- }
18
- function parseFecBlockProfile(value, where) {
19
- if (isFecBlockProfile(value))
20
- return value;
21
- if (value === void 0) {
22
- throw new Error(`${where} is required: name the FEC block profile ("iso-ssbg1-v1")`);
23
- }
24
- throw new Error(`${where} must be "iso-ssbg1-v1" (got ${JSON.stringify(value)})`);
25
- }
26
-
27
- // ../mmt-base/dist/catalog-fec-source.js
28
- var ALL_ROLES = Object.freeze(["video", "audio"]);
29
-
30
1
  // src/repair-layers.ts
31
2
  var REPAIR_PRIORITY_MIN = 192;
32
3
  var REPAIR_PRIORITY_MAX = 255;
@@ -35,312 +6,6 @@ var MAX_RAPTORQ_SOURCE_SYMBOLS = 56403;
35
6
  var MAX_REPAIR_SYMBOLS = 16777215;
36
7
  var MAX_ENCODING_SYMBOL_ID = 16777215;
37
8
  var MAX_REED_SOLOMON_BLOCK_SYMBOLS = 255;
38
- var RepairContractError = class extends Error {
39
- constructor(code, path, message) {
40
- super(`[repair-layers:${code}] ${path}: ${message}`);
41
- this.code = code;
42
- this.path = path;
43
- this.name = "RepairContractError";
44
- }
45
- };
46
- var throwRepairContractError = (code, path, message) => {
47
- throw new RepairContractError(code, path, message);
48
- };
49
- function readFecBlockProfile(value, path, declaresFecInstance, fail) {
50
- if (value === void 0 && !declaresFecInstance) return void 0;
51
- if (isFecBlockProfile(value)) return value;
52
- if (typeof value === "string" && value.length > 0) {
53
- return fail(
54
- "track_fec_block_profile_unimplemented",
55
- path,
56
- `${JSON.stringify(value)} is not an implemented FEC block profile; only "iso-ssbg1-v1" is implemented`
57
- );
58
- }
59
- try {
60
- return parseFecBlockProfile(value, "blockProfile");
61
- } catch (error) {
62
- return fail("track_fec_block_profile", path, error.message);
63
- }
64
- }
65
- var REPAIR_FIELDS = ["depends", "repairLayer", "repairSymbols", "priority", "scope", "sourceSymbols"];
66
- var REPAIR_TRACK_GEOMETRY_KEYS = [
67
- "mmtpMode",
68
- "timescale",
69
- "groupDurationMs",
70
- "groupDurationTicks",
71
- "keyframeIntervalMs",
72
- "keyframeIntervalTicks",
73
- "fec",
74
- "symbolSize",
75
- "interleaveDepthMs"
76
- ];
77
- var REPAIR_TRACK_ONLY_KEYS = ["repairLayer", "repairSymbols", "sourceSymbols", "scope"];
78
- function rejectRepairTrackGeometry(path, fields, fail) {
79
- for (const key of REPAIR_TRACK_GEOMETRY_KEYS) {
80
- if (fields[key] !== void 0) {
81
- fail(
82
- "track_repair_geometry",
83
- `${path}.${key}`,
84
- "a repair track carries no block geometry; it is shared with the source track's fec object"
85
- );
86
- }
87
- }
88
- }
89
- function repairReachability(fecObjects) {
90
- let declaresFecSource = false;
91
- const layerZeroNames = /* @__PURE__ */ new Set();
92
- for (const candidate of fecObjects) {
93
- if (typeof candidate !== "object" || candidate === null || Array.isArray(candidate)) continue;
94
- const fec = candidate;
95
- if (fec["algorithm"] === "none") continue;
96
- declaresFecSource = true;
97
- const repairTrack = fec["repairTrack"];
98
- if (typeof repairTrack === "string" && repairTrack.length > 0) layerZeroNames.add(repairTrack);
99
- }
100
- return { declaresFecSource, layerZeroNames };
101
- }
102
- function assertRepairTrackReachable(descriptor, reachability, fail) {
103
- if (dependsTarget(descriptor) !== void 0) return;
104
- if (reachability.declaresFecSource && !reachability.layerZeroNames.has(descriptor.name)) {
105
- fail(
106
- "track_repair_depends",
107
- `${descriptor.path}.depends`,
108
- "no source names this repair track in fec.repairTrack and it declares no depends"
109
- );
110
- }
111
- }
112
- function rejectRepairFieldsOnMediaTrack(path, fields, fail) {
113
- for (const key of REPAIR_TRACK_ONLY_KEYS) {
114
- if (fields[key] !== void 0) {
115
- fail("track_repair_layer", `${path}.${key}`, `${key} is a repair track field`);
116
- }
117
- }
118
- }
119
- function describeRepairTrack(name, path, fields) {
120
- const descriptor = { name, path };
121
- for (const field of REPAIR_FIELDS) {
122
- if (field in fields) descriptor[field] = fields[field];
123
- }
124
- return descriptor;
125
- }
126
- function isSafeInteger(value) {
127
- return typeof value === "number" && Number.isSafeInteger(value);
128
- }
129
- function positiveInteger(value) {
130
- return isSafeInteger(value) && value > 0;
131
- }
132
- function dependsTarget(descriptor) {
133
- const depends = descriptor.depends;
134
- return Array.isArray(depends) && depends.length === 1 && typeof depends[0] === "string" && depends[0].length > 0 ? depends[0] : void 0;
135
- }
136
- function validateRepairTrackFields(descriptor, fail) {
137
- const { path } = descriptor;
138
- if (descriptor.depends !== void 0 && dependsTarget(descriptor) === void 0) {
139
- fail("track_repair_depends", `${path}.depends`, "must name exactly one source track");
140
- }
141
- if (descriptor.repairLayer !== void 0 && (!isSafeInteger(descriptor.repairLayer) || descriptor.repairLayer < 0)) {
142
- fail("track_repair_layer", `${path}.repairLayer`, "must be a non-negative integer");
143
- }
144
- if (descriptor.repairSymbols !== void 0 && (!positiveInteger(descriptor.repairSymbols) || descriptor.repairSymbols > MAX_REPAIR_SYMBOLS)) {
145
- fail("track_repair_layer", `${path}.repairSymbols`, `must be a positive integer at most ${MAX_REPAIR_SYMBOLS}`);
146
- }
147
- if (descriptor.priority !== void 0 && (!isSafeInteger(descriptor.priority) || descriptor.priority < REPAIR_PRIORITY_MIN || descriptor.priority > REPAIR_PRIORITY_MAX)) {
148
- fail(
149
- "track_repair_priority",
150
- `${path}.priority`,
151
- `must be an integer from ${REPAIR_PRIORITY_MIN} to ${REPAIR_PRIORITY_MAX} (MoQT scale, lower first)`
152
- );
153
- }
154
- if (descriptor.scope !== void 0) {
155
- if (descriptor.scope !== "keyframe") {
156
- fail("track_repair_overlay", `${path}.scope`, 'must be "keyframe"');
157
- }
158
- if (descriptor.repairLayer !== void 0) {
159
- fail("track_repair_overlay", `${path}.repairLayer`, "an overlay is a separate FEC instance and carries no repairLayer");
160
- }
161
- for (const field of ["depends", "sourceSymbols", "repairSymbols", "priority"]) {
162
- if (descriptor[field] === void 0) {
163
- fail("track_repair_overlay", `${path}.${field}`, `an overlay must declare ${field}`);
164
- }
165
- }
166
- }
167
- if (descriptor.sourceSymbols !== void 0) {
168
- if (descriptor.scope === void 0) {
169
- fail("track_repair_overlay", `${path}.sourceSymbols`, "only an overlay (scope: keyframe) declares its own sourceSymbols");
170
- }
171
- if (!positiveInteger(descriptor.sourceSymbols) || descriptor.sourceSymbols > MAX_RAPTORQ_SOURCE_SYMBOLS) {
172
- fail(
173
- "track_fec_bounds",
174
- `${path}.sourceSymbols`,
175
- `must be a positive integer at most ${MAX_RAPTORQ_SOURCE_SYMBOLS} (RFC 6330 source block limit)`
176
- );
177
- }
178
- }
179
- if (isSafeInteger(descriptor.repairLayer) && descriptor.repairLayer >= 1) {
180
- for (const field of ["depends", "repairSymbols", "priority"]) {
181
- if (descriptor[field] === void 0) {
182
- fail("track_repair_layer", `${path}.${field}`, `repair layer ${descriptor.repairLayer} must declare ${field}`);
183
- }
184
- }
185
- }
186
- }
187
- function assembleRepairLayers(source, descriptors, fail = throwRepairContractError, options = {}) {
188
- const layerZeroName = typeof source.repairTrack === "string" && source.repairTrack.length > 0 ? source.repairTrack : void 0;
189
- const layerZero = layerZeroName === void 0 ? void 0 : descriptors.find((d) => d.name === layerZeroName);
190
- if (layerZeroName !== void 0 && layerZero === void 0 && options.layerZeroMustBeDeclared) {
191
- fail("track_repair_track", `${source.path}.repairTrack`, `unknown FEC repair track ${JSON.stringify(layerZeroName)}`);
192
- }
193
- const dependents = descriptors.filter((d) => d.name !== layerZeroName && dependsTarget(d) === source.name);
194
- const k = positiveInteger(source.sourceSymbols) ? source.sourceSymbols : 0;
195
- if (source.algorithm === "raptorq" && k > MAX_RAPTORQ_SOURCE_SYMBOLS) {
196
- fail(
197
- "track_fec_bounds",
198
- `${source.path}.sourceSymbols`,
199
- `must be at most ${MAX_RAPTORQ_SOURCE_SYMBOLS} (RFC 6330 source block limit)`
200
- );
201
- }
202
- if (layerZeroName === void 0) {
203
- if (dependents.length === 0) return void 0;
204
- fail(
205
- "track_repair_layer",
206
- `${dependents[0].path}.depends`,
207
- `repair layers of ${JSON.stringify(source.name)} require a layer 0 (fec.repairTrack) on the source`
208
- );
209
- }
210
- const layered = dependents.length > 0;
211
- let layerZeroSymbols = 0;
212
- if (positiveInteger(source.repairSymbols)) {
213
- layerZeroSymbols = source.repairSymbols;
214
- } else if (layered) {
215
- fail("track_fec", `${source.path}.repairSymbols`, "layered or overlay repair needs a positive integer repairSymbols on layer 0");
216
- }
217
- if (layered && !positiveInteger(source.sourceSymbols)) {
218
- fail("track_fec", `${source.path}.sourceSymbols`, "layered or overlay repair needs a positive integer sourceSymbols on the source");
219
- }
220
- const reedSolomon = source.algorithm === "reed-solomon";
221
- if (layered && source.algorithm !== "raptorq" && !reedSolomon) {
222
- fail(
223
- "track_fec",
224
- `${source.path}.algorithm`,
225
- "repair layers and overlays are defined only for raptorq and reed-solomon (draft-ramadan-moq-fec-01 6.3.4 rule 7)"
226
- );
227
- }
228
- let layerZeroPriority = DEFAULT_REPAIR_PRIORITY;
229
- if (layerZero !== void 0) {
230
- if (layerZero.depends !== void 0 && dependsTarget(layerZero) !== source.name) {
231
- fail(
232
- "track_repair_depends",
233
- `${layerZero.path}.depends`,
234
- `layer 0 of ${JSON.stringify(source.name)} must depend on that source`
235
- );
236
- }
237
- if (layerZero.repairLayer !== void 0 && layerZero.repairLayer !== 0) {
238
- fail("track_repair_layer", `${layerZero.path}.repairLayer`, "the track named by fec.repairTrack is layer 0");
239
- }
240
- if (layerZero.scope !== void 0) {
241
- fail("track_repair_overlay", `${layerZero.path}.scope`, "the track named by fec.repairTrack is base layer 0, not an overlay");
242
- }
243
- if (layerZero.repairSymbols !== void 0 && layerZero.repairSymbols !== layerZeroSymbols) {
244
- fail(
245
- "track_repair_layer",
246
- `${layerZero.path}.repairSymbols`,
247
- `must agree with the source's fec.repairSymbols (${layerZeroSymbols})`
248
- );
249
- }
250
- if (typeof layerZero.priority === "number") layerZeroPriority = layerZero.priority;
251
- }
252
- const baseLayers = [
253
- { layer: 0, repairTrackName: layerZeroName, repairSymbols: layerZeroSymbols, rsIdOffset: 0, priority: layerZeroPriority }
254
- ];
255
- const overlays = [];
256
- for (const d of dependents) {
257
- if (d.scope === void 0 && d.repairLayer === void 0) {
258
- fail(
259
- "track_repair_layer",
260
- `${d.path}.repairLayer`,
261
- `a repair track that depends on ${JSON.stringify(source.name)} must declare repairLayer (1..n) or scope: "keyframe"`
262
- );
263
- }
264
- }
265
- const layerTracks = dependents.filter((d) => d.scope === void 0).sort((a, b) => a.repairLayer - b.repairLayer);
266
- for (const d of dependents) {
267
- if (d.scope !== "keyframe") continue;
268
- if (overlays.length === 1) {
269
- fail(
270
- "track_repair_overlay",
271
- `${d.path}.scope`,
272
- `${JSON.stringify(source.name)} already has keyframe overlay ${JSON.stringify(overlays[0].repairTrackName)}: a RAP packet carries exactly two Source FEC Payload IDs (base, then overlay), so one overlay per source`
273
- );
274
- }
275
- const sourceSymbols = d.sourceSymbols;
276
- const repairSymbols = d.repairSymbols;
277
- if (sourceSymbols + repairSymbols - 1 > MAX_ENCODING_SYMBOL_ID) {
278
- fail(
279
- "track_fec_bounds",
280
- `${d.path}.repairSymbols`,
281
- `overlay sourceSymbols + repairSymbols - 1 exceeds the 24-bit ESI space (${MAX_ENCODING_SYMBOL_ID})`
282
- );
283
- }
284
- if (reedSolomon && sourceSymbols + repairSymbols > MAX_REED_SOLOMON_BLOCK_SYMBOLS) {
285
- fail(
286
- "track_fec_bounds",
287
- `${d.path}.repairSymbols`,
288
- `reed-solomon overlay sourceSymbols + repairSymbols exceeds ${MAX_REED_SOLOMON_BLOCK_SYMBOLS} (draft-ramadan-moq-fec-01 6.3.4 rule 12)`
289
- );
290
- }
291
- overlays.push({ repairTrackName: d.name, scope: "keyframe", sourceSymbols, repairSymbols, priority: d.priority });
292
- }
293
- let offset = layerZeroSymbols;
294
- let previousPriority = layerZeroPriority;
295
- layerTracks.forEach((d, i) => {
296
- const expected = i + 1;
297
- if (d.repairLayer === 0) {
298
- fail("track_repair_layer", `${d.path}.repairLayer`, `layer 0 of ${JSON.stringify(source.name)} is ${JSON.stringify(layerZeroName)}, named by fec.repairTrack`);
299
- }
300
- if (d.repairLayer !== expected) {
301
- fail(
302
- "track_repair_layer",
303
- `${d.path}.repairLayer`,
304
- i > 0 && d.repairLayer === layerTracks[i - 1].repairLayer ? `repair layer ${d.repairLayer} is declared twice for ${JSON.stringify(source.name)}` : `repair layers must be contiguous from 1: expected ${expected}, found ${d.repairLayer}`
305
- );
306
- }
307
- const priority = d.priority;
308
- if (priority < previousPriority) {
309
- fail(
310
- "track_repair_priority",
311
- `${d.path}.priority`,
312
- `must be at least ${previousPriority}, the priority of layer ${expected - 1}: priority is monotonic non-decreasing with layer index`
313
- );
314
- }
315
- previousPriority = priority;
316
- const repairSymbols = d.repairSymbols;
317
- baseLayers.push({ layer: expected, repairTrackName: d.name, repairSymbols, rsIdOffset: offset, priority });
318
- offset += repairSymbols;
319
- });
320
- const totalBaseRepairSymbols = offset;
321
- if (totalBaseRepairSymbols > MAX_REPAIR_SYMBOLS) {
322
- fail(
323
- "track_fec_bounds",
324
- `${layerTracks.length === 0 ? source.path : layerTracks[layerTracks.length - 1].path}.repairSymbols`,
325
- `total repair symbols across base layers exceeds the 24-bit RS_ID space (${MAX_REPAIR_SYMBOLS})`
326
- );
327
- }
328
- if (k + totalBaseRepairSymbols - 1 > MAX_ENCODING_SYMBOL_ID) {
329
- fail(
330
- "track_fec_bounds",
331
- `${source.path}.sourceSymbols`,
332
- `sourceSymbols + total base repair symbols - 1 exceeds the 24-bit ESI space (${MAX_ENCODING_SYMBOL_ID})`
333
- );
334
- }
335
- if (reedSolomon && k + totalBaseRepairSymbols > MAX_REED_SOLOMON_BLOCK_SYMBOLS) {
336
- fail(
337
- "track_fec_bounds",
338
- `${source.path}.sourceSymbols`,
339
- `reed-solomon sourceSymbols + total base repair symbols exceeds ${MAX_REED_SOLOMON_BLOCK_SYMBOLS} (draft-ramadan-moq-fec-01 6.3.4 rule 12)`
340
- );
341
- }
342
- return { sourceTrackName: source.name, baseLayers, overlays, totalBaseRepairSymbols };
343
- }
344
9
  export {
345
10
  DEFAULT_REPAIR_PRIORITY,
346
11
  MAX_ENCODING_SYMBOL_ID,
@@ -348,19 +13,6 @@ export {
348
13
  MAX_REED_SOLOMON_BLOCK_SYMBOLS,
349
14
  MAX_REPAIR_SYMBOLS,
350
15
  REPAIR_PRIORITY_MAX,
351
- REPAIR_PRIORITY_MIN,
352
- REPAIR_TRACK_GEOMETRY_KEYS,
353
- REPAIR_TRACK_ONLY_KEYS,
354
- RepairContractError,
355
- assembleRepairLayers,
356
- assertRepairTrackReachable,
357
- dependsTarget,
358
- describeRepairTrack,
359
- readFecBlockProfile,
360
- rejectRepairFieldsOnMediaTrack,
361
- rejectRepairTrackGeometry,
362
- repairReachability,
363
- throwRepairContractError,
364
- validateRepairTrackFields
16
+ REPAIR_PRIORITY_MIN
365
17
  };
366
18
  //# sourceMappingURL=repair-layers.js.map