简介
由于一帧音视频数据有时候会很大,比如几十M甚至更大。但是为了方便在网络上传输,需要把数据拆分成一个个较小的块,这里称之为消息块(Chunk)。常见的是每块大小为4000 byte左右。
Chunk的结构如下:
- [Chunk Basic Header]
- [Chunk Message Header]
- [Extended TimeStamp]
- [Chunk Data]
[Chunk Basic Header][Chunk Message Header][Extended TimeStamp] 3个合在一起都是 Chunk Header。
struct rtmp_chunk_header_t
{
uint8_t fmt; // RTMP_CHUNK_TYPE_XXX
uint32_t cid; // chunk stream id(22-bits)
uint32_t timestamp; // delta(24-bits) / extended timestamp(32-bits)
uint32_t length; // message length (24-bits)
uint8_t type; // message type id
uint32_t stream_id; // message stream id
};
Chunk Basic Header
Header Type + Channel ID 组成,长度在1~3个字节之间
Header Type (FMT)
FMT决定[Chunk Message Header]的长度,取值有0~3,对应关系是:
- 0 : 11 bytes
- 1 : 7 bytes
- 2 : 3 bytes
- 3 : 0 byte
Channel ID
通道id号常用的有:
- 2 : Protocol Control Messages (1,2,3,5,6) & User Control Messages Event (4)
- 3 : Invoke通道,这个通道适用的消息很多,比较灵活, connect, create_stream, release_stream, delete_stream, fcpublish, fcunpublish, publish, play, pause, seek, send_get_stream_length, 以及script脚本数据
- 4 : Audio通道
- 5 : Vidio通道
- 6 : 可以传输自定义的媒体流通道
Chunk Basic Header的组成
Chunk Basic Header的长度由[Channel ID]决定,对应关系是
if(cid>=(64+255))
size=3;
else if(cid>=64)
size=2;
else
size=1;
Chunk Basic Header
/*
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
计算公式如下:
/**
* out : Basic Header Data
* fmt : Header Type
* id : Channel ID
* return : Basic Header Data Length
*/
int rtmp_chunk_basic_header_write(uint8_t* out, uint8_t fmt, uint32_t id)
{
if (id >= 64 + 255)
{
*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;
}
}
Chunk Message Header
前面有提到,FMT决定[Chunk Message Header]的长度,取值有0~3,对应关系是:
- 0 : 11 bytes , timestamp(3) + length(3) + stream type(1) + stream id(4)
- 1 : 7 bytes , timestamp(3) + length(3) + stream type(1)
- 2 : 3 bytes , timestamp(3)
3 : 0 byte
timestamp是时间戳,3个byte,超过0xFFFFFF时填0xFFFFFF,然后使用Extended TimeStamp
- length是帧长度,3个byte
- stream type是[Channel ID],一个byte
Extended TimeStamp
补充的时间戳,在Chunk Message Header的时间戳3个byte不够时才使用,4byte
Chunk Data
块数据,比如一帧数据长度为8080byte,以4000 byte拆分,第一个Chunk的Chunk Data就是前4000byte,第二个Chunk的Chunk Data就是第4001byte~8000byte,第三个Chunk的Chunk Data就是剩下的80byte。