`
`H. Parmar, Ed.
`M. Thornburgh, Ed.
`Adobe
`December 21, 2012
`
`Adobe’s Real Time Messaging Protocol
`
`Abstract
`
` This memo describes Adobe’s Real Time Messaging Protocol (RTMP), an
` application-level protocol designed for multiplexing and packetizing
` multimedia transport streams (such as audio, video, and interactive
` content) over a suitable transport protocol (such as TCP).
`
`Table of Contents
`
`1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
`1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 3
`2. Contributors . . . . . . . . . . . . . . . . . . . . . . . . . 3
`3. Definitions . . . . . . . . . . . . . . . . . . . . . . . . . 3
`4. Byte Order, Alignment, and Time Format . . . . . . . . . . . . 5
`5. RTMP Chunk Stream . . . . . . . . . . . . . . . . . . . . . . 5
`5.1. Message Format . . . . . . . . . . . . . . . . . . . . . . 6
`5.2. Handshake . . . . . . . . . . . . . . . . . . . . . . . . 7
`5.2.1. Handshake Sequence . . . . . . . . . . . . . . . . . . 7
`5.2.2. C0 and S0 Format . . . . . . . . . . . . . . . . . . . 7
`5.2.3. C1 and S1 Format . . . . . . . . . . . . . . . . . . . 8
`5.2.4. C2 and S2 Format . . . . . . . . . . . . . . . . . . . 8
`5.2.5. Handshake Diagram . . . . . . . . . . . . . . . . . . 10
`5.3. Chunking . . . . . . . . . . . . . . . . . . . . . . . . . 11
`5.3.1. Chunk Format . . . . . . . . . . . . . . . . . . . . . 11
`5.3.1.1. Chunk Basic Header . . . . . . . . . . . . . . . . 12
`5.3.1.2. Chunk Message Header . . . . . . . . . . . . . . . 13
`5.3.1.2.1. Type 0 . . . . . . . . . . . . . . . . . . . . 14
`5.3.1.2.2. Type 1 . . . . . . . . . . . . . . . . . . . . 14
`5.3.1.2.3. Type 2 . . . . . . . . . . . . . . . . . . . . 15
`5.3.1.2.4. Type 3 . . . . . . . . . . . . . . . . . . . . 15
`5.3.1.2.5. Common Header Fields . . . . . . . . . . . . . 15
`5.3.1.3. Extended Timestamp . . . . . . . . . . . . . . . . 16
`5.3.2. Examples . . . . . . . . . . . . . . . . . . . . . . . 16
`5.3.2.1. Example 1 . . . . . . . . . . . . . . . . . . . . 16
`5.3.2.2. Example 2 . . . . . . . . . . . . . . . . . . . . 17
`5.4. Protocol Control Messages . . . . . . . . . . . . . . . . 18
`5.4.1. Set Chunk Size (1) . . . . . . . . . . . . . . . . . . 19
`5.4.2. Abort Message (2) . . . . . . . . . . . . . . . . . . 19
`5.4.3. Acknowledgement (3) . . . . . . . . . . . . . . . . . 20
`
`Parmar & Thornburgh
`
`[Page 1]
`
`Sportradar 1036
`Page 1
`
`
`
` Adobe RTMP December 2012
`
` 5.4.4. Window Acknowledgement Size (5) . . . . . . . . . . . 20
` 5.4.5. Set Peer Bandwidth (6) . . . . . . . . . . . . . . . . 21
` 6. RTMP Message Formats . . . . . . . . . . . . . . . . . . . . . 21
` 6.1. RTMP Message Format . . . . . . . . . . . . . . . . . . . 22
` 6.1.1. Message Header . . . . . . . . . . . . . . . . . . . . 22
` 6.1.2. Message Payload . . . . . . . . . . . . . . . . . . . 22
` 6.2. User Control Messages (4) . . . . . . . . . . . . . . . . 23
` 7. RTMP Command Messages . . . . . . . . . . . . . . . . . . . . 23
` 7.1. Types of Messages . . . . . . . . . . . . . . . . . . . . 24
` 7.1.1. Command Message (20, 17) . . . . . . . . . . . . . . . 24
` 7.1.2. Data Message (18, 15) . . . . . . . . . . . . . . . . 24
` 7.1.3. Shared Object Message (19, 16) . . . . . . . . . . . . 24
` 7.1.4. Audio Message (8) . . . . . . . . . . . . . . . . . . 26
` 7.1.5. Video Message (9) . . . . . . . . . . . . . . . . . . 26
` 7.1.6. Aggregate Message (22) . . . . . . . . . . . . . . . . 26
` 7.1.7. User Control Message Events . . . . . . . . . . . . . 27
` 7.2. Types of Commands . . . . . . . . . . . . . . . . . . . . 28
` 7.2.1. NetConnection Commands . . . . . . . . . . . . . . . . 29
` 7.2.1.1. connect . . . . . . . . . . . . . . . . . . . . . 29
` 7.2.1.2. Call . . . . . . . . . . . . . . . . . . . . . . . 35
` 7.2.1.3. createStream . . . . . . . . . . . . . . . . . . . 36
` 7.2.2. NetStream Commands . . . . . . . . . . . . . . . . . . 37
` 7.2.2.1. play . . . . . . . . . . . . . . . . . . . . . . . 38
` 7.2.2.2. play2 . . . . . . . . . . . . . . . . . . . . . . 42
` 7.2.2.3. deleteStream . . . . . . . . . . . . . . . . . . . 43
` 7.2.2.4. receiveAudio . . . . . . . . . . . . . . . . . . . 44
` 7.2.2.5. receiveVideo . . . . . . . . . . . . . . . . . . . 45
` 7.2.2.6. publish . . . . . . . . . . . . . . . . . . . . . 45
` 7.2.2.7. seek . . . . . . . . . . . . . . . . . . . . . . . 46
` 7.2.2.8. pause . . . . . . . . . . . . . . . . . . . . . . 47
` 7.3. Message Exchange Examples . . . . . . . . . . . . . . . . 48
` 7.3.1. Publish Recorded Video . . . . . . . . . . . . . . . . 48
` 7.3.2. Broadcast a Shared Object Message . . . . . . . . . . 50
` 7.3.3. Publish Metadata from Recorded Stream . . . . . . . . 50
` 8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 51
` Authors’ Addresses . . . . . . . . . . . . . . . . . . . . . . . . 52
`
`Parmar & Thornburgh [Page 2]
`
`Sportradar 1036
`Page 2
`
`
`
` Adobe RTMP December 2012
`
`1. Introduction
`
` Adobe’s Real Time Messaging Protocol (RTMP) provides a bidirectional
` message multiplex service over a reliable stream transport, such as
` TCP [RFC0793], intended to carry parallel streams of video, audio,
` and data messages, with associated timing information, between a pair
` of communicating peers. Implementations typically assign different
` priorities to different classes of messages, which can effect the
` order in which messages are enqueued to the underlying stream
` transport when transport capacity is constrained.
`
` This memo describes the syntax and operation of the Real Time
` Messaging Protocol.
`
`1.1. Terminology
`
` The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
` "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
` "OPTIONAL" in this memo are to be interpreted as described in
` [RFC2119].
`
`2. Contributors
`
` Rajesh Mallipeddi, formerly of Adobe Systems, was the original editor
` of this specification, and provided most of its original text.
`
` Mohit Srivastava of Adobe Systems contributed to the development of
` this specification.
`
`3. Definitions
`
` Payload: The data contained in a packet, for example audio samples
` or compressed video data. The payload format and interpretation
` are beyond the scope of this document.
`
` Packet: A data packet consists of fixed header and payload data.
` Some underlying protocols may require an encapsulation of the
` packet to be defined.
`
` Port: The "abstraction that transport protocols use to distinguish
` among multiple destinations within a given host computer. TCP/IP
` protocols identify ports using small positive integers." The
` transport selectors (TSEL) used by the OSI transport layer are
` equivalent to ports.
`
`Parmar & Thornburgh [Page 3]
`
`Sportradar 1036
`Page 3
`
`
`
` Adobe RTMP December 2012
`
` Transport address: The combination of a network address and port
` that identifies a transport-level endpoint, for example an IP
` address and a TCP port. Packets are transmitted from a source
` transport address to a destination transport address.
`
` Message stream: A logical channel of communication in which messages
` flow.
`
` Message stream ID: Each message has an ID associated with it to
` identify the message stream in which it is flowing.
`
` Chunk: A fragment of a message. The messages are broken into
` smaller parts and interleaved before they are sent over the
` network. The chunks ensure timestamp-ordered end-to-end delivery
` of all messages, across multiple streams.
`
` Chunk stream: A logical channel of communication that allows flow of
` chunks in a particular direction. The chunk stream can travel
` from the client to the server and reverse.
`
` Chunk stream ID: Every chunk has an ID associated with it to
` identify the chunk stream in which it is flowing.
`
` Multiplexing: Process of making separate audio/video data into one
` coherent audio/video stream, making it possible to transmit
` several video and audio simultaneously.
`
` DeMultiplexing: Reverse process of multiplexing, in which
` interleaved audio and video data are assembled to form the
` original audio and video data.
`
` Remote Procedure Call (RPC): A request that allows a client or a
` server to call a subroutine or procedure at the peer end.
`
` Metadata: A description about the data. The metadata of a movie
` includes the movie title, duration, date of creation, and so on.
`
` Application Instance: The instance of the application at the server
` with which the clients connect by sending the connect request.
`
` Action Message Format (AMF): A compact binary format that is used to
` serialize ActionScript object graphs. AMF has two versions: AMF 0
` [AMF0] and AMF 3 [AMF3].
`
`Parmar & Thornburgh [Page 4]
`
`Sportradar 1036
`Page 4
`
`
`
` Adobe RTMP December 2012
`
`4. Byte Order, Alignment, and Time Format
`
` All integer fields are carried in network byte order, byte zero is
` the first byte shown, and bit zero is the most significant bit in a
` word or field. This byte order is commonly known as big-endian. The
` transmission order is described in detail in Internet Protocol
` [RFC0791]. Unless otherwise noted, numeric constants in this
` document are in decimal (base 10).
`
` Except as otherwise specified, all data in RTMP is byte-aligned; for
` example, a 16-bit field may be at an odd byte offset. Where padding
` is indicated, padding bytes SHOULD have the value zero.
`
` Timestamps in RTMP are given as an integer number of milliseconds
` relative to an unspecified epoch. Typically, each stream will start
` with a timestamp of 0, but this is not required, as long as the two
` endpoints agree on the epoch. Note that this means that any
` synchronization across multiple streams (especially from separate
` hosts) requires some additional mechanism outside of RTMP.
`
` Because timestamps are 32 bits long, they roll over every 49 days, 17
` hours, 2 minutes and 47.296 seconds. Because streams are allowed to
` run continuously, potentially for years on end, an RTMP application
` SHOULD use serial number arithmetic [RFC1982] when processing
` timestamps, and SHOULD be capable of handling wraparound. For
` example, an application assumes that all adjacent timestamps are
` within 2^31 - 1 milliseconds of each other, so 10000 comes after
` 4000000000, and 3000000000 comes before 4000000000.
`
` Timestamp deltas are also specified as an unsigned integer number of
` milliseconds, relative to the previous timestamp. Timestamp deltas
` may be either 24 or 32 bits long.
`
`5. RTMP Chunk Stream
`
` This section specifies the Real Time Messaging Protocol Chunk Stream
` (RTMP Chunk Stream). It provides multiplexing and packetizing
` services for a higher-level multimedia stream protocol.
`
` While RTMP Chunk Stream was designed to work with the Real Time
` Messaging Protocol (Section 6), it can handle any protocol that sends
` a stream of messages. Each message contains timestamp and payload
` type identification. RTMP Chunk Stream and RTMP together are
` suitable for a wide variety of audio-video applications, from one-to-
` one and one-to-many live broadcasting to video-on-demand services to
` interactive conferencing applications.
`
`Parmar & Thornburgh [Page 5]
`
`Sportradar 1036
`Page 5
`
`
`
` Adobe RTMP December 2012
`
` When used with a reliable transport protocol such as TCP [RFC0793],
` RTMP Chunk Stream provides guaranteed timestamp-ordered end-to-end
` delivery of all messages, across multiple streams. RTMP Chunk Stream
` does not provide any prioritization or similar forms of control, but
` can be used by higher-level protocols to provide such prioritization.
` For example, a live video server might choose to drop video messages
` for a slow client to ensure that audio messages are received in a
` timely fashion, based on either the time to send or the time to
` acknowledge each message.
`
` RTMP Chunk Stream includes its own in-band protocol control messages,
` and also offers a mechanism for the higher-level protocol to embed
` user control messages.
`
`5.1. Message Format
`
` The format of a message that can be split into chunks to support
` multiplexing depends on a higher level protocol. The message format
` SHOULD however contain the following fields which are necessary for
` creating the chunks.
`
` Timestamp: Timestamp of the message. This field can transport 4
` bytes.
`
` Length: Length of the message payload. If the message header cannot
` be elided, it should be included in the length. This field
` occupies 3 bytes in the chunk header.
`
` Type Id: A range of type IDs are reserved for protocol control
` messages. These messages which propagate information are handled
` by both RTMP Chunk Stream protocol and the higher-level protocol.
` All other type IDs are available for use by the higher-level
` protocol, and treated as opaque values by RTMP Chunk Stream. In
` fact, nothing in RTMP Chunk Stream requires these values to be
` used as a type; all (non-protocol) messages could be of the same
` type, or the application could use this field to distinguish
` simultaneous tracks rather than types. This field occupies 1 byte
` in the chunk header.
`
` Message Stream ID: The message stream ID can be any arbitrary value.
` Different message streams multiplexed onto the same chunk stream
` are demultiplexed based on their message stream IDs. Beyond that,
` as far as RTMP Chunk Stream is concerned, this is an opaque value.
` This field occupies 4 bytes in the chunk header in little endian
` format.
`
`Parmar & Thornburgh [Page 6]
`
`Sportradar 1036
`Page 6
`
`
`
` Adobe RTMP December 2012
`
`5.2. Handshake
`
` An RTMP connection begins with a handshake. The handshake is unlike
` the rest of the protocol; it consists of three static-sized chunks
` rather than consisting of variable-sized chunks with headers.
`
` The client (the endpoint that has initiated the connection) and the
` server each send the same three chunks. For exposition, these chunks
` will be designated C0, C1, and C2 when sent by the client; S0, S1,
` and S2 when sent by the server.
`
`5.2.1. Handshake Sequence
`
` The handshake begins with the client sending the C0 and C1 chunks.
`
` The client MUST wait until S1 has been received before sending C2.
` The client MUST wait until S2 has been received before sending any
` other data.
`
` The server MUST wait until C0 has been received before sending S0 and
` S1, and MAY wait until after C1 as well. The server MUST wait until
` C1 has been received before sending S2. The server MUST wait until
` C2 has been received before sending any other data.
`
`5.2.2. C0 and S0 Format
`
` The C0 and S0 packets are a single octet, treated as a single 8-bit
` integer field:
`
` 0 1 2 3 4 5 6 7
` +-+-+-+-+-+-+-+-+
` | version |
` +-+-+-+-+-+-+-+-+
`
` C0 and S0 bits
`
` Following are the fields in the C0/S0 packets:
`
` Version (8 bits): In C0, this field identifies the RTMP version
` requested by the client. In S0, this field identifies the RTMP
` version selected by the server. The version defined by this
` specification is 3. Values 0-2 are deprecated values used by
` earlier proprietary products; 4-31 are reserved for future
` implementations; and 32-255 are not allowed (to allow
` distinguishing RTMP from text-based protocols, which always start
` with a printable character). A server that does not recognize the
` client’s requested version SHOULD respond with 3. The client MAY
` choose to degrade to version 3, or to abandon the handshake.
`
`Parmar & Thornburgh [Page 7]
`
`Sportradar 1036
`Page 7
`
`
`
` Adobe RTMP December 2012
`
`5.2.3. C1 and S1 Format
`
` The C1 and S1 packets are 1536 octets long, consisting of the
` following fields:
`
` 0 1 2 3
` 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | time (4 bytes) |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | zero (4 bytes) |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | random bytes |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | random bytes |
` | (cont) |
` | .... |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`
` C1 and S1 bits
`
` Time (4 bytes): This field contains a timestamp, which SHOULD be
` used as the epoch for all future chunks sent from this endpoint.
` This may be 0, or some arbitrary value. To synchronize multiple
` chunkstreams, the endpoint may wish to send the current value of
` the other chunkstream’s timestamp.
`
` Zero (4 bytes): This field MUST be all 0s.
`
` Random data (1528 bytes): This field can contain any arbitrary
` values. Since each endpoint has to distinguish between the
` response to the handshake it has initiated and the handshake
` initiated by its peer,this data SHOULD send something sufficiently
` random. But there is no need for cryptographically-secure
` randomness, or even dynamic values.
`
`5.2.4. C2 and S2 Format
`
` The C2 and S2 packets are 1536 octets long, and nearly an echo of S1
` and C1 (respectively), consisting of the following fields:
`
`Parmar & Thornburgh [Page 8]
`
`Sportradar 1036
`Page 8
`
`
`
` Adobe RTMP December 2012
`
` 0 1 2 3
` 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | time (4 bytes) |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | time2 (4 bytes) |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | random echo |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | random echo |
` | (cont) |
` | .... |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`
` C2 and S2 bits
`
` Time (4 bytes): This field MUST contain the timestamp sent by the
` peer in S1 (for C2) or C1 (for S2).
`
` Time2 (4 bytes): This field MUST contain the timestamp at which the
` previous packet(s1 or c1) sent by the peer was read.
`
` Random echo (1528 bytes): This field MUST contain the random data
` field sent by the peer in S1 (for C2) or S2 (for C1). Either peer
` can use the time and time2 fields together with the current
` timestamp as a quick estimate of the bandwidth and/or latency of
` the connection, but this is unlikely to be useful.
`
`Parmar & Thornburgh [Page 9]
`
`Sportradar 1036
`Page 9
`
`
`
` Adobe RTMP December 2012
`
`5.2.5. Handshake Diagram
`
` +-------------+ +-------------+
` | Client | TCP/IP Network | Server |
` +-------------+ | +-------------+
` | | |
` Uninitialized | Uninitialized
` | C0 | |
` |------------------->| C0 |
` | |-------------------->|
` | C1 | |
` |------------------->| S0 |
` | |<--------------------|
` | | S1 |
` Version sent |<--------------------|
` | S0 | |
` |<-------------------| |
` | S1 | |
` |<-------------------| Version sent
` | | C1 |
` | |-------------------->|
` | C2 | |
` |------------------->| S2 |
` | |<--------------------|
` Ack sent | Ack Sent
` | S2 | |
` |<-------------------| |
` | | C2 |
` | |-------------------->|
` Handshake Done | Handshake Done
` | | |
`
` Pictorial Representation of Handshake
`
` The following describes the states mentioned in the handshake
` diagram:
`
` Uninitialized: The protocol version is sent during this stage. Both
` the client and server are uninitialized. The The client sends the
` protocol version in packet C0. If the server supports the
` version, it sends S0 and S1 in response. If not, the server
` responds by taking the appropriate action. In RTMP, this action
` is terminating the connection.
`
` Version Sent: Both client and server are in the Version Sent state
` after the Uninitialized state. The client is waiting for the
` packet S1 and the server is waiting for the packet C1. On
` receiving the awaited packets, the client sends the packet C2 and
`
`Parmar & Thornburgh [Page 10]
`
`Sportradar 1036
`Page 10
`
`
`
` Adobe RTMP December 2012
`
` the server sends the packet S2. The state then becomes Ack Sent.
`
` Ack Sent The client and the server wait for S2 and C2 respectively.
`
` Handshake Done: The client and the server exchange messages.
`
`5.3. Chunking
`
` After handshaking, the connection multiplexes one or more chunk
` streams. Each chunk stream carries messages of one type from one
` message stream. Each chunk that is created has a unique ID
` associated with it called chunk stream ID. The chunks are
` transmitted over the network. While transmitting, each chunk must be
` sent in full before the next chunk. At the receiver end, the chunks
` are assembled into messages based on the chunk stream ID.
`
` Chunking allows large messages at the higher-level protocol to be
` broken into smaller messages, for example to prevent large low-
` priority messages (such as video) from blocking smaller high-priority
` messages (such as audio or control).
`
` Chunking also allows small messages to be sent with less overhead, as
` the chunk header contains a compressed representation of information
` that would otherwise have to be included in the message itself.
`
` The chunk size is configurable. It can be set using a Set Chunk Size
` control message (Section 5.4.1). Larger chunk sizes reduce CPU
` usage, but also commit to larger writes that can delay other content
` on lower bandwidth connections. Smaller chunks are not good for high
` bit rate streaming. Chunk size is maintained independently for each
` direction.
`
`5.3.1. Chunk Format
`
` Each chunk consists of a header and data. The header itself has
` three parts:
`
` +--------------+----------------+--------------------+--------------+
` | Basic Header | Message Header | Extended Timestamp | Chunk Data |
` +--------------+----------------+--------------------+--------------+
` | |
` |<------------------- Chunk Header ----------------->|
`
` Chunk Format
`
`Parmar & Thornburgh [Page 11]
`
`Sportradar 1036
`Page 11
`
`
`
` Adobe RTMP December 2012
`
` Basic Header (1 to 3 bytes): This field encodes the chunk stream ID
` and the chunk type. Chunk type determines the format of the
` encoded message header. The length depends entirely on the chunk
` stream ID, which is a variable-length field.
`
` Message Header (0, 3, 7, or 11 bytes): This field encodes
` information about the message being sent (whether in whole or in
` part). The length can be determined using the chunk type
` specified in the chunk header.
`
` Extended Timestamp (0 or 4 bytes): This field is present in certain
` circumstances depending on the encoded timestamp or timestamp
` delta field in the Chunk Message header. See Section 5.3.1.3 for
` more information.
`
` Chunk Data (variable size): The payload of this chunk, up to the
` configured maximum chunk size.
`
`5.3.1.1. Chunk Basic Header
`
` The Chunk Basic Header encodes the chunk stream ID and the chunk type
` (represented by fmt field in the figure below). Chunk type
` determines the format of the encoded message header. Chunk Basic
` Header field may be 1, 2, or 3 bytes, depending on the chunk stream
` ID.
`
` An implementation SHOULD use the smallest representation that can
` hold the ID.
`
` The protocol supports up to 65597 streams with IDs 3-65599. The IDs
` 0, 1, and 2 are reserved. Value 0 indicates the 2 byte form and an
` ID in the range of 64-319 (the second byte + 64). Value 1 indicates
` the 3 byte form and an ID in the range of 64-65599 ((the third
` byte)*256 + the second byte + 64). Values in the range of 3-63
` represent the complete stream ID. Chunk Stream ID with value 2 is
` reserved for low-level protocol control messages and commands.
`
` The bits 0-5 (least significant) in the chunk basic header represent
` the chunk stream ID.
`
` Chunk stream IDs 2-63 can be encoded in the 1-byte version of this
` field.
`
`Parmar & Thornburgh [Page 12]
`
`Sportradar 1036
`Page 12
`
`
`
` Adobe RTMP December 2012
`
` 0 1 2 3 4 5 6 7
` +-+-+-+-+-+-+-+-+
` |fmt| cs id |
` +-+-+-+-+-+-+-+-+
`
` Chunk basic header 1
`
` Chunk stream IDs 64-319 can be encoded in the 2-byte form of the
` header. ID is computed as (the second byte + 64).
`
` 0 1
` 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` |fmt| 0 | cs id - 64 |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`
` Chunk basic header 2
`
` Chunk stream IDs 64-65599 can be encoded in the 3-byte version of
` this field. ID is computed as ((the third byte)*256 + (the second
` byte) + 64).
`
` 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` |fmt| 1 | cs id - 64 |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`
` Chunk basic header 3
`
` cs id (6 bits): This field contains the chunk stream ID, for values
` from 2-63. Values 0 and 1 are used to indicate the 2- or 3-byte
` versions of this field.
`
` fmt (2 bits): This field identifies one of four format used by the
` ’chunk message header’. The ’chunk message header’ for each of
` the chunk types is explained in the next section.
`
` cs id - 64 (8 or 16 bits): This field contains the chunk stream ID
` minus 64. For example, ID 365 would be represented by a 1 in cs
` id, and a 16-bit 301 here.
`
` Chunk stream IDs with values 64-319 could be represented by either
` the 2-byte or 3-byte form of the header.
`
`5.3.1.2. Chunk Message Header
`
` There are four different formats for the chunk message header,
` selected by the "fmt" field in the chunk basic header.
`
`Parmar & Thornburgh [Page 13]
`
`Sportradar 1036
`Page 13
`
`
`
` Adobe RTMP December 2012
`
` An implementation SHOULD use the most compact representation possible
` for each chunk message header.
`
`5.3.1.2.1. Type 0
`
` Type 0 chunk headers are 11 bytes long. This type MUST be used at
` the start of a chunk stream, and whenever the stream timestamp goes
` backward (e.g., because of a backward seek).
`
` 0 1 2 3
` 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | timestamp |message length |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | message length (cont) |message type id| msg stream id |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | message stream id (cont) |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`
` Chunk Message Header - Type 0
`
` timestamp (3 bytes): For a type-0 chunk, the absolute timestamp of
` the message is sent here. If the timestamp is greater than or
` equal to 16777215 (hexadecimal 0xFFFFFF), this field MUST be
` 16777215, indicating the presence of the Extended Timestamp field
` to encode the full 32 bit timestamp. Otherwise, this field SHOULD
` be the entire timestamp.
`
`5.3.1.2.2. Type 1
`
` Type 1 chunk headers are 7 bytes long. The message stream ID is not
` included; this chunk takes the same stream ID as the preceding chunk.
` Streams with variable-sized messages (for example, many video
` formats) SHOULD use this format for the first chunk of each new
` message after the first.
`
` 0 1 2 3
` 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | timestamp delta |message length |
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
` | message length (cont) |message type id|
` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`
` Chunk Message Header - Type 1
`
`Parmar & Thornburgh [Page 14]
`
`Sportradar 1036
`Page 14
`
`
`
` Adobe RTMP December 2012
`
`5.3.1.2.3. Type 2
`
` Type 2 chunk headers are 3 bytes long. Neither the stream ID nor the
` message length is included; this chunk has the same stream ID and
` message length as the preceding chunk. Streams with constant-sized
` messages (for example, some audio and data formats) SHOULD use this
` format for the first chunk of each message after the first.
`
` 0