Expand description
RTMP chunk stream — basic header, message header, extended timestamp (Adobe RTMP 1.0 §5.3).
See docs/rtmp.md §3 (RTMP Chunk Stream) for the wire
layout: chunk format (§5.3.1), basic header (§5.3.1.1), the four message
header fmt variants (§5.3.1.2), and extended timestamp (§5.3.1.3).
This module implements the chunk header wire types (BasicHeader,
MessageHeader) and the stateful reassembly engine built on top of them:
ChunkAssembler (inbound, tracks prior-chunk state per csid so fmt
1/2/3 headers can inherit the fields they omit, and reassembles chunked
payload back into whole Messages) and ChunkWriter (outbound,
splits a Message into fmt 0 + 3 chunks at the configured chunk
size).
Structs§
- Basic
Header - Chunk Basic Header (§5.3.1.1): 1 to 3 bytes encoding the 2-bit
fmtand the chunk stream id (csid). Length depends only on the csid value; the implementation SHOULD (and thisSerializeimpl does) use the smallest form that holds the id. - Chunk
Assembler - Stateful inbound chunk reassembler (§5.3): feed inbound bytes, get back
each complete
Messageas soon as its last chunk arrives. - Chunk
Writer - Stateless-per-message outbound chunk writer (§5.3): serializes a
Messageinto chunk bytes at the current chunk size. - Message
- One fully reassembled RTMP message: the payload of a single message
stream at a single (resolved, absolute) timestamp (§6.1). Produced by
ChunkAssembler::pushand consumed byChunkWriter::write.
Enums§
- Fmt
- The 2-bit
fmtfield selecting one of the 4 Chunk Message Header formats (§5.3.1.1, §5.3.1.2). - Message
Header - Chunk Message Header: one of 4 formats selected by
Fmt(§5.3.1.2), carrying decreasing field sets — each format after Type 0 inherits the fields it omits from the preceding chunk on the same chunk stream.
Constants§
- DEFAULT_
CHUNK_ SIZE - Default maximum chunk size (§5.3, §5.4.1): 128 bytes, in effect until a Set Chunk Size protocol control message changes it.
- EXTENDED_
TIMESTAMP_ MARKER - The 24-bit sentinel value that, in a Type 0/1/2 message header’s
timestamp/timestamp deltafield, signals that the field does not carry the real value: the full 32-bit value instead follows in a 4-byte Extended Timestamp (§5.3.1.3). Per §5.3.1.2.1, any real timestamp/delta>= EXTENDED_TIMESTAMP_MARKERis encoded this way. - MAX_
CHUNK_ SIZE - Largest chunk size
ChunkAssembler::set_chunk_size/ChunkWriter::set_chunk_sizewill adopt from a Set Chunk Size protocol control message (§5.4.1): 16 MiB. The wire field is a 31-bit value (up to ~2 GiB), but no real publisher/player needs a chunk size anywhere near that — a single chunk this large would already hold many seconds of encoded audio/video — so this is a defensive ceiling, not a spec limit: values above it are clamped down rather than rejected, matching the existing floor-of-1 behaviour for values below it. - MAX_
CSIDS - Largest number of distinct chunk stream ids
ChunkAssemblerwill track reassembly state for concurrently. A well-behaved publisher uses only a handful of chunk streams (2/3 for control/command traffic, plus a few more for audio/video) — this bound is generous headroom above that, not a spec limit — so a flood of chunks opening many distinct (and mostly bogus) csids is rejected rather than growing the per-csid state map without bound. - MAX_
MESSAGE_ LEN - Largest total
message_length(§5.3.1.2)ChunkAssemblerwill begin buffering for a single reassembled message: 8 MiB.message_lengthis a fully attacker-controlled 24-bit wire field (max ~16 MiB); real RTMP audio/video/command messages are always far smaller than this (a single compressed video frame, even a keyframe, is normally well under 1 MiB), so this is a generous ceiling that still bounds worst-case allocation per in-progress message. A Type 0/1 header declaring a largermessage_lengthis rejected byChunkAssemblerbefore any buffer for it is allocated.