@blockcast/mmt-base 0.1.0 → 0.3.0-main.10140e847083

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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # @blockcast/mmt-base
2
2
 
3
- The shared MMTP packet-parsing leaf for libmmt's TypeScript packages. It hosts the low-level MMTP / MPU / MFU header parsers, FEC payload-id predicates, and ALTA-trailer extractor — everything that operates on raw MMTP packet bytes **with zero FEC-decode dependency**. RFC 6330 OTI geometry belongs to `@blockcast/mmt-fec`.
3
+ The shared MMTP packet-parsing leaf for libmmt's TypeScript packages. It hosts the low-level MMTP / MPU / MFU header parsers, and FEC payload-id predicates — everything that operates on raw MMTP packet bytes **with zero FEC-decode dependency**. RFC 6330 OTI geometry belongs to `@blockcast/mmt-fec`.
4
4
 
5
- It exists for one structural reason. Both `@blockcast/mmt-fec` and `@blockcast/mmt-container` need these primitives. Before this package they lived in `mmt-container`, so `mmt-fec` had to import `mmt-container` for them — while `mmt-container`'s `FecManager` already imports `mmt-fec`. That is a circular dependency. Extracting the primitives into this leaf breaks the cycle: both packages now import **down** into `mmt-base` rather than across into each other. Its only dependency is `@blockcast/mmt-alta-parse` (for the ALTA trailer types it re-exports).
5
+ It exists for one structural reason. Both `@blockcast/mmt-fec` and `@blockcast/mmt-container` need these primitives. Before this package they lived in `mmt-container`, so `mmt-fec` had to import `mmt-container` for them — while `mmt-container`'s `FecManager` already imports `mmt-fec`. That is a circular dependency. Extracting the primitives into this leaf breaks the cycle: both packages now import **down** into `mmt-base` rather than across into each other. It has no runtime dependencies.
6
6
 
7
7
  ```bash
8
8
  pnpm add @blockcast/mmt-base
@@ -46,7 +46,7 @@ Single entry point — `package.json#exports` declares only `.`, and `src/index.
46
46
  | `MMTP_HEADER_SIZE` (12), `MPU_HEADER_SIZE` (8), `MFU_DU_HEADER_SIZE_TIMED` (14), `MFU_DU_HEADER_SIZE_NONTIMED` (4) | const | Fixed header sizes |
47
47
  | `PACKET_TYPE_MPU` (0x00), `PACKET_TYPE_SIGNALING` (0x02), `PACKET_TYPE_REPAIR` (0x03) | const | MMTP `packet_type` values |
48
48
 
49
- MPU `payload_length` is interpreted strictly as ISO's length-after-field value: six remaining MPU-header bytes plus the data-unit header and media. ALTA and Source FEC Payload ID suffixes are outside that span; malformed, zero-length, media-only, and ambiguous declarations are rejected.
49
+ MPU `payload_length` is interpreted strictly as ISO's length-after-field value: six remaining MPU-header bytes plus the data-unit header and media. The legacy `0xf0a1` authenticator trailer (skipped, never verified — provenance is `@blockcast/mmt-manifest-verify`) and the Source FEC Payload ID are outside that span; malformed, zero-length, media-only, and ambiguous declarations are rejected.
50
50
 
51
51
  ### FEC payload-id, repair & AL-FEC signaling
52
52
 
@@ -57,19 +57,23 @@ MPU `payload_length` is interpreted strictly as ISO's length-after-field value:
57
57
  | `extractFecPayloadId` | function | `{ ssId }` from a source packet's FEC payload id (or `null`) |
58
58
  | `extractRepairFecPayloadId` | function | Repair-flow FEC payload id (13-byte, `REPAIR_FEC_PID_SIZE`) |
59
59
  | `parseMoqRepairFrame` | function | Strictly parse a mode-0 MMTP Annex C repair frame → `MoqRepairFrame` |
60
- | `parseAlFecMessage` | function | Parse an AL-FEC signaling message → `AlFecConfig` |
61
- | `MoqRepairFrame`, `AlFecConfig` | type | Repair-frame / AL-FEC config shapes |
60
+ | `MoqRepairFrame` | type | Repair-frame shape |
62
61
  | `ALFEC_MESSAGE_ID` (0x0203), `FEC_CODE_XOR` (1), `FEC_CODE_RAPTORQ` (2), `REPAIR_FEC_PID_SIZE` (13) | const | AL-FEC signaling + payload-id constants |
62
+ | `MMTP_SIGNALING_PACKET_ID` (0), `MMTP_PACKET_ID_MAX` (0xffff) | const | Signaling-flow `packet_id` (never a track's) and the 16-bit `packet_id` ceiling; a track's `packet_id` is 1..65535 |
63
63
 
64
- ### ALTA trailer (re-exported from `@blockcast/mmt-alta-parse`)
64
+ ### Signalling messages (`signalling.ts`, packet_id 0)
65
+
66
+ Total parsers (malformed or unsupported input → `null`, never a throw), per
67
+ ISO/IEC 23008-1:2023 9.3.4.2, 10.2-10.3, 10.6 and Annex C Table C.3 as
68
+ replaced by Amd 1:2025.
65
69
 
66
70
  | Symbol | Kind | Purpose |
67
71
  |--------|------|---------|
68
- | `extractAltaTrailer` | function | Extract the ALTA authentication trailer from an MMTP packet |
69
- | `AltaTrailer` | type | Parsed trailer shape |
70
- | `MMTP_EXT_TYPE_ALTA_AUTH`, `MMTP_EXT_TRAILER_HEADER_SIZE` | const | ALTA extension-header identifiers |
71
-
72
- These four are re-exported so callers that already pull MMTP primitives from here don't need a second import from `@blockcast/mmt-alta-parse` just for the trailer.
72
+ | `parseSignallingPayload` | function | Split a signalling packet into complete messages behind the 9.3.4.2 header (Figure 15); the payload form is always `iso-9.3.4.2`. A message straight after the MMTP header (the retired bare AL-FEC form) is refused |
73
+ | `parseSignallingPacket` | function | Decode every message of a signalling packet → `al-fec` / `pa` / `mpt` / `other` |
74
+ | `parseAlFecMessage`, `parseAlFecMessageBody` | function | Every FEC flow of an AL-FEC message: all asset packet_ids, one-stage / two-stage / LA-FEC repair flows, private fields → `AlFecMessage` |
75
+ | `alFecRaptorQFlowConfig` | function | One flow's decoder geometry under the Blockcast one-stage RaptorQ profile: coding byte 0x14 (`iso-ssbg1-v1`) or 0x15 (its low bit, reserved "1" in the unamended 2023 Table C.3, is reported, not interpreted), private field = OTI + interleave depth → `AlFecRaptorQFlowConfig`; any other coding byte (0x10 ssbg_mode0 included) → `null` |
76
+ | `parsePaMessageBody`, `parseMptMessageBody`, `parseMpTable`, `mpAssetPacketIds` | function | PA / MPT messages and the MP table: asset → packet_id mapping |
73
77
 
74
78
  ## Why this package exists
75
79
 
@@ -105,13 +109,12 @@ npm test # vitest run
105
109
 
106
110
  The direct suite owns header parsing, MFU extraction, payload-ID predicates,
107
111
  declared-boundary rejection, C/X optional headers, and
108
- ALTA/FEC suffix coverage. Downstream suites exercise integration only.
112
+ legacy-authenticator/FEC suffix coverage. Downstream suites exercise integration only.
109
113
 
110
114
  ## Related packages
111
115
 
112
116
  | Package | Relationship |
113
117
  |---------|-------------|
114
- | [`@blockcast/mmt-alta-parse`](../mmt-alta-parse) | Only dependency — supplies the ALTA trailer types this package re-exports |
115
118
  | [`@blockcast/mmt-fec`](../fec) | Imports these parsers in `block-processor` to turn decoded FEC blocks back into MFU fragments |
116
119
  | [`@blockcast/mmt-container`](../container) | Imports these primitives directly and builds the `FecManager`, MFU reassembler, and CMAF demuxer on top |
117
120
 
@@ -0,0 +1,55 @@
1
+ /** The block profile a catalog `fec.blockProfile` may name: the one this library implements. */
2
+ export type FecBlockProfile = 'iso-ssbg1-v1';
3
+ /** Every accepted `fec.blockProfile` token. */
4
+ export declare const FEC_BLOCK_PROFILES: readonly FecBlockProfile[];
5
+ /** True for a block-profile token this library implements. */
6
+ export declare function isFecBlockProfile(value: unknown): value is FecBlockProfile;
7
+ /**
8
+ * Read a required `fec.blockProfile`. Throws on an absent token and on any
9
+ * token other than `iso-ssbg1-v1`: there is no default and nothing is
10
+ * inferred from the wire (draft-ramadan-moq-fec §5.1).
11
+ *
12
+ * @param where the catalog path of the field, for the error message.
13
+ */
14
+ export declare function parseFecBlockProfile(value: unknown, where: string): FecBlockProfile;
15
+ /** ISO/IEC 23008-1 C.3.3 ssbg_mode1: the two-octet packet length field. */
16
+ export declare const SSBG1_LENGTH_FIELD_BYTES = 2;
17
+ /** The largest protected packet an ssbg_mode1 symbol of size T can carry. */
18
+ export declare function ssbg1MaxPacketLength(symbolSize: number): number;
19
+ /** Whether a protected packet of `packetLength` bytes fits one T-byte ssbg_mode1 symbol. */
20
+ export declare function ssbg1FitsSymbol(packetLength: number, symbolSize: number): boolean;
21
+ /**
22
+ * Build one ssbg_mode1 source symbol (C.3.3): the protected packet's length
23
+ * in two octets, network byte order, then the packet, then zero octets up to
24
+ * T. The protected packet is the MMTP packet before its Source FEC Payload ID
25
+ * is appended (C.4.2).
26
+ *
27
+ * @throws when `length + 2 > T`: the packet cannot be protected under this
28
+ * profile, and silently truncating it would corrupt every repair symbol.
29
+ */
30
+ export declare function buildSsbg1SourceSymbol(packet: Uint8Array, symbolSize: number): Uint8Array;
31
+ /**
32
+ * Recover the protected packet from one ssbg_mode1 source symbol: the bytes
33
+ * the length field names. Returns null, never a guess, when the length field
34
+ * points past the symbol or any padding octet is non-zero (C.3.3 padding is
35
+ * all 00h), since either means the recovered symbol is not what was sent.
36
+ */
37
+ export declare function trimSsbg1SourceSymbol(symbol: Uint8Array): Uint8Array | null;
38
+ /** The SS_ID after the last source symbol of `[ssStart, ssStart + ssbLength)`. */
39
+ export declare function isoBlockEnd(ssStart: number, ssbLength: number): number;
40
+ /**
41
+ * Range membership (C.5.2, C.5.3): whether `ssId` is one of the
42
+ * `ssbLength` consecutive SS_IDs starting at `ssStart`, modulo 2^32.
43
+ */
44
+ export declare function isoBlockContains(ssStart: number, ssbLength: number, ssId: number): boolean;
45
+ /**
46
+ * A lower bound on how many blocks the block starting at `a` lies behind the
47
+ * one starting at `b` (0 when `a` does not precede `b`). An iso-ssbg1-v1
48
+ * block holds at most `kMax` source symbols (the catalog `sourceSymbols`, the
49
+ * AL-FEC maximum_k_for_repair_flow), so `n * kMax` SS_IDs always span at least
50
+ * `n` blocks. Every interleave horizon in the receiver (decoder retention,
51
+ * worker retirement, ordered-relay settlement) uses this one bound, so the
52
+ * manager's horizon can never fall inside the decoder's.
53
+ */
54
+ export declare function isoBlocksBehindLowerBound(a: number, b: number, kMax: number): number;
55
+ //# sourceMappingURL=fec-block-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fec-block-profile.d.ts","sourceRoot":"","sources":["../src/fec-block-profile.ts"],"names":[],"mappings":"AA6BA,gGAAgG;AAChG,MAAM,MAAM,eAAe,GAAG,cAAc,CAAA;AAE5C,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,EAAE,SAAS,eAAe,EAEvD,CAAA;AAEF,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAMnF;AAED,2EAA2E;AAC3E,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAOjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAczF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAS3E;AAED,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKpF"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * FEC block profile (BLO-35597, ISO/IEC 23008-1 Annex C).
3
+ *
4
+ * Every catalog `fec` object that declares an FEC instance names its block
5
+ * profile in `fec.blockProfile`. A receiver applies all of a profile's rules
6
+ * or none of them, so the token is the one explicit per-stream discriminator:
7
+ * it is never defaulted and never inferred from the wire.
8
+ *
9
+ * draft-ramadan-moq-fec §5.1 defines exactly one value, and it is the only
10
+ * profile this library implements:
11
+ *
12
+ * - `iso-ssbg1-v1`: ssbg_mode1 (C.3.3): a source symbol is
13
+ * `u16 length || protected packet || zero padding` to T; a block is a
14
+ * K' = SSB_length RaptorQ block (C.5.3) and repair ESI = SSB_length + RS_ID;
15
+ * SS_ID increments by one per FEC source packet and wraps at 2^32 (C.5.2),
16
+ * so a block is located by membership in `[SS_Start, SS_Start + SSB_length)`
17
+ * under RFC 1982 serial arithmetic; the MoQ repair group id is the 62-bit
18
+ * wrap-epoch-extended SS_Start. The AL-FEC coding byte for this profile is
19
+ * 0x14 (one-stage, ssbg_mode1, fec_payload_id_mode 0, Amd 1:2025 Table C.3).
20
+ *
21
+ * A track whose `blockProfile` is absent or names any other token (the
22
+ * retired Blockcast-private `k-padded-v1` included) has no FEC: a receiver
23
+ * consumes its source without FEC and joins none of its repair tracks
24
+ * (draft-ramadan-moq-fec §5.1). `parseFecBlockProfile` throws for such a
25
+ * token; the per-track catalog resolver turns the same rule into a typed
26
+ * per-track "FEC unavailable" outcome instead of failing the session.
27
+ */
28
+ import { serial32Add, serial32Distance, serial32Precedes } from './serial-number.js';
29
+ /** Every accepted `fec.blockProfile` token. */
30
+ export const FEC_BLOCK_PROFILES = Object.freeze([
31
+ 'iso-ssbg1-v1',
32
+ ]);
33
+ /** True for a block-profile token this library implements. */
34
+ export function isFecBlockProfile(value) {
35
+ return value === 'iso-ssbg1-v1';
36
+ }
37
+ /**
38
+ * Read a required `fec.blockProfile`. Throws on an absent token and on any
39
+ * token other than `iso-ssbg1-v1`: there is no default and nothing is
40
+ * inferred from the wire (draft-ramadan-moq-fec §5.1).
41
+ *
42
+ * @param where the catalog path of the field, for the error message.
43
+ */
44
+ export function parseFecBlockProfile(value, where) {
45
+ if (isFecBlockProfile(value))
46
+ return value;
47
+ if (value === undefined) {
48
+ throw new Error(`${where} is required: name the FEC block profile ("iso-ssbg1-v1")`);
49
+ }
50
+ throw new Error(`${where} must be "iso-ssbg1-v1" (got ${JSON.stringify(value)})`);
51
+ }
52
+ /** ISO/IEC 23008-1 C.3.3 ssbg_mode1: the two-octet packet length field. */
53
+ export const SSBG1_LENGTH_FIELD_BYTES = 2;
54
+ /** The largest protected packet an ssbg_mode1 symbol of size T can carry. */
55
+ export function ssbg1MaxPacketLength(symbolSize) {
56
+ return symbolSize - SSBG1_LENGTH_FIELD_BYTES;
57
+ }
58
+ /** Whether a protected packet of `packetLength` bytes fits one T-byte ssbg_mode1 symbol. */
59
+ export function ssbg1FitsSymbol(packetLength, symbolSize) {
60
+ return (Number.isSafeInteger(packetLength) &&
61
+ packetLength >= 0 &&
62
+ packetLength <= ssbg1MaxPacketLength(symbolSize) &&
63
+ packetLength <= 0xffff);
64
+ }
65
+ /**
66
+ * Build one ssbg_mode1 source symbol (C.3.3): the protected packet's length
67
+ * in two octets, network byte order, then the packet, then zero octets up to
68
+ * T. The protected packet is the MMTP packet before its Source FEC Payload ID
69
+ * is appended (C.4.2).
70
+ *
71
+ * @throws when `length + 2 > T`: the packet cannot be protected under this
72
+ * profile, and silently truncating it would corrupt every repair symbol.
73
+ */
74
+ export function buildSsbg1SourceSymbol(packet, symbolSize) {
75
+ if (!Number.isSafeInteger(symbolSize) || symbolSize <= SSBG1_LENGTH_FIELD_BYTES) {
76
+ throw new Error(`ssbg_mode1 symbol size must exceed ${SSBG1_LENGTH_FIELD_BYTES} (got ${symbolSize})`);
77
+ }
78
+ if (!ssbg1FitsSymbol(packet.byteLength, symbolSize)) {
79
+ throw new Error(`ssbg_mode1 source symbol needs ${packet.byteLength} + ${SSBG1_LENGTH_FIELD_BYTES} bytes but T is ${symbolSize}`);
80
+ }
81
+ const symbol = new Uint8Array(symbolSize);
82
+ symbol[0] = (packet.byteLength >>> 8) & 0xff;
83
+ symbol[1] = packet.byteLength & 0xff;
84
+ symbol.set(packet, SSBG1_LENGTH_FIELD_BYTES);
85
+ return symbol;
86
+ }
87
+ /**
88
+ * Recover the protected packet from one ssbg_mode1 source symbol: the bytes
89
+ * the length field names. Returns null, never a guess, when the length field
90
+ * points past the symbol or any padding octet is non-zero (C.3.3 padding is
91
+ * all 00h), since either means the recovered symbol is not what was sent.
92
+ */
93
+ export function trimSsbg1SourceSymbol(symbol) {
94
+ if (symbol.byteLength < SSBG1_LENGTH_FIELD_BYTES)
95
+ return null;
96
+ const length = (symbol[0] << 8) | symbol[1];
97
+ const end = SSBG1_LENGTH_FIELD_BYTES + length;
98
+ if (end > symbol.byteLength)
99
+ return null;
100
+ for (let i = end; i < symbol.byteLength; i++) {
101
+ if (symbol[i] !== 0)
102
+ return null;
103
+ }
104
+ return symbol.subarray(SSBG1_LENGTH_FIELD_BYTES, end);
105
+ }
106
+ /** The SS_ID after the last source symbol of `[ssStart, ssStart + ssbLength)`. */
107
+ export function isoBlockEnd(ssStart, ssbLength) {
108
+ return serial32Add(ssStart, ssbLength);
109
+ }
110
+ /**
111
+ * Range membership (C.5.2, C.5.3): whether `ssId` is one of the
112
+ * `ssbLength` consecutive SS_IDs starting at `ssStart`, modulo 2^32.
113
+ */
114
+ export function isoBlockContains(ssStart, ssbLength, ssId) {
115
+ return serial32Distance(ssStart, ssId) < ssbLength;
116
+ }
117
+ /**
118
+ * A lower bound on how many blocks the block starting at `a` lies behind the
119
+ * one starting at `b` (0 when `a` does not precede `b`). An iso-ssbg1-v1
120
+ * block holds at most `kMax` source symbols (the catalog `sourceSymbols`, the
121
+ * AL-FEC maximum_k_for_repair_flow), so `n * kMax` SS_IDs always span at least
122
+ * `n` blocks. Every interleave horizon in the receiver (decoder retention,
123
+ * worker retirement, ordered-relay settlement) uses this one bound, so the
124
+ * manager's horizon can never fall inside the decoder's.
125
+ */
126
+ export function isoBlocksBehindLowerBound(a, b, kMax) {
127
+ if (!Number.isSafeInteger(kMax) || kMax <= 0) {
128
+ throw new Error(`iso-ssbg1-v1 block horizon needs a positive maximum K (got ${kMax})`);
129
+ }
130
+ return serial32Precedes(a, b) ? Math.floor(serial32Distance(a, b) / kMax) : 0;
131
+ }
132
+ //# sourceMappingURL=fec-block-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fec-block-profile.js","sourceRoot":"","sources":["../src/fec-block-profile.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,7 @@
1
1
  export * from './mmtp.js';
2
+ export * from './net-constants.js';
3
+ export * from './ntp-short.js';
4
+ export * from './signalling.js';
5
+ export * from './serial-number.js';
6
+ export * from './fec-block-profile.js';
2
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,oBAAoB,CAAA;AAClC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA"}
package/dist/index.js CHANGED
@@ -1,2 +1,7 @@
1
1
  export * from './mmtp.js';
2
+ export * from './net-constants.js';
3
+ export * from './ntp-short.js';
4
+ export * from './signalling.js';
5
+ export * from './serial-number.js';
6
+ export * from './fec-block-profile.js';
2
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,oBAAoB,CAAA;AAClC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA"}
package/dist/mmtp.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { extractAltaTrailer as _leafExtractAltaTrailer, type AltaTrailer as _LeafAltaTrailer } from '@blockcast/mmt-alta-parse';
2
1
  /**
3
2
  * @mmt/container - MMTP Parser
4
3
  *
@@ -74,12 +73,32 @@ export declare const PACKET_TYPE_MPU = 0;
74
73
  export declare const PACKET_TYPE_SIGNALING = 2;
75
74
  export declare const PACKET_TYPE_REPAIR = 3;
76
75
  export declare const ALFEC_MESSAGE_ID = 515;
76
+ /**
77
+ * MMTP `packet_id` of the signaling flow, which carries PACKET_TYPE_SIGNALING
78
+ * packets such as the AL-FEC message (ALFEC_MESSAGE_ID). The FFmpeg `moq_mmt`
79
+ * muxer sends that message on this packet_id into the same multicast group as
80
+ * the media, and moqcast-draft (PR #44) makes advertising it for a track a
81
+ * MUST NOT. A track's packet_id is therefore 1..MMTP_PACKET_ID_MAX.
82
+ */
83
+ export declare const MMTP_SIGNALING_PACKET_ID = 0;
84
+ /** Largest value of the 16-bit MMTP `packet_id` header field. */
85
+ export declare const MMTP_PACKET_ID_MAX = 65535;
77
86
  export declare const FEC_CODE_XOR = 1;
78
87
  export declare const FEC_CODE_RAPTORQ = 2;
79
88
  /**
80
89
  * Parse MMTP header from buffer
81
90
  */
82
91
  export declare function parseMMTPHeader(buffer: Uint8Array): MMTPHeader;
92
+ /**
93
+ * The MMTP `packet_id` of `buffer`, or null exactly when parseMMTPHeader would
94
+ * throw for it (short buffer, V != 0, truncated packet_counter or header
95
+ * extension).
96
+ *
97
+ * This is the per-packet filter a receiver runs before any other work, so it
98
+ * builds no header object, DataView or BigInt timestamp (BLO-36599). Use
99
+ * parseMMTPHeader when any other header field is needed.
100
+ */
101
+ export declare function readMMTPPacketId(buffer: Uint8Array): number | null;
83
102
  /**
84
103
  * Unwrap MMTP packet to extract payload
85
104
  */
@@ -96,6 +115,18 @@ export declare function unwrapMMTP(buffer: Uint8Array): MMTPPacket;
96
115
  */
97
116
  export declare function parseMPUHeader(payload: Uint8Array): MPUHeader;
98
117
  export declare function parseTimedMfuDuHeader(payload: Uint8Array, offset: number): MFUDuHeader | null;
118
+ /**
119
+ * Why `extractMFUPayload` refused a packet.
120
+ *
121
+ * These identifiers are part of the public contract: callers surface them in
122
+ * diagnostics, so renaming one is a breaking change.
123
+ */
124
+ export type MFURejectionGate = 'packet-shorter-than-mmtp-plus-mpu-header' | 'mmtp-header-unparseable' | 'not-an-mpu-packet' | 'payload-shorter-than-mpu-header' | 'aggregation-flag-set' | 'mpu-payload-length-below-header-remainder' | 'mpu-declared-end-exceeds-payload' | 'mfu-offset-at-or-past-declared-end' | 'source-fec-payload-id-width-mismatch' | 'declared-trailers-unresolved';
125
+ export interface MFURejection {
126
+ gate: MFURejectionGate;
127
+ /** Human-readable detail, including the byte arithmetic that decided it. */
128
+ detail: string;
129
+ }
99
130
  /**
100
131
  * Extract NAL unit payload from MMTP packet
101
132
  */
@@ -120,29 +151,31 @@ export interface MFUExtraction {
120
151
  } | null;
121
152
  }
122
153
  /**
123
- * Extract MFU payload from a raw MMTP packet.
154
+ * Report why `extractMFUPayload` would refuse this packet, or null if it would
155
+ * accept it.
124
156
  *
125
- * Handles all the byte arithmetic for:
126
- * - MMTP header (12 bytes)
127
- * - MPU sub-header (8 bytes, payloadLength field)
128
- * - MFU DU header (14 bytes timed / 4 bytes non-timed, only for FI ≤ 1)
129
- * - Source FEC Payload ID (4 bytes at end, only when `FEC_type == 1`)
130
- *
131
- * `payloadLength` is the ISO length-after-field value: six remaining MPU-header
132
- * bytes, then the MFU DU header when present, then media. ALTA and Source FEC
133
- * trailers are outside that declared span and must consume the exact suffix.
134
- *
135
- * @param mmtpPacket Raw MMTP packet (from multicast or MoQ)
136
- * @param options.skipFecId When true, do NOT subtract the 4-byte Source FEC Payload ID
137
- * from the payload boundary, even if fecType >= 1 in the MMTP header. Use this for
138
- * FEC-recovered symbols where the FEC PID was already stripped before WASM decoding
139
- * but the fecType bits in byte 0 still reflect the original packet (FEC Type=1 per
140
- * draft-ramadan-moq-mmt-00 §3.1).
141
- * @returns Extracted MFU data + metadata, or null if packet is too small
157
+ * `extractMFUPayload` returns bare `null` on ten distinct conditions, which
158
+ * makes a producer/consumer framing disagreement indistinguishable from a
159
+ * publisher that never started — both render as silence. Use this wherever
160
+ * that distinction matters: diagnostics, contract tests, and operator-facing
161
+ * logs.
142
162
  */
163
+ export declare function explainMFURejection(mmtpPacket: Uint8Array, options?: {
164
+ skipFecId?: boolean;
165
+ }): MFURejection | null;
143
166
  export declare function extractMFUPayload(mmtpPacket: Uint8Array, options?: {
144
167
  skipFecId?: boolean;
145
168
  }): MFUExtraction | null;
169
+ /**
170
+ * extractMFUPayload for a caller that already holds this packet's parsed MMTP
171
+ * header, so the header is not parsed a second time (BLO-36599).
172
+ *
173
+ * `header` must be `parseMMTPHeader(mmtpPacket)` of this same packet; the
174
+ * result is then identical to `extractMFUPayload(mmtpPacket, options)`.
175
+ */
176
+ export declare function extractMFUPayloadWithHeader(mmtpPacket: Uint8Array, header: MMTPHeader, options?: {
177
+ skipFecId?: boolean;
178
+ }): MFUExtraction | null;
146
179
  /**
147
180
  * Extract timestamp from MMTP packet
148
181
  */
@@ -157,9 +190,10 @@ export declare function isFecRepairPacket(mmtpPacket: Uint8Array): boolean;
157
190
  * source packet per ISO/IEC 23008-1:2023 Section C.5.2 Figure C.10.
158
191
  *
159
192
  * SS_ID is a flat 32-bit monotonic counter (incremented by 1 per packet
160
- * for ssbg_mode0 and ssbg_mode1). Block membership and ESI are derived
161
- * at recovery time from repair packet SS_Start and SSB_length:
162
- * SBN = floor(SS_ID / K), ESI = SS_ID % K
193
+ * for ssbg_mode0 and ssbg_mode1). Block membership and ESI use the
194
+ * configured K; repair SS_Start identifies the first SS_ID of the block and
195
+ * SSB_length records the authored source-symbol count:
196
+ * SBN = floor(SS_ID / K), ESI = SS_ID % K
163
197
  * SS_Start = SBN * K (first SS_ID of the block)
164
198
  *
165
199
  * This matches FFmpeg moqenc_mmt.c, the drafts (draft-ramadan-moq-fec §6.2),
@@ -174,17 +208,17 @@ export declare function extractFecPayloadId(mmtpPacket: Uint8Array): {
174
208
  */
175
209
  export declare function hasSourceFecPayloadId(mmtpPacket: Uint8Array): boolean;
176
210
  /**
177
- * MMTP header-extension ext_type assigned to the detached ALTA authenticator
178
- * trailer (Path 2 / 08-07). Carried in an `[ext_type][ext_length][auth]`
179
- * block appended after the MPU's declared payload bytes, before the 4-byte
180
- * Source FEC Payload ID. MMTP X-bit stays 0 — non-ALTA MMTP receivers treat
181
- * the trailer as bytes past `payload_length` and skip it (per ISO 23008-1
182
- * §9.2.2 "may be discarded without impacting correct processing").
211
+ * The Source FEC Payload ID of a packet whose MMTP header the caller already
212
+ * parsed, or null when the packet carries none: present only when FEC_type=1
213
+ * and the exact suffix after the ISO-declared MPU payload holds the four-byte
214
+ * ID (ISO/IEC 23008-1 §C.5.2). Same answer as extractFecPayloadId, without a
215
+ * second header parse (BLO-36599).
216
+ *
217
+ * `header` must be `parseMMTPHeader(mmtpPacket)` of this same packet.
183
218
  */
184
- export declare const MMTP_EXT_TYPE_ALTA_AUTH = 61601;
185
- export declare const MMTP_EXT_TRAILER_HEADER_SIZE = 4;
186
- export type AltaTrailer = _LeafAltaTrailer;
187
- export declare const extractAltaTrailer: typeof _leafExtractAltaTrailer;
219
+ export declare function sourceFecPayloadIdOf(mmtpPacket: Uint8Array, header: MMTPHeader): {
220
+ ssId: number;
221
+ } | null;
188
222
  /** Size of Repair FEC Payload ID per ISO/IEC 23008-1 Section C.5.3 */
189
223
  export declare const REPAIR_FEC_PID_SIZE = 13;
190
224
  /**
@@ -212,7 +246,7 @@ export interface MoqRepairFrame {
212
246
  rsbLength: number;
213
247
  /** RS_ID (24 bits): repair symbol index (0-based) */
214
248
  rsId: number;
215
- /** SSB_length (24 bits): number of source symbols (K) */
249
+ /** SSB_length (24 bits): authored source-symbol count (1..=configured K) */
216
250
  ssbLength: number;
217
251
  /** Repair symbol data after the dynamic MMTP header and 13-byte FEC payload ID. */
218
252
  symbolData: Uint8Array;
@@ -225,7 +259,7 @@ export interface MoqRepairFrame {
225
259
  * then SS_Start (4 bytes) → block identifier
226
260
  * then RSB_length (3 bytes) → P
227
261
  * then RS_ID (3 bytes) → ESI = K + RS_ID
228
- * then SSB_length (3 bytes) → K
262
+ * then SSB_length (3 bytes) → authored source-symbol count (1..=K)
229
263
  * then Repair Symbol Data (T bytes)
230
264
  *
231
265
  * @param frame - Raw MoQ repair frame bytes
@@ -233,39 +267,13 @@ export interface MoqRepairFrame {
233
267
  */
234
268
  export declare function parseMoqRepairFrame(frame: Uint8Array): MoqRepairFrame | null;
235
269
  /**
236
- * AL-FEC signaling configuration parsed from ISO/IEC 23008-1:2023 Table C.3 message.
237
- */
238
- export interface AlFecConfig {
239
- fecCodeId: number;
240
- fecPayloadIdMode: 0;
241
- repairSymbolSize: number;
242
- maximumK: number;
243
- maximumP: number;
244
- interleaveDepth: number;
245
- oti: Uint8Array;
246
- }
247
- /**
248
- * Parse AL-FEC signaling message from a full MMTP signaling packet.
249
- *
250
- * Wire format (ISO/IEC 23008-1:2023 Table C.3, Amendment 1:2025):
251
- * [12-byte MMTP header (packet_type=0x02)]
252
- * message_id(2) = 0x0203
253
- * version(1)
254
- * message_length(2) = length of remaining payload
255
- * flags(1) = fec_flag(1) | private_fec_flag(1) | reserved(6)
256
- * fec_flow_descriptor:
257
- * length(2)
258
- * num_flows(1)
259
- * per flow:
260
- * fec_flow_id(1), source_flow_id(1), num_assets(1), packet_ids(2*N),
261
- * coding_params(1), repair_symbol_size(2),
262
- * [one-stage]: repair_flow_id(2), fec_code_id(1),
263
- * [private_fec_flag]: private_header(1){flag(1)|len(7)},
264
- * current RaptorQ profile OTI(12) + interleave_depth(1)
265
- * max_k(3), max_p(3), protection_window_time(4), protection_window_size(4)
270
+ * parseMoqRepairFrame for a caller that already holds this frame's parsed MMTP
271
+ * header, so the header is not parsed a second time (BLO-36599). The router's
272
+ * multicast repair branch uses it: one repair packet in every K + P otherwise
273
+ * paid two header parses.
266
274
  *
267
- * @param mmtpPacket Full MMTP packet including 12-byte header
268
- * @returns Parsed config or null if not an AL-FEC signaling message
275
+ * `header` must be `parseMMTPHeader(frame)` of this same frame; the result is
276
+ * then identical to `parseMoqRepairFrame(frame)`.
269
277
  */
270
- export declare function parseAlFecMessage(mmtpPacket: Uint8Array): AlFecConfig | null;
278
+ export declare function parseMoqRepairFrameWithHeader(frame: Uint8Array, header: MMTPHeader): MoqRepairFrame | null;
271
279
  //# sourceMappingURL=mmtp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mmtp.d.ts","sourceRoot":"","sources":["../src/mmtp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mmtp.d.ts","sourceRoot":"","sources":["../src/mmtp.ts"],"names":[],"mappings":"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"}