@blockcast/mmt-container 2.1.0 → 2.2.0-main.050b52fb9b00

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 (105) hide show
  1. package/README.md +29 -17
  2. package/dist/browser-runtime.js +1949 -374
  3. package/dist/browser-runtime.js.map +4 -4
  4. package/dist/carp-catalog.js.map +1 -1
  5. package/dist/catalog-fec-params.d.ts +17 -1
  6. package/dist/catalog-fec-params.d.ts.map +1 -1
  7. package/dist/catalog-fec-params.js +15 -0
  8. package/dist/catalog-fec-params.js.map +2 -2
  9. package/dist/catalog-network-source.js.map +1 -1
  10. package/dist/cmcd-producer.d.ts +65 -47
  11. package/dist/cmcd-producer.d.ts.map +1 -1
  12. package/dist/cmcd-producer.js +138 -109
  13. package/dist/cmcd-producer.js.map +2 -2
  14. package/dist/delivery-catalog.js +26 -16
  15. package/dist/delivery-catalog.js.map +2 -2
  16. package/dist/delta-fallback-config.js.map +1 -1
  17. package/dist/fec-manager.d.ts +70 -12
  18. package/dist/fec-manager.d.ts.map +1 -1
  19. package/dist/fec-manager.js +403 -58
  20. package/dist/fec-manager.js.map +2 -2
  21. package/dist/fec-state.js.map +1 -1
  22. package/dist/fec-worker-setup.d.ts +1 -1
  23. package/dist/fec-worker-setup.js +1 -1
  24. package/dist/fec-worker-setup.js.map +1 -1
  25. package/dist/held-layer-admission.js.map +1 -1
  26. package/dist/index.d.ts +6 -5
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +9 -1
  29. package/dist/index.js.map +2 -2
  30. package/dist/iso-block-locator.d.ts +48 -13
  31. package/dist/iso-block-locator.d.ts.map +1 -1
  32. package/dist/iso-block-locator.js +97 -25
  33. package/dist/iso-block-locator.js.map +2 -2
  34. package/dist/iso-bmff-timing.d.ts +10 -1
  35. package/dist/iso-bmff-timing.d.ts.map +1 -1
  36. package/dist/iso-bmff-timing.js +36 -2
  37. package/dist/iso-bmff-timing.js.map +2 -2
  38. package/dist/media-router.js.map +1 -1
  39. package/dist/mfu-reassembler.js +12 -19
  40. package/dist/mfu-reassembler.js.map +2 -2
  41. package/dist/mmtp-container-parser.d.ts +79 -10
  42. package/dist/mmtp-container-parser.d.ts.map +1 -1
  43. package/dist/mmtp-container-parser.js +219 -45
  44. package/dist/mmtp-container-parser.js.map +2 -2
  45. package/dist/mmtp-container-parser.no-modules.js +342 -63
  46. package/dist/mmtp-container-parser.no-modules.js.map +3 -3
  47. package/dist/mmtp-decode-pipeline.js +218 -45
  48. package/dist/mmtp-decode-pipeline.js.map +2 -2
  49. package/dist/mmtp-fec-session.d.ts +41 -3
  50. package/dist/mmtp-fec-session.d.ts.map +1 -1
  51. package/dist/mmtp-fec-session.js +118 -13
  52. package/dist/mmtp-fec-session.js.map +3 -3
  53. package/dist/mmtp-router.d.ts +43 -9
  54. package/dist/mmtp-router.d.ts.map +1 -1
  55. package/dist/mmtp-router.js +2006 -95
  56. package/dist/mmtp-router.js.map +4 -4
  57. package/dist/multicast-auth-catalog.js.map +1 -1
  58. package/dist/multicast-input.js.map +1 -1
  59. package/dist/multicast-manager.d.ts +28 -5
  60. package/dist/multicast-manager.d.ts.map +1 -1
  61. package/dist/multicast-manager.js +16116 -15005
  62. package/dist/multicast-manager.js.map +4 -4
  63. package/dist/multicast-transport.d.ts +11 -3
  64. package/dist/multicast-transport.d.ts.map +1 -1
  65. package/dist/multicast-transport.js +281 -35
  66. package/dist/multicast-transport.js.map +4 -4
  67. package/dist/multicast-unwrap.js +12 -19
  68. package/dist/multicast-unwrap.js.map +2 -2
  69. package/dist/no-modules.js +336 -59
  70. package/dist/no-modules.js.map +3 -3
  71. package/dist/repair-fetch.d.ts +36 -8
  72. package/dist/repair-fetch.d.ts.map +1 -1
  73. package/dist/repair-fetch.js +285 -26
  74. package/dist/repair-fetch.js.map +3 -3
  75. package/dist/repair-layer-subscriptions.d.ts +82 -0
  76. package/dist/repair-layer-subscriptions.d.ts.map +1 -0
  77. package/dist/repair-layer-subscriptions.js +192 -0
  78. package/dist/repair-layer-subscriptions.js.map +7 -0
  79. package/dist/signaling.js.map +2 -2
  80. package/dist/timestamp-codec.js +12 -19
  81. package/dist/timestamp-codec.js.map +2 -2
  82. package/dist/track-session.d.ts +1 -1
  83. package/dist/track-session.d.ts.map +1 -1
  84. package/dist/track-session.js +1 -0
  85. package/dist/track-session.js.map +2 -2
  86. package/dist/wasm-mfu-reassembler.js.map +1 -1
  87. package/dist/wasm-mmtp-container-parser.js +218 -45
  88. package/dist/wasm-mmtp-container-parser.js.map +2 -2
  89. package/package.json +8 -5
  90. package/schemas/catalog.schema.json +4 -0
  91. package/src/catalog-fec-params.ts +36 -1
  92. package/src/cmcd-producer.ts +194 -179
  93. package/src/fec-manager.ts +433 -32
  94. package/src/fec-worker-setup.ts +2 -2
  95. package/src/index.ts +20 -2
  96. package/src/iso-block-locator.ts +133 -31
  97. package/src/iso-bmff-timing.ts +40 -1
  98. package/src/mmtp-container-parser.ts +306 -29
  99. package/src/mmtp-fec-session.ts +115 -15
  100. package/src/mmtp-router.ts +629 -54
  101. package/src/multicast-manager.ts +70 -11
  102. package/src/multicast-transport.ts +44 -20
  103. package/src/repair-fetch.ts +363 -49
  104. package/src/repair-layer-subscriptions.ts +261 -0
  105. package/src/track-session.ts +4 -1
@@ -41,6 +41,18 @@
41
41
  * or otherwise never sent cancels nothing (§11.4.5 item 3), and an audio
42
42
  * request never preempts. A P2 that never ran before its block resolved
43
43
  * is reported as `repair-deferred`.
44
+ * - A hole walked over the one-Group transport (no `rangeTransport`) is
45
+ * repair the run gets before its FEC deadline (`walkHole`). On a video
46
+ * track it is keyframe repair (class `unknown`): P0, and no audio or
47
+ * delta FETCH is issued while one of its Group FETCHes is outstanding
48
+ * (fec-multicast-00 rule 3). It reaches no FEC deadline, so it preempts
49
+ * nothing and holds back no audio or delta request: one that comes due
50
+ * cancels the walk's Group FETCH and goes out at once, and the walk asks
51
+ * for that Group again after it (`yieldVideoWalks`). On an audio track
52
+ * it is audio repair: P1 at the audio wire priority, one Group per FETCH,
53
+ * and like any audio request it waits while keyframe repair is
54
+ * outstanding, stopping before its next Group, and is preempted by a
55
+ * keyframe FETCH sent.
44
56
  * - A block reclassified to a higher class while its P2 fetch is in flight
45
57
  * is re-issued at once under the new class's wire priority: the running
46
58
  * FETCH is aborted (FETCH_CANCEL) and a new one sent.
@@ -101,8 +113,8 @@
101
113
  */
102
114
  import { type FecBlockProfile } from '@blockcast/mmt-base';
103
115
  import { type RepairFetchRange } from '@blockcast/mmt-fec';
104
- import { type BlockClass, type ClassifierMode, type RepairPriority } from './block-policy.js';
105
- import type { UndelimitedIsoLoss } from './fec-manager.js';
116
+ import { type BlockClass, type ClassifierMode, type RepairPriority, type TrackKind } from './block-policy.js';
117
+ import type { ExpiredIsoHole, UndelimitedIsoLoss } from './fec-manager.js';
106
118
  import type { RepairLifecycleObserver } from './multicast-manager.js';
107
119
  /**
108
120
  * The highest value in the Source Media priority range of
@@ -322,10 +334,14 @@ export interface WireRepairFetchOptions {
322
334
  keyframeRepairBudgetMs?: (packetId: number, catalogTrackName?: string) => number;
323
335
  /**
324
336
  * Range repair for a lost SS_ID whose block no repair delimited
325
- * (draft-ramadan-moq-fec §7.5), optional. Given, the host keeps such a gap
326
- * as a pending hole and the scheduler FETCHes `repairFetchRange(x, K,
327
- * anchor)` for it under the same admission, priority and abort rules as a
328
- * block request (class `unknown`, P0). Requires `repairEpochReference`.
337
+ * (draft-ramadan-moq-fec §7.5), optional. A host that can keep such a gap as
338
+ * a pending hole gets range repair either way, under the same admission,
339
+ * priority and abort rules as a block request (class `unknown`, P0). Given,
340
+ * the scheduler FETCHes `repairFetchRange(x, K, anchor)` over it, and
341
+ * requires `repairEpochReference`. Absent, it walks the hole over
342
+ * `transport` one Group at a time from the hole's start, whose Group is a
343
+ * block's, each repair stating where the next block starts (BLO-52085),
344
+ * under the class of the hole's track (see the module note).
329
345
  */
330
346
  rangeTransport?: RepairRangeFetchTransport;
331
347
  /**
@@ -410,6 +426,12 @@ export interface RepairFetchHost {
410
426
  holdBlockForRepair(sbn: number, packetId: number, catalogTrackName: string | undefined, untilAtMs: number): boolean;
411
427
  /** The admitted FETCH ended without delivering: back to the multicast wait. */
412
428
  releaseRepairHold(sbn: number, packetId: number, catalogTrackName?: string): void;
429
+ /** Run `fn` with `receivedAtMs` as the receipt time of what it feeds (optional). */
430
+ withReceiptTime?(receivedAtMs: number, fn: () => void): void;
431
+ /** The configured media kind of a packetId (optional; absent reads as video). */
432
+ trackKindFor?(packetId: number): TrackKind | undefined;
433
+ /** The stream's D-28 repair deadline: how long after a block's sources it asks for repair (optional). */
434
+ repairDeadlineMsForPacket?(packetId: number): number | undefined;
413
435
  };
414
436
  onRepairSubscribe(cb: RepairSubscribeCallback): void;
415
437
  /**
@@ -423,8 +445,14 @@ export interface RepairFetchHost {
423
445
  noteKeyframeBudgetGranted?(extensionMs: number, sbn: number, packetId: number, catalogTrackName?: string): void;
424
446
  addRepairLifecycleObserver(observer: RepairLifecycleObserver): () => void;
425
447
  addTrackResetObserver(observer: (packetId: number, catalogTrackName: string) => void): () => void;
426
- /** Register for lost SS_IDs in undelimited spans (required with `rangeTransport`). */
427
- onUndelimitedLoss?(cb: (loss: UndelimitedIsoLoss) => void): void;
448
+ /**
449
+ * Register for lost SS_IDs in undelimited spans (required with
450
+ * `rangeTransport`). A host that offers it and `closeIsoHoles` keeps such a
451
+ * gap as a pending hole for the scheduler to repair. `onExpired` is told of
452
+ * a pending hole the stream ran past the locator's horizon; returning true,
453
+ * the scheduler closes it (`closeIsoHoles`), otherwise the host discards it.
454
+ */
455
+ onUndelimitedLoss?(cb: (loss: UndelimitedIsoLoss) => void, onExpired?: (hole: ExpiredIsoHole) => boolean): void;
428
456
  /** A hole's range repair ended, or none is sent: feed what was not stated. */
429
457
  closeIsoHoles?(packetId: number, catalogTrackName: string | undefined, start: number, length: number): void;
430
458
  clearRepairForBlock(sbn: number, packetId: number, catalogTrackName?: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"repair-fetch.d.ts","sourceRoot":"","sources":["../src/repair-fetch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"repair-fetch.d.ts","sourceRoot":"","sources":["../src/repair-fetch.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,131 @@
1
1
  // ../mmt-base/dist/mmtp.js
2
+ var MMTP_HEADER_SIZE = 12;
2
3
  var MPU_HEADER_SIZE = 8;
3
4
  var MPU_LENGTH_FIELD_SIZE = 2;
4
5
  var MPU_HEADER_REMAINDER_SIZE = MPU_HEADER_SIZE - MPU_LENGTH_FIELD_SIZE;
6
+ var PACKET_TYPE_REPAIR = 3;
7
+ function parseMMTPHeader(buffer) {
8
+ if (buffer.length < MMTP_HEADER_SIZE) {
9
+ throw new Error(`MMTP packet too small: ${buffer.length} bytes`);
10
+ }
11
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
12
+ const version = buffer[0] >> 6 & 3;
13
+ if (version !== 0) {
14
+ throw new Error(`Unsupported MMTP version: ${version}`);
15
+ }
16
+ const fecType = buffer[0] >> 3 & 3;
17
+ const packetCounterFlag = (buffer[0] & 32) !== 0;
18
+ const extensionFlag = (buffer[0] & 2) !== 0;
19
+ const rapFlag = (buffer[0] & 1) === 1;
20
+ const packetType = buffer[1] & 63;
21
+ let offset = 2;
22
+ const packetId = view.getUint16(offset, false);
23
+ offset += 2;
24
+ const timestamp = BigInt(view.getUint32(offset, false));
25
+ offset += 4;
26
+ const sequenceNumber = view.getUint32(offset, false);
27
+ offset += 4;
28
+ let packetCounter;
29
+ if (packetCounterFlag) {
30
+ if (offset + 4 > buffer.length)
31
+ throw new Error("MMTP packet truncated in packet_counter");
32
+ packetCounter = view.getUint32(offset, false);
33
+ offset += 4;
34
+ }
35
+ let extension;
36
+ if (extensionFlag) {
37
+ if (offset + 4 > buffer.length)
38
+ throw new Error("MMTP packet truncated in header extension");
39
+ const type = view.getUint16(offset, false);
40
+ const length = view.getUint16(offset + 2, false);
41
+ offset += 4;
42
+ if (offset + length > buffer.length)
43
+ throw new Error("MMTP packet truncated in header extension value");
44
+ extension = { type, data: buffer.subarray(offset, offset + length) };
45
+ offset += length;
46
+ }
47
+ return {
48
+ version,
49
+ packetType,
50
+ packetId,
51
+ timestamp,
52
+ sequenceNumber,
53
+ payloadLength: buffer.length - offset,
54
+ fecType,
55
+ packetCounterFlag,
56
+ packetCounter,
57
+ extensionFlag,
58
+ extension,
59
+ headerLength: offset,
60
+ rapFlag
61
+ };
62
+ }
63
+ var REPAIR_FEC_PID_SIZE = 13;
64
+ function readRepairFecPayloadIdFields(mmtpPacket, parsedHeader) {
65
+ let header;
66
+ if (parsedHeader) {
67
+ header = parsedHeader;
68
+ } else {
69
+ try {
70
+ header = parseMMTPHeader(mmtpPacket);
71
+ } catch {
72
+ return null;
73
+ }
74
+ }
75
+ if (header.packetType !== PACKET_TYPE_REPAIR || header.fecType !== 2)
76
+ return null;
77
+ const off = header.headerLength;
78
+ if (mmtpPacket.length < off + REPAIR_FEC_PID_SIZE)
79
+ return null;
80
+ const ssStart = (mmtpPacket[off] << 24 | mmtpPacket[off + 1] << 16 | mmtpPacket[off + 2] << 8 | mmtpPacket[off + 3]) >>> 0;
81
+ const rsbLength = mmtpPacket[off + 4] << 16 | mmtpPacket[off + 5] << 8 | mmtpPacket[off + 6];
82
+ const rsId = mmtpPacket[off + 7] << 16 | mmtpPacket[off + 8] << 8 | mmtpPacket[off + 9];
83
+ const ssbLength = mmtpPacket[off + 10] << 16 | mmtpPacket[off + 11] << 8 | mmtpPacket[off + 12];
84
+ return {
85
+ packetId: header.packetId,
86
+ ssStart,
87
+ rsbLength,
88
+ rsId,
89
+ ssbLength,
90
+ dataOffset: off + REPAIR_FEC_PID_SIZE
91
+ };
92
+ }
93
+ function extractRepairFecPayloadId(mmtpPacket) {
94
+ const fields = readRepairFecPayloadIdFields(mmtpPacket);
95
+ if (!fields)
96
+ return null;
97
+ return {
98
+ ssStart: fields.ssStart,
99
+ rsbLength: fields.rsbLength,
100
+ rsId: fields.rsId,
101
+ ssbLength: fields.ssbLength
102
+ };
103
+ }
5
104
 
6
105
  // ../mmt-base/dist/ntp-short.js
7
106
  var NTP_SHORT_BITS = 32;
8
107
  var NTP_SHORT_MODULUS = 2 ** NTP_SHORT_BITS;
9
108
  var NTP_SHORT_HALF_RANGE = 2 ** (NTP_SHORT_BITS - 1);
10
109
 
110
+ // ../mmt-base/dist/serial-number.js
111
+ var SERIAL32_SPAN = 4294967296;
112
+ var SERIAL32_HALF = 2147483648;
113
+ function assertUint32(value, name) {
114
+ if (!Number.isInteger(value) || value < 0 || value >= SERIAL32_SPAN) {
115
+ throw new RangeError(`${name} must be a uint32 (got ${value})`);
116
+ }
117
+ }
118
+ function serial32Add(s, n) {
119
+ assertUint32(s, "s");
120
+ if (!Number.isInteger(n) || n <= -SERIAL32_HALF || n >= SERIAL32_HALF) {
121
+ throw new RangeError(`serial addend must lie in (-2^31, 2^31) (got ${n})`);
122
+ }
123
+ return (s + n + SERIAL32_SPAN) % SERIAL32_SPAN;
124
+ }
125
+ function serial32Distance(from, to) {
126
+ return to - from >>> 0;
127
+ }
128
+
11
129
  // ../mmt-base/dist/fec-block-profile.js
12
130
  var FEC_BLOCK_PROFILES = Object.freeze([
13
131
  "iso-ssbg1-v1"
@@ -53,6 +171,7 @@ var REPAIR_PRIORITY_MIN = 192;
53
171
 
54
172
  // src/repair-fetch.ts
55
173
  var MOQT_PRIORITY_MAX = 255;
174
+ var WALK_LEAD_MS = 3;
56
175
  var SOURCE_MEDIA_PRIORITY_MAX = REPAIR_PRIORITY_MIN - 1;
57
176
  function isMoqtPriority(value) {
58
177
  return Number.isSafeInteger(value) && value >= 0 && value <= MOQT_PRIORITY_MAX;
@@ -103,8 +222,17 @@ function wireRepairFetch(mc, opts) {
103
222
  mc.noteRepairScheduling(type, entry.sbn, entry.packetId, entry.catalogTrackName);
104
223
  };
105
224
  const clearEntry = (entry) => {
106
- if (entry.range) mc.closeIsoHoles(entry.packetId, entry.catalogTrackName, entry.sbn, entry.range.holeLength);
107
- else clearRepair(entry.sbn, entry.packetId, entry.catalogTrackName);
225
+ const { range } = entry;
226
+ if (range) {
227
+ atReport(range, () => mc.closeIsoHoles(entry.packetId, entry.catalogTrackName, entry.sbn, range.holeLength));
228
+ } else {
229
+ clearRepair(entry.sbn, entry.packetId, entry.catalogTrackName);
230
+ }
231
+ };
232
+ const atReport = (range, work) => {
233
+ const fec = mc.fecManager;
234
+ if (range.groups !== null || fec.withReceiptTime === void 0) work();
235
+ else fec.withReceiptTime(range.reportedAt, work);
108
236
  };
109
237
  const releaseHold = (entry) => {
110
238
  if (entry.range) return;
@@ -171,21 +299,42 @@ function wireRepairFetch(mc, opts) {
171
299
  const admit = (entry, now) => {
172
300
  const budgetMs = entry.deadlineAt - now;
173
301
  const rttMs = readRtt();
174
- const reason = !entry.range && !groupCanComplete(entry.sbn, entry.packetId, entry.catalogTrackName) ? "group-cannot-complete" : rttMs === null ? "rtt-unmeasured" : rttMs < budgetMs ? null : "rtt-exceeds-budget";
302
+ const reason = refusal(entry, now, rttMs);
175
303
  if (reason === null) return rttMs;
176
304
  skip(entry, reason, rttMs, budgetMs);
177
305
  return null;
178
306
  };
307
+ const refusal = (entry, now, rttMs) => !entry.range && !groupCanComplete(entry.sbn, entry.packetId, entry.catalogTrackName) ? "group-cannot-complete" : rttMs === null ? "rtt-unmeasured" : rttMs < entry.deadlineAt - now ? null : "rtt-exceeds-budget";
179
308
  const retire = (entry) => {
180
309
  if (entries.get(entry.key) === entry) entries.delete(entry.key);
181
310
  if (entry.expiry !== void 0) clearTimeout(entry.expiry);
182
311
  };
183
- const outstandingBelow = (priority) => {
312
+ const holdsBack = (entry, priority, videoWalks = true) => {
313
+ if (entry.priority >= priority) return false;
314
+ const { walk } = entry;
315
+ if (walk === void 0) return true;
316
+ if (entry.priority !== 0 || !videoWalks) return false;
317
+ return entry.running === null || walk.group !== null && !walk.group.controller.signal.aborted;
318
+ };
319
+ const outstandingBelow = (priority, videoWalks = true) => {
184
320
  for (const entry of entries.values()) {
185
- if (entry.priority < priority) return true;
321
+ if (holdsBack(entry, priority, videoWalks)) return true;
186
322
  }
187
323
  return false;
188
324
  };
325
+ const yieldVideoWalks = (queued) => {
326
+ const now = performance.now();
327
+ const rttMs = readRtt();
328
+ const due = queued.some((entry) => entry.priority !== 0 && entry.walk === void 0 && !outstandingBelow(entry.priority, false) && refusal(entry, now, rttMs) === null);
329
+ if (!due) return;
330
+ for (const entry of entries.values()) {
331
+ const walk = entry.walk;
332
+ if (entry.priority !== 0 || walk === void 0 || walk.group === null) continue;
333
+ if (walk.group.controller.signal.aborted) continue;
334
+ walk.yielded = true;
335
+ walk.group.controller.abort();
336
+ }
337
+ };
189
338
  const preemptBestEffort = () => {
190
339
  for (const entry of entries.values()) {
191
340
  if (entry.priority === 0 || !entry.running) continue;
@@ -214,7 +363,8 @@ function wireRepairFetch(mc, opts) {
214
363
  }
215
364
  const rttMs = admit(entry, now);
216
365
  if (rttMs === null) return;
217
- if (entry.priority === 0) preemptBestEffort();
366
+ if (entry.priority === 0 && entry.walk === void 0) preemptBestEffort();
367
+ if (entry.range === void 0) leaveWalkedGroup(entry);
218
368
  if (counted) entry.attempts++;
219
369
  mc.noteRepairFetchSent?.(entry.priority, entry.sbn, entry.packetId, entry.catalogTrackName, {
220
370
  rttMs,
@@ -236,6 +386,14 @@ function wireRepairFetch(mc, opts) {
236
386
  }
237
387
  void execute(entry, run);
238
388
  };
389
+ const leaveWalkedGroup = (block) => {
390
+ for (const entry of entries.values()) {
391
+ const group = entry.walk?.group;
392
+ if (group?.sbn === block.sbn && entry.packetId === block.packetId && entry.catalogTrackName === block.catalogTrackName) {
393
+ group.controller.abort();
394
+ }
395
+ }
396
+ };
239
397
  const dispatch = () => {
240
398
  if (disposed) return;
241
399
  const now = performance.now();
@@ -260,6 +418,7 @@ function wireRepairFetch(mc, opts) {
260
418
  for (const entry of queued) {
261
419
  if (entry.priority === 0) start(entry);
262
420
  }
421
+ yieldVideoWalks(queued);
263
422
  if (outstandingBelow(1)) return;
264
423
  for (const entry of queued) {
265
424
  if (entry.priority === 1) start(entry);
@@ -286,6 +445,16 @@ function wireRepairFetch(mc, opts) {
286
445
  }
287
446
  return counts.sources + counts.repairGroupLength >= counts.authoredLength;
288
447
  };
448
+ const groupServed = (sbn, packetId, catalogTrackName) => {
449
+ if (mc.fecManager.blockSymbolCounts === void 0) return false;
450
+ const counts = symbolCounts(sbn, packetId, catalogTrackName);
451
+ if (counts === void 0 || counts.authoredLength === void 0) return true;
452
+ return counts.sources + counts.repairs >= counts.authoredLength || !groupCanComplete(sbn, packetId, catalogTrackName);
453
+ };
454
+ const statedEnd = (sbn, packetId, catalogTrackName) => {
455
+ const length = symbolCounts(sbn, packetId, catalogTrackName)?.authoredLength;
456
+ return length === void 0 ? void 0 : serial32Add(sbn, length);
457
+ };
289
458
  const finish = (entry, run, fed, error) => {
290
459
  if (run.stopped !== null || entry.running !== run || entries.get(entry.key) !== entry) {
291
460
  return;
@@ -330,27 +499,81 @@ function wireRepairFetch(mc, opts) {
330
499
  signal: run.controller.signal,
331
500
  subscriberPriority: entry.subscriberPriority
332
501
  };
502
+ const { range } = entry;
503
+ const feed = (packet) => {
504
+ if (entry.catalogTrackName === void 0) {
505
+ mc.processRepairFromMoQ(packet, entry.packetId);
506
+ } else {
507
+ mc.processRepairFromMoQ(packet, entry.packetId, entry.catalogTrackName);
508
+ }
509
+ };
333
510
  try {
334
- const packets = entry.range ? opts.rangeTransport({
511
+ const packets = range === void 0 ? opts.transport({ ...common, sbn: entry.sbn }) : entry.walk !== void 0 ? walkHole(entry, entry.walk, range, common) : opts.rangeTransport({
335
512
  ...common,
336
- startGroup: entry.range.startGroup,
337
- endGroup: entry.range.endGroup,
338
- lostSsId: entry.range.lostSsId
339
- }) : opts.transport({ ...common, sbn: entry.sbn });
513
+ startGroup: range.groups.startGroup,
514
+ endGroup: range.groups.endGroup,
515
+ lostSsId: range.lostSsId
516
+ });
340
517
  for await (const packet of packets) {
341
518
  if (run.stopped !== null || entry.running !== run) break;
342
519
  fed++;
343
- if (entry.catalogTrackName === void 0) {
344
- mc.processRepairFromMoQ(packet, entry.packetId);
345
- } else {
346
- mc.processRepairFromMoQ(packet, entry.packetId, entry.catalogTrackName);
347
- }
520
+ if (range === void 0) feed(packet);
521
+ else atReport(range, () => feed(packet));
348
522
  }
349
523
  finish(entry, run, fed, void 0);
350
524
  } catch (error) {
351
525
  finish(entry, run, fed, error ?? new Error("repair transport rejected"));
352
526
  }
353
527
  };
528
+ async function* walkHole(entry, walk, hole, common) {
529
+ const lostAt = serial32Distance(entry.sbn, hole.lostSsId);
530
+ for (let first = true; !common.signal.aborted; first = false) {
531
+ if (!first && entry.priority !== 0 && outstandingBelow(1)) {
532
+ stop(entry, "preempted");
533
+ note("repair-preempted", entry);
534
+ return;
535
+ }
536
+ if (!first && entry.priority === 0) {
537
+ dispatch();
538
+ if (common.signal.aborted) return;
539
+ }
540
+ const sbn = walk.next;
541
+ let next;
542
+ if (entries.get(requestKey(sbn, entry.packetId, entry.catalogTrackName))?.running == null) {
543
+ const rsIds = /* @__PURE__ */ new Set();
544
+ const group = new AbortController();
545
+ const cancel = () => group.abort();
546
+ common.signal.addEventListener("abort", cancel, { once: true });
547
+ walk.group = { sbn, controller: group };
548
+ try {
549
+ for await (const packet of opts.transport({ ...common, sbn, signal: group.signal })) {
550
+ yield packet;
551
+ const id = extractRepairFecPayloadId(packet);
552
+ if (id === null || id.ssStart !== sbn || id.ssbLength === 0) continue;
553
+ next ??= serial32Add(sbn, id.ssbLength);
554
+ rsIds.add(id.rsId);
555
+ if (rsIds.size >= id.rsbLength || groupServed(sbn, entry.packetId, entry.catalogTrackName)) {
556
+ group.abort();
557
+ break;
558
+ }
559
+ }
560
+ } catch (error) {
561
+ if (!group.signal.aborted || common.signal.aborted) throw error;
562
+ } finally {
563
+ common.signal.removeEventListener("abort", cancel);
564
+ walk.group = null;
565
+ }
566
+ if (walk.yielded) {
567
+ walk.yielded = false;
568
+ continue;
569
+ }
570
+ }
571
+ next ??= statedEnd(sbn, entry.packetId, entry.catalogTrackName);
572
+ if (next === void 0) return;
573
+ if (serial32Distance(entry.sbn, next) > lostAt) return;
574
+ walk.next = next;
575
+ }
576
+ }
354
577
  const removeResetObserver = mc.addTrackResetObserver((packetId, catalogTrackName) => {
355
578
  for (const entry of [...entries.values()]) {
356
579
  if (entry.packetId !== packetId || entry.catalogTrackName !== catalogTrackName) continue;
@@ -546,7 +769,37 @@ function wireRepairFetch(mc, opts) {
546
769
  throw error;
547
770
  }
548
771
  };
549
- if (opts.rangeTransport !== void 0) {
772
+ const trackKind = (packetId) => {
773
+ try {
774
+ return mc.fecManager.trackKindFor?.(packetId);
775
+ } catch {
776
+ return void 0;
777
+ }
778
+ };
779
+ const walkDeadlineAt = (packetId, now, deadlineAt) => {
780
+ let repairDeadlineMs;
781
+ try {
782
+ repairDeadlineMs = mc.fecManager.repairDeadlineMsForPacket?.(packetId);
783
+ } catch {
784
+ repairDeadlineMs = void 0;
785
+ }
786
+ if (repairDeadlineMs === void 0 || !Number.isFinite(repairDeadlineMs)) return deadlineAt;
787
+ return Math.min(deadlineAt, now + repairDeadlineMs - WALK_LEAD_MS);
788
+ };
789
+ const onHoleExpired = (hole) => {
790
+ if (disposed) return false;
791
+ const entry = [...entries.values()].find((candidate) => candidate.walk !== void 0 && candidate.packetId === hole.packetId && candidate.catalogTrackName === hole.catalogTrackName && serial32Distance(candidate.sbn, hole.holeStart) < candidate.range.holeLength);
792
+ if (entry === void 0) return false;
793
+ queueMicrotask(() => {
794
+ if (entries.get(entry.key) !== entry) return;
795
+ retire(entry);
796
+ stop(entry, "expired");
797
+ clearEntry(entry);
798
+ dispatch();
799
+ });
800
+ return true;
801
+ };
802
+ if (mc.onUndelimitedLoss !== void 0 && mc.closeIsoHoles !== void 0) {
550
803
  mc.onUndelimitedLoss((loss) => {
551
804
  const { packetId, catalogTrackName, holeStart, holeLength } = loss;
552
805
  const close = () => mc.closeIsoHoles(packetId, catalogTrackName, holeStart, holeLength);
@@ -554,9 +807,11 @@ function wireRepairFetch(mc, opts) {
554
807
  const blockProfile = blockProfileOf(packetId);
555
808
  const target = opts.resolveTarget(packetId, catalogTrackName);
556
809
  if (!target) return close();
557
- const priority = repairPriorityForClass("unknown");
558
- const range = rangeFor(loss, target.repairTrack);
559
- if (range === null) {
810
+ const walked = opts.rangeTransport === void 0;
811
+ const holeClass = walked && trackKind(packetId) === "audio" ? "audio" : "unknown";
812
+ const priority = repairPriorityForClass(holeClass);
813
+ const groups = walked ? null : rangeFor(loss, target.repairTrack);
814
+ if (!walked && groups === null) {
560
815
  close();
561
816
  mc.noteRepairSkipped("range-no-anchor", { rttMs: readRtt(), budgetMs: 0, priority }, holeStart, packetId, catalogTrackName);
562
817
  return;
@@ -567,8 +822,10 @@ function wireRepairFetch(mc, opts) {
567
822
  packetId,
568
823
  ...catalogTrackName === void 0 ? {} : { catalogTrackName }
569
824
  };
570
- const wire = wirePriority(identity, "unknown");
571
- const deadline = presentationDeadlineAt(holeStart, packetId, catalogTrackName, performance.now(), "unknown");
825
+ const wire = wirePriority(identity, holeClass);
826
+ if (wire === null) return close();
827
+ const now = performance.now();
828
+ const deadline = presentationDeadlineAt(holeStart, packetId, catalogTrackName, now, holeClass);
572
829
  if (deadline === null) {
573
830
  close();
574
831
  mc.noteRepairSkipped(
@@ -580,6 +837,7 @@ function wireRepairFetch(mc, opts) {
580
837
  );
581
838
  return;
582
839
  }
840
+ const deadlineAt = walked ? walkDeadlineAt(packetId, now, deadline.deadlineAt) : deadline.deadlineAt;
583
841
  const entry = {
584
842
  key: JSON.stringify(["range", packetId, catalogTrackName ?? null, holeStart]),
585
843
  ...identity,
@@ -587,15 +845,16 @@ function wireRepairFetch(mc, opts) {
587
845
  blockProfile,
588
846
  priority,
589
847
  subscriberPriority: wire.subscriberPriority,
590
- deadlineAt: deadline.deadlineAt,
591
- playoutDeadlineAt: deadline.deadlineAt - deadline.extensionMs,
848
+ deadlineAt,
849
+ playoutDeadlineAt: deadlineAt - deadline.extensionMs,
592
850
  anchorAt: deadline.anchorAt,
593
851
  delayMs: deadline.delayMs,
594
852
  bound: deadline.bound,
595
853
  order: enqueueOrder++,
596
854
  attempts: 0,
597
855
  running: null,
598
- range: { ...range, lostSsId: loss.lostSsId, holeLength }
856
+ range: { lostSsId: loss.lostSsId, holeLength, groups, reportedAt: now },
857
+ ...walked ? { walk: { next: holeStart, group: null, yielded: false } } : {}
599
858
  };
600
859
  const previous = entries.get(entry.key);
601
860
  if (previous) {
@@ -605,7 +864,7 @@ function wireRepairFetch(mc, opts) {
605
864
  entries.set(entry.key, entry);
606
865
  entry.expiry = setTimeout(dispatch, Math.max(0, entry.deadlineAt - performance.now()) + 1);
607
866
  dispatch();
608
- });
867
+ }, onHoleExpired);
609
868
  }
610
869
  const removeRapObserver = mc.addRapCompleteObserver?.((packetId) => {
611
870
  queueMicrotask(() => {