@blockcast/mmt-base 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mmtp.js ADDED
@@ -0,0 +1,568 @@
1
+ import { MMTP_EXT_TYPE_ALTA_AUTH as _LEAF_MMTP_EXT_TYPE_ALTA_AUTH, MMTP_EXT_TRAILER_HEADER_SIZE as _LEAF_MMTP_EXT_TRAILER_HEADER_SIZE, extractAltaTrailer as _leafExtractAltaTrailer, } from '@blockcast/mmt-alta-parse';
2
+ export const MMTP_HEADER_SIZE = 12;
3
+ export const MPU_HEADER_SIZE = 8;
4
+ export const MFU_DU_HEADER_SIZE_TIMED = 14; // T=1: timed media (video/audio samples)
5
+ export const MFU_DU_HEADER_SIZE_NONTIMED = 4; // T=0: non-timed media (item_id only)
6
+ const MPU_LENGTH_FIELD_SIZE = 2;
7
+ const MPU_HEADER_REMAINDER_SIZE = MPU_HEADER_SIZE - MPU_LENGTH_FIELD_SIZE;
8
+ const SOURCE_FEC_PAYLOAD_ID_SIZE = 4;
9
+ // MMTP Packet Types (ISO/IEC 23008-1:2023 Section 9.2.2)
10
+ export const PACKET_TYPE_MPU = 0x00;
11
+ export const PACKET_TYPE_SIGNALING = 0x02;
12
+ export const PACKET_TYPE_REPAIR = 0x03;
13
+ // AL-FEC Signaling Message ID (ISO/IEC 23008-1:2023 Amendment 1:2025)
14
+ export const ALFEC_MESSAGE_ID = 0x0203;
15
+ // FEC Code IDs
16
+ export const FEC_CODE_XOR = 1;
17
+ export const FEC_CODE_RAPTORQ = 2;
18
+ /**
19
+ * Parse MMTP header from buffer
20
+ */
21
+ export function parseMMTPHeader(buffer) {
22
+ if (buffer.length < MMTP_HEADER_SIZE) {
23
+ throw new Error(`MMTP packet too small: ${buffer.length} bytes`);
24
+ }
25
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
26
+ const version = (buffer[0] >> 6) & 0x03;
27
+ if (version !== 0) {
28
+ throw new Error(`Unsupported MMTP version: ${version}`);
29
+ }
30
+ // Extract FEC type from byte 0, bits 3-4
31
+ const fecType = (buffer[0] >> 3) & 0x03;
32
+ const packetCounterFlag = (buffer[0] & 0x20) !== 0;
33
+ const extensionFlag = (buffer[0] & 0x02) !== 0;
34
+ // Extract RAP flag from byte 0, bit 0 (R bit - Random Access Point)
35
+ const rapFlag = (buffer[0] & 0x01) === 1;
36
+ // ISO/IEC 23008-1:2023 Figure 8 (V=0) places reserved(2) before
37
+ // packet_type(6), so packet_type occupies the low six bits of byte 1.
38
+ const packetType = buffer[1] & 0x3F;
39
+ let offset = 2;
40
+ // Packet ID (2 bytes, big-endian)
41
+ const packetId = view.getUint16(offset, false);
42
+ offset += 2;
43
+ // Timestamp (4 bytes, big-endian)
44
+ const timestamp = BigInt(view.getUint32(offset, false));
45
+ offset += 4;
46
+ // Sequence number (4 bytes, big-endian)
47
+ const sequenceNumber = view.getUint32(offset, false);
48
+ offset += 4;
49
+ let packetCounter;
50
+ if (packetCounterFlag) {
51
+ if (offset + 4 > buffer.length)
52
+ throw new Error('MMTP packet truncated in packet_counter');
53
+ packetCounter = view.getUint32(offset, false);
54
+ offset += 4;
55
+ }
56
+ let extension;
57
+ if (extensionFlag) {
58
+ if (offset + 4 > buffer.length)
59
+ throw new Error('MMTP packet truncated in header extension');
60
+ const type = view.getUint16(offset, false);
61
+ const length = view.getUint16(offset + 2, false);
62
+ offset += 4;
63
+ if (offset + length > buffer.length)
64
+ throw new Error('MMTP packet truncated in header extension value');
65
+ extension = { type, data: buffer.subarray(offset, offset + length) };
66
+ offset += length;
67
+ }
68
+ return {
69
+ version,
70
+ packetType,
71
+ packetId,
72
+ timestamp,
73
+ sequenceNumber,
74
+ payloadLength: buffer.length - offset,
75
+ fecType,
76
+ packetCounterFlag,
77
+ packetCounter,
78
+ extensionFlag,
79
+ extension,
80
+ headerLength: offset,
81
+ rapFlag,
82
+ };
83
+ }
84
+ /**
85
+ * Unwrap MMTP packet to extract payload
86
+ */
87
+ export function unwrapMMTP(buffer) {
88
+ const header = parseMMTPHeader(buffer);
89
+ const payload = buffer.subarray(header.headerLength);
90
+ return { header, payload };
91
+ }
92
+ /**
93
+ * Parse MPU header from payload
94
+ * ISO/IEC 23008-1:2023 Section 9.2.3.3
95
+ *
96
+ * MPU Header format (8 bytes) as written by FFmpeg/libmmt:
97
+ * - Bytes 0-1: payload_length (16 bits, big-endian)
98
+ * - Byte 2: FT(4) | T(1) | FI(2) | A(1)
99
+ * - Byte 3: fragment_counter (8 bits)
100
+ * - Bytes 4-7: MPU_sequence_number (32 bits, big-endian)
101
+ */
102
+ export function parseMPUHeader(payload) {
103
+ if (payload.length < MPU_HEADER_SIZE) {
104
+ throw new Error(`Payload too small for MPU header: ${payload.length} bytes`);
105
+ }
106
+ const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);
107
+ // Bytes 0-1: payload_length (16 bits, big-endian)
108
+ const payloadLength = view.getUint16(0, false);
109
+ // Byte 2: FT(4) | T(1) | FI(2) | A(1)
110
+ const flagsByte = payload[2];
111
+ const timedFlag = (flagsByte >> 3) & 0x01;
112
+ const fragmentationIndicator = (flagsByte >> 1) & 0x03;
113
+ const aggregationFlag = (flagsByte & 0x01) !== 0;
114
+ // Byte 3: fragment_counter (8 bits). The high bit is part of the counter in
115
+ // the current libmmt/FFmpeg writer ABI.
116
+ const fragmentCounter = payload[3];
117
+ // Bytes 4-7: MPU_sequence_number (32 bits, big-endian)
118
+ const mpuSequenceNumber = view.getUint32(4, false);
119
+ return {
120
+ mpuSequenceNumber,
121
+ fragmentationIndicator,
122
+ fragmentCounter,
123
+ timedFlag,
124
+ aggregationFlag,
125
+ payloadLength,
126
+ };
127
+ }
128
+ export function parseTimedMfuDuHeader(payload, offset) {
129
+ if (offset < 0 || offset + MFU_DU_HEADER_SIZE_TIMED > payload.length)
130
+ return null;
131
+ const view = new DataView(payload.buffer, payload.byteOffset + offset, MFU_DU_HEADER_SIZE_TIMED);
132
+ return {
133
+ movieFragmentSequenceNumber: view.getUint32(0, false),
134
+ sampleNumber: view.getUint32(4, false),
135
+ offset: view.getUint32(8, false),
136
+ priority: payload[offset + 12],
137
+ dependencyCounter: payload[offset + 13],
138
+ };
139
+ }
140
+ function resolveMfuPayloadLayout(mpu, fragmentType, payload) {
141
+ if (mpu.payloadLength < MPU_HEADER_REMAINDER_SIZE)
142
+ return null;
143
+ // ISO/IEC 23008-1 defines payload_length from immediately after its own
144
+ // two-byte field. It therefore includes the remaining six MPU-header bytes.
145
+ const declaredEnd = MPU_LENGTH_FIELD_SIZE + mpu.payloadLength;
146
+ if (declaredEnd > payload.length)
147
+ return null;
148
+ const hasHeader = fragmentType === 2 && mpu.fragmentationIndicator <= 1;
149
+ const mfuHeaderSize = mpu.timedFlag ? MFU_DU_HEADER_SIZE_TIMED : MFU_DU_HEADER_SIZE_NONTIMED;
150
+ const mfuOffset = MPU_HEADER_SIZE + (hasHeader ? mfuHeaderSize : 0);
151
+ if (mfuOffset >= declaredEnd)
152
+ return null;
153
+ return {
154
+ hasMfuDuHeader: hasHeader,
155
+ mfuOffset,
156
+ dataEnd: declaredEnd,
157
+ };
158
+ }
159
+ function isEmptyOrExactAltaTrailer(payload, start, end) {
160
+ if (start === end)
161
+ return true;
162
+ if (start < 0 || end > payload.length || start + _LEAF_MMTP_EXT_TRAILER_HEADER_SIZE > end) {
163
+ return false;
164
+ }
165
+ const view = new DataView(payload.buffer, payload.byteOffset + start, end - start);
166
+ if (view.getUint16(0, false) !== _LEAF_MMTP_EXT_TYPE_ALTA_AUTH)
167
+ return false;
168
+ const authLength = view.getUint16(2, false);
169
+ return start + _LEAF_MMTP_EXT_TRAILER_HEADER_SIZE + authLength === end;
170
+ }
171
+ function resolveDeclaredTrailers(payload, declaredEnd, fecType, options) {
172
+ if (declaredEnd > payload.length)
173
+ return null;
174
+ if (options?.skipFecId) {
175
+ return isEmptyOrExactAltaTrailer(payload, declaredEnd, payload.length)
176
+ ? { hasFecId: false }
177
+ : null;
178
+ }
179
+ if (fecType === 1) {
180
+ const fecStart = payload.length - SOURCE_FEC_PAYLOAD_ID_SIZE;
181
+ if (fecStart < declaredEnd || !isEmptyOrExactAltaTrailer(payload, declaredEnd, fecStart)) {
182
+ return null;
183
+ }
184
+ return { hasFecId: true };
185
+ }
186
+ if (fecType !== 0)
187
+ return null;
188
+ if (isEmptyOrExactAltaTrailer(payload, declaredEnd, payload.length)) {
189
+ return { hasFecId: false };
190
+ }
191
+ return null;
192
+ }
193
+ /**
194
+ * Extract NAL unit payload from MMTP packet
195
+ */
196
+ export function extractNALUnit(mmtpPacket) {
197
+ const extraction = extractMFUPayload(mmtpPacket);
198
+ if (!extraction)
199
+ throw new Error('Malformed MMTP MPU payload');
200
+ return extraction.data;
201
+ }
202
+ /**
203
+ * Extract MFU payload from a raw MMTP packet.
204
+ *
205
+ * Handles all the byte arithmetic for:
206
+ * - MMTP header (12 bytes)
207
+ * - MPU sub-header (8 bytes, payloadLength field)
208
+ * - MFU DU header (14 bytes timed / 4 bytes non-timed, only for FI ≤ 1)
209
+ * - Source FEC Payload ID (4 bytes at end, only when `FEC_type == 1`)
210
+ *
211
+ * `payloadLength` is the ISO length-after-field value: six remaining MPU-header
212
+ * bytes, then the MFU DU header when present, then media. ALTA and Source FEC
213
+ * trailers are outside that declared span and must consume the exact suffix.
214
+ *
215
+ * @param mmtpPacket Raw MMTP packet (from multicast or MoQ)
216
+ * @param options.skipFecId When true, do NOT subtract the 4-byte Source FEC Payload ID
217
+ * from the payload boundary, even if fecType >= 1 in the MMTP header. Use this for
218
+ * FEC-recovered symbols where the FEC PID was already stripped before WASM decoding
219
+ * but the fecType bits in byte 0 still reflect the original packet (FEC Type=1 per
220
+ * draft-ramadan-moq-mmt-00 §3.1).
221
+ * @returns Extracted MFU data + metadata, or null if packet is too small
222
+ */
223
+ export function extractMFUPayload(mmtpPacket, options) {
224
+ if (mmtpPacket.length < MMTP_HEADER_SIZE + MPU_HEADER_SIZE)
225
+ return null;
226
+ let header;
227
+ try {
228
+ header = parseMMTPHeader(mmtpPacket);
229
+ }
230
+ catch {
231
+ return null;
232
+ }
233
+ if (header.packetType !== PACKET_TYPE_MPU)
234
+ return null;
235
+ const payload = mmtpPacket.subarray(header.headerLength);
236
+ if (payload.length < MPU_HEADER_SIZE)
237
+ return null;
238
+ const mpu = parseMPUHeader(payload);
239
+ if (mpu.aggregationFlag)
240
+ return null;
241
+ // Fragment type from byte 2 upper nibble (not returned by parseMPUHeader)
242
+ const fragmentType = (payload[2] >> 4) & 0x0f;
243
+ const layout = resolveMfuPayloadLayout(mpu, fragmentType, payload);
244
+ if (!layout)
245
+ return null;
246
+ const trailerLayout = resolveDeclaredTrailers(payload, layout.dataEnd, header.fecType, options);
247
+ if (!trailerLayout)
248
+ return null;
249
+ const mfuDuHeaderPresent = layout.hasMfuDuHeader;
250
+ const mfuOffset = layout.mfuOffset;
251
+ const dataEnd = layout.dataEnd;
252
+ if (mfuOffset >= dataEnd)
253
+ return null;
254
+ const mfuDuHeader = mfuDuHeaderPresent && mpu.timedFlag === 1
255
+ ? parseTimedMfuDuHeader(payload, MPU_HEADER_SIZE)
256
+ : null;
257
+ const itemId = mfuDuHeaderPresent && mpu.timedFlag === 0
258
+ ? new DataView(payload.buffer, payload.byteOffset + MPU_HEADER_SIZE, 4).getUint32(0, false)
259
+ : null;
260
+ const data = payload.subarray(mfuOffset, dataEnd);
261
+ const fecPayloadId = trailerLayout.hasFecId
262
+ ? {
263
+ ssId: new DataView(mmtpPacket.buffer, mmtpPacket.byteOffset + mmtpPacket.length - SOURCE_FEC_PAYLOAD_ID_SIZE, SOURCE_FEC_PAYLOAD_ID_SIZE).getUint32(0, false),
264
+ }
265
+ : null;
266
+ return { header, mpu, fragmentType, data, mfuDuHeader, itemId, fecPayloadId };
267
+ }
268
+ /**
269
+ * Extract timestamp from MMTP packet
270
+ */
271
+ export function extractTimestamp(mmtpPacket) {
272
+ const { header } = unwrapMMTP(mmtpPacket);
273
+ return header.timestamp;
274
+ }
275
+ /**
276
+ * Check if MMTP packet is an FEC repair packet
277
+ * FEC_type 2 and 3 are repair packets
278
+ */
279
+ export function isFecRepairPacket(mmtpPacket) {
280
+ if (mmtpPacket.length < 1)
281
+ return false;
282
+ const fecType = (mmtpPacket[0] >> 3) & 0x03;
283
+ return fecType >= 2;
284
+ }
285
+ /**
286
+ * Extract Source FEC Payload ID (SS_ID) from the last 4 bytes of an MMTP
287
+ * source packet per ISO/IEC 23008-1:2023 Section C.5.2 Figure C.10.
288
+ *
289
+ * SS_ID is a flat 32-bit monotonic counter (incremented by 1 per packet
290
+ * for ssbg_mode0 and ssbg_mode1). Block membership and ESI are derived
291
+ * at recovery time from repair packet SS_Start and SSB_length:
292
+ * SBN = floor(SS_ID / K), ESI = SS_ID % K
293
+ * SS_Start = SBN * K (first SS_ID of the block)
294
+ *
295
+ * This matches FFmpeg moqenc_mmt.c, the drafts (draft-ramadan-moq-fec §6.2),
296
+ * and ATSC A/331 §8.1.2.5 which defers to ISO 23008-1 Annex C.
297
+ */
298
+ export function extractFecPayloadId(mmtpPacket) {
299
+ if (!hasSourceFecPayloadId(mmtpPacket))
300
+ return null;
301
+ // Flat 4-byte SS_ID: encoder writes block_id * K + symbol_id
302
+ const off = mmtpPacket.length - SOURCE_FEC_PAYLOAD_ID_SIZE;
303
+ const view = new DataView(mmtpPacket.buffer, mmtpPacket.byteOffset + off, SOURCE_FEC_PAYLOAD_ID_SIZE);
304
+ return { ssId: view.getUint32(0, false) };
305
+ }
306
+ /**
307
+ * Return true when FEC_type=1 and the exact suffix after the ISO-declared MPU
308
+ * payload contains a four-byte Source FEC Payload ID.
309
+ */
310
+ export function hasSourceFecPayloadId(mmtpPacket) {
311
+ if (mmtpPacket.length < MMTP_HEADER_SIZE + MPU_HEADER_SIZE)
312
+ return false;
313
+ let header;
314
+ try {
315
+ header = parseMMTPHeader(mmtpPacket);
316
+ }
317
+ catch {
318
+ return false;
319
+ }
320
+ if (header.packetType !== PACKET_TYPE_MPU)
321
+ return false;
322
+ const payload = mmtpPacket.subarray(header.headerLength);
323
+ if (payload.length < MPU_HEADER_SIZE)
324
+ return false;
325
+ const mpu = parseMPUHeader(payload);
326
+ if (mpu.payloadLength < MPU_HEADER_REMAINDER_SIZE)
327
+ return false;
328
+ const declaredEnd = MPU_LENGTH_FIELD_SIZE + mpu.payloadLength;
329
+ return resolveDeclaredTrailers(payload, declaredEnd, header.fecType)?.hasFecId ?? false;
330
+ }
331
+ /**
332
+ * MMTP header-extension ext_type assigned to the detached ALTA authenticator
333
+ * trailer (Path 2 / 08-07). Carried in an `[ext_type][ext_length][auth]`
334
+ * block appended after the MPU's declared payload bytes, before the 4-byte
335
+ * Source FEC Payload ID. MMTP X-bit stays 0 — non-ALTA MMTP receivers treat
336
+ * the trailer as bytes past `payload_length` and skip it (per ISO 23008-1
337
+ * §9.2.2 "may be discarded without impacting correct processing").
338
+ */
339
+ // Re-export the ALTA trailer helper from the zero-dep leaf package. The leaf
340
+ // owns the implementation so container and FEC consumers share one parser
341
+ // without creating a package cycle.
342
+ export const MMTP_EXT_TYPE_ALTA_AUTH = _LEAF_MMTP_EXT_TYPE_ALTA_AUTH;
343
+ export const MMTP_EXT_TRAILER_HEADER_SIZE = _LEAF_MMTP_EXT_TRAILER_HEADER_SIZE;
344
+ export const extractAltaTrailer = _leafExtractAltaTrailer;
345
+ /** Size of Repair FEC Payload ID per ISO/IEC 23008-1 Section C.5.3 */
346
+ export const REPAIR_FEC_PID_SIZE = 13;
347
+ /** Parse the 13-byte Repair FEC Payload ID after the complete dynamic MMTP header. */
348
+ function readRepairFecPayloadIdFields(mmtpPacket) {
349
+ let header;
350
+ try {
351
+ header = parseMMTPHeader(mmtpPacket);
352
+ }
353
+ catch {
354
+ return null;
355
+ }
356
+ if (header.packetType !== PACKET_TYPE_REPAIR || header.fecType !== 2)
357
+ return null;
358
+ const off = header.headerLength;
359
+ if (mmtpPacket.length < off + REPAIR_FEC_PID_SIZE)
360
+ return null;
361
+ const view = new DataView(mmtpPacket.buffer, mmtpPacket.byteOffset + off, REPAIR_FEC_PID_SIZE);
362
+ const ssStart = view.getUint32(0, false); // 32 bits
363
+ const rsbLength = (mmtpPacket[off + 4] << 16) | (mmtpPacket[off + 5] << 8) | mmtpPacket[off + 6]; // 24 bits
364
+ const rsId = (mmtpPacket[off + 7] << 16) | (mmtpPacket[off + 8] << 8) | mmtpPacket[off + 9]; // 24 bits
365
+ const ssbLength = (mmtpPacket[off + 10] << 16) | (mmtpPacket[off + 11] << 8) | mmtpPacket[off + 12]; // 24 bits
366
+ return {
367
+ packetId: header.packetId,
368
+ ssStart,
369
+ rsbLength,
370
+ rsId,
371
+ ssbLength,
372
+ dataOffset: off + REPAIR_FEC_PID_SIZE,
373
+ };
374
+ }
375
+ /**
376
+ * Extract Repair FEC Payload ID from a raw-multicast MMTP repair packet.
377
+ * Per ISO/IEC 23008-1:2023 Section C.5.3 (ssbg_mode0, one-stage, no FFSRP_TS):
378
+ * [MMTP header][SS_Start:4][RSB_length:3][RS_ID:3][SSB_length:3][repair data]
379
+ * OTI is delivered via AL-FEC signaling message (Table C.3), not per-packet.
380
+ *
381
+ * Byte 1 is reserved(2)|packet_type(6) for V=0, so repair type 0x03 is 0x03.
382
+ * Pre-migration high-bits bytes (0x0c) are rejected — no compatibility decode.
383
+ */
384
+ export function extractRepairFecPayloadId(mmtpPacket) {
385
+ const fields = readRepairFecPayloadIdFields(mmtpPacket);
386
+ if (!fields)
387
+ return null;
388
+ return {
389
+ ssStart: fields.ssStart,
390
+ rsbLength: fields.rsbLength,
391
+ rsId: fields.rsId,
392
+ ssbLength: fields.ssbLength,
393
+ };
394
+ }
395
+ /**
396
+ * Parse a MoQ repair frame (ISO/IEC 23008-1 Annex C format).
397
+ *
398
+ * Wire format per ISO 23008-1 §C.4.3 + §C.5.3:
399
+ * MMTP Header: fixed 12 bytes plus C/X optional fields
400
+ * then SS_Start (4 bytes) → block identifier
401
+ * then RSB_length (3 bytes) → P
402
+ * then RS_ID (3 bytes) → ESI = K + RS_ID
403
+ * then SSB_length (3 bytes) → K
404
+ * then Repair Symbol Data (T bytes)
405
+ *
406
+ * @param frame - Raw MoQ repair frame bytes
407
+ * @returns Parsed frame or null if invalid
408
+ */
409
+ export function parseMoqRepairFrame(frame) {
410
+ const repairId = readRepairFecPayloadIdFields(frame);
411
+ if (!repairId)
412
+ return null;
413
+ const symbolData = frame.subarray(repairId.dataOffset);
414
+ if (repairId.rsbLength === 0 ||
415
+ repairId.ssbLength === 0 ||
416
+ repairId.rsId >= repairId.rsbLength ||
417
+ symbolData.length === 0)
418
+ return null;
419
+ return {
420
+ packetId: repairId.packetId,
421
+ ssStart: repairId.ssStart,
422
+ rsbLength: repairId.rsbLength,
423
+ rsId: repairId.rsId,
424
+ ssbLength: repairId.ssbLength,
425
+ symbolData,
426
+ };
427
+ }
428
+ function canonicalRaptorQOtiK(oti, repairSymbolSize) {
429
+ if (oti.length !== 12 || oti[5] !== 0)
430
+ return null;
431
+ const transferLength = (oti[0] * 0x1_0000_0000) +
432
+ (((oti[1] << 24) | (oti[2] << 16) | (oti[3] << 8) | oti[4]) >>> 0);
433
+ const symbolSize = (oti[6] << 8) | oti[7];
434
+ const sourceBlocks = oti[8];
435
+ const subBlocks = (oti[9] << 8) | oti[10];
436
+ const alignment = oti[11];
437
+ if (!Number.isSafeInteger(transferLength) || transferLength <= 0 ||
438
+ symbolSize !== repairSymbolSize || symbolSize === 0 || symbolSize % 8 !== 0 ||
439
+ sourceBlocks !== 1 || subBlocks !== 1 || alignment !== 8 ||
440
+ transferLength % symbolSize !== 0) {
441
+ return null;
442
+ }
443
+ const k = transferLength / symbolSize;
444
+ return Number.isInteger(k) && k >= 1 && k <= 56_403 ? k : null;
445
+ }
446
+ /**
447
+ * Parse AL-FEC signaling message from a full MMTP signaling packet.
448
+ *
449
+ * Wire format (ISO/IEC 23008-1:2023 Table C.3, Amendment 1:2025):
450
+ * [12-byte MMTP header (packet_type=0x02)]
451
+ * message_id(2) = 0x0203
452
+ * version(1)
453
+ * message_length(2) = length of remaining payload
454
+ * flags(1) = fec_flag(1) | private_fec_flag(1) | reserved(6)
455
+ * fec_flow_descriptor:
456
+ * length(2)
457
+ * num_flows(1)
458
+ * per flow:
459
+ * fec_flow_id(1), source_flow_id(1), num_assets(1), packet_ids(2*N),
460
+ * coding_params(1), repair_symbol_size(2),
461
+ * [one-stage]: repair_flow_id(2), fec_code_id(1),
462
+ * [private_fec_flag]: private_header(1){flag(1)|len(7)},
463
+ * current RaptorQ profile OTI(12) + interleave_depth(1)
464
+ * max_k(3), max_p(3), protection_window_time(4), protection_window_size(4)
465
+ *
466
+ * @param mmtpPacket Full MMTP packet including 12-byte header
467
+ * @returns Parsed config or null if not an AL-FEC signaling message
468
+ */
469
+ export function parseAlFecMessage(mmtpPacket) {
470
+ if (mmtpPacket.length < MMTP_HEADER_SIZE + 9)
471
+ return null;
472
+ let header;
473
+ try {
474
+ header = parseMMTPHeader(mmtpPacket);
475
+ }
476
+ catch {
477
+ return null;
478
+ }
479
+ if (header.packetType !== PACKET_TYPE_SIGNALING || header.fecType !== 0)
480
+ return null;
481
+ const payload = mmtpPacket.subarray(header.headerLength);
482
+ if (payload.length < 9)
483
+ return null;
484
+ const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);
485
+ let off = 0;
486
+ const messageId = view.getUint16(off, false);
487
+ off += 2;
488
+ if (messageId !== ALFEC_MESSAGE_ID)
489
+ return null;
490
+ const version = payload[off];
491
+ off += 1;
492
+ const messageLength = view.getUint16(off, false);
493
+ off += 2;
494
+ if (version !== 1 || messageLength === 0 || messageLength !== payload.length - off)
495
+ return null;
496
+ const flags = payload[off];
497
+ off += 1;
498
+ const fecFlag = (flags >> 7) & 1;
499
+ const privateFecFlag = (flags >> 6) & 1;
500
+ if (fecFlag !== 1 || privateFecFlag !== 1 || (flags & 0x3f) !== 0x3f)
501
+ return null;
502
+ if (off + 2 > payload.length)
503
+ return null;
504
+ const descriptorLength = view.getUint16(off, false);
505
+ off += 2;
506
+ const descriptorEnd = off + descriptorLength;
507
+ if (descriptorLength === 0 || descriptorEnd !== payload.length)
508
+ return null;
509
+ const numFlows = payload[off];
510
+ off += 1;
511
+ if (numFlows !== 1 || off + 3 > descriptorEnd)
512
+ return null;
513
+ off += 2; // fec_flow_id, source_flow_id
514
+ const numAssets = payload[off];
515
+ off += 1;
516
+ if (numAssets === 0 || off + (numAssets * 2) > descriptorEnd)
517
+ return null;
518
+ off += numAssets * 2;
519
+ if (off + 3 > descriptorEnd)
520
+ return null;
521
+ const codingParams = payload[off];
522
+ off += 1;
523
+ const fecCodingStructure = (codingParams >> 4) & 0x0f;
524
+ const ssbgMode = (codingParams >> 2) & 0x03;
525
+ const ffsrptsFlag = (codingParams >> 1) & 0x01;
526
+ const fecPayloadIdMode = codingParams & 0x01;
527
+ if (fecCodingStructure !== 1 || ssbgMode !== 0 || ffsrptsFlag !== 0 || fecPayloadIdMode !== 0) {
528
+ return null;
529
+ }
530
+ const repairSymbolSize = view.getUint16(off, false);
531
+ off += 2;
532
+ if (repairSymbolSize === 0 || repairSymbolSize % 8 !== 0)
533
+ return null;
534
+ if (off + 4 > descriptorEnd)
535
+ return null;
536
+ off += 2; // Amendment 1:2025 replaces Table C.3 with a 16-bit repair_flow_id
537
+ const fecCodeId = payload[off];
538
+ off += 1;
539
+ if (fecCodeId !== FEC_CODE_RAPTORQ)
540
+ return null;
541
+ const privateHeader = payload[off];
542
+ off += 1;
543
+ const privateFlag = privateHeader >> 7;
544
+ const privateFieldLength = privateHeader & 0x7f;
545
+ if (privateFlag !== 1 || privateFieldLength !== 13 || off + 13 > descriptorEnd)
546
+ return null;
547
+ const oti = payload.slice(off, off + 12);
548
+ off += 12;
549
+ const interleaveDepth = payload[off];
550
+ off += 1;
551
+ const otiK = canonicalRaptorQOtiK(oti, repairSymbolSize);
552
+ if (otiK === null || interleaveDepth === 0)
553
+ return null;
554
+ if (off + 14 !== descriptorEnd)
555
+ return null;
556
+ const maximumK = (payload[off] << 16) | (payload[off + 1] << 8) | payload[off + 2];
557
+ off += 3;
558
+ const maximumP = (payload[off] << 16) | (payload[off + 1] << 8) | payload[off + 2];
559
+ off += 3;
560
+ if (maximumK !== otiK || maximumP === 0 || maximumK + maximumP - 1 > 0x00ff_ffff) {
561
+ return null;
562
+ }
563
+ off += 8; // protection_window_time, protection_window_size
564
+ if (off !== descriptorEnd)
565
+ return null;
566
+ return { fecCodeId, fecPayloadIdMode, repairSymbolSize, maximumK, maximumP, interleaveDepth, oti };
567
+ }
568
+ //# sourceMappingURL=mmtp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mmtp.js","sourceRoot":"","sources":["../src/mmtp.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@blockcast/mmt-base",
3
+ "version": "0.1.0",
4
+ "description": "Shared MMTP packet parsing primitives (zero FEC dependency). Hosts MMTP_HEADER_SIZE, parseMMTPHeader, extractMFUPayload, and friends so both @blockcast/mmt-fec and @blockcast/mmt-container can import them without a circular dep.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "src"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "clean": "rm -rf dist",
22
+ "typecheck": "tsc --noEmit",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest"
25
+ },
26
+ "dependencies": {
27
+ "@blockcast/mmt-alta-parse": "^0.1.0"
28
+ },
29
+ "devDependencies": {
30
+ "typescript": "^5.3.0",
31
+ "vitest": "^1.0.0"
32
+ },
33
+ "keywords": [
34
+ "mmt",
35
+ "mmtp",
36
+ "iso23008-1"
37
+ ],
38
+ "license": "Apache-2.0",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/Blockcast/libmmt.git",
42
+ "directory": "packages/mmt-base"
43
+ }
44
+ }