@blockcast/mmt-container 2.0.0-main.609e08d7e29f → 2.0.1-main.0f2de6af487b
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 +1 -1
- package/dist/browser-runtime.js +96 -10
- package/dist/browser-runtime.js.map +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +2 -2
- package/dist/mmtp-router.d.ts +26 -1
- package/dist/mmtp-router.d.ts.map +1 -1
- package/dist/mmtp-router.js +66 -1
- package/dist/mmtp-router.js.map +2 -2
- package/dist/multicast-manager.d.ts +4 -1
- package/dist/multicast-manager.d.ts.map +1 -1
- package/dist/multicast-manager.js +96 -10
- package/dist/multicast-manager.js.map +2 -2
- package/package.json +5 -5
- package/src/index.ts +1 -0
- package/src/mmtp-router.ts +80 -1
- package/src/multicast-manager.ts +52 -16
package/README.md
CHANGED
|
@@ -277,7 +277,7 @@ per-commit `0.1.0-main.<sha>` prerelease from `stamp-prerelease.mjs`), and a
|
|
|
277
277
|
> Superseded by BLO-40665. Every package is now bumped in lockstep by a `v*`
|
|
278
278
|
> tag and the sibling ranges move with it, so the objection above no longer
|
|
279
279
|
> applies -- it was an argument against bumping *one* package. The set is at
|
|
280
|
-
> `2.0.
|
|
280
|
+
> `2.0.1`; see `RELEASES.md`.
|
|
281
281
|
|
|
282
282
|
#### Track-role convention (Phase 14)
|
|
283
283
|
|
package/dist/browser-runtime.js
CHANGED
|
@@ -22647,6 +22647,14 @@ var MmtpRouter = class {
|
|
|
22647
22647
|
#packetIdRoles = /* @__PURE__ */ new Map();
|
|
22648
22648
|
/** Explicit catalog ownership for dedicated repair-track packet IDs. */
|
|
22649
22649
|
#repairOwnersByPacketId = /* @__PURE__ */ new Map();
|
|
22650
|
+
/** Keyframe-overlay repair PID → the source its FEC instance protects
|
|
22651
|
+
* (draft-ramadan-mmt-fec-02 7.4.1). Never an owner in
|
|
22652
|
+
* #repairOwnersByPacketId: the overlay is decoded as its own instance. */
|
|
22653
|
+
#overlayLegs = /* @__PURE__ */ new Map();
|
|
22654
|
+
/** Keyframe-overlay repair track names, which name a leg too: a catalog
|
|
22655
|
+
* may state no PID for it (learned at subscribe time). */
|
|
22656
|
+
#overlayRepairNames = /* @__PURE__ */ new Map();
|
|
22657
|
+
#overlayStats = { repairDropped: 0, ownerRefused: 0 };
|
|
22650
22658
|
/** Callback fired when a delta-track FEC block completes or fails. */
|
|
22651
22659
|
#onDeltaBlockCompleteCb = null;
|
|
22652
22660
|
// Debug counters
|
|
@@ -23165,13 +23173,53 @@ var MmtpRouter = class {
|
|
|
23165
23173
|
/** Replace catalog-derived repair ownership before a catalog reconfiguration. */
|
|
23166
23174
|
clearRepairPacketIdOwners() {
|
|
23167
23175
|
this.#repairOwnersByPacketId.clear();
|
|
23176
|
+
this.#overlayLegs.clear();
|
|
23177
|
+
this.#overlayRepairNames.clear();
|
|
23168
23178
|
}
|
|
23169
|
-
/** Bind one dedicated repair-track PID to its authoritative media PID.
|
|
23179
|
+
/** Bind one dedicated repair-track PID to its authoritative media PID. A
|
|
23180
|
+
* known keyframe-overlay PID is refused, and counted: its symbols belong to
|
|
23181
|
+
* the overlay instance, never to the source's base decoder (mmt-02 7.4.4). */
|
|
23170
23182
|
setRepairPacketIdOwner(repairPacketId, ownerPacketId) {
|
|
23183
|
+
if (this.#overlayLegs.has(repairPacketId)) {
|
|
23184
|
+
this.#overlayStats.ownerRefused++;
|
|
23185
|
+
return;
|
|
23186
|
+
}
|
|
23171
23187
|
const owners = this.#repairOwnersByPacketId.get(repairPacketId) ?? /* @__PURE__ */ new Set();
|
|
23172
23188
|
owners.add(ownerPacketId);
|
|
23173
23189
|
this.#repairOwnersByPacketId.set(repairPacketId, owners);
|
|
23174
23190
|
}
|
|
23191
|
+
/**
|
|
23192
|
+
* Record a keyframe-overlay repair leg (draft-ramadan-mmt-fec-02 7.4): its
|
|
23193
|
+
* PID, the source it protects, and its repair track name. Either one names
|
|
23194
|
+
* the leg, so a catalog that states no PID (learned at subscribe time) is
|
|
23195
|
+
* covered by the name. Overlay repair is then never resolved to a base
|
|
23196
|
+
* owner, on multicast or MoQ. Cleared with the catalog owners
|
|
23197
|
+
* (`clearRepairPacketIdOwners`).
|
|
23198
|
+
*/
|
|
23199
|
+
setKeyframeOverlayLeg(repairPacketId, leg) {
|
|
23200
|
+
if (leg.repairTrackName !== void 0) this.#overlayRepairNames.set(leg.repairTrackName, { ...leg });
|
|
23201
|
+
if (repairPacketId === void 0) return;
|
|
23202
|
+
this.#repairOwnersByPacketId.delete(repairPacketId);
|
|
23203
|
+
this.#overlayLegs.set(repairPacketId, { ...leg });
|
|
23204
|
+
}
|
|
23205
|
+
/** The keyframe-overlay leg registered on `repairPacketId`, if any. */
|
|
23206
|
+
keyframeOverlayLeg(repairPacketId) {
|
|
23207
|
+
return this.#overlayLegs.get(repairPacketId);
|
|
23208
|
+
}
|
|
23209
|
+
/** Overlay repair dropped for want of an overlay instance, and base-owner
|
|
23210
|
+
* registrations refused on an overlay PID. */
|
|
23211
|
+
get keyframeOverlayStats() {
|
|
23212
|
+
return { ...this.#overlayStats };
|
|
23213
|
+
}
|
|
23214
|
+
#isOverlayRepair(repairPacketId, repairTrackName) {
|
|
23215
|
+
return this.#overlayLegs.has(repairPacketId) || repairTrackName !== void 0 && this.#overlayRepairNames.has(repairTrackName);
|
|
23216
|
+
}
|
|
23217
|
+
/** Overlay repair has no decoder until the overlay instance lands
|
|
23218
|
+
* (BLO-52077 PR 2): drop it before any base owner, locator or decoder. */
|
|
23219
|
+
#dropOverlayRepair(repairPacketId) {
|
|
23220
|
+
this.#overlayStats.repairDropped++;
|
|
23221
|
+
debugRouter(`[MmtpRouter] Dropping keyframe-overlay repair pid=${repairPacketId}: no overlay instance`);
|
|
23222
|
+
}
|
|
23175
23223
|
/**
|
|
23176
23224
|
* Register callback fired when a delta-track FEC block completes or fails.
|
|
23177
23225
|
*
|
|
@@ -23595,6 +23643,10 @@ var MmtpRouter = class {
|
|
|
23595
23643
|
return;
|
|
23596
23644
|
}
|
|
23597
23645
|
const repairPacketId = header.packetId;
|
|
23646
|
+
if (this.#isOverlayRepair(repairPacketId, repairTrackName)) {
|
|
23647
|
+
this.#dropOverlayRepair(repairPacketId);
|
|
23648
|
+
return;
|
|
23649
|
+
}
|
|
23598
23650
|
const hintedOwner = ownerPacketIdHint != null && this.#classifyPacketId(ownerPacketIdHint) !== null ? ownerPacketIdHint : null;
|
|
23599
23651
|
const ownerPacketId = hintedOwner ?? (this.#classifyPacketId(repairPacketId) !== null ? repairPacketId : null);
|
|
23600
23652
|
if (ownerPacketId === null) {
|
|
@@ -23970,6 +24022,13 @@ var MmtpRouter = class {
|
|
|
23970
24022
|
this.#packetIdRoles.delete(packetId);
|
|
23971
24023
|
this.#catalogTrackNamesByPacketId.delete(packetId);
|
|
23972
24024
|
this.#repairOwnersByPacketId.delete(packetId);
|
|
24025
|
+
this.#overlayLegs.delete(packetId);
|
|
24026
|
+
for (const [repairPacketId, leg] of [...this.#overlayLegs]) {
|
|
24027
|
+
if (leg.sourcePacketId === packetId) this.#overlayLegs.delete(repairPacketId);
|
|
24028
|
+
}
|
|
24029
|
+
for (const [name, leg] of [...this.#overlayRepairNames]) {
|
|
24030
|
+
if (leg.sourcePacketId === packetId) this.#overlayRepairNames.delete(name);
|
|
24031
|
+
}
|
|
23973
24032
|
delete this.#pidCounts[packetId];
|
|
23974
24033
|
delete this.#repairPidCounts[packetId];
|
|
23975
24034
|
delete this.#moqRepairPidCounts[packetId];
|
|
@@ -24208,6 +24267,8 @@ var MmtpRouter = class {
|
|
|
24208
24267
|
this.#parserDiagnostics.clear();
|
|
24209
24268
|
this.#catalogTrackNamesByPacketId.clear();
|
|
24210
24269
|
this.#repairOwnersByPacketId.clear();
|
|
24270
|
+
this.#overlayLegs.clear();
|
|
24271
|
+
this.#overlayRepairNames.clear();
|
|
24211
24272
|
for (const { receiver } of this.#provenance.values()) receiver.release();
|
|
24212
24273
|
this.#provenance.clear();
|
|
24213
24274
|
this.#provenanceStreamFlow.clear();
|
|
@@ -24563,6 +24624,10 @@ var MmtpRouter = class {
|
|
|
24563
24624
|
}
|
|
24564
24625
|
}
|
|
24565
24626
|
if (info.isRepair) {
|
|
24627
|
+
if (this.#isOverlayRepair(info.packetId, catalogTrackNameForPacket(ingress, info.packetId))) {
|
|
24628
|
+
this.#dropOverlayRepair(info.packetId);
|
|
24629
|
+
return;
|
|
24630
|
+
}
|
|
24566
24631
|
const ownerPacketId = this.#resolveRepairOwnerPacketId(info.packetId, ingress);
|
|
24567
24632
|
if (ownerPacketId != null && this.#fecManager && hasAmbiguousCatalogTrackName(ingress, ownerPacketId)) return;
|
|
24568
24633
|
const repair = this.#readRepairObject(
|
|
@@ -27193,9 +27258,7 @@ function repairTrackNamesBySource(tracks) {
|
|
|
27193
27258
|
}
|
|
27194
27259
|
function boundRepairNames(binding) {
|
|
27195
27260
|
if (binding?.status !== "ok") return [];
|
|
27196
|
-
|
|
27197
|
-
if (binding.overlay) names.push(binding.overlay.repairTrackName);
|
|
27198
|
-
return names;
|
|
27261
|
+
return binding.layers.map((layer) => layer.repairTrackName);
|
|
27199
27262
|
}
|
|
27200
27263
|
var MulticastManager = class {
|
|
27201
27264
|
#fec;
|
|
@@ -27961,7 +28024,11 @@ var MulticastManager = class {
|
|
|
27961
28024
|
console.warn("[MulticastManager] repair group release failed", error);
|
|
27962
28025
|
}
|
|
27963
28026
|
};
|
|
27964
|
-
const repairOwners = endpoints.flatMap((endpoint) => endpoint.repairOwners)
|
|
28027
|
+
const repairOwners = endpoints.flatMap((endpoint) => endpoint.repairOwners.map((owner) => owner.instance !== "keyframe" ? owner : {
|
|
28028
|
+
...owner,
|
|
28029
|
+
ownerTrackName: endpoint.tracks.find((t) => t.packetId === owner.ownerPacketId)?.name,
|
|
28030
|
+
repairTrackName: endpoint.tracks.find((t) => t.packetId === owner.packetId)?.name
|
|
28031
|
+
}));
|
|
27965
28032
|
this.#applyRepairOwners(repairOwners);
|
|
27966
28033
|
for (const endpoint of endpoints) {
|
|
27967
28034
|
const ingress = {
|
|
@@ -28009,9 +28076,17 @@ var MulticastManager = class {
|
|
|
28009
28076
|
return release;
|
|
28010
28077
|
}
|
|
28011
28078
|
#applyRepairOwners(owners) {
|
|
28012
|
-
for (const { packetId, ownerPacketId } of owners) {
|
|
28079
|
+
for (const { packetId, ownerPacketId, instance, ownerTrackName, repairTrackName } of owners) {
|
|
28013
28080
|
this.#router.setPacketIdRole(packetId, "repair");
|
|
28014
|
-
|
|
28081
|
+
if (instance === "keyframe") {
|
|
28082
|
+
this.#router.setKeyframeOverlayLeg(packetId, {
|
|
28083
|
+
sourcePacketId: ownerPacketId,
|
|
28084
|
+
...ownerTrackName === void 0 ? {} : { sourceCatalogTrackName: ownerTrackName },
|
|
28085
|
+
...repairTrackName === void 0 ? {} : { repairTrackName }
|
|
28086
|
+
});
|
|
28087
|
+
} else {
|
|
28088
|
+
this.#router.setRepairPacketIdOwner(packetId, ownerPacketId);
|
|
28089
|
+
}
|
|
28015
28090
|
}
|
|
28016
28091
|
}
|
|
28017
28092
|
// ---------------------------------------------------------------------------
|
|
@@ -28275,8 +28350,8 @@ var MulticastManager = class {
|
|
|
28275
28350
|
this.#fec.setMulticastSymbolDelivery(delivery);
|
|
28276
28351
|
}
|
|
28277
28352
|
/** Process a repair packet from MoQ (reliable QUIC). */
|
|
28278
|
-
processRepairFromMoQ(packet, ownerPacketId, catalogTrackName) {
|
|
28279
|
-
this.#router.feedRepairPacket(packet, ownerPacketId, catalogTrackName);
|
|
28353
|
+
processRepairFromMoQ(packet, ownerPacketId, catalogTrackName, repairTrackName) {
|
|
28354
|
+
this.#router.feedRepairPacket(packet, ownerPacketId, catalogTrackName, repairTrackName);
|
|
28280
28355
|
}
|
|
28281
28356
|
/** Route a Worker-recovered FEC block through the MMTP parser + dedup pipeline. */
|
|
28282
28357
|
routeRecoveredBlock(blockId, data, packetId, catalogTrackName) {
|
|
@@ -28328,7 +28403,10 @@ var MulticastManager = class {
|
|
|
28328
28403
|
const ownedRepairNames = /* @__PURE__ */ new Set();
|
|
28329
28404
|
const claimed = /* @__PURE__ */ new Map();
|
|
28330
28405
|
for (const binding of bindings.values()) {
|
|
28331
|
-
|
|
28406
|
+
const overlay = binding.status === "ok" ? binding.overlay?.repairTrackName : void 0;
|
|
28407
|
+
for (const name of [...boundRepairNames(binding), ...overlay === void 0 ? [] : [overlay]]) {
|
|
28408
|
+
claimed.set(name, (claimed.get(name) ?? 0) + 1);
|
|
28409
|
+
}
|
|
28332
28410
|
}
|
|
28333
28411
|
for (const [name, count] of claimed) if (count === 1) ownedRepairNames.add(name);
|
|
28334
28412
|
const repairOwnerGroup = /* @__PURE__ */ new Map();
|
|
@@ -28459,6 +28537,14 @@ var MulticastManager = class {
|
|
|
28459
28537
|
this.#router.setRepairPacketIdOwner(repairTrack.packetId, track.packetId);
|
|
28460
28538
|
}
|
|
28461
28539
|
}
|
|
28540
|
+
const overlayName = binding.overlay?.repairTrackName;
|
|
28541
|
+
if (overlayName !== void 0 && ownedRepairNames.has(overlayName)) {
|
|
28542
|
+
this.#router.setKeyframeOverlayLeg(catalogTracksByName.get(overlayName)?.packetId, {
|
|
28543
|
+
sourcePacketId: track.packetId,
|
|
28544
|
+
sourceCatalogTrackName: track.name,
|
|
28545
|
+
repairTrackName: overlayName
|
|
28546
|
+
});
|
|
28547
|
+
}
|
|
28462
28548
|
}
|
|
28463
28549
|
const wasmDecoder = fecDecoders.get(i);
|
|
28464
28550
|
if (track.packetId !== void 0 && wasmDecoder !== void 0) {
|