@blockcast/mmt-container 2.1.0 → 2.2.0-main.0f6aad7bb803

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 (62) hide show
  1. package/dist/browser-runtime.js +458 -77
  2. package/dist/browser-runtime.js.map +4 -4
  3. package/dist/carp-catalog.js.map +1 -1
  4. package/dist/catalog-fec-params.js.map +1 -1
  5. package/dist/catalog-network-source.js.map +1 -1
  6. package/dist/cmcd-producer.d.ts +5 -0
  7. package/dist/cmcd-producer.d.ts.map +1 -1
  8. package/dist/cmcd-producer.js.map +2 -2
  9. package/dist/delivery-catalog.js.map +1 -1
  10. package/dist/delta-fallback-config.js.map +1 -1
  11. package/dist/fec-manager.js.map +2 -2
  12. package/dist/fec-state.js.map +1 -1
  13. package/dist/fec-worker-setup.js.map +1 -1
  14. package/dist/held-layer-admission.js.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js.map +2 -2
  18. package/dist/iso-block-locator.js.map +1 -1
  19. package/dist/mfu-reassembler.js +12 -19
  20. package/dist/mfu-reassembler.js.map +2 -2
  21. package/dist/mmtp-container-parser.js +12 -19
  22. package/dist/mmtp-container-parser.js.map +2 -2
  23. package/dist/mmtp-container-parser.no-modules.js +133 -34
  24. package/dist/mmtp-container-parser.no-modules.js.map +3 -3
  25. package/dist/mmtp-decode-pipeline.js +12 -19
  26. package/dist/mmtp-decode-pipeline.js.map +2 -2
  27. package/dist/mmtp-fec-session.d.ts +41 -3
  28. package/dist/mmtp-fec-session.d.ts.map +1 -1
  29. package/dist/mmtp-fec-session.js +118 -13
  30. package/dist/mmtp-fec-session.js.map +3 -3
  31. package/dist/mmtp-router.d.ts +9 -1
  32. package/dist/mmtp-router.d.ts.map +1 -1
  33. package/dist/mmtp-router.js +1468 -33
  34. package/dist/mmtp-router.js.map +4 -4
  35. package/dist/multicast-auth-catalog.js.map +1 -1
  36. package/dist/multicast-input.js.map +1 -1
  37. package/dist/multicast-manager.d.ts +15 -2
  38. package/dist/multicast-manager.d.ts.map +1 -1
  39. package/dist/multicast-manager.js +15246 -14969
  40. package/dist/multicast-manager.js.map +4 -4
  41. package/dist/multicast-transport.d.ts +11 -3
  42. package/dist/multicast-transport.d.ts.map +1 -1
  43. package/dist/multicast-transport.js +255 -19
  44. package/dist/multicast-transport.js.map +4 -4
  45. package/dist/multicast-unwrap.js +12 -19
  46. package/dist/multicast-unwrap.js.map +2 -2
  47. package/dist/no-modules.js +130 -33
  48. package/dist/no-modules.js.map +3 -3
  49. package/dist/repair-fetch.js.map +1 -1
  50. package/dist/signaling.js.map +2 -2
  51. package/dist/timestamp-codec.js +12 -19
  52. package/dist/timestamp-codec.js.map +2 -2
  53. package/dist/wasm-mfu-reassembler.js.map +1 -1
  54. package/dist/wasm-mmtp-container-parser.js +12 -19
  55. package/dist/wasm-mmtp-container-parser.js.map +2 -2
  56. package/package.json +5 -5
  57. package/src/cmcd-producer.ts +5 -0
  58. package/src/index.ts +2 -0
  59. package/src/mmtp-fec-session.ts +115 -15
  60. package/src/mmtp-router.ts +81 -16
  61. package/src/multicast-manager.ts +26 -5
  62. package/src/multicast-transport.ts +44 -20
@@ -23,11 +23,20 @@
23
23
  * uses. A packet below B_0 at or after the anchor fails the session closed:
24
24
  * `stats.failClosed` reports why, and every later repair is refused.
25
25
  *
26
+ * Catalog-less (draft-ramadan-moq-mmt-02 8.3, 13.2): a receiver holding
27
+ * layer 0 under the AL-FEC message alone builds the session from the message's
28
+ * fec_flow entry (`alFecFlow`) instead. K, T, the code point and the repair
29
+ * packet_id come from that entry, and layer 0 is held at
30
+ * maximum_p_for_repair_flow, standing for O_0 + P_0, by the anchored clause of
31
+ * draft-ramadan-moq-fec-core-00 7.3.2 alone. A later version that raises the
32
+ * field raises the held total (updateAlFecFlow()); the message carries no
33
+ * millisecond budget, so the caller states the retention (fec-core-00 9.4).
34
+ *
26
35
  * Every repair packet that cannot be used is counted under the reason it was
27
36
  * refused, and every block ends under exactly one outcome, so a stream whose
28
37
  * FEC is doing nothing can be told apart from one with nothing to repair.
29
38
  */
30
- import { type FecBlockProfile } from '@blockcast/mmt-base';
39
+ import { type AlFecFlow, type FecBlockProfile } from '@blockcast/mmt-base';
31
40
  import { type FecFailClosedReason, type HeldLayerInput } from './held-layer-admission.js';
32
41
  export type { FecFailClosedReason, HeldLayerInput } from './held-layer-admission.js';
33
42
  /** The mmt-wasm `MmtFecDecoder` members the session drives. */
@@ -70,6 +79,23 @@ export interface MmtpFecSessionConfig {
70
79
  /** The layers the caller holds (fec-01 6.3.9). Absent: [0]. */
71
80
  heldLayers?: readonly number[];
72
81
  }
82
+ /**
83
+ * A catalog-less session: one fec_flow entry of the AL-FEC message
84
+ * (`parseAlFecMessage(...).flows[i]`), draft-ramadan-moq-mmt-02 8.3.
85
+ */
86
+ export interface MmtpFecSessionMessageConfig {
87
+ /** The source track's entry; it must pass `alFecRaptorQFlowConfig`. */
88
+ alFecFlow: AlFecFlow;
89
+ /**
90
+ * The decoder retention in blocks. The message carries no elapsed-time
91
+ * budget (mmt-02 7.5), so open-block state is bounded by local policy
92
+ * (fec-core-00 9.4); required, never defaulted.
93
+ */
94
+ retentionBlocks: number;
95
+ Decoder: MmtpFecSessionDecoderConstructor;
96
+ }
97
+ /** What updateAlFecFlow() did with a later version of the message. */
98
+ export type MmtpFecSessionMessageUpdate = 'raised' | 'unchanged' | 'refused';
73
99
  /**
74
100
  * The path a symbol arrived on: its MoQT subscription, or the multicast
75
101
  * group (native SSM or AMT) carrying the same asset. The caller states it;
@@ -147,7 +173,7 @@ export declare class MmtpFecSession {
147
173
  readonly algorithm: 'raptorq' | 'reed-solomon';
148
174
  readonly sourceSymbols: number;
149
175
  /** P_0 = B_0, the held total every repair packet is checked against. */
150
- readonly repairSymbols: number;
176
+ get repairSymbols(): number;
151
177
  readonly symbolSize: number;
152
178
  /** The decoder's retention, in blocks, derived from the catalog budget. */
153
179
  readonly retentionBlocks: number;
@@ -156,7 +182,19 @@ export declare class MmtpFecSession {
156
182
  * the scheme, the block profile, K, P_0 (`repairSymbols`), T,
157
183
  * `interleaveDepthMs` or `reorderToleranceMs`. None is defaulted.
158
184
  */
159
- constructor(config: MmtpFecSessionConfig);
185
+ constructor(config: MmtpFecSessionConfig | MmtpFecSessionMessageConfig);
186
+ /**
187
+ * A later version of the AL-FEC message, catalog-less sessions only. A
188
+ * maximum_p_for_repair_flow above the held total raises it (`raised`): the
189
+ * anchored check restarts at the new total, so a block generated under the
190
+ * previous one stays valid before the first block carrying the new total
191
+ * (fec-core-00 7.3.2, mmt-02 8.3). A field at or below it changes nothing
192
+ * (`unchanged`): no publisher lowers it, and the check catches a wire that
193
+ * does. An entry with another asset, repair flow, code point, K or T, or
194
+ * one outside 8.3, is `refused`: that is a new source encoding, which needs
195
+ * a new session. A latched fail-closed stays latched either way.
196
+ */
197
+ updateAlFecFlow(flow: AlFecFlow): MmtpFecSessionMessageUpdate;
160
198
  /** True once release() ran. */
161
199
  get released(): boolean;
162
200
  get stats(): MmtpFecSessionStats;
@@ -1 +1 @@
1
- {"version":3,"file":"mmtp-fec-session.d.ts","sourceRoot":"","sources":["../src/mmtp-fec-session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mmtp-fec-session.d.ts","sourceRoot":"","sources":["../src/mmtp-fec-session.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,9 @@ var MPU_HEADER_SIZE = 8;
4
4
  var MPU_LENGTH_FIELD_SIZE = 2;
5
5
  var MPU_HEADER_REMAINDER_SIZE = MPU_HEADER_SIZE - MPU_LENGTH_FIELD_SIZE;
6
6
  var PACKET_TYPE_REPAIR = 3;
7
+ var MMTP_SIGNALING_PACKET_ID = 0;
8
+ var FEC_CODE_REED_SOLOMON = 1;
9
+ var FEC_CODE_RAPTORQ = 3;
7
10
  function parseMMTPHeader(buffer) {
8
11
  if (buffer.length < MMTP_HEADER_SIZE) {
9
12
  throw new Error(`MMTP packet too small: ${buffer.length} bytes`);
@@ -128,6 +131,50 @@ var NTP_SHORT_BITS = 32;
128
131
  var NTP_SHORT_MODULUS = 2 ** NTP_SHORT_BITS;
129
132
  var NTP_SHORT_HALF_RANGE = 2 ** (NTP_SHORT_BITS - 1);
130
133
 
134
+ // ../mmt-base/dist/signalling.js
135
+ var FEC_CODING_STRUCTURE_ONE_STAGE = 1;
136
+ var SSBG_MODE_1 = 1;
137
+ var RAPTORQ_MAX_SOURCE_SYMBOLS = 56403;
138
+ var REPAIR_SYMBOL_ID_MAX = 16777215;
139
+ var MIN_REPAIR_SYMBOL_SIZE = 14;
140
+ var REED_SOLOMON_MAX_BLOCK = 255;
141
+ function alFecRaptorQFlowConfig(flow) {
142
+ if (flow.fecCodingStructure !== FEC_CODING_STRUCTURE_ONE_STAGE || flow.repairFlows.length !== 1)
143
+ return null;
144
+ if (flow.ssbgMode !== SSBG_MODE_1 || flow.ffsrptsFlag !== 0 || flow.fecPayloadIdMode !== 0)
145
+ return null;
146
+ if (flow.packetIds.length !== 1)
147
+ return null;
148
+ const repair = flow.repairFlows[0];
149
+ const { fecCodeId, maximumK: k, maximumP: p } = repair;
150
+ const t = flow.repairSymbolSize;
151
+ if (t < MIN_REPAIR_SYMBOL_SIZE || k < 1 || p < 1 || k + p - 1 > REPAIR_SYMBOL_ID_MAX)
152
+ return null;
153
+ if (fecCodeId === FEC_CODE_RAPTORQ) {
154
+ if (t % 8 !== 0 || k > RAPTORQ_MAX_SOURCE_SYMBOLS)
155
+ return null;
156
+ } else if (fecCodeId === FEC_CODE_REED_SOLOMON) {
157
+ if (k + p > REED_SOLOMON_MAX_BLOCK)
158
+ return null;
159
+ } else {
160
+ return null;
161
+ }
162
+ if (repair.repairFlowId === MMTP_SIGNALING_PACKET_ID || repair.repairFlowId === flow.packetIds[0])
163
+ return null;
164
+ return {
165
+ sourcePacketIds: [...flow.packetIds],
166
+ repairFlowId: repair.repairFlowId,
167
+ fecCodeId,
168
+ ssbgMode: flow.ssbgMode,
169
+ fecPayloadIdMode: flow.fecPayloadIdMode,
170
+ repairSymbolSize: t,
171
+ maximumK: k,
172
+ maximumP: p,
173
+ protectionWindowTime: repair.protectionWindowTime,
174
+ protectionWindowSize: repair.protectionWindowSize
175
+ };
176
+ }
177
+
131
178
  // ../mmt-base/dist/serial-number.js
132
179
  var SERIAL32_SPAN = 4294967296;
133
180
  var SERIAL32_HALF = 2147483648;
@@ -304,7 +351,14 @@ var HeldLayerAdmission = class {
304
351
  var PATH_BITS = { moq: 1, multicast: 2 };
305
352
  var MIXED_PATHS = PATH_BITS.moq | PATH_BITS.multicast;
306
353
  var MmtpFecSession = class {
354
+ /** P_0 = B_0, the held total every repair packet is checked against. */
355
+ get repairSymbols() {
356
+ return this.#repairSymbols;
357
+ }
307
358
  #decoder;
359
+ #repairSymbols;
360
+ /** The message entry a catalog-less session was built from; undefined under a catalog. */
361
+ #message;
308
362
  /** Blocks a repair has defined and that are not settled yet, by SS_Start. */
309
363
  #blocks = /* @__PURE__ */ new Map();
310
364
  /** SS_Starts of settled blocks, so a later repair for one is refused. */
@@ -342,6 +396,24 @@ var MmtpFecSession = class {
342
396
  * `interleaveDepthMs` or `reorderToleranceMs`. None is defaulted.
343
397
  */
344
398
  constructor(config) {
399
+ if (config && "alFecFlow" in config) {
400
+ const message = alFecRaptorQFlowConfig(config.alFecFlow);
401
+ if (!message) {
402
+ throw new Error("MmtpFecSession: the AL-FEC entry is outside draft-ramadan-moq-mmt-02 8.3 (iso-ssbg1-v1)");
403
+ }
404
+ this.#message = message;
405
+ this.blockProfile = parseFecBlockProfile("iso-ssbg1-v1", "alFecFlow");
406
+ this.algorithm = message.fecCodeId === FEC_CODE_RAPTORQ ? "raptorq" : "reed-solomon";
407
+ this.sourceSymbols = message.maximumK;
408
+ this.#repairSymbols = message.maximumP;
409
+ this.symbolSize = message.repairSymbolSize;
410
+ this.retentionBlocks = requirePositiveInteger(config.retentionBlocks, "retentionBlocks");
411
+ this.#repairPacketId = message.repairFlowId;
412
+ this.#heldLayers = layerZero(message.maximumP);
413
+ this.#anchorHorizon = heldLayerAnchorHorizon(this.retentionBlocks, this.sourceSymbols);
414
+ this.#decoder = buildDecoder(config.Decoder, this);
415
+ return;
416
+ }
345
417
  const fec = config?.fec;
346
418
  if (!fec || typeof fec !== "object") {
347
419
  throw new Error("MmtpFecSession: the catalog fec instance is required");
@@ -352,7 +424,7 @@ var MmtpFecSession = class {
352
424
  }
353
425
  this.algorithm = fec.scheme;
354
426
  this.sourceSymbols = requirePositiveInteger(fec.sourceSymbols, "fec.sourceSymbols");
355
- this.repairSymbols = requirePositiveInteger(fec.repairSymbols, "fec.repairSymbols");
427
+ this.#repairSymbols = requirePositiveInteger(fec.repairSymbols, "fec.repairSymbols");
356
428
  this.symbolSize = requirePositiveInteger(fec.symbolSize, "fec.symbolSize");
357
429
  const interleaveDepthMs = requireNumber(fec.interleaveDepthMs, "fec.interleaveDepthMs");
358
430
  const reorderToleranceMs = requireNumber(fec.reorderToleranceMs, "fec.reorderToleranceMs");
@@ -372,17 +444,30 @@ var MmtpFecSession = class {
372
444
  config.heldLayers
373
445
  );
374
446
  this.#anchorHorizon = heldLayerAnchorHorizon(this.retentionBlocks, this.sourceSymbols);
375
- if (typeof config.Decoder !== "function") {
376
- throw new Error("MmtpFecSession: a decoder constructor (wasm_bindgen.MmtFecDecoder) is required");
377
- }
378
- const decoder = new config.Decoder(this.retentionBlocks, this.blockProfile, this.algorithm);
379
- try {
380
- decoder.configure_params(this.sourceSymbols, this.symbolSize);
381
- } catch (error) {
382
- decoder.free();
383
- throw error;
447
+ this.#decoder = buildDecoder(config.Decoder, this);
448
+ }
449
+ /**
450
+ * A later version of the AL-FEC message, catalog-less sessions only. A
451
+ * maximum_p_for_repair_flow above the held total raises it (`raised`): the
452
+ * anchored check restarts at the new total, so a block generated under the
453
+ * previous one stays valid before the first block carrying the new total
454
+ * (fec-core-00 7.3.2, mmt-02 8.3). A field at or below it changes nothing
455
+ * (`unchanged`): no publisher lowers it, and the check catches a wire that
456
+ * does. An entry with another asset, repair flow, code point, K or T, or
457
+ * one outside 8.3, is `refused`: that is a new source encoding, which needs
458
+ * a new session. A latched fail-closed stays latched either way.
459
+ */
460
+ updateAlFecFlow(flow) {
461
+ const held = this.#message;
462
+ if (!held) throw new Error("MmtpFecSession: updateAlFecFlow() needs a session built from an AL-FEC entry");
463
+ const next = alFecRaptorQFlowConfig(flow);
464
+ if (!next || next.sourcePacketIds[0] !== held.sourcePacketIds[0] || next.repairFlowId !== held.repairFlowId || next.fecCodeId !== held.fecCodeId || next.maximumK !== held.maximumK || next.repairSymbolSize !== held.repairSymbolSize) {
465
+ return "refused";
384
466
  }
385
- this.#decoder = decoder;
467
+ if (next.maximumP <= this.#repairSymbols) return "unchanged";
468
+ this.#repairSymbols = next.maximumP;
469
+ this.#heldLayers = layerZero(next.maximumP);
470
+ return "raised";
386
471
  }
387
472
  /** True once release() ran. */
388
473
  get released() {
@@ -477,7 +562,7 @@ var MmtpFecSession = class {
477
562
  }
478
563
  if (admission.reject) {
479
564
  const verdict2 = this.#heldLayers.failsClosed(
480
- repairTrackName,
565
+ this.#trackFor(repairTrackName),
481
566
  frame.ssStart,
482
567
  frame.rsbLength,
483
568
  this.#anchorHorizon,
@@ -492,7 +577,7 @@ var MmtpFecSession = class {
492
577
  this.#repairPacketId ??= frame.packetId;
493
578
  if (frame.ssbLength > this.sourceSymbols) return this.#drop("repair:ssb-length");
494
579
  const verdict = this.#heldLayers.admit(
495
- repairTrackName,
580
+ this.#trackFor(repairTrackName),
496
581
  frame.ssStart,
497
582
  frame.rsbLength,
498
583
  this.#anchorHorizon,
@@ -551,6 +636,10 @@ var MmtpFecSession = class {
551
636
  decoder.free();
552
637
  return true;
553
638
  }
639
+ /** Catalog-less: layer 0 has no own-track clause (mmt-02 8.3), so no track name is judged. */
640
+ #trackFor(repairTrackName) {
641
+ return this.#message ? void 0 : repairTrackName;
642
+ }
554
643
  #drop(reason) {
555
644
  this.#stats.dropped[reason] = (this.#stats.dropped[reason] ?? 0) + 1;
556
645
  return [];
@@ -672,6 +761,22 @@ var MmtpFecSession = class {
672
761
  }
673
762
  }
674
763
  };
764
+ function layerZero(total) {
765
+ return new HeldLayerAdmission([{ layer: 0, repairTrackName: "", rsIdOffset: 0, repairSymbols: total }]);
766
+ }
767
+ function buildDecoder(Decoder, session) {
768
+ if (typeof Decoder !== "function") {
769
+ throw new Error("MmtpFecSession: a decoder constructor (wasm_bindgen.MmtFecDecoder) is required");
770
+ }
771
+ const decoder = new Decoder(session.retentionBlocks, session.blockProfile, session.algorithm);
772
+ try {
773
+ decoder.configure_params(session.sourceSymbols, session.symbolSize);
774
+ } catch (error) {
775
+ decoder.free();
776
+ throw error;
777
+ }
778
+ return decoder;
779
+ }
675
780
  function requirePositiveInteger(value, path) {
676
781
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
677
782
  throw new Error(`MmtpFecSession: ${path} must be a positive integer (got ${String(value)})`);