@blockcast/mmt-fec 0.3.0 → 0.4.0-main.248efb07e294
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 +17 -15
- package/dist/block-manager.d.ts +7 -4
- package/dist/block-manager.d.ts.map +1 -1
- package/dist/block-manager.js +8 -5
- package/dist/block-manager.js.map +1 -1
- package/dist/block-processor.d.ts +19 -20
- package/dist/block-processor.d.ts.map +1 -1
- package/dist/block-processor.js +28 -94
- package/dist/block-processor.js.map +1 -1
- package/dist/fec-block-mapper.d.ts +16 -72
- package/dist/fec-block-mapper.d.ts.map +1 -1
- package/dist/fec-block-mapper.js +17 -96
- package/dist/fec-block-mapper.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/oti.d.ts +18 -29
- package/dist/oti.d.ts.map +1 -1
- package/dist/oti.js +9 -39
- package/dist/oti.js.map +1 -1
- package/dist/repair-group.d.ts +86 -0
- package/dist/repair-group.d.ts.map +1 -1
- package/dist/repair-group.js +135 -0
- package/dist/repair-group.js.map +1 -1
- package/package.json +5 -6
- package/src/block-manager.ts +9 -6
- package/src/block-processor.ts +32 -111
- package/src/fec-block-mapper.ts +23 -108
- package/src/index.ts +6 -2
- package/src/oti.ts +20 -51
- package/src/repair-group.ts +176 -0
- package/test-vectors/repair-epoch.json +119 -0
- package/node_modules/@blockcast/mmt-alta-parse/README.md +0 -181
- package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +0 -57
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +0 -115
- package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +0 -1
- package/node_modules/@blockcast/mmt-alta-parse/package.json +0 -50
- package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +0 -136
- package/node_modules/@blockcast/mmt-base/README.md +0 -134
- package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +0 -55
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +0 -128
- package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts +0 -7
- package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/index.js +0 -7
- package/node_modules/@blockcast/mmt-base/dist/index.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +0 -292
- package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js +0 -612
- package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +0 -18
- package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/net-constants.js +0 -18
- package/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +0 -47
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.js +0 -54
- package/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +0 -57
- package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/serial-number.js +0 -98
- package/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +0 -312
- package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +0 -1
- package/node_modules/@blockcast/mmt-base/dist/signalling.js +0 -637
- package/node_modules/@blockcast/mmt-base/dist/signalling.js.map +0 -1
- package/node_modules/@blockcast/mmt-base/package.json +0 -49
- package/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +0 -145
- package/node_modules/@blockcast/mmt-base/src/index.ts +0 -6
- package/node_modules/@blockcast/mmt-base/src/mmtp.ts +0 -892
- package/node_modules/@blockcast/mmt-base/src/net-constants.ts +0 -17
- package/node_modules/@blockcast/mmt-base/src/ntp-short.ts +0 -67
- package/node_modules/@blockcast/mmt-base/src/serial-number.ts +0 -107
- package/node_modules/@blockcast/mmt-base/src/signalling.ts +0 -862
package/README.md
CHANGED
|
@@ -10,26 +10,26 @@ pnpm add @blockcast/mmt-fec
|
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
12
|
import { FecBlockManager, processFecBlock } from "@blockcast/mmt-fec"
|
|
13
|
-
import { buildOTIFromCatalog,
|
|
13
|
+
import { buildOTIFromCatalog, fecBlockBudgetMs } from "@blockcast/mmt-fec"
|
|
14
14
|
|
|
15
15
|
// Catalog says K=32 source symbols, P=8 repair, T=1320 byte symbols,
|
|
16
|
-
// interleaveDepthMs=200 (the FULL FEC block span in ms, §5.1),
|
|
16
|
+
// interleaveDepthMs=200 (the FULL FEC block span in ms, §5.1),
|
|
17
|
+
// reorderToleranceMs=40 (the signaled network allowance, §9).
|
|
17
18
|
const K = 32
|
|
18
19
|
const T = 1320
|
|
19
20
|
const interleaveDepthMs = 200
|
|
20
|
-
const
|
|
21
|
-
const gopDurationMs = 1000 / fps
|
|
21
|
+
const reorderToleranceMs = 40
|
|
22
22
|
|
|
23
23
|
const oti = buildOTIFromCatalog(K, T)
|
|
24
|
-
|
|
25
|
-
const timeoutMs =
|
|
24
|
+
// §9: span + tolerance, each once. No K, group count or multiplier.
|
|
25
|
+
const timeoutMs = fecBlockBudgetMs(interleaveDepthMs, reorderToleranceMs)
|
|
26
26
|
const blocks = new FecBlockManager({ k: K, timeoutMs })
|
|
27
27
|
|
|
28
28
|
// `recovered` comes from the container/worker-owned MmtFecDecoder.
|
|
29
29
|
if (recoveredBlock) {
|
|
30
30
|
// K source symbols concatenated. Split them back into MFU fragments under
|
|
31
31
|
// the catalog fec.blockProfile (required; there is no default profile or T).
|
|
32
|
-
const { symbols } = processFecBlock(recoveredBlock, { blockProfile: "
|
|
32
|
+
const { symbols } = processFecBlock(recoveredBlock, { blockProfile: "iso-ssbg1-v1", k: K, symbolSize: T })
|
|
33
33
|
for (const s of symbols) reassembler.addFragment(s.fragment)
|
|
34
34
|
}
|
|
35
35
|
```
|
|
@@ -48,7 +48,7 @@ Mirrors `package.json#exports`. Each subpath is a tree-shakeable entry point.
|
|
|
48
48
|
| `./cmaf-recovery` | `src/cmaf-recovery.ts` | `CmafFecRecovery` — stateful recovery for CMAF chunks + LOC frames |
|
|
49
49
|
| `./loc` | `src/loc-symbols.ts` | `splitFrameToSymbol`, `recoverFrameFromSymbol` — LOC 1:1 frame ↔ symbol |
|
|
50
50
|
|
|
51
|
-
The aggregator entry also re-exports OTI helpers (`buildOTI`, `buildOTIFromCatalog`, `parseOTI`, `
|
|
51
|
+
The aggregator entry also re-exports OTI helpers (`buildOTI`, `buildOTIFromCatalog`, `parseOTI`, `fecBlockDeadlineMs`, `fecBlockBudgetMs`, `parseRepairPacket`) the block-geometry mappers (`FecBlockMapper`, `NullBlockMapper`, `createMapper`, `recoveredPacketMediaGroup`), and the `iso-ssbg1-v1` MoQ repair group helpers (`extSsStart`, `extendSsId`, `repairFetchRange`, `repairGroupIdMatches`). Canonical MMTP Source FEC Payload ID parsing lives in `@blockcast/mmt-base`; canonical LOC FEC source information lives in `@blockcast/mmt-container`.
|
|
52
52
|
|
|
53
53
|
## Architecture
|
|
54
54
|
|
|
@@ -104,7 +104,7 @@ container or worker.
|
|
|
104
104
|
|
|
105
105
|
The WASM decoder hands back `K * symbolSize` bytes (K source symbols concatenated). `processFecBlock` (`src/block-processor.ts:68`) walks each symbol, parses its MMTP header, extracts the MFU payload via `@blockcast/mmt-base`'s `extractMFUPayload`, and emits a `ParsedFecSymbol[]` sorted with wrapping 32-bit MMTP serial-number arithmetic (source-symbol index breaks duplicate ties) — undoing FEC interleaving so the reassembler sees `FI=1` before `FI=2/3` for the same MPU, including across `0xffff_ffff → 0`.
|
|
106
106
|
|
|
107
|
-
Both `processFecBlock` and `processFecSymbol` require the stream's catalog `fec.blockProfile`, and `processFecBlock` requires the symbol size T; neither is defaulted
|
|
107
|
+
Both `processFecBlock` and `processFecSymbol` require the stream's catalog `fec.blockProfile`, and `processFecBlock` requires the symbol size T; neither is defaulted, and the only profile is `iso-ssbg1-v1` (the retired `k-padded-v1` token throws like any unknown one). A recovered symbol is the ISO/IEC 23008-1 C.3.3 ssbg_mode1 `u16 length || packet || 00h padding`: the length field alone delimits the packet, and a length past the symbol or non-zero padding is counted as `bad_ssbg1_length`. The processor never infers packet boundaries from MFU contents, padding scans or alternate length conventions.
|
|
108
108
|
|
|
109
109
|
```ts
|
|
110
110
|
interface ParsedFecSymbol {
|
|
@@ -169,14 +169,16 @@ The higher-level `FecManager` that orchestrates CMSF catalog parsing, base/delta
|
|
|
169
169
|
```ts
|
|
170
170
|
buildOTIFromCatalog(K, T) // fixed profile: F=K*T, Z=1, N=1, Al=8
|
|
171
171
|
parseOTI(otiBytes) // returns { transferLength, symbolSize, ... K }
|
|
172
|
-
|
|
173
|
-
//
|
|
172
|
+
fecBlockDeadlineMs({ firstAcceptedAtMs, interleaveDepthMs, reorderToleranceMs })
|
|
173
|
+
// first-accepted ts + span + tolerance (§9)
|
|
174
|
+
fecBlockBudgetMs(interleaveDepthMs, reorderToleranceMs)
|
|
175
|
+
// span + tolerance, for duration-only APIs
|
|
174
176
|
parseRepairPacket(mmtpPacket) // ISO 23008-1 §C.5.3 repair FEC PID
|
|
175
177
|
```
|
|
176
178
|
|
|
177
|
-
`
|
|
179
|
+
`fecBlockDeadlineMs` is the block-recovery deadline (draft-ramadan-moq-fec §9): the first accepted packet's receiver-local timestamp plus the catalog `interleaveDepthMs` (the full block span, §5.1) plus the catalog `reorderToleranceMs`, each added once. Nothing derives a span or deadline from K, a Group count, or a multiplier. **Do not** hardcode `setTimeout` values upstream.
|
|
178
180
|
|
|
179
|
-
`./` (root) exposes the catalog block geometry via `FecBlockMapper` (`k`, `d`, `interleaveDepthMs`, `gopDurationMs`, `pacingThresholdMs`, and the required `blockProfile`). It does not map MoQ groups to FEC blocks: a recovered packet's media group comes from its own header (`mediaGroupOf` / `recoveredPacketMediaGroup`), and `fromSsId`
|
|
181
|
+
`./` (root) exposes the catalog block geometry via `FecBlockMapper` (`k`, `d`, `interleaveDepthMs`, `gopDurationMs`, `pacingThresholdMs`, and the required `blockProfile`). It does not map MoQ groups to FEC blocks: a recovered packet's media group comes from its own header (`mediaGroupOf` / `recoveredPacketMediaGroup`), and `fromSsId` throws for every stream with an FEC instance, whose `iso-ssbg1-v1` blocks are located by `(SS_Start, SSB_length)` range membership. `NullBlockMapper` (no FEC, no profile) keeps its identity `derive` and `fromSsId`; `createMapper({ mode: 'object' })` throws, since per-group object FEC numbers SS_IDs on the retired `k-padded-v1` stride. Under `iso-ssbg1-v1` the MoQ repair group id is the 62-bit wrap-epoch-extended SS_Start (`extSsStart`); a receiver that lost SS_ID x in a block it has not delimited FETCHes `repairFetchRange(x, K, { previousBlockStart })`, or `repairFetchRange(x, K, { reference })` from its wrap-epoch reference when no delimited block ends before x (draft-ramadan-moq-fec §7.5), and discards a repair object whose Group ID fails `repairGroupIdMatches`.
|
|
180
182
|
|
|
181
183
|
## WASM module loading
|
|
182
184
|
|
|
@@ -228,8 +230,8 @@ Common broadcast configuration (also documented in the parent README):
|
|
|
228
230
|
Specs:
|
|
229
231
|
- **RFC 6330** — RaptorQ Forward Error Correction Scheme (incl. §3.3.2.1 interleaved scheme)
|
|
230
232
|
- **ISO/IEC 23008-1:2023** — MMT, Annex C; Amendment 1:2025 — AL-FEC framework
|
|
231
|
-
- **ATSC A/331
|
|
232
|
-
- **draft-ramadan-moq-fec-
|
|
233
|
+
- **ATSC A/331:2026-02 8.1.2.5** — AL-FEC for MMTP (informative for draft-fec-01)
|
|
234
|
+
- **draft-ramadan-moq-fec-01** — AL-FEC over MoQ wire format: §4.2 RaptorQ OTI, §7.1 repair object header, §8.3 source symbol location (SS_ID), §9 interleaving; the §7.6 `moq-object-v1` block profile is not implemented here
|
|
233
235
|
|
|
234
236
|
## Performance
|
|
235
237
|
|
package/dist/block-manager.d.ts
CHANGED
|
@@ -10,9 +10,12 @@
|
|
|
10
10
|
* ↓
|
|
11
11
|
* FALLBACK (timeout) → WebTransport repair → DECODED
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* Receiver behaviour (block-level reading of draft-ramadan-moq-fec-01 Section 11.4
|
|
14
|
+
* and draft-ramadan-moq-multicast-01 Section 6.2):
|
|
14
15
|
* - k source symbols complete a block (no FEC decode needed)
|
|
15
|
-
* - After timeout, missing symbols are requested via WebTransport
|
|
16
|
+
* - After timeout, missing symbols are requested via WebTransport (libmmt falls
|
|
17
|
+
* back for every block class; it does not implement the Section 11.4.1
|
|
18
|
+
* classification or the keyframe-only repair-track FETCH)
|
|
16
19
|
* - With k symbols (source + repair), FEC decode recovers block
|
|
17
20
|
*/
|
|
18
21
|
export declare const FEC_STATE: {
|
|
@@ -28,7 +31,7 @@ export interface FecBlockManagerOptions {
|
|
|
28
31
|
/** Block timeout (ms). Derive from catalog: interleaveDepthMs or frameDurationMs * K. Required. */
|
|
29
32
|
timeoutMs: number;
|
|
30
33
|
/** K — source symbols per block from catalog fec.sourceSymbols. Required for interleaved mode.
|
|
31
|
-
* For object FEC (
|
|
34
|
+
* For object FEC (Blockcast extension, not in draft-ramadan-moq-fec-01), this is the max K — actual K varies per block via addSourcePacket/addRepairPacket blockK param. */
|
|
32
35
|
k: number;
|
|
33
36
|
/** Max concurrent blocks in flight. Resource bound, not timing — default 64. */
|
|
34
37
|
maxBlocks?: number;
|
|
@@ -64,7 +67,7 @@ export declare class FecBlockManager {
|
|
|
64
67
|
}): void;
|
|
65
68
|
/**
|
|
66
69
|
* Add a source symbol to a block.
|
|
67
|
-
* @param blockK — per-block K for object FEC (
|
|
70
|
+
* @param blockK — per-block K for object FEC (Blockcast extension, not in draft-ramadan-moq-fec-01). When provided, overrides
|
|
68
71
|
* the global K for this block. For interleaved mode, omit (uses global K).
|
|
69
72
|
*/
|
|
70
73
|
addSourcePacket(blockId: number, esi: number, data: Uint8Array, blockK?: number): Uint8Array | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-manager.d.ts","sourceRoot":"","sources":["../src/block-manager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"block-manager.d.ts","sourceRoot":"","sources":["../src/block-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,eAAO,MAAM,SAAS;;;;;;;CAOZ,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACtC,mGAAmG;IACnG,SAAS,EAAE,MAAM,CAAC;IAClB;iLAC6K;IAC7K,CAAC,EAAE,MAAM,CAAC;IACV,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACrB;AAqED;;;;;;;;GAQG;AACH,qBAAa,eAAe;;IAI3B,SAAS,EAAE,MAAM,CAAC;gBAaN,OAAO,EAAE,sBAAsB;IAQ3C,iBAAiB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,GAAG,IAAI;IAInF,iBAAiB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IAI9E,YAAY,CAAC,MAAM,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAK9D;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAgBnG;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAoBnG,QAAQ,IAAI,aAAa;IAWzB,KAAK,IAAI,IAAI;CAmJb"}
|
package/dist/block-manager.js
CHANGED
|
@@ -10,9 +10,12 @@
|
|
|
10
10
|
* ↓
|
|
11
11
|
* FALLBACK (timeout) → WebTransport repair → DECODED
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* Receiver behaviour (block-level reading of draft-ramadan-moq-fec-01 Section 11.4
|
|
14
|
+
* and draft-ramadan-moq-multicast-01 Section 6.2):
|
|
14
15
|
* - k source symbols complete a block (no FEC decode needed)
|
|
15
|
-
* - After timeout, missing symbols are requested via WebTransport
|
|
16
|
+
* - After timeout, missing symbols are requested via WebTransport (libmmt falls
|
|
17
|
+
* back for every block class; it does not implement the Section 11.4.1
|
|
18
|
+
* classification or the keyframe-only repair-track FETCH)
|
|
16
19
|
* - With k symbols (source + repair), FEC decode recovers block
|
|
17
20
|
*/
|
|
18
21
|
export const FEC_STATE = {
|
|
@@ -128,7 +131,7 @@ export class FecBlockManager {
|
|
|
128
131
|
}
|
|
129
132
|
/**
|
|
130
133
|
* Add a source symbol to a block.
|
|
131
|
-
* @param blockK — per-block K for object FEC (
|
|
134
|
+
* @param blockK — per-block K for object FEC (Blockcast extension, not in draft-ramadan-moq-fec-01). When provided, overrides
|
|
132
135
|
* the global K for this block. For interleaved mode, omit (uses global K).
|
|
133
136
|
*/
|
|
134
137
|
addSourcePacket(blockId, esi, data, blockK) {
|
|
@@ -191,7 +194,7 @@ export class FecBlockManager {
|
|
|
191
194
|
};
|
|
192
195
|
}
|
|
193
196
|
/**
|
|
194
|
-
* @param blockK — per-block K for object FEC (
|
|
197
|
+
* @param blockK — per-block K for object FEC (Blockcast extension, not in draft-ramadan-moq-fec-01). Falls back to global #k.
|
|
195
198
|
*/
|
|
196
199
|
#createBlock(blockId, blockK) {
|
|
197
200
|
if (this.#blocks.size >= this.maxBlocks) {
|
|
@@ -199,7 +202,7 @@ export class FecBlockManager {
|
|
|
199
202
|
}
|
|
200
203
|
const k = blockK ?? this.#k;
|
|
201
204
|
if (k <= 0) {
|
|
202
|
-
throw new Error(`[FecBlockManager] Cannot create block ${blockId}: K=${k}. Derive K from catalog (interleaved) or frame size (object
|
|
205
|
+
throw new Error(`[FecBlockManager] Cannot create block ${blockId}: K=${k}. Derive K from catalog (interleaved) or frame size (object FEC, a Blockcast extension).`);
|
|
203
206
|
}
|
|
204
207
|
const block = new FecBlock(blockId, k);
|
|
205
208
|
this.#blocks.set(blockId, block);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-manager.js","sourceRoot":"","sources":["../src/block-manager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"block-manager.js","sourceRoot":"","sources":["../src/block-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FEC Block Processor
|
|
3
3
|
*
|
|
4
|
-
* Splits decoded FEC blocks (
|
|
4
|
+
* Splits decoded FEC blocks (SSB_length symbols concatenated by the WASM decoder)
|
|
5
5
|
* into individual MFU fragments ready for reassembly and decoding.
|
|
6
6
|
*
|
|
7
7
|
* Extracted from moqtail.html's inline processFecBlock() for reuse across
|
|
@@ -49,9 +49,9 @@ export interface ProcessFecBlockResult {
|
|
|
49
49
|
/** Options for {@link processFecSymbol}. */
|
|
50
50
|
export interface ProcessFecSymbolOptions {
|
|
51
51
|
/**
|
|
52
|
-
* The stream's catalog `fec.blockProfile`. Required, never defaulted:
|
|
53
|
-
*
|
|
54
|
-
*
|
|
52
|
+
* The stream's catalog `fec.blockProfile`. Required, never defaulted:
|
|
53
|
+
* the profile fixes how a packet is laid into a symbol, and the only one
|
|
54
|
+
* implemented is `iso-ssbg1-v1`.
|
|
55
55
|
*/
|
|
56
56
|
blockProfile: FecBlockProfile;
|
|
57
57
|
/** Symbol index within the block, used only for diagnostics. */
|
|
@@ -66,9 +66,9 @@ export interface ProcessFecBlockOptions {
|
|
|
66
66
|
/** Symbol size T in bytes (catalog `fec.symbolSize`). Required: there is no default T. */
|
|
67
67
|
symbolSize: number;
|
|
68
68
|
/**
|
|
69
|
-
* Source symbols in the decoded block: K
|
|
70
|
-
*
|
|
71
|
-
*
|
|
69
|
+
* Source symbols in the decoded block: its SSB_length (K'). When omitted
|
|
70
|
+
* the block must be a whole number of T-byte symbols and K' is that
|
|
71
|
+
* number; a partial symbol throws.
|
|
72
72
|
*/
|
|
73
73
|
k?: number;
|
|
74
74
|
/** Keep only symbols for this packetId. */
|
|
@@ -77,30 +77,29 @@ export interface ProcessFecBlockOptions {
|
|
|
77
77
|
/**
|
|
78
78
|
* Parse one recovered FEC source symbol into an MFU fragment.
|
|
79
79
|
*
|
|
80
|
-
* The symbol is
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
80
|
+
* The symbol is the `iso-ssbg1-v1` ssbg_mode1 `u16 length || packet || zero
|
|
81
|
+
* padding` (ISO/IEC 23008-1 C.3.3): the length field alone delimits the
|
|
82
|
+
* protected packet, which is then parsed as an MMTP MPU packet. Failures are
|
|
83
|
+
* counted by reason (`bad_ssbg1_length` is the length/padding refusal), never
|
|
84
|
+
* thrown.
|
|
85
85
|
*
|
|
86
|
-
* @throws when `options.blockProfile` is absent or not
|
|
86
|
+
* @throws when `options.blockProfile` is absent or not `iso-ssbg1-v1`.
|
|
87
87
|
*/
|
|
88
88
|
export declare function processFecSymbol(symbolData: Uint8Array, options: ProcessFecSymbolOptions): ProcessFecBlockResult;
|
|
89
89
|
/**
|
|
90
90
|
* Process a decoded FEC block into individual MFU fragments.
|
|
91
91
|
*
|
|
92
92
|
* The WASM RaptorQ decoder returns every source symbol of the block
|
|
93
|
-
* concatenated (
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* structured results sorted for reassembly.
|
|
93
|
+
* concatenated (SSB_length x T bytes). This function splits them apart,
|
|
94
|
+
* recovers each protected packet from its ssbg_mode1 length field (see
|
|
95
|
+
* {@link processFecSymbol}), extracts the MFU payload via shared
|
|
96
|
+
* extractMFUPayload, and returns structured results sorted for reassembly.
|
|
98
97
|
*
|
|
99
98
|
* @param blockData - Concatenated source symbols from the WASM decoder
|
|
100
99
|
* @param options - Block profile and symbol size T are required; see {@link ProcessFecBlockOptions}
|
|
101
100
|
* @throws when the block profile or symbol size is absent or invalid, when an
|
|
102
|
-
* omitted `k` cannot be read exactly from the block length, or when
|
|
103
|
-
*
|
|
101
|
+
* omitted `k` cannot be read exactly from the block length, or when the
|
|
102
|
+
* block is not exactly `k` symbols long.
|
|
104
103
|
*/
|
|
105
104
|
export declare function processFecBlock(blockData: Uint8Array, options: ProcessFecBlockOptions): ProcessFecBlockResult;
|
|
106
105
|
//# sourceMappingURL=block-processor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-processor.d.ts","sourceRoot":"","sources":["../src/block-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"block-processor.d.ts","sourceRoot":"","sources":["../src/block-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAON,KAAK,eAAe,EAEpB,MAAM,qBAAqB,CAAC;AAE7B,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC/B,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,EAAE;QACT,iBAAiB,EAAE,MAAM,CAAC;QAC1B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,eAAe,EAAE,MAAM,CAAC;QACxB,IAAI,EAAE,UAAU,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,2BAA2B,CAAC,EAAE,MAAM,CAAC;QACrC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,gFAAgF;IAChF,UAAU,EAAE,OAAO,CAAC;IACpB,qDAAqD;IACrD,SAAS,EAAE,UAAU,CAAC;CACtB;AAED,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACrC,uFAAuF;IACvF,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACvC;;;;OAIG;IACH,YAAY,EAAE,eAAe,CAAC;IAC9B,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,2CAA2C;AAC3C,MAAM,WAAW,sBAAsB;IACtC,iGAAiG;IACjG,YAAY,EAAE,eAAe,CAAC;IAC9B,0FAA0F;IAC1F,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AA0ID;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC/B,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,uBAAuB,GAC9B,qBAAqB,CAyBvB;AA2CD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC9B,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,sBAAsB,GAC7B,qBAAqB,CAgCvB"}
|
package/dist/block-processor.js
CHANGED
|
@@ -1,59 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FEC Block Processor
|
|
3
3
|
*
|
|
4
|
-
* Splits decoded FEC blocks (
|
|
4
|
+
* Splits decoded FEC blocks (SSB_length symbols concatenated by the WASM decoder)
|
|
5
5
|
* into individual MFU fragments ready for reassembly and decoding.
|
|
6
6
|
*
|
|
7
7
|
* Extracted from moqtail.html's inline processFecBlock() for reuse across
|
|
8
8
|
* both moq-lib and moqtail players. Pure function — no side effects.
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
11
|
-
function hasUniformPaddingFrom(data, start) {
|
|
12
|
-
if (start >= data.length)
|
|
13
|
-
return false;
|
|
14
|
-
const pad = data[start];
|
|
15
|
-
if (pad !== 0x00 && pad !== 0xee)
|
|
16
|
-
return false;
|
|
17
|
-
for (let i = start + 1; i < data.length; i++) {
|
|
18
|
-
if (data[i] !== pad)
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
function maybeExtendAltaTrailer(symbolData, packetEnd) {
|
|
24
|
-
if (packetEnd + MMTP_EXT_TRAILER_HEADER_SIZE > symbolData.length)
|
|
25
|
-
return packetEnd;
|
|
26
|
-
const view = new DataView(symbolData.buffer, symbolData.byteOffset + packetEnd, symbolData.byteLength - packetEnd);
|
|
27
|
-
const extType = view.getUint16(0, false);
|
|
28
|
-
if (extType !== MMTP_EXT_TYPE_ALTA_AUTH)
|
|
29
|
-
return packetEnd;
|
|
30
|
-
const extLen = view.getUint16(2, false);
|
|
31
|
-
const trailerEnd = packetEnd + MMTP_EXT_TRAILER_HEADER_SIZE + extLen;
|
|
32
|
-
return trailerEnd <= symbolData.length ? trailerEnd : packetEnd;
|
|
33
|
-
}
|
|
34
|
-
function trimDecodedSourceSymbol(symbolData) {
|
|
35
|
-
if (symbolData.length < MMTP_HEADER_SIZE + MPU_HEADER_SIZE)
|
|
36
|
-
return null;
|
|
37
|
-
const headerLength = parseMMTPHeader(symbolData).headerLength;
|
|
38
|
-
if (symbolData.length < headerLength + MPU_HEADER_SIZE)
|
|
39
|
-
return null;
|
|
40
|
-
const payload = symbolData.subarray(headerLength);
|
|
41
|
-
const mpu = parseMPUHeader(payload);
|
|
42
|
-
const trailingMpuHeaderSize = MPU_HEADER_SIZE - 2;
|
|
43
|
-
if (mpu.payloadLength < trailingMpuHeaderSize)
|
|
44
|
-
return null;
|
|
45
|
-
// Recovered source symbols are fixed-width and may be padded, but their wire
|
|
46
|
-
// boundary is still the ISO length-after-field coordinate. ALTA may extend the
|
|
47
|
-
// packet from exactly that point; no MFU-content or alternate-length guessing.
|
|
48
|
-
const declaredEnd = headerLength + 2 + mpu.payloadLength;
|
|
49
|
-
if (declaredEnd > symbolData.length)
|
|
50
|
-
return null;
|
|
51
|
-
const packetEnd = maybeExtendAltaTrailer(symbolData, declaredEnd);
|
|
52
|
-
if (packetEnd < symbolData.length && !hasUniformPaddingFrom(symbolData, packetEnd)) {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
return symbolData.subarray(0, packetEnd);
|
|
56
|
-
}
|
|
10
|
+
import { MMTP_HEADER_SIZE, SSBG1_LENGTH_FIELD_BYTES, extractMFUPayload, parseFecBlockProfile, parseMMTPHeader, trimSsbg1SourceSymbol, } from "@blockcast/mmt-base";
|
|
57
11
|
function emptyProcessResult() {
|
|
58
12
|
return {
|
|
59
13
|
symbols: [],
|
|
@@ -77,8 +31,8 @@ function resultFromSymbols(parsed, failedCount, failReasons, ownerPacketId) {
|
|
|
77
31
|
// Reassembler needs FI=1 before FI=2/3 for the same mpuSequenceNumber.
|
|
78
32
|
parsed.sort(comparePacketSequence);
|
|
79
33
|
// When ownerPacketId is set, only keep symbols matching the track that owns
|
|
80
|
-
// this FEC block. Other packetIds
|
|
81
|
-
//
|
|
34
|
+
// this FEC block. Other packetIds are garbage and must be rejected to
|
|
35
|
+
// prevent decoder crashes.
|
|
82
36
|
const symbols = ownerPacketId != null
|
|
83
37
|
? parsed.filter((s) => s.packetId === ownerPacketId)
|
|
84
38
|
: parsed;
|
|
@@ -87,9 +41,8 @@ function resultFromSymbols(parsed, failedCount, failReasons, ownerPacketId) {
|
|
|
87
41
|
/**
|
|
88
42
|
* Gate one candidate MMTP packet on its fixed header: long enough, version 0,
|
|
89
43
|
* parseable, and an MPU packet. Returns the parsed header, or null after
|
|
90
|
-
* counting why it was refused.
|
|
91
|
-
*
|
|
92
|
-
* length-delimited packet under iso-ssbg1-v1).
|
|
44
|
+
* counting why it was refused. It sees the length-delimited protected packet,
|
|
45
|
+
* never the padded symbol.
|
|
93
46
|
*/
|
|
94
47
|
function gateMpuHeader(data, bump) {
|
|
95
48
|
if (data.length < MMTP_HEADER_SIZE) {
|
|
@@ -115,10 +68,10 @@ function gateMpuHeader(data, bump) {
|
|
|
115
68
|
*/
|
|
116
69
|
function parseProtectedPacket(packetData, hdr, index, bump) {
|
|
117
70
|
// WASM-decoded source symbols retain fecType bits from the original FFmpeg
|
|
118
|
-
// packet (fecType=1 per draft-ramadan-moq-mmt-
|
|
71
|
+
// packet (fecType=1 per draft-ramadan-moq-mmt-01 §3.1), but the 4-byte
|
|
119
72
|
// Source FEC Payload ID (ISO 23008-1 §C.5.2) is never part of the protected
|
|
120
73
|
// packet (C.4.2). Tell extractMFUPayload to skip FEC PID subtraction so it
|
|
121
|
-
// does not truncate video data; any
|
|
74
|
+
// does not truncate video data; any legacy authenticator trailer must then consume the
|
|
122
75
|
// exact suffix after the declared payload.
|
|
123
76
|
const extraction = extractMFUPayload(packetData, { skipFecId: true });
|
|
124
77
|
if (!extraction) {
|
|
@@ -147,22 +100,6 @@ function parseProtectedPacket(packetData, hdr, index, bump) {
|
|
|
147
100
|
rawSymbol: packetData,
|
|
148
101
|
};
|
|
149
102
|
}
|
|
150
|
-
/**
|
|
151
|
-
* k-padded-v1: the symbol is the protected packet zero-padded to T with no
|
|
152
|
-
* length field, so the packet ends at its ISO-declared MPU boundary (plus an
|
|
153
|
-
* ALTA trailer starting exactly there) and the rest must be uniform padding.
|
|
154
|
-
*/
|
|
155
|
-
function parseKPaddedSymbol(symbolData, index, bump) {
|
|
156
|
-
const hdr = gateMpuHeader(symbolData, bump);
|
|
157
|
-
if (!hdr)
|
|
158
|
-
return null;
|
|
159
|
-
const packetData = trimDecodedSourceSymbol(symbolData);
|
|
160
|
-
if (!packetData) {
|
|
161
|
-
bump("bad_length");
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
return parseProtectedPacket(packetData, hdr, index, bump);
|
|
165
|
-
}
|
|
166
103
|
/**
|
|
167
104
|
* iso-ssbg1-v1 (ISO/IEC 23008-1 C.3.3 ssbg_mode1): the symbol is
|
|
168
105
|
* `u16be(length) || protected packet || 00h padding`. The length field alone
|
|
@@ -183,16 +120,16 @@ function parseSsbg1Symbol(symbolData, index, bump) {
|
|
|
183
120
|
/**
|
|
184
121
|
* Parse one recovered FEC source symbol into an MFU fragment.
|
|
185
122
|
*
|
|
186
|
-
* The symbol is
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
123
|
+
* The symbol is the `iso-ssbg1-v1` ssbg_mode1 `u16 length || packet || zero
|
|
124
|
+
* padding` (ISO/IEC 23008-1 C.3.3): the length field alone delimits the
|
|
125
|
+
* protected packet, which is then parsed as an MMTP MPU packet. Failures are
|
|
126
|
+
* counted by reason (`bad_ssbg1_length` is the length/padding refusal), never
|
|
127
|
+
* thrown.
|
|
191
128
|
*
|
|
192
|
-
* @throws when `options.blockProfile` is absent or not
|
|
129
|
+
* @throws when `options.blockProfile` is absent or not `iso-ssbg1-v1`.
|
|
193
130
|
*/
|
|
194
131
|
export function processFecSymbol(symbolData, options) {
|
|
195
|
-
|
|
132
|
+
parseFecBlockProfile(options?.blockProfile, "processFecSymbol options.blockProfile");
|
|
196
133
|
const failReasons = {};
|
|
197
134
|
let failedCount = 0;
|
|
198
135
|
const bump = (reason) => {
|
|
@@ -204,9 +141,7 @@ export function processFecSymbol(symbolData, options) {
|
|
|
204
141
|
const index = options.index ?? 0;
|
|
205
142
|
let parsed;
|
|
206
143
|
try {
|
|
207
|
-
parsed =
|
|
208
|
-
? parseSsbg1Symbol(symbolData, index, bump)
|
|
209
|
-
: parseKPaddedSymbol(symbolData, index, bump);
|
|
144
|
+
parsed = parseSsbg1Symbol(symbolData, index, bump);
|
|
210
145
|
}
|
|
211
146
|
catch {
|
|
212
147
|
bump("exception");
|
|
@@ -214,19 +149,19 @@ export function processFecSymbol(symbolData, options) {
|
|
|
214
149
|
}
|
|
215
150
|
return resultFromSymbols(parsed ? [parsed] : [], failedCount, failReasons, options.ownerPacketId);
|
|
216
151
|
}
|
|
217
|
-
function requireSymbolSize(symbolSize
|
|
152
|
+
function requireSymbolSize(symbolSize) {
|
|
218
153
|
if (symbolSize === undefined) {
|
|
219
154
|
throw new Error("processFecBlock options.symbolSize is required: name the catalog fec.symbolSize (T)");
|
|
220
155
|
}
|
|
221
156
|
if (typeof symbolSize !== "number" || !Number.isSafeInteger(symbolSize) || symbolSize <= 0) {
|
|
222
157
|
throw new Error(`processFecBlock options.symbolSize must be a positive integer (got ${String(symbolSize)})`);
|
|
223
158
|
}
|
|
224
|
-
if (
|
|
159
|
+
if (symbolSize <= SSBG1_LENGTH_FIELD_BYTES) {
|
|
225
160
|
throw new Error(`processFecBlock options.symbolSize must exceed the ${SSBG1_LENGTH_FIELD_BYTES}-byte ssbg_mode1 length field (got ${symbolSize})`);
|
|
226
161
|
}
|
|
227
162
|
return symbolSize;
|
|
228
163
|
}
|
|
229
|
-
function requireSourceSymbolCount(k, blockLength, symbolSize
|
|
164
|
+
function requireSourceSymbolCount(k, blockLength, symbolSize) {
|
|
230
165
|
if (k === undefined) {
|
|
231
166
|
if (blockLength % symbolSize !== 0) {
|
|
232
167
|
throw new Error(`processFecBlock: ${blockLength} bytes is not a whole number of ${symbolSize}-byte symbols; pass options.k`);
|
|
@@ -238,7 +173,7 @@ function requireSourceSymbolCount(k, blockLength, symbolSize, blockProfile) {
|
|
|
238
173
|
}
|
|
239
174
|
// An iso-ssbg1-v1 block is exactly K' = SSB_length symbols of T bytes
|
|
240
175
|
// (C.5.3); any other length is not the block the repair symbols described.
|
|
241
|
-
if (
|
|
176
|
+
if (blockLength !== k * symbolSize) {
|
|
242
177
|
throw new Error(`processFecBlock: an iso-ssbg1-v1 block of ${k} symbols of ${symbolSize} bytes is ${k * symbolSize} bytes (got ${blockLength})`);
|
|
243
178
|
}
|
|
244
179
|
return k;
|
|
@@ -247,24 +182,23 @@ function requireSourceSymbolCount(k, blockLength, symbolSize, blockProfile) {
|
|
|
247
182
|
* Process a decoded FEC block into individual MFU fragments.
|
|
248
183
|
*
|
|
249
184
|
* The WASM RaptorQ decoder returns every source symbol of the block
|
|
250
|
-
* concatenated (
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
* structured results sorted for reassembly.
|
|
185
|
+
* concatenated (SSB_length x T bytes). This function splits them apart,
|
|
186
|
+
* recovers each protected packet from its ssbg_mode1 length field (see
|
|
187
|
+
* {@link processFecSymbol}), extracts the MFU payload via shared
|
|
188
|
+
* extractMFUPayload, and returns structured results sorted for reassembly.
|
|
255
189
|
*
|
|
256
190
|
* @param blockData - Concatenated source symbols from the WASM decoder
|
|
257
191
|
* @param options - Block profile and symbol size T are required; see {@link ProcessFecBlockOptions}
|
|
258
192
|
* @throws when the block profile or symbol size is absent or invalid, when an
|
|
259
|
-
* omitted `k` cannot be read exactly from the block length, or when
|
|
260
|
-
*
|
|
193
|
+
* omitted `k` cannot be read exactly from the block length, or when the
|
|
194
|
+
* block is not exactly `k` symbols long.
|
|
261
195
|
*/
|
|
262
196
|
export function processFecBlock(blockData, options) {
|
|
263
197
|
const blockProfile = parseFecBlockProfile(options?.blockProfile, "processFecBlock options.blockProfile");
|
|
264
|
-
const symbolSize = requireSymbolSize(options.symbolSize
|
|
198
|
+
const symbolSize = requireSymbolSize(options.symbolSize);
|
|
265
199
|
if (!blockData || blockData.length === 0)
|
|
266
200
|
return emptyProcessResult();
|
|
267
|
-
const k = requireSourceSymbolCount(options.k, blockData.length, symbolSize
|
|
201
|
+
const k = requireSourceSymbolCount(options.k, blockData.length, symbolSize);
|
|
268
202
|
const failReasons = {};
|
|
269
203
|
let failedCount = 0;
|
|
270
204
|
const parsed = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-processor.js","sourceRoot":"","sources":["../src/block-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACN,
|
|
1
|
+
{"version":3,"file":"block-processor.js","sourceRoot":"","sources":["../src/block-processor.ts"],"names":[],"mappings":"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"}
|