a-zlm/3rdpart/media-server/librtmp/source/rtmp-chunk-header.c

147 lines
3.2 KiB
C++

#include "rtmp-chunk-header.h"
#include "rtmp-util.h"
// 5.3.1.1. Chunk Basic Header (p12)
/*
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|fmt| cs id |
+-+-+-+-+-+-+-+-+
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|fmt| 0 | cs id - 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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
int rtmp_chunk_basic_header_read(const uint8_t* data, uint8_t* fmt, uint32_t* cid)
{
*fmt = data[0] >> 6;
*cid = data[0] & 0x3F;
if (0 == *cid)
{
*cid = 64 + (uint32_t)data[1];
return 2;
}
else if (1 == *cid)
{
*cid = 64 + (uint32_t)data[1] + ((uint32_t)data[2] << 8) /* 256 */;
return 3;
}
else
{
return 1;
}
}
int rtmp_chunk_basic_header_write(uint8_t* out, uint8_t fmt, uint32_t id)
{
if (id >= 64 + 256)
{
*out++ = (fmt << 6) | 1;
*out++ = (uint8_t)((id - 64) & 0xFF);
*out++ = (uint8_t)(((id - 64) >> 8) & 0xFF);
return 3;
}
else if (id >= 64)
{
*out++ = (fmt << 6) | 0;
*out++ = (uint8_t)(id - 64);
return 2;
}
else
{
*out++ = (fmt << 6) | (uint8_t)id;
return 1;
}
}
// 5.3.1.2. Chunk Message Header (p13)
/*
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) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
int rtmp_chunk_message_header_read(const uint8_t* data, struct rtmp_chunk_header_t* header)
{
int offset = 0;
// timestamp / delta
if (header->fmt <= RTMP_CHUNK_TYPE_2)
{
be_read_uint24(data + offset, &header->timestamp);
offset += 3;
}
// message length + type
if (header->fmt <= RTMP_CHUNK_TYPE_1)
{
be_read_uint24(data + offset, &header->length);
header->type = data[offset + 3];
offset += 4;
}
// message stream id
if (header->fmt == RTMP_CHUNK_TYPE_0)
{
le_read_uint32(data + offset, &header->stream_id);
offset += 4;
}
return offset;
}
int rtmp_chunk_message_header_write(uint8_t* out, const struct rtmp_chunk_header_t* header)
{
const static int s_header_size[] = { 11, 7, 3, 0 };
// timestamp / delta
if (header->fmt <= RTMP_CHUNK_TYPE_2)
{
be_write_uint24(out, header->timestamp >= 0xFFFFFF ? 0xFFFFFF : header->timestamp);
out += 3;
}
// message length + type
if (header->fmt <= RTMP_CHUNK_TYPE_1)
{
be_write_uint24(out, header->length);
out[3] = header->type;
out += 4;
}
// message stream id
if (header->fmt == RTMP_CHUNK_TYPE_0)
{
le_write_uint32(out, header->stream_id);
out += 4;
}
return s_header_size[header->fmt % 4];
}
// 5.3.1.3. Extended Timestamp (p16)
int rtmp_chunk_extended_timestamp_read(const uint8_t* out, uint32_t* timestamp)
{
// extended timestamp
be_read_uint32(out, timestamp);
return 4;
}
int rtmp_chunk_extended_timestamp_write(uint8_t* out, uint32_t timestamp)
{
// extended timestamp
be_write_uint32(out, timestamp);
return 4;
}