@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
@@ -117,6 +117,15 @@ export interface MulticastTransportStats {
117
117
  * `droppedPacketIds` slot.
118
118
  */
119
119
  packetsDroppedSignaling: number;
120
+ /**
121
+ * From a sender other than the one this join locked to (BLO-50098). An
122
+ * unprotected ASM subscription admits any source, so two senders can share
123
+ * one (G, port, packet_id); the first sender whose packet is accepted owns
124
+ * the sub-flow until the next join, and every other sender is dropped here,
125
+ * before any gap, duplicate or FEC ledger sees it. A join or a silence
126
+ * failback releases the lock.
127
+ */
128
+ packetsDroppedForeignSender: number;
120
129
  }
121
130
  /**
122
131
  * join() calls by how they resolved, cumulative for the life of the transport:
@@ -133,13 +142,23 @@ export interface MulticastJoinStats {
133
142
  }
134
143
  export declare class MulticastTransport<TPacketContext = never> {
135
144
  #private;
145
+ /**
146
+ * `lockedTo` reads the sender another transport is locked to (a repair
147
+ * group follows its media join, whose publisher sends both). While it reads
148
+ * a sender, this join admits only that one; until then its own lock applies.
149
+ */
136
150
  constructor(onPacket: (packet: Uint8Array, context?: TPacketContext) => void, options?: {
137
151
  gateway?: WindowMulticastGateway;
152
+ lockedTo?: () => string | undefined;
138
153
  });
139
154
  static isAvailable(): boolean;
140
155
  join(config: MulticastTransportConfig, context?: TPacketContext): Promise<boolean>;
141
- /** Feed a raw packet from an external source (e.g., AMT tunnel or ASM subscription). */
142
- feedPacket(data: ArrayBuffer | Uint8Array, context?: TPacketContext): void;
156
+ /**
157
+ * Feed a raw packet from an external source (e.g., AMT tunnel or ASM
158
+ * subscription). `sourceAddress` is the datagram's sender when the source
159
+ * knows it; see packetsDroppedForeignSender.
160
+ */
161
+ feedPacket(data: ArrayBuffer | Uint8Array, context?: TPacketContext, sourceAddress?: string): void;
143
162
  confirmVideo(): void;
144
163
  confirmAudio(): void;
145
164
  onTakeover(cb: () => void): void;
@@ -229,6 +248,8 @@ export declare class MulticastTransport<TPacketContext = never> {
229
248
  * cumulative across rejoins.
230
249
  */
231
250
  get withdrawnPacketIdDrops(): number;
251
+ /** The sender this join is locked to; undefined until one is known. */
252
+ get sender(): string | undefined;
232
253
  /** Whether a subscription is live: joined, and not yet released or replaced. */
233
254
  get joined(): boolean;
234
255
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"multicast-transport.d.ts","sourceRoot":"","sources":["../src/multicast-transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"multicast-transport.d.ts","sourceRoot":"","sources":["../src/multicast-transport.ts"],"names":[],"mappings":"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"}
@@ -241,8 +241,12 @@ var FEC_BLOCK_PROFILES = Object.freeze([
241
241
  "iso-ssbg1-v1"
242
242
  ]);
243
243
 
244
- // node_modules/@blockcast/mmt-base/dist/catalog-fec-source.js
245
- var ALL_ROLES = Object.freeze(["video", "audio"]);
244
+ // node_modules/@blockcast/mmt-base/dist/fec-bindings.js
245
+ var RUNTIME_FEC_RECEIVER = Object.freeze({
246
+ schemes: Object.freeze(["raptorq", "reed-solomon"]),
247
+ blockProfiles: Object.freeze(["iso-ssbg1-v1"]),
248
+ overlays: true
249
+ });
246
250
 
247
251
  // node_modules/@blockcast/mmt-transport/dist/multicast-orchestrator.js
248
252
  var DEFAULT_DWELL_MS = 3e3;
@@ -1433,8 +1437,12 @@ var FEC_BLOCK_PROFILES2 = Object.freeze([
1433
1437
  "iso-ssbg1-v1"
1434
1438
  ]);
1435
1439
 
1436
- // ../mmt-base/dist/catalog-fec-source.js
1437
- var ALL_ROLES2 = Object.freeze(["video", "audio"]);
1440
+ // ../mmt-base/dist/fec-bindings.js
1441
+ var RUNTIME_FEC_RECEIVER2 = Object.freeze({
1442
+ schemes: Object.freeze(["raptorq", "reed-solomon"]),
1443
+ blockProfiles: Object.freeze(["iso-ssbg1-v1"]),
1444
+ overlays: true
1445
+ });
1438
1446
 
1439
1447
  // src/multicast-transport.ts
1440
1448
  var JOIN_SUCCEEDED = Object.freeze({ ok: true });
@@ -1461,6 +1469,10 @@ function getMulticastGlobals() {
1461
1469
  function hasMulticastGateway() {
1462
1470
  return typeof getMulticastGlobals().multicast?.subscribe === "function";
1463
1471
  }
1472
+ function senderOf(event) {
1473
+ const sourceAddress = event.sourceAddress;
1474
+ return typeof sourceAddress === "string" ? sourceAddress : void 0;
1475
+ }
1464
1476
  function normalizeBytesEventDetail(detail) {
1465
1477
  const value = detail && typeof detail === "object" && "data" in detail ? detail.data : detail;
1466
1478
  if (value instanceof Uint8Array) return value;
@@ -1507,7 +1519,8 @@ var MulticastTransport = class {
1507
1519
  bytesReceived: 0,
1508
1520
  packetsDroppedUnregisteredPid: 0,
1509
1521
  packetsDroppedUnparseable: 0,
1510
- packetsDroppedSignaling: 0
1522
+ packetsDroppedSignaling: 0,
1523
+ packetsDroppedForeignSender: 0
1511
1524
  };
1512
1525
  // join() calls by how they resolved; see joinStats.
1513
1526
  #joinsSucceeded = 0;
@@ -1532,6 +1545,11 @@ var MulticastTransport = class {
1532
1545
  // per packet once a count outgrows the small-integer range.
1533
1546
  #acceptedBytesByPacketId = /* @__PURE__ */ new Map();
1534
1547
  #packetIds = null;
1548
+ // The sender S this join's accepted packets came from, once known; see
1549
+ // packetsDroppedForeignSender. Cleared by every join and by a silence
1550
+ // failback, so a replacement publisher is not locked out.
1551
+ #sender = void 0;
1552
+ #lockedTo;
1535
1553
  // What the live join delivers with each accepted packet. A field, not a
1536
1554
  // listener closure, so an in-place admission change (setContext) applies
1537
1555
  // from the next packet on without rejoining.
@@ -1553,9 +1571,15 @@ var MulticastTransport = class {
1553
1571
  #joinGeneration = 0;
1554
1572
  // The provider to subscribe through; window.multicast when unset.
1555
1573
  #gateway;
1574
+ /**
1575
+ * `lockedTo` reads the sender another transport is locked to (a repair
1576
+ * group follows its media join, whose publisher sends both). While it reads
1577
+ * a sender, this join admits only that one; until then its own lock applies.
1578
+ */
1556
1579
  constructor(onPacket, options = {}) {
1557
1580
  this.#onPacket = onPacket;
1558
1581
  this.#gateway = options.gateway;
1582
+ this.#lockedTo = options.lockedTo;
1559
1583
  }
1560
1584
  static isAvailable() {
1561
1585
  return hasMulticastGateway();
@@ -1564,6 +1588,7 @@ var MulticastTransport = class {
1564
1588
  const generation = ++this.#joinGeneration;
1565
1589
  this.#releaseSubscription();
1566
1590
  this.#dataPlaneLive = false;
1591
+ this.#sender = void 0;
1567
1592
  if (this.#disposed) return this.#declined(generation, "disposed");
1568
1593
  const gateway = this.#gateway ?? getMulticastGlobals().multicast;
1569
1594
  if (typeof gateway?.subscribe !== "function") {
@@ -1605,7 +1630,8 @@ var MulticastTransport = class {
1605
1630
  }
1606
1631
  this.#subscription = subscription;
1607
1632
  const live = () => !this.#disposed && generation === this.#joinGeneration;
1608
- const packetListener = subscriptionDeliversPacketBatches(subscription) ? {
1633
+ const anySource = !config.sourceAddress && !config.senderAddress && !config.atsc3;
1634
+ const packetListener = !anySource && subscriptionDeliversPacketBatches(subscription) ? {
1609
1635
  type: "packets",
1610
1636
  listener: (event) => {
1611
1637
  if (!live()) return;
@@ -1615,7 +1641,7 @@ var MulticastTransport = class {
1615
1641
  type: "bytes",
1616
1642
  listener: (event) => {
1617
1643
  if (!live()) return;
1618
- if (this.#deliver(event.detail)) this.#resetWatchdog();
1644
+ if (this.#deliver(event.detail, senderOf(event))) this.#resetWatchdog();
1619
1645
  }
1620
1646
  };
1621
1647
  this.#packetListener = packetListener;
@@ -1706,13 +1732,13 @@ var MulticastTransport = class {
1706
1732
  * One packet from the subscription: filter, count, and hand it to the
1707
1733
  * callback. Returns whether it was delivered; the caller notes liveness.
1708
1734
  */
1709
- #deliver(detail) {
1735
+ #deliver(detail, sourceAddress) {
1710
1736
  const packet = normalizeBytesEventDetail(detail);
1711
1737
  if (!packet) {
1712
1738
  this.#stats.packetsDroppedUnparseable++;
1713
1739
  return false;
1714
1740
  }
1715
- if (!this.#acceptPacket(packet)) return false;
1741
+ if (!this.#acceptPacket(packet, sourceAddress)) return false;
1716
1742
  this.#onPacket(packet, this.#context);
1717
1743
  return true;
1718
1744
  }
@@ -1753,11 +1779,15 @@ var MulticastTransport = class {
1753
1779
  throw failures[0];
1754
1780
  }
1755
1781
  }
1756
- /** Feed a raw packet from an external source (e.g., AMT tunnel or ASM subscription). */
1757
- feedPacket(data, context) {
1782
+ /**
1783
+ * Feed a raw packet from an external source (e.g., AMT tunnel or ASM
1784
+ * subscription). `sourceAddress` is the datagram's sender when the source
1785
+ * knows it; see packetsDroppedForeignSender.
1786
+ */
1787
+ feedPacket(data, context, sourceAddress) {
1758
1788
  if (this.#disposed) return;
1759
1789
  const packet = data instanceof Uint8Array ? data : new Uint8Array(data);
1760
- if (!this.#acceptPacket(packet)) return;
1790
+ if (!this.#acceptPacket(packet, sourceAddress)) return;
1761
1791
  this.#onPacket(packet, context);
1762
1792
  this.#resetWatchdog();
1763
1793
  }
@@ -1907,6 +1937,10 @@ var MulticastTransport = class {
1907
1937
  get withdrawnPacketIdDrops() {
1908
1938
  return this.#withdrawnPacketIdDrops;
1909
1939
  }
1940
+ /** The sender this join is locked to; undefined until one is known. */
1941
+ get sender() {
1942
+ return this.#sender;
1943
+ }
1910
1944
  /** Whether a subscription is live: joined, and not yet released or replaced. */
1911
1945
  get joined() {
1912
1946
  return this.#subscription !== null;
@@ -2069,11 +2103,16 @@ var MulticastTransport = class {
2069
2103
  this.#withdrawnPacketIds.clear();
2070
2104
  }
2071
2105
  /** The ingress filter; an accepted packet is counted here, once. */
2072
- #acceptPacket(packet) {
2106
+ #acceptPacket(packet, sourceAddress) {
2107
+ const owner = this.#lockedTo?.() ?? this.#sender;
2108
+ if (sourceAddress !== void 0 && owner !== void 0 && sourceAddress !== owner) {
2109
+ this.#stats.packetsDroppedForeignSender++;
2110
+ return false;
2111
+ }
2073
2112
  const packetId = readMMTPPacketId(packet);
2074
2113
  if (packetId === null) {
2075
2114
  if (!this.#packetIds) {
2076
- this.#countAccepted(packet, null);
2115
+ this.#countAccepted(packet, null, sourceAddress);
2077
2116
  return true;
2078
2117
  }
2079
2118
  this.#stats.packetsDroppedUnparseable++;
@@ -2084,14 +2123,15 @@ var MulticastTransport = class {
2084
2123
  return false;
2085
2124
  }
2086
2125
  if (!this.#packetIds || this.#packetIds.has(packetId)) {
2087
- this.#countAccepted(packet, packetId);
2126
+ this.#countAccepted(packet, packetId, sourceAddress);
2088
2127
  return true;
2089
2128
  }
2090
2129
  this.#recordUnregisteredPidDrop(packetId);
2091
2130
  return false;
2092
2131
  }
2093
2132
  /** Receive counters for one accepted packet; `packetId` is null when it has none. */
2094
- #countAccepted(packet, packetId) {
2133
+ #countAccepted(packet, packetId, sourceAddress) {
2134
+ this.#sender ??= sourceAddress;
2095
2135
  this.#stats.packetsReceived++;
2096
2136
  this.#stats.bytesReceived += packet.byteLength;
2097
2137
  if (packetId === null) return;
@@ -2162,6 +2202,7 @@ var MulticastTransport = class {
2162
2202
  console.warn(
2163
2203
  `[MulticastTransport] No packets for ${this.#failbackWindowMs}ms; failing back to MoQ`
2164
2204
  );
2205
+ this.#sender = void 0;
2165
2206
  this.#onFailback({ kind: "silence", windowMs: this.#failbackWindowMs });
2166
2207
  }, delayMs);
2167
2208
  }