@blockcast/fec-worker 0.1.0-main.ce3c8aeb7f68 → 0.1.0-main.d0bb31684c09
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 +8 -4
- package/dist/block-order.d.ts +22 -0
- package/dist/block-order.d.ts.map +1 -0
- package/dist/block-order.js +38 -0
- package/dist/block-order.js.map +1 -0
- package/dist/fec-worker-client.d.ts +0 -2
- package/dist/fec-worker-client.d.ts.map +1 -1
- package/dist/fec-worker-client.js +0 -8
- package/dist/fec-worker-client.js.map +1 -1
- package/dist/fec-worker-types.d.ts +44 -8
- package/dist/fec-worker-types.d.ts.map +1 -1
- package/dist/fec-worker.js +54 -45
- package/dist/fec-worker.js.map +3 -3
- package/package.json +2 -2
- package/src/block-order.ts +42 -0
- package/src/fec-worker-client.ts +0 -9
- package/src/fec-worker-types.ts +44 -5
- package/src/fec-worker.ts +84 -66
package/README.md
CHANGED
|
@@ -129,7 +129,6 @@ All messages are typed as discriminated unions in `fec-worker-types.ts`. Both th
|
|
|
129
129
|
| `snapshot` | `stats: FecTrackStats` | none (structured clone) |
|
|
130
130
|
| `capabilities` | `commands: FecWorkerOptionalCommand[]` (after `configure`) | none |
|
|
131
131
|
| `blockUpdate` | `block: FecBlockSnapshot` (only after `subscribeBlockUpdates`) | none |
|
|
132
|
-
| `greenFill` | `sbn: number`, `data: ArrayBuffer` | `data` |
|
|
133
132
|
| `cleanupComplete` | `sbns: number[]` | none |
|
|
134
133
|
| `error` | `message: string` | none |
|
|
135
134
|
|
|
@@ -144,7 +143,7 @@ new FecWorkerClient(url)
|
|
|
144
143
|
│ worker spawned with { type: "module" }
|
|
145
144
|
▼
|
|
146
145
|
client.configure(config, wasmModule [, altaPublicKey, altaWasmModule])
|
|
147
|
-
│ worker initSyncs WASM, instantiates MmtFecDecoder(interleaveDepth
|
|
146
|
+
│ worker initSyncs WASM, instantiates MmtFecDecoder(interleaveDepth),
|
|
148
147
|
│ immediately configures exact catalog K/T (no decoder defaults),
|
|
149
148
|
│ derives pendingVerifyCap = ceil(D × 1.5) and TTL = ceil(K × interleaveMs × 1.5)
|
|
150
149
|
│ from catalog values, throws if any of K / D / interleaveMs ≤ 0,
|
|
@@ -158,7 +157,9 @@ client.feedSource(...) / feedRepair(...) ◄── steady state
|
|
|
158
157
|
client.cleanup(sbn) ◄── per-block inactivity deadline
|
|
159
158
|
│ coalesces queued SBNs behind one worker queue-drain barrier
|
|
160
159
|
│ evicts blocks relative to max(sbns) − D × 3
|
|
161
|
-
│
|
|
160
|
+
│ retires exactly those SBNs via WASM cleanup_blocks_detailed(); a lost
|
|
161
|
+
│ block is never answered with a synthesised frame (sinks hold the last
|
|
162
|
+
│ good frame, per @blockcast/mmt-container conceal-timeline)
|
|
162
163
|
│ acknowledges every SBN in {type:"cleanupComplete", sbns}
|
|
163
164
|
│ any block still in "collecting" at eviction time is counted as failed
|
|
164
165
|
▼
|
|
@@ -183,13 +184,16 @@ The `snapshot` event delivers a `FecTrackStats` every 200 ms (catalog-derived; n
|
|
|
183
184
|
| `blocksComplete` | Block had all K source symbols without needing repair |
|
|
184
185
|
| `blocksRecovered` | Block was recovered using ≥1 repair symbol |
|
|
185
186
|
| `blocksFailed` | Block aged out before reaching K |
|
|
186
|
-
| `greenFillFrames` | Frames substituted with green-fill on unrecoverable loss |
|
|
187
187
|
| `recoveryRate` | `recovered / (recovered + failed)`, 0–100 |
|
|
188
188
|
| `avgRecoveryMs`, `maxRecoveryMs` | Rolling decode latency (capped at 1000 samples) |
|
|
189
189
|
| `liveSbn` | Highest source-block number observed |
|
|
190
|
+
| `repairSymbolSizeMismatch` | Repair symbols rejected before WASM because their byte length did not match `T` |
|
|
191
|
+
| `sourceDroppedRetired` / `sourceDroppedTerminal` / `sourceDroppedDuplicate` | Source symbols dropped before WASM, by **first matching** cause (see below) |
|
|
190
192
|
| `blocks` | Up to `max(D × 3, 24)` recent `FecBlockSnapshot`s for live visualization |
|
|
191
193
|
| `interleaveWindowBlocks` | `D` from config |
|
|
192
194
|
|
|
195
|
+
The three `sourceDropped*` counters split by cause for the same reason the ALTA four-way split exists — so a dashboard can tell the failure modes apart. They are tested in a fixed order, each returning early — `Retired` → `Terminal` → `Duplicate` — so a symbol counts once, under the **first** cause that matches: a symbol that is both past retention and a repeat counts only as `Retired`, and `Terminal` absorbs every post-settle duplicate. A block that settles at K-1 source symbols (BLO-35597 defect 2) is explained by a late symbol past retention (`Retired`), a symbol for a block that had already settled — complete, recovered **or failed** (`Terminal`), or a repeated `(SBN, ESI)` (`Duplicate`). `Retired` and `Terminal` narrow the cause; they do not attribute it. `Duplicate` does: it cannot fire once a block settles — the `Terminal` check returns first, and `markBlockTerminal` retires the block's accepted-ESI set anyway — so a non-zero `Duplicate` is positive evidence that a repeated `(SBN, ESI)` reached the worker while the block was **still collecting** — usually a duplicate packet on the wire, sometimes an SBN/ESI derivation collision. It attributes the **timing**, not the origin. A symbol lost in transit never reaches the worker and increments nothing, so **all three reading zero is not evidence of a publisher defect** — wire loss produces an identical shape. Separate those with `FecBlockSnapshot.ssbLength`: below `k` is a genuinely short authored block, equal to `k` with fewer accepted is loss-or-late, undefined (no repair symbol yet) leaves both open. All three are cumulative across decoder epochs, so they stay comparable against the `sourceSymbols` denominator; only a reset zeroes them.
|
|
196
|
+
|
|
193
197
|
When ALTA is enabled, the snapshot also carries the four-state verification accounting — `altaVerified` (crypto passed), `altaFailed` (tamper-confirmed), `altaPending` (unverifiable, e.g. missing trailer / late-joiner anchor gap), `altaError` (verifier threw — infrastructure flake, not tamper) — plus `altaInitFailed` (true if the ALTA WASM didn't initialize), `altaPendingEvictedCap` / `altaPendingEvictedTtl` (deferred-queue eviction reasons), and a bounded `altaFailedDetails[]` ring with the last ≤16 tamper events. The four-way split exists so ops alerting can distinguish a network problem (`altaPending` rising) from an attack (`altaFailed` rising) from a runtime bug (`altaError` rising).
|
|
194
198
|
|
|
195
199
|
`FecTrackStats` is also the shape consumed downstream by `@blockcast/mmt-container`'s `CmcdProducer` and the diagnostics `fec-panel` — keep it stable when you extend it.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Order of K-stride FEC blocks on the 32-bit SS_ID (ISO/IEC 23008-1:2023
|
|
3
|
+
* C.5.2; RFC 1982 serial arithmetic, SERIAL_BITS = 32; BLO-35597 iso:5).
|
|
4
|
+
*
|
|
5
|
+
* Block `sbn` starts at SS_ID `sbn * K mod 2^32`, and blocks are ordered by
|
|
6
|
+
* serial comparison of their starts. That is identical to comparing SBNs
|
|
7
|
+
* with < for any two blocks less than 2^31 SS_IDs apart, so only the order
|
|
8
|
+
* across the SS_ID wrap changes.
|
|
9
|
+
*
|
|
10
|
+
* The canonical helpers are @blockcast/mmt-base `kStrideBlockPrecedes` /
|
|
11
|
+
* `kStrideBlocksBehind`. This worker bundle does not depend on mmt-base, so
|
|
12
|
+
* it carries these two, and block-order.test.ts pins them to the same wrap
|
|
13
|
+
* vectors.
|
|
14
|
+
*/
|
|
15
|
+
/** Whether block `a` precedes block `b`. */
|
|
16
|
+
export declare function blockPrecedes(a: number, b: number, k: number): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* How many blocks `a` lies behind `b`: 0 unless `a` precedes `b`. Across the
|
|
19
|
+
* wrap the short pre-wrap block (2^32 mod K symbols) counts as one block.
|
|
20
|
+
*/
|
|
21
|
+
export declare function blocksBehind(a: number, b: number, k: number): number;
|
|
22
|
+
//# sourceMappingURL=block-order.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-order.d.ts","sourceRoot":"","sources":["../src/block-order.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAgBH,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAGpE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Order of K-stride FEC blocks on the 32-bit SS_ID (ISO/IEC 23008-1:2023
|
|
3
|
+
* C.5.2; RFC 1982 serial arithmetic, SERIAL_BITS = 32; BLO-35597 iso:5).
|
|
4
|
+
*
|
|
5
|
+
* Block `sbn` starts at SS_ID `sbn * K mod 2^32`, and blocks are ordered by
|
|
6
|
+
* serial comparison of their starts. That is identical to comparing SBNs
|
|
7
|
+
* with < for any two blocks less than 2^31 SS_IDs apart, so only the order
|
|
8
|
+
* across the SS_ID wrap changes.
|
|
9
|
+
*
|
|
10
|
+
* The canonical helpers are @blockcast/mmt-base `kStrideBlockPrecedes` /
|
|
11
|
+
* `kStrideBlocksBehind`. This worker bundle does not depend on mmt-base, so
|
|
12
|
+
* it carries these two, and block-order.test.ts pins them to the same wrap
|
|
13
|
+
* vectors.
|
|
14
|
+
*/
|
|
15
|
+
const SPAN = 0x1_0000_0000;
|
|
16
|
+
const HALF = 0x8000_0000;
|
|
17
|
+
function blockStart(sbn, k) {
|
|
18
|
+
// sbn < 2^32 and k <= 56 403 keep the product below 2^48: exact.
|
|
19
|
+
return (sbn * k) % SPAN;
|
|
20
|
+
}
|
|
21
|
+
/** Forward SS_ID distance from block `a`'s start to block `b`'s, or null when `a` does not precede `b`. */
|
|
22
|
+
function precedingDistance(a, b, k) {
|
|
23
|
+
const distance = (blockStart(b, k) - blockStart(a, k) + SPAN) % SPAN;
|
|
24
|
+
return distance !== 0 && distance < HALF ? distance : null;
|
|
25
|
+
}
|
|
26
|
+
/** Whether block `a` precedes block `b`. */
|
|
27
|
+
export function blockPrecedes(a, b, k) {
|
|
28
|
+
return precedingDistance(a, b, k) !== null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* How many blocks `a` lies behind `b`: 0 unless `a` precedes `b`. Across the
|
|
32
|
+
* wrap the short pre-wrap block (2^32 mod K symbols) counts as one block.
|
|
33
|
+
*/
|
|
34
|
+
export function blocksBehind(a, b, k) {
|
|
35
|
+
const distance = precedingDistance(a, b, k);
|
|
36
|
+
return distance === null ? 0 : Math.ceil(distance / k);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=block-order.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-order.js","sourceRoot":"","sources":["../src/block-order.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,IAAI,GAAG,aAAa,CAAC;AAC3B,MAAM,IAAI,GAAG,WAAW,CAAC;AAEzB,SAAS,UAAU,CAAC,GAAW,EAAE,CAAS;IACzC,iEAAiE;IACjE,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;AACzB,CAAC;AAED,2GAA2G;AAC3G,SAAS,iBAAiB,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS;IACzD,MAAM,QAAQ,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACrE,OAAO,QAAQ,KAAK,CAAC,IAAI,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5D,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS;IAC5D,OAAO,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS;IAC3D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5C,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -71,8 +71,6 @@ export declare class FecWorkerClient {
|
|
|
71
71
|
* announce it posts them unasked.
|
|
72
72
|
*/
|
|
73
73
|
onBlockUpdate(cb: (block: FecBlockSnapshot) => void): void;
|
|
74
|
-
/** Register callback for green-fill frames. */
|
|
75
|
-
onGreenFill(cb: (sbn: number, data: ArrayBuffer) => void): void;
|
|
76
74
|
/** Register callback fired after the Worker drains all commands queued before cleanup. */
|
|
77
75
|
onCleanupComplete(cb: (sbn: number) => void): void;
|
|
78
76
|
/** Register callback for Worker errors. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fec-worker-client.d.ts","sourceRoot":"","sources":["../src/fec-worker-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAIX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,MAAM,uBAAuB,CAAC;AAE/B,qBAAa,eAAe;;
|
|
1
|
+
{"version":3,"file":"fec-worker-client.d.ts","sourceRoot":"","sources":["../src/fec-worker-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAIX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,MAAM,uBAAuB,CAAC;AAE/B,qBAAa,eAAe;;IA2B3B;;;OAGG;gBACS,WAAW,EAAE,MAAM,GAAG,GAAG;IAgBrC;;;;;;OAMG;IACH,SAAS,CACR,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,WAAW,CAAC,MAAM,EAC9B,aAAa,CAAC,EAAE,WAAW,EAC3B,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,GACjC,IAAI;IAmBP;;;;;;;;;OASG;IACH,UAAU,CACT,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,EACjB,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAC9C,IAAI;IAoBP;;;;;;;;OAQG;IACH,UAAU,CACT,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,EACjB,EAAE,EAAE,MAAM,GACR,IAAI;IAqCP;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI;IASrE;;;;;OAKG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAgBjC,8EAA8E;IAC9E,KAAK,IAAI,IAAI;IAoBb,+DAA+D;IAC/D,OAAO,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,IAAI;IAI/D,+DAA+D;IAC/D,UAAU,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAIpD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI;IAkB1D,0FAA0F;IAC1F,iBAAiB,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIlD,2CAA2C;IAC3C,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI;IAIvE;;;;;OAKG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;OAGG;IACH,OAAO,IAAI,IAAI;CA6Df"}
|
|
@@ -12,7 +12,6 @@ export class FecWorkerClient {
|
|
|
12
12
|
#onFrame = null;
|
|
13
13
|
#onSnapshot = null;
|
|
14
14
|
#onBlockUpdate = null;
|
|
15
|
-
#onGreenFill = null;
|
|
16
15
|
#onCleanupComplete = null;
|
|
17
16
|
#onError = null;
|
|
18
17
|
#cleanupInFlight = null;
|
|
@@ -225,10 +224,6 @@ export class FecWorkerClient {
|
|
|
225
224
|
this.#blockUpdatesSubscribed = true;
|
|
226
225
|
this.#worker.postMessage({ type: "subscribeBlockUpdates" });
|
|
227
226
|
}
|
|
228
|
-
/** Register callback for green-fill frames. */
|
|
229
|
-
onGreenFill(cb) {
|
|
230
|
-
this.#onGreenFill = cb;
|
|
231
|
-
}
|
|
232
227
|
/** Register callback fired after the Worker drains all commands queued before cleanup. */
|
|
233
228
|
onCleanupComplete(cb) {
|
|
234
229
|
this.#onCleanupComplete = cb;
|
|
@@ -301,9 +296,6 @@ export class FecWorkerClient {
|
|
|
301
296
|
case "blockUpdate":
|
|
302
297
|
this.#onBlockUpdate?.(event.block);
|
|
303
298
|
break;
|
|
304
|
-
case "greenFill":
|
|
305
|
-
this.#onGreenFill?.(event.sbn, event.data);
|
|
306
|
-
break;
|
|
307
299
|
case "cleanupComplete":
|
|
308
300
|
for (const sbn of event.sbns) {
|
|
309
301
|
this.#onCleanupComplete?.(sbn);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fec-worker-client.js","sourceRoot":"","sources":["../src/fec-worker-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,MAAM,OAAO,eAAe;IAClB,OAAO,CAAS;IACzB,QAAQ,GAA0D,IAAI,CAAC;IACvE,WAAW,GAA4C,IAAI,CAAC;IAC5D,cAAc,GAA+C,IAAI,CAAC;IAClE,
|
|
1
|
+
{"version":3,"file":"fec-worker-client.js","sourceRoot":"","sources":["../src/fec-worker-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,7 +32,12 @@ export interface FecTrackConfig {
|
|
|
32
32
|
repairCount: number;
|
|
33
33
|
/** Bytes per symbol */
|
|
34
34
|
symbolSize: number;
|
|
35
|
-
/**
|
|
35
|
+
/** Retained decoder horizon as a BLOCK COUNT (SBN distance), not D.
|
|
36
|
+
* `isRetiredSbn` retires blocks more than this many blocks behind
|
|
37
|
+
* `liveSbn` (serial order on SS_ID, BLO-35597 iso:5) and
|
|
38
|
+
* `MmtFecDecoder::new` documents it as "the number of interleaved blocks".
|
|
39
|
+
* Never assign `deriveFecInterleaveDepth()` here — that returns media units
|
|
40
|
+
* per block, which is a different quantity (BLO-35597). */
|
|
36
41
|
interleaveDepth: number;
|
|
37
42
|
/** Interleave depth in milliseconds (D * frameDurationMs) */
|
|
38
43
|
interleaveMs: number;
|
|
@@ -52,7 +57,7 @@ export interface FecBlockSnapshot {
|
|
|
52
57
|
/** Source block number */
|
|
53
58
|
sbn: number;
|
|
54
59
|
/** Current block state */
|
|
55
|
-
state: "collecting" | "complete" | "recovered" | "failed"
|
|
60
|
+
state: "collecting" | "complete" | "recovered" | "failed";
|
|
56
61
|
/** Number of source symbols received */
|
|
57
62
|
sourceReceived: number;
|
|
58
63
|
/** Number of repair symbols received */
|
|
@@ -90,8 +95,6 @@ export interface FecTrackStats {
|
|
|
90
95
|
blocksRecovered: number;
|
|
91
96
|
/** Blocks that failed (unrecoverable) */
|
|
92
97
|
blocksFailed: number;
|
|
93
|
-
/** Frames replaced with green-fill */
|
|
94
|
-
greenFillFrames: number;
|
|
95
98
|
/** Recovery success rate 0-100 */
|
|
96
99
|
recoveryRate: number;
|
|
97
100
|
/** Packets with valid publisher ALTA signature */
|
|
@@ -142,6 +145,43 @@ export interface FecTrackStats {
|
|
|
142
145
|
maxRecoveryMs: number;
|
|
143
146
|
/** Repair symbols rejected before WASM because their byte length did not match T. */
|
|
144
147
|
repairSymbolSizeMismatch?: number;
|
|
148
|
+
/**
|
|
149
|
+
* Source symbols whose SBN had already fallen below the retained window.
|
|
150
|
+
*
|
|
151
|
+
* This and its two peers below are dropped before WASM and narrow the
|
|
152
|
+
* explanations for a block that settles at K-1 source symbols (BLO-35597
|
|
153
|
+
* defect 2): a late symbol past retention, a symbol for a block that had
|
|
154
|
+
* already settled (complete, recovered *or failed*), or a repeated
|
|
155
|
+
* (SBN, ESI).
|
|
156
|
+
*
|
|
157
|
+
* They narrow; they do not uniquely attribute. A symbol lost in transit
|
|
158
|
+
* never reaches the worker and increments nothing, so all three reading
|
|
159
|
+
* zero on a short block means only that no *receiver-side* drop was
|
|
160
|
+
* recorded — wire loss and a short authored block both remain open. Use
|
|
161
|
+
* `FecBlockSnapshot.ssbLength` to separate them: below `k` is a genuinely
|
|
162
|
+
* short authored block, equal to `k` with fewer accepted is loss-or-late.
|
|
163
|
+
* `ssbLength` is undefined until a repair symbol declares it, in which case
|
|
164
|
+
* both stay open.
|
|
165
|
+
*
|
|
166
|
+
* All three are cumulative across decoder epochs: `configure` clears block
|
|
167
|
+
* tracking but none of them, so they stay comparable against the
|
|
168
|
+
* `sourceSymbols` denominator. Only a reset zeroes them.
|
|
169
|
+
*/
|
|
170
|
+
sourceDroppedRetired?: number;
|
|
171
|
+
/** Source symbols for a block that had already completed, recovered or failed. */
|
|
172
|
+
sourceDroppedTerminal?: number;
|
|
173
|
+
/**
|
|
174
|
+
* Source symbols repeating an (SBN, ESI) already accepted in the current
|
|
175
|
+
* epoch; `configure` clears the accepted-ESI sets.
|
|
176
|
+
*
|
|
177
|
+
* Unlike the other two, this one cannot fire once a block settles — the
|
|
178
|
+
* terminal check returns first, and marking a block terminal retires its
|
|
179
|
+
* accepted-ESI set anyway — so a non-zero value means the repeat reached
|
|
180
|
+
* the worker while the block was **still collecting**. It attributes the
|
|
181
|
+
* timing, not the origin: usually a duplicate packet on the wire,
|
|
182
|
+
* sometimes an SBN/ESI derivation collision.
|
|
183
|
+
*/
|
|
184
|
+
sourceDroppedDuplicate?: number;
|
|
145
185
|
/** Native decoder counters, converted to numbers so browser diagnostics remain JSON-safe. */
|
|
146
186
|
decoder?: {
|
|
147
187
|
sourcePackets: number;
|
|
@@ -268,10 +308,6 @@ export type FecWorkerEvent = {
|
|
|
268
308
|
} | {
|
|
269
309
|
type: "blockUpdate";
|
|
270
310
|
block: FecBlockSnapshot;
|
|
271
|
-
} | {
|
|
272
|
-
type: "greenFill";
|
|
273
|
-
sbn: number;
|
|
274
|
-
data: ArrayBuffer;
|
|
275
311
|
} | {
|
|
276
312
|
type: "cleanupComplete";
|
|
277
313
|
sbns: number[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fec-worker-types.d.ts","sourceRoot":"","sources":["../src/fec-worker-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,mFAAmF;AACnF,MAAM,WAAW,cAAc;IAC9B,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,2CAA2C;IAC3C,UAAU,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,CAAC,EAAE,MAAM,CAAC;IACV,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB
|
|
1
|
+
{"version":3,"file":"fec-worker-types.d.ts","sourceRoot":"","sources":["../src/fec-worker-types.ts"],"names":[],"mappings":"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"}
|
package/dist/fec-worker.js
CHANGED
|
@@ -7,6 +7,24 @@ function toOwnedArrayBuffer(view) {
|
|
|
7
7
|
return copy.buffer;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
// src/block-order.ts
|
|
11
|
+
var SPAN = 4294967296;
|
|
12
|
+
var HALF = 2147483648;
|
|
13
|
+
function blockStart(sbn, k) {
|
|
14
|
+
return sbn * k % SPAN;
|
|
15
|
+
}
|
|
16
|
+
function precedingDistance(a, b, k) {
|
|
17
|
+
const distance = (blockStart(b, k) - blockStart(a, k) + SPAN) % SPAN;
|
|
18
|
+
return distance !== 0 && distance < HALF ? distance : null;
|
|
19
|
+
}
|
|
20
|
+
function blockPrecedes(a, b, k) {
|
|
21
|
+
return precedingDistance(a, b, k) !== null;
|
|
22
|
+
}
|
|
23
|
+
function blocksBehind(a, b, k) {
|
|
24
|
+
const distance = precedingDistance(a, b, k);
|
|
25
|
+
return distance === null ? 0 : Math.ceil(distance / k);
|
|
26
|
+
}
|
|
27
|
+
|
|
10
28
|
// src/fec-worker.ts
|
|
11
29
|
var wasmDecoder = null;
|
|
12
30
|
var config = null;
|
|
@@ -27,7 +45,6 @@ var repairSymbols = 0;
|
|
|
27
45
|
var blocksComplete = 0;
|
|
28
46
|
var blocksRecovered = 0;
|
|
29
47
|
var blocksFailed = 0;
|
|
30
|
-
var greenFillFrames = 0;
|
|
31
48
|
var altaVerified = 0;
|
|
32
49
|
var altaFailed = 0;
|
|
33
50
|
var altaFailedDetails = [];
|
|
@@ -39,8 +56,11 @@ var altaInitFailed = false;
|
|
|
39
56
|
var relayBlocksVerified = 0;
|
|
40
57
|
var relayBlocksFailed = 0;
|
|
41
58
|
var liveSbn = 0;
|
|
42
|
-
var
|
|
59
|
+
var liveSbnKnown = false;
|
|
43
60
|
var repairSymbolSizeMismatch = 0;
|
|
61
|
+
var sourceDroppedRetired = 0;
|
|
62
|
+
var sourceDroppedTerminal = 0;
|
|
63
|
+
var sourceDroppedDuplicate = 0;
|
|
44
64
|
var recoveryTimes = [];
|
|
45
65
|
var pendingVerify = /* @__PURE__ */ new Map();
|
|
46
66
|
var pendingVerifyCap = 0;
|
|
@@ -65,20 +85,22 @@ function clearBlockTracking() {
|
|
|
65
85
|
pendingVerify.clear();
|
|
66
86
|
recoveryTimes.length = 0;
|
|
67
87
|
liveSbn = 0;
|
|
68
|
-
|
|
88
|
+
liveSbnKnown = false;
|
|
89
|
+
}
|
|
90
|
+
function isRetiredSbn(sbn) {
|
|
91
|
+
return config !== null && liveSbnKnown && blocksBehind(sbn, liveSbn, config.k) > config.interleaveDepth;
|
|
69
92
|
}
|
|
70
93
|
function trimBlockRetention() {
|
|
71
94
|
for (const [sbn, block] of blocks) {
|
|
72
|
-
if (!isTerminalBlock(block) || sbn
|
|
95
|
+
if (!isTerminalBlock(block) || !isRetiredSbn(sbn)) continue;
|
|
73
96
|
blocks.delete(sbn);
|
|
74
97
|
retireAcceptedIds(sbn);
|
|
75
98
|
}
|
|
76
99
|
}
|
|
77
100
|
function advanceMediaHorizon(sbn) {
|
|
78
|
-
if (!config ||
|
|
101
|
+
if (!config || liveSbnKnown && !blockPrecedes(liveSbn, sbn, config.k)) return;
|
|
79
102
|
liveSbn = sbn;
|
|
80
|
-
|
|
81
|
-
retiredSbnFrontier = Math.max(retiredSbnFrontier, firstRetainedSbn - 1);
|
|
103
|
+
liveSbnKnown = true;
|
|
82
104
|
trimBlockRetention();
|
|
83
105
|
}
|
|
84
106
|
function markBlockTerminal(block, state) {
|
|
@@ -88,7 +110,7 @@ function markBlockTerminal(block, state) {
|
|
|
88
110
|
trimBlockRetention();
|
|
89
111
|
}
|
|
90
112
|
function synchronizeDecoderHorizon() {
|
|
91
|
-
if (!wasmDecoder) return;
|
|
113
|
+
if (!wasmDecoder || !liveSbnKnown) return;
|
|
92
114
|
const expired = wasmDecoder.cleanup_by_sbn(liveSbn);
|
|
93
115
|
for (const sbn of expired) {
|
|
94
116
|
const block = blocks.get(sbn);
|
|
@@ -148,7 +170,6 @@ function buildStatsSnapshot() {
|
|
|
148
170
|
blocksComplete,
|
|
149
171
|
blocksRecovered,
|
|
150
172
|
blocksFailed,
|
|
151
|
-
greenFillFrames,
|
|
152
173
|
recoveryRate: blocksComplete + blocksRecovered > 0 ? Math.round(
|
|
153
174
|
blocksRecovered / (blocksRecovered + blocksFailed) * 100
|
|
154
175
|
) || 0 : 0,
|
|
@@ -169,6 +190,9 @@ function buildStatsSnapshot() {
|
|
|
169
190
|
avgRecoveryMs: Math.round(avgRecoveryMs * 100) / 100,
|
|
170
191
|
maxRecoveryMs: Math.round(maxRecoveryMs * 100) / 100,
|
|
171
192
|
repairSymbolSizeMismatch,
|
|
193
|
+
sourceDroppedRetired,
|
|
194
|
+
sourceDroppedTerminal,
|
|
195
|
+
sourceDroppedDuplicate,
|
|
172
196
|
decoder
|
|
173
197
|
};
|
|
174
198
|
}
|
|
@@ -265,10 +289,7 @@ async function handleConfigure(cmd) {
|
|
|
265
289
|
wasmDecoder?.free();
|
|
266
290
|
wasmDecoder = null;
|
|
267
291
|
clearBlockTracking();
|
|
268
|
-
wasmDecoder = new wasm.MmtFecDecoder(
|
|
269
|
-
cmd.config.interleaveDepth,
|
|
270
|
-
cmd.config.trackType === "video"
|
|
271
|
-
);
|
|
292
|
+
wasmDecoder = new wasm.MmtFecDecoder(cmd.config.interleaveDepth);
|
|
272
293
|
config = cmd.config;
|
|
273
294
|
altaEnabled = !!cmd.altaPublicKey;
|
|
274
295
|
pendingVerifyCap = Math.ceil(config.interleaveDepth * 1.5);
|
|
@@ -310,10 +331,19 @@ function handleFeedSource(cmd) {
|
|
|
310
331
|
const view = new Uint8Array(cmd.data);
|
|
311
332
|
const sbn = config.k > 0 ? Math.floor(cmd.ssId / config.k) : cmd.ssId;
|
|
312
333
|
const esi = cmd.ssId % config.k;
|
|
313
|
-
if (sbn
|
|
334
|
+
if (isRetiredSbn(sbn)) {
|
|
335
|
+
sourceDroppedRetired++;
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
314
338
|
const existingBlock = blocks.get(sbn);
|
|
315
|
-
if (existingBlock && isTerminalBlock(existingBlock))
|
|
316
|
-
|
|
339
|
+
if (existingBlock && isTerminalBlock(existingBlock)) {
|
|
340
|
+
sourceDroppedTerminal++;
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
if (acceptedSourceEsis.get(sbn)?.has(esi)) {
|
|
344
|
+
sourceDroppedDuplicate++;
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
317
347
|
const result = wasmDecoder.add_source(cmd.ssId, view, cmd.ts);
|
|
318
348
|
advanceMediaHorizon(sbn);
|
|
319
349
|
let sourceEsis = acceptedSourceEsis.get(sbn);
|
|
@@ -371,7 +401,7 @@ function handleFeedRepair(cmd) {
|
|
|
371
401
|
}
|
|
372
402
|
const sbn = Math.floor(cmd.ssStart / config.k);
|
|
373
403
|
const repairEsi = config.k + cmd.rsId;
|
|
374
|
-
if (sbn
|
|
404
|
+
if (isRetiredSbn(sbn)) return;
|
|
375
405
|
const existingBlock = blocks.get(sbn);
|
|
376
406
|
if (existingBlock && isTerminalBlock(existingBlock)) return;
|
|
377
407
|
if (acceptedRepairEsis.get(sbn)?.has(repairEsi)) return;
|
|
@@ -432,12 +462,14 @@ function handleCleanup(cmd) {
|
|
|
432
462
|
throw new Error("[FecWorker] cleanup: invalid SBNs");
|
|
433
463
|
}
|
|
434
464
|
const sbns = [...new Set(cmd.sbns)].sort((a, b) => a - b);
|
|
435
|
-
const pendingSbns = sbns.filter((sbn) => sbn
|
|
465
|
+
const pendingSbns = sbns.filter((sbn) => !isRetiredSbn(sbn));
|
|
436
466
|
try {
|
|
437
467
|
if (!wasmDecoder) {
|
|
438
468
|
throw new Error("[FecWorker] cleanup: not configured");
|
|
439
469
|
}
|
|
440
|
-
|
|
470
|
+
if (pendingSbns.length > 0) {
|
|
471
|
+
wasmDecoder.cleanup_blocks_detailed(Uint32Array.from(pendingSbns));
|
|
472
|
+
}
|
|
441
473
|
for (const sbn of pendingSbns) {
|
|
442
474
|
let currentBlock = blocks.get(sbn);
|
|
443
475
|
if (currentBlock && isTerminalBlock(currentBlock)) {
|
|
@@ -454,35 +486,10 @@ function handleCleanup(cmd) {
|
|
|
454
486
|
}
|
|
455
487
|
emitBlockUpdate(currentBlock);
|
|
456
488
|
}
|
|
457
|
-
const greenFills = decodeCleanupRecords(cleanupRecords);
|
|
458
|
-
for (const { sbn, data } of greenFills) {
|
|
459
|
-
greenFillFrames++;
|
|
460
|
-
emit({ type: "greenFill", sbn, data }, [data]);
|
|
461
|
-
}
|
|
462
489
|
} finally {
|
|
463
490
|
emit({ type: "cleanupComplete", sbns });
|
|
464
491
|
}
|
|
465
492
|
}
|
|
466
|
-
function decodeCleanupRecords(framed) {
|
|
467
|
-
const records = [];
|
|
468
|
-
const view = new DataView(framed.buffer, framed.byteOffset, framed.byteLength);
|
|
469
|
-
let offset = 0;
|
|
470
|
-
while (offset < framed.byteLength) {
|
|
471
|
-
if (framed.byteLength - offset < 8) {
|
|
472
|
-
throw new Error("[FecWorker] cleanup_blocks_detailed: truncated record header");
|
|
473
|
-
}
|
|
474
|
-
const sbn = view.getUint32(offset, false);
|
|
475
|
-
const length = view.getUint32(offset + 4, false);
|
|
476
|
-
offset += 8;
|
|
477
|
-
if (length > framed.byteLength - offset) {
|
|
478
|
-
throw new Error("[FecWorker] cleanup_blocks_detailed: truncated record payload");
|
|
479
|
-
}
|
|
480
|
-
const data = toOwnedArrayBuffer(framed.subarray(offset, offset + length));
|
|
481
|
-
records.push({ sbn, data });
|
|
482
|
-
offset += length;
|
|
483
|
-
}
|
|
484
|
-
return records;
|
|
485
|
-
}
|
|
486
493
|
function handleDispose() {
|
|
487
494
|
if (snapshotTimer !== null) {
|
|
488
495
|
clearInterval(snapshotTimer);
|
|
@@ -523,7 +530,6 @@ function handleReset() {
|
|
|
523
530
|
blocksComplete = 0;
|
|
524
531
|
blocksRecovered = 0;
|
|
525
532
|
blocksFailed = 0;
|
|
526
|
-
greenFillFrames = 0;
|
|
527
533
|
altaVerified = 0;
|
|
528
534
|
altaFailed = 0;
|
|
529
535
|
altaFailedDetails.length = 0;
|
|
@@ -534,6 +540,9 @@ function handleReset() {
|
|
|
534
540
|
relayBlocksVerified = 0;
|
|
535
541
|
relayBlocksFailed = 0;
|
|
536
542
|
repairSymbolSizeMismatch = 0;
|
|
543
|
+
sourceDroppedRetired = 0;
|
|
544
|
+
sourceDroppedTerminal = 0;
|
|
545
|
+
sourceDroppedDuplicate = 0;
|
|
537
546
|
emit({ type: "resetComplete" });
|
|
538
547
|
if (config) emitSnapshot();
|
|
539
548
|
}
|