@blockcast/mmt-container 2.2.0-main.75b39a2cdddf → 2.2.0-main.7e8a9d13c01c
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/dist/browser-runtime.js +634 -129
- package/dist/browser-runtime.js.map +3 -3
- package/dist/delta-fallback-config.js.map +1 -1
- package/dist/fec-manager.d.ts +37 -11
- package/dist/fec-manager.d.ts.map +1 -1
- package/dist/fec-manager.js +181 -52
- package/dist/fec-manager.js.map +2 -2
- package/dist/fec-worker-setup.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +2 -2
- package/dist/iso-block-locator.d.ts +39 -13
- package/dist/iso-block-locator.d.ts.map +1 -1
- package/dist/iso-block-locator.js +80 -25
- package/dist/iso-block-locator.js.map +2 -2
- package/dist/media-router.js.map +1 -1
- package/dist/mmtp-container-parser.d.ts +21 -0
- package/dist/mmtp-container-parser.d.ts.map +1 -1
- package/dist/mmtp-container-parser.js +114 -11
- package/dist/mmtp-container-parser.js.map +2 -2
- package/dist/mmtp-container-parser.no-modules.js +113 -12
- package/dist/mmtp-container-parser.no-modules.js.map +2 -2
- package/dist/mmtp-decode-pipeline.js +114 -11
- package/dist/mmtp-decode-pipeline.js.map +2 -2
- package/dist/mmtp-router.d.ts +18 -9
- package/dist/mmtp-router.d.ts.map +1 -1
- package/dist/mmtp-router.js +254 -44
- package/dist/mmtp-router.js.map +2 -2
- package/dist/multicast-manager.d.ts +13 -3
- package/dist/multicast-manager.d.ts.map +1 -1
- package/dist/multicast-manager.js +455 -103
- package/dist/multicast-manager.js.map +2 -2
- package/dist/no-modules.js +114 -11
- package/dist/no-modules.js.map +2 -2
- package/dist/repair-fetch.d.ts +36 -8
- package/dist/repair-fetch.d.ts.map +1 -1
- package/dist/repair-fetch.js +285 -26
- package/dist/repair-fetch.js.map +3 -3
- package/dist/track-session.d.ts.map +1 -1
- package/dist/track-session.js +1 -0
- package/dist/track-session.js.map +2 -2
- package/dist/wasm-mmtp-container-parser.js +114 -11
- package/dist/wasm-mmtp-container-parser.js.map +2 -2
- package/package.json +5 -5
- package/src/fec-manager.ts +156 -26
- package/src/index.ts +2 -0
- package/src/iso-block-locator.ts +114 -31
- package/src/mmtp-container-parser.ts +181 -10
- package/src/mmtp-router.ts +231 -58
- package/src/multicast-manager.ts +44 -6
- package/src/repair-fetch.ts +363 -49
- package/src/track-session.ts +3 -0
|
@@ -6005,7 +6005,10 @@ var BlockcastMmt = (() => {
|
|
|
6005
6005
|
function ssIdAfter(a, b) {
|
|
6006
6006
|
return (a - b | 0) > 0;
|
|
6007
6007
|
}
|
|
6008
|
-
|
|
6008
|
+
function holdsRebuilt(stream) {
|
|
6009
|
+
return stream.buf.some(({ meta }) => meta.fecSbnFirst !== void 0);
|
|
6010
|
+
}
|
|
6011
|
+
var _streams2, _gate, _emit2, _recordStat2, _deferDepth, _deferredStreams, _FecReleaseSequencer_instances, drainUnlessDeferred_fn, streamFor_fn2, drain_fn, drainLoop_fn, cursorPassed_fn, release_fn;
|
|
6009
6012
|
var FecReleaseSequencer = class {
|
|
6010
6013
|
constructor(gate, emit, recordStat) {
|
|
6011
6014
|
__privateAdd(this, _FecReleaseSequencer_instances);
|
|
@@ -6065,6 +6068,7 @@ var BlockcastMmt = (() => {
|
|
|
6065
6068
|
stream.lastSbn = void 0;
|
|
6066
6069
|
stream.discontinuity = false;
|
|
6067
6070
|
stream.rapSsId = void 0;
|
|
6071
|
+
stream.sourced = false;
|
|
6068
6072
|
}
|
|
6069
6073
|
if (stream.last !== null && compareFrameOrder(frame, stream.last) <= 0) {
|
|
6070
6074
|
__privateGet(this, _recordStat2).call(this, "droppedStale");
|
|
@@ -6091,6 +6095,7 @@ var BlockcastMmt = (() => {
|
|
|
6091
6095
|
if (compareFrameOrder(stream.buf[mid], frame) < 0) lo = mid + 1;
|
|
6092
6096
|
else hi = mid;
|
|
6093
6097
|
}
|
|
6098
|
+
if (stream.buf[lo]?.passed === true) frame.passed = true;
|
|
6094
6099
|
stream.buf.splice(lo, 0, frame);
|
|
6095
6100
|
__privateMethod(this, _FecReleaseSequencer_instances, drainUnlessDeferred_fn).call(this, stream);
|
|
6096
6101
|
}
|
|
@@ -6126,6 +6131,41 @@ var BlockcastMmt = (() => {
|
|
|
6126
6131
|
}
|
|
6127
6132
|
return false;
|
|
6128
6133
|
}
|
|
6134
|
+
/**
|
|
6135
|
+
* These streams' sink is being replaced by one that has seen no source
|
|
6136
|
+
* frame yet. First, from a stream that holds a frame the overlay rebuilt,
|
|
6137
|
+
* release to the sink being replaced the frames the unanchored path had
|
|
6138
|
+
* already released to it (#cursorPassed): there they waited in its queue,
|
|
6139
|
+
* which its replacement flushes. A stream that holds none is not drained:
|
|
6140
|
+
* it holds nothing the anchor kept back, and a drain would still force out
|
|
6141
|
+
* a frame held past the hold limit, which before the anchor waited for the
|
|
6142
|
+
* next push. Then treat the streams as unsourced until a source frame is
|
|
6143
|
+
* released.
|
|
6144
|
+
*/
|
|
6145
|
+
unsource(packetId, catalogTrackName) {
|
|
6146
|
+
for (const stream of __privateGet(this, _streams2).values()) {
|
|
6147
|
+
if (stream.packetId === packetId && (catalogTrackName === void 0 || stream.catalogTrackName === catalogTrackName)) {
|
|
6148
|
+
if (stream.draining === 0 && holdsRebuilt(stream)) {
|
|
6149
|
+
if (__privateGet(this, _deferDepth) > 0) __privateGet(this, _deferredStreams).add(stream);
|
|
6150
|
+
else __privateMethod(this, _FecReleaseSequencer_instances, drain_fn).call(this, stream, true);
|
|
6151
|
+
}
|
|
6152
|
+
stream.sourced = false;
|
|
6153
|
+
}
|
|
6154
|
+
}
|
|
6155
|
+
}
|
|
6156
|
+
/**
|
|
6157
|
+
* Whether a stream of `packetId` holds a frame the keyframe overlay rebuilt
|
|
6158
|
+
* (FrameMeta.fecSbnFirst). Without `catalogTrackName`, every stream of the
|
|
6159
|
+
* packetId.
|
|
6160
|
+
*/
|
|
6161
|
+
holdsRebuilt(packetId, catalogTrackName) {
|
|
6162
|
+
for (const stream of __privateGet(this, _streams2).values()) {
|
|
6163
|
+
if (stream.packetId !== packetId) continue;
|
|
6164
|
+
if (catalogTrackName !== void 0 && stream.catalogTrackName !== catalogTrackName) continue;
|
|
6165
|
+
if (holdsRebuilt(stream)) return true;
|
|
6166
|
+
}
|
|
6167
|
+
return false;
|
|
6168
|
+
}
|
|
6129
6169
|
/** Re-evaluate held gaps after FEC state changed. */
|
|
6130
6170
|
poke(streamKey) {
|
|
6131
6171
|
if (streamKey !== void 0) {
|
|
@@ -6229,16 +6269,32 @@ var BlockcastMmt = (() => {
|
|
|
6229
6269
|
last: null,
|
|
6230
6270
|
lastSbn: void 0,
|
|
6231
6271
|
discontinuity: false,
|
|
6232
|
-
rapSsId: void 0
|
|
6272
|
+
rapSsId: void 0,
|
|
6273
|
+
sourced: false,
|
|
6274
|
+
draining: 0
|
|
6233
6275
|
};
|
|
6234
6276
|
__privateGet(this, _streams2).set(streamKey, stream);
|
|
6235
6277
|
}
|
|
6236
6278
|
return stream;
|
|
6237
6279
|
};
|
|
6238
|
-
|
|
6280
|
+
/** `asUnanchored`: release overlay-rebuilt frames when unanchored did (#cursorPassed). */
|
|
6281
|
+
drain_fn = function(stream, asUnanchored = false) {
|
|
6282
|
+
stream.draining++;
|
|
6283
|
+
try {
|
|
6284
|
+
__privateMethod(this, _FecReleaseSequencer_instances, drainLoop_fn).call(this, stream, asUnanchored);
|
|
6285
|
+
} finally {
|
|
6286
|
+
stream.draining--;
|
|
6287
|
+
}
|
|
6288
|
+
};
|
|
6289
|
+
drainLoop_fn = function(stream, asUnanchored) {
|
|
6239
6290
|
while (stream.buf.length > 0 && stream.last !== null) {
|
|
6240
6291
|
const head = stream.buf[0];
|
|
6241
6292
|
const last = stream.last;
|
|
6293
|
+
if (compareFrameOrder(head, last) <= 0) {
|
|
6294
|
+
stream.buf.shift();
|
|
6295
|
+
__privateMethod(this, _FecReleaseSequencer_instances, release_fn).call(this, stream, head, void 0);
|
|
6296
|
+
continue;
|
|
6297
|
+
}
|
|
6242
6298
|
if (stream.discontinuity) {
|
|
6243
6299
|
stream.discontinuity = false;
|
|
6244
6300
|
stream.buf.shift();
|
|
@@ -6252,9 +6308,10 @@ var BlockcastMmt = (() => {
|
|
|
6252
6308
|
}
|
|
6253
6309
|
const headSbn = head.meta.fecSbn;
|
|
6254
6310
|
const from = stream.lastSbn ?? headSbn;
|
|
6255
|
-
const to = headSbn ?? stream.lastSbn;
|
|
6311
|
+
const to = head.meta.fecSbnFirst ?? headSbn ?? stream.lastSbn;
|
|
6256
6312
|
let lost = [];
|
|
6257
6313
|
const unanchored = from === void 0 && to === void 0;
|
|
6314
|
+
let unresolved = false;
|
|
6258
6315
|
if (from !== void 0 && to !== void 0) {
|
|
6259
6316
|
const resolved = __privateGet(this, _gate).resolvedLoss(
|
|
6260
6317
|
stream.packetId,
|
|
@@ -6263,7 +6320,8 @@ var BlockcastMmt = (() => {
|
|
|
6263
6320
|
Math.max(from, to),
|
|
6264
6321
|
from
|
|
6265
6322
|
);
|
|
6266
|
-
|
|
6323
|
+
unresolved = resolved === null;
|
|
6324
|
+
if (unresolved && !__privateMethod(this, _FecReleaseSequencer_instances, cursorPassed_fn).call(this, stream, asUnanchored)) {
|
|
6267
6325
|
const heldMs = performance.now() - head.arrivedAtMs;
|
|
6268
6326
|
if (heldMs <= __privateGet(this, _gate).holdLimitMs(stream.packetId, stream.catalogTrackName)) return;
|
|
6269
6327
|
__privateGet(this, _recordStat2).call(this, "forcedWindowFlushes");
|
|
@@ -6271,18 +6329,52 @@ var BlockcastMmt = (() => {
|
|
|
6271
6329
|
__privateMethod(this, _FecReleaseSequencer_instances, release_fn).call(this, stream, head, __privateGet(this, _gate).decide(last, head, [], true));
|
|
6272
6330
|
continue;
|
|
6273
6331
|
}
|
|
6274
|
-
lost = resolved;
|
|
6332
|
+
lost = resolved ?? [];
|
|
6275
6333
|
}
|
|
6276
6334
|
stream.buf.shift();
|
|
6277
|
-
__privateMethod(this, _FecReleaseSequencer_instances, release_fn).call(this, stream, head, lost.length > 0 || unanchored || authoredGap(last.meta, head.meta) ? __privateGet(this, _gate).decide(last, head, lost, false) : void 0);
|
|
6335
|
+
__privateMethod(this, _FecReleaseSequencer_instances, release_fn).call(this, stream, head, lost.length > 0 || unanchored || unresolved || authoredGap(last.meta, head.meta) ? __privateGet(this, _gate).decide(last, head, lost, false) : void 0);
|
|
6278
6336
|
}
|
|
6279
6337
|
};
|
|
6338
|
+
/**
|
|
6339
|
+
* An overlay-rebuilt frame (fecSbnFirst) waits no longer than the BLO-53342
|
|
6340
|
+
* source cursor holds it unanchored, and neither does a later frame behind
|
|
6341
|
+
* it. Unanchored, a frame that waits on no block (fecSbnFirst set, or no
|
|
6342
|
+
* fecSbn) left the gate once every frame ahead of it had: mark it `passed`,
|
|
6343
|
+
* like each frame that arrived in front of it since (stale there). The head
|
|
6344
|
+
* then goes, decided as it would be unanchored, once a frame the base path
|
|
6345
|
+
* delivered (a source frame, or one base FEC recovered) is buffered after a
|
|
6346
|
+
* marked one: the base path has passed that one, so a frame still missing
|
|
6347
|
+
* before it can only come from a repair. It also goes while no source frame
|
|
6348
|
+
* has been released, when the direct path shows a recovered frame at once.
|
|
6349
|
+
* And it goes at once while a staged switch decides on when frames arrive
|
|
6350
|
+
* (FecReleaseGate.releaseUnanchored), and when unsource releases into a
|
|
6351
|
+
* sink being replaced: unanchored, it had already reached the sink.
|
|
6352
|
+
* The scan also writes: the `passed` marks it sets stay on the frames,
|
|
6353
|
+
* and push marks a frame it inserts in front of a marked one from them.
|
|
6354
|
+
*/
|
|
6355
|
+
cursorPassed_fn = function(stream, asUnanchored) {
|
|
6356
|
+
let at = -1;
|
|
6357
|
+
for (let i = 0; i < stream.buf.length; i++) {
|
|
6358
|
+
const frame = stream.buf[i];
|
|
6359
|
+
if (frame.meta.fecSbnFirst !== void 0 || frame.meta.fecSbn === void 0) {
|
|
6360
|
+
frame.passed = true;
|
|
6361
|
+
if (at < 0) at = i;
|
|
6362
|
+
} else if (frame.passed !== true) break;
|
|
6363
|
+
}
|
|
6364
|
+
if (at < 0) return false;
|
|
6365
|
+
return asUnanchored || !stream.sourced || __privateGet(this, _gate).releaseUnanchored?.(stream.packetId, stream.catalogTrackName) === true || stream.buf.some(({ meta }, i) => i > at && meta.fecSbnFirst === void 0 && (meta.recovered !== true || meta.fecSbn !== void 0));
|
|
6366
|
+
};
|
|
6280
6367
|
release_fn = function(stream, frame, decision) {
|
|
6368
|
+
const stale = stream.last !== null && compareFrameOrder(frame, stream.last) <= 0;
|
|
6369
|
+
if (stale) __privateGet(this, _recordStat2).call(this, "droppedStale");
|
|
6281
6370
|
if (decision) frame.meta.gapBefore = decision;
|
|
6282
6371
|
stream.last = frame;
|
|
6283
|
-
if (frame.meta.fecSbn !== void 0
|
|
6372
|
+
if (frame.meta.fecSbn !== void 0 && (frame.meta.fecSbnFirst === void 0 || stream.lastSbn !== void 0)) {
|
|
6373
|
+
stream.lastSbn = frame.meta.fecSbn;
|
|
6374
|
+
}
|
|
6375
|
+
if (frame.meta.recovered !== true) stream.sourced = true;
|
|
6284
6376
|
__privateGet(this, _gate).onReleased?.(frame.data, frame.meta);
|
|
6285
|
-
__privateGet(this, _emit2).call(this, frame.data, frame.meta);
|
|
6377
|
+
if (!stale) __privateGet(this, _emit2).call(this, frame.data, frame.meta);
|
|
6286
6378
|
};
|
|
6287
6379
|
var FMPU_BOX_TYPES = /* @__PURE__ */ new Set(["ftyp", "moov", "moof"]);
|
|
6288
6380
|
function isFmp4Box(data) {
|
|
@@ -6525,6 +6617,14 @@ var BlockcastMmt = (() => {
|
|
|
6525
6617
|
fecReleaseRapAbove(packetId, catalogTrackName, ssId) {
|
|
6526
6618
|
return __privateGet(this, _fecSequencer)?.rapAbove(packetId, catalogTrackName, ssId) ?? false;
|
|
6527
6619
|
}
|
|
6620
|
+
/** See FecReleaseSequencer.unsource. */
|
|
6621
|
+
unsourceFecRelease(packetId, catalogTrackName) {
|
|
6622
|
+
__privateGet(this, _fecSequencer)?.unsource(packetId, catalogTrackName);
|
|
6623
|
+
}
|
|
6624
|
+
/** See FecReleaseSequencer.holdsRebuilt. */
|
|
6625
|
+
fecReleaseHoldsRebuilt(packetId, catalogTrackName) {
|
|
6626
|
+
return __privateGet(this, _fecSequencer)?.holdsRebuilt(packetId, catalogTrackName) ?? false;
|
|
6627
|
+
}
|
|
6528
6628
|
/** Re-evaluate held gaps after FEC block state changed. */
|
|
6529
6629
|
pokeFecRelease(packetId, catalogTrackName) {
|
|
6530
6630
|
if (!__privateGet(this, _fecSequencer)) return;
|
|
@@ -7149,7 +7249,7 @@ var BlockcastMmt = (() => {
|
|
|
7149
7249
|
headTiming.size
|
|
7150
7250
|
);
|
|
7151
7251
|
if (readyOnRegister) {
|
|
7152
|
-
const deferred = __privateMethod(this, _MmtpContainerParser_instances, emitCombinedSample_fn).call(this, readyOnRegister, info, resolver, options?.recovered === true, options?.fecSbn);
|
|
7252
|
+
const deferred = __privateMethod(this, _MmtpContainerParser_instances, emitCombinedSample_fn).call(this, readyOnRegister, info, resolver, options?.recovered === true, options?.fecSbn, options?.fecSbnFirst);
|
|
7153
7253
|
if (deferred.record === void 0) __privateMethod(this, _MmtpContainerParser_instances, countDeferredOutcome_fn).call(this, deferred.reason);
|
|
7154
7254
|
}
|
|
7155
7255
|
}
|
|
@@ -7236,7 +7336,7 @@ var BlockcastMmt = (() => {
|
|
|
7236
7336
|
fragmentCounter: mpu.fragmentCounter
|
|
7237
7337
|
};
|
|
7238
7338
|
}
|
|
7239
|
-
const outcome = __privateMethod(this, _MmtpContainerParser_instances, emitCombinedSample_fn).call(this, combined, info, resolver, options?.recovered === true, options?.fecSbn);
|
|
7339
|
+
const outcome = __privateMethod(this, _MmtpContainerParser_instances, emitCombinedSample_fn).call(this, combined, info, resolver, options?.recovered === true, options?.fecSbn, options?.fecSbnFirst);
|
|
7240
7340
|
if (outcome.record !== void 0) return outcome.record;
|
|
7241
7341
|
return __privateMethod(this, _MmtpContainerParser_instances, drop_fn).call(this, outcome.reason);
|
|
7242
7342
|
};
|
|
@@ -7255,7 +7355,7 @@ var BlockcastMmt = (() => {
|
|
|
7255
7355
|
* attribution exists to keep readable. Leaving the choice at the call site
|
|
7256
7356
|
* is what keeps both true.
|
|
7257
7357
|
*/
|
|
7258
|
-
emitCombinedSample_fn = function(combined, info, resolver, recovered, fecSbn) {
|
|
7358
|
+
emitCombinedSample_fn = function(combined, info, resolver, recovered, fecSbn, fecSbnFirst) {
|
|
7259
7359
|
const timing = resolver.sampleTiming(
|
|
7260
7360
|
combined.mpuSequenceNumber,
|
|
7261
7361
|
combined.movieFragmentSequenceNumber,
|
|
@@ -7266,6 +7366,7 @@ var BlockcastMmt = (() => {
|
|
|
7266
7366
|
const meta = __privateMethod(this, _MmtpContainerParser_instances, buildFrameMeta_fn).call(this, combined, info.packetId, info.sequenceNumber, timing, recovered);
|
|
7267
7367
|
if (!meta) return { reason: "combined-meta-build-failed" };
|
|
7268
7368
|
if (fecSbn !== void 0) meta.fecSbn = fecSbn;
|
|
7369
|
+
if (fecSbnFirst !== void 0) meta.fecSbnFirst = fecSbnFirst;
|
|
7269
7370
|
if (!resolver.consumeSample(
|
|
7270
7371
|
combined.mpuSequenceNumber,
|
|
7271
7372
|
combined.movieFragmentSequenceNumber,
|