Skip to content

Instantly share code, notes, and snippets.

@suzp1984
Created March 13, 2024 07:04
Show Gist options
  • Save suzp1984/d7c38eddf134be0435d5bc89de82e849 to your computer and use it in GitHub Desktop.
Save suzp1984/d7c38eddf134be0435d5bc89de82e849 to your computer and use it in GitHub Desktop.
SRS: how to read RTMP basic header?
/*
* https://github.com/ossrs/srs/blob/fa8096ad0117a085515729e12a3758ca26036552/trunk/src/protocol/srs_protocol_rtmp_stack.cpp#L843-L924
*/
/**
* 6.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.
*
* 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.
* 0 1 2 3 4 5 6 7
* +-+-+-+-+-+-+-+-+
* |fmt| cs id |
* +-+-+-+-+-+-+-+-+
* Figure 6 Chunk basic header 1
*
* Chunk stream IDs 64-319 can be encoded in the 2-byte version of this
* field. 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 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* Figure 7 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 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* Figure 8 Chunk basic header 3
*
* cs id: 6 bits
* fmt: 2 bits
* cs id - 64: 8 or 16 bits
*
* Chunk stream IDs with values 64-319 could be represented by both 2-
* byte version and 3-byte version of this field.
*/
srs_error_t SrsProtocol::read_basic_header(char& fmt, int& cid)
{
srs_error_t err = srs_success;
if ((err = in_buffer->grow(skt, 1)) != srs_success) {
return srs_error_wrap(err, "basic header requires 1 bytes");
}
fmt = in_buffer->read_1byte();
cid = fmt & 0x3f;
fmt = (fmt >> 6) & 0x03;
// 2-63, 1B chunk header
if (cid > 1) {
return err;
// 64-319, 2B chunk header
} else if (cid == 0) {
if ((err = in_buffer->grow(skt, 1)) != srs_success) {
return srs_error_wrap(err, "basic header requires 2 bytes");
}
cid = 64;
cid += (uint8_t)in_buffer->read_1byte();
// 64-65599, 3B chunk header
} else {
srs_assert(cid == 1);
if ((err = in_buffer->grow(skt, 2)) != srs_success) {
return srs_error_wrap(err, "basic header requires 3 bytes");
}
cid = 64;
cid += (uint8_t)in_buffer->read_1byte();
cid += ((uint8_t)in_buffer->read_1byte()) * 256;
}
return err;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment