/** * How the signalling payload of an MMTP packet was framed: always * `iso-9.3.4.2`, the 2-byte `f_i(2) RES(4) H(1) A(1) | frag_counter(8)` * header of ISO/IEC 23008-1:2023 9.3.4.2 ahead of the message(s). * * The pre-remediation Blockcast form, an AL-FEC message directly after the * MMTP header, is not accepted (BLO-35597, Phase L). Its first two bytes, * `0x02 0x03`, read as a 9.3.4.2 header claiming three further fragments * of a complete message, which the header parser refuses: such a packet * parses to null, never to a guess. */ export type SignallingPayloadForm = 'iso-9.3.4.2'; export interface SignallingPayload { form: SignallingPayloadForm; /** Each complete signalling message, starting at its message_id. */ messages: Uint8Array[]; } /** f_i (Table 19): payload contains one or more complete signalling messages. */ export declare const SIGNALLING_FRAGMENTATION_COMPLETE = 0; /** * Split the payload of an MMTP signalling packet into its complete * signalling messages. * * Returns null when the packet is not a well-formed, unprotected (FEC_type 0) * signalling packet, or when it carries a fragment (f_i != 00): reassembly * across packets is not implemented, and a fragment is not a message. */ export declare function parseSignallingPayload(mmtpPacket: Uint8Array): SignallingPayload | null; export declare const PA_MESSAGE_ID = 0; export declare const MPI_MESSAGE_ID_FIRST = 1; export declare const MPI_MESSAGE_ID_LAST = 16; export declare const MPT_MESSAGE_ID_FIRST = 17; /** MPT message carrying the complete MP table (Table 101). */ export declare const MPT_MESSAGE_ID_COMPLETE = 32; /** * Whether a message's `length` field is 32 bits (Table 20: PA and MPI * messages; Table 101: the 0x7000-0x7FFF range "32-bit length message"). */ export declare function signallingMessageHas32BitLength(messageId: number): boolean; /** fec_coding_structure values (Table C.8 as replaced by Amd 1:2025). */ export declare const FEC_CODING_STRUCTURE_NONE = 0; export declare const FEC_CODING_STRUCTURE_ONE_STAGE = 1; export declare const FEC_CODING_STRUCTURE_TWO_STAGE = 2; export declare const FEC_CODING_STRUCTURE_LAYER_AWARE = 3; export declare const FEC_CODING_STRUCTURE_ADAPTIVE = 4; /** ssbg_mode values (Table C.5). b11 is reserved. */ export declare const SSBG_MODE_0 = 0; export declare const SSBG_MODE_1 = 1; export declare const SSBG_MODE_2 = 2; export interface AlFecPrivateField { privateFlag: 0 | 1; data: Uint8Array; } export interface AlFecRepairFlow { /** * repair_flow_id (16 bits under Amd 1:2025 for one-stage, two-stage and * LA-FEC). Blockcast senders set it to the repair flow's MMTP packet_id. */ repairFlowId: number; /** * fec_code_id_for_repair_flow. Under LA-FEC (0011) one value is signalled * per FEC flow and is repeated here on every layer. */ fecCodeId: number; /** * The private_flag/private_field_length/private_field triple, present * exactly when the message's private_fec_flag is 1. Shared by every layer * under LA-FEC, like fecCodeId. */ privateField?: AlFecPrivateField; maximumK: number; maximumP: number; protectionWindowTime: number; protectionWindowSize: number; } export interface AlFecFlow { fecFlowId: number; sourceFlowId: number; /** Every asset packet_id of the FEC source flow, in signalled order. */ packetIds: number[]; fecCodingStructure: number; ssbgMode: number; ffsrptsFlag: 0 | 1; /** * The low bit of the coding byte. Amd 1:2025 Table C.3 names it * fec_payload_id_mode (Table C.7: 0 = mode 0, Source FEC Payload ID added * to each packet; 1 = mode 1, C.7, packets unmodified). The unamended 2023 * Table C.3 lists the same bit as reserved "1". The parse never depends on * it — no later field is conditional on it — so both readings are * accepted and the value is reported, not interpreted (BLO-35597 N1). */ fecPayloadIdMode: 0 | 1; /** length_of_repair_symbol, in bytes. */ repairSymbolSize: number; /** Present exactly when ssbg_mode is b10. */ ssbgMode2?: { numRepairSymbolPerPacket: number; numSymbolElementPerSourceSymbol: number; }; /** num_of_sub_block_per_source_block, two-stage (0010) only. */ numSubBlockPerSourceBlock?: number; /** One entry for one-stage; N3 parity flows; N4 LA-FEC layers; none for 0000. */ repairFlows: AlFecRepairFlow[]; } export interface AlFecMessageBody { /** The message's version counter (C.6.3). Any value is accepted. */ version: number; fecFlag: 0 | 1; privateFecFlag: 0 | 1; /** Empty exactly when fec_flag is 0 (no FEC source flow). */ flows: AlFecFlow[]; } export interface AlFecMessage extends AlFecMessageBody { payloadForm: SignallingPayloadForm; } /** * Parse a complete AL-FEC message (Table C.3, Amd 1:2025), starting at its * message_id. Every FEC flow, every asset packet_id and every * coding-structure-conditional field is returned. */ export declare function parseAlFecMessageBody(message: Uint8Array): AlFecMessageBody | null; /** * Parse the AL-FEC message carried by a full MMTP signalling packet (a * 9.3.4.2 payload, see SignallingPayloadForm). Returns null when the packet * carries no AL-FEC message, more than one, or a malformed one. */ export declare function parseAlFecMessage(mmtpPacket: Uint8Array): AlFecMessage | null; /** * Decoder geometry of one FEC flow under the Blockcast one-stage RaptorQ * profile: private_field = RaptorQ FEC OTI (RFC 6330 3.3.2-3.3.3, 12 bytes) * followed by the interleave depth (1 byte). */ export interface AlFecRaptorQFlowConfig { sourcePacketIds: number[]; repairFlowId: number; /** Always `SSBG_MODE_1` (`iso-ssbg1-v1`). */ ssbgMode: number; /** The coding byte's low bit as signalled (see AlFecFlow.fecPayloadIdMode). */ fecPayloadIdMode: 0 | 1; repairSymbolSize: number; maximumK: number; maximumP: number; interleaveDepth: number; oti: Uint8Array; protectionWindowTime: number; protectionWindowSize: number; } /** * Validate one parsed FEC flow against the Blockcast one-stage RaptorQ * profile and return its decoder geometry, or null when the flow is outside * the profile. Nothing is inferred: K comes from the OTI and must equal * maximum_k_for_repair_flow. * * The profile is `iso-ssbg1-v1`, whose AL-FEC coding byte is 0x14 * (draft-ramadan-moq-fec §7.3; ISO/IEC 23008-1 Table C.3 as replaced by * Amd 1:2025): one-stage, ssbg_mode1, ffsrpts_flag 0, fec_payload_id_mode 0. * 0x15 is accepted too: its low bit is fec_payload_id_mode 1 under Amd * 1:2025 but reserved "1" in the unamended 2023 Table C.3, so a 2023 sender * of the same profile emits it. No later field depends on the bit, and each * source packet's FEC_type says whether it carries a Source FEC Payload ID, * so the bit is reported, not interpreted (BLO-35597 N1). Any other coding * byte is refused here, though `parseAlFecMessageBody` still reports it: * ssbg_mode0 (0x10/0x11, the retired `k-padded-v1` wire) carries no length * field; ffsrpts_flag=1 changes the source/repair packet trailer layout. */ export declare function alFecRaptorQFlowConfig(flow: AlFecFlow): AlFecRaptorQFlowConfig | null; /** location_type values (Table 96) a receiver may meet in an asset location. */ export type MmtGeneralLocation = { locationType: 0x00; packetId: number; } | { locationType: 0x01; srcAddress: Uint8Array; dstAddress: Uint8Array; dstPort: number; packetId: number; } | { locationType: 0x02; srcAddress: Uint8Array; dstAddress: Uint8Array; dstPort: number; packetId: number; } | { locationType: 0x03; networkId: number; transportStreamId: number; mpeg2Pid: number; } | { locationType: 0x04; srcAddress: Uint8Array; dstAddress: Uint8Array; dstPort: number; mpeg2Pid: number; } | { locationType: 0x05; url: Uint8Array; } | { locationType: 0x06; data: Uint8Array; }; /** Identifier_mapping() (Table 98). */ export type MmtIdentifierMapping = { identifierType: 0x00; assetIdScheme: number; assetId: Uint8Array; } | { identifierType: 0x01; urls: Uint8Array[]; } | { identifierType: 0x02; regex: Uint8Array; } | { identifierType: 0x03; representationId: Uint8Array; } | { identifierType: number; privateIdentifier: Uint8Array; }; /** table_id range of the MP table (Table 102): subset 0..14, then complete. */ export declare const MP_TABLE_ID_SUBSET_0 = 17; export declare const MP_TABLE_ID_COMPLETE = 32; export declare const MPI_TABLE_ID_FIRST = 1; export declare const MPI_TABLE_ID_LAST = 16; export interface MpAsset { identifier: MmtIdentifierMapping; /** asset_type, a 4CC (for example 'hvc1', 'mp4a'). */ assetType: string; assetModificationFlag: boolean; defaultAssetFlag: boolean; /** Present exactly when asset_clock_relation_flag is 1. */ assetClockRelationId?: number; /** Present exactly when asset_timescale_flag is 1. */ assetTimescale?: number; locations: MmtGeneralLocation[]; descriptors: Uint8Array; } export interface MpTable { tableId: number; version: number; /** MP_table_mode (Table 30); b11 is reserved and reported as read. */ mpTableMode: number; /** Present exactly for the complete table (0x20) and subset 0 (0x11). */ packageId?: Uint8Array; /** Present exactly for the complete table (0x20) and subset 0 (0x11). */ descriptors?: Uint8Array; assets: MpAsset[]; } /** Parse a complete MP table (Table 29), starting at its table_id. */ export declare function parseMpTable(bytes: Uint8Array): MpTable | null; /** * The packet_ids an Asset is delivered on: every location of type 0x00 * (same MMTP packet flow), 0x01 (UDP/IPv4) or 0x02 (UDP/IPv6), in * signalled order. */ export declare function mpAssetPacketIds(asset: MpAsset): number[]; export interface MmtSignallingTable { tableId: number; version: number; /** The complete table, starting at its table_id. */ bytes: Uint8Array; } export interface PaMessage { version: number; /** Every table of the message payload, in order. */ tables: MmtSignallingTable[]; /** The MP tables among `tables`, decoded. */ mpTables: MpTable[]; } export interface MptMessage { /** 0x0011-0x001F carry subset 0-14, 0x0020 the complete MP table. */ messageId: number; version: number; table: MpTable; } /** * Parse a complete PA message (Table 21), starting at its message_id. * * Every table in the payload is delimited by its own 16-bit `length` and * must match the extension's table_id and table_version. For non-MPI tables * table_length is "a copy of the length field" (10.3.2.3) and must match it * too; for an MPI table it is derived differently, so it is not compared. */ export declare function parsePaMessageBody(message: Uint8Array): PaMessage | null; /** Parse a complete MPT message (Table 23), starting at its message_id. */ export declare function parseMptMessageBody(message: Uint8Array): MptMessage | null; export type MmtSignallingMessage = { kind: 'al-fec'; message: AlFecMessageBody; } | { kind: 'pa'; message: PaMessage; } | { kind: 'mpt'; message: MptMessage; } /** A message this module does not decode, delimited and length-checked. */ | { kind: 'other'; messageId: number; version: number; bytes: Uint8Array; }; export interface MmtSignallingPacket { payloadForm: SignallingPayloadForm; messages: MmtSignallingMessage[]; } /** * Parse every signalling message of a full MMTP signalling packet (the * packet_id 0 flow). Returns null when the packet or any message in it is * malformed: one unparseable message leaves the receiver unable to say what * the packet signalled. Only the 9.3.4.2 payload form is accepted. */ export declare function parseSignallingPacket(mmtpPacket: Uint8Array): MmtSignallingPacket | null; //# sourceMappingURL=signalling.d.ts.map