RTMP服务器(一)
一:chunk_header/rtmp_header
块由头和数据组成。块头由三部分组成:
块基本头:1到3 字节
本字段包含块流ID和块类型。块类型决定编码的消息头的格式。长度取决于块流ID。块流ID是可变长字段。
块消息头:0,3,7或11字节。本字段编码要发送的消息的信息。本字段的长度,取决于块头中指定的块类型。
扩展时间戳:0个或4字节
本字段必须在发送普通时间戳(普通时间戳是指块消息头中的时间戳)设置为0xffffff时发送,正常时间戳为其他值时都不应发送本值。当普通时间戳的值小于0xffffff时,本字段不用出现,而应当使用正常时间戳字段。
//rtmp packet
typedef struct RtmpPacket
{
ChunkHeader m_ChunkHeader; //chunkheader 1-3字节
//chunk msg header
unsigned int m_TimeStamp; //时间戳3字节 大端模式
unsigned int m_MessageLenth; //数据大小3个字节//amfsize 大端模式
unsigned char m_MessageTypeID; //数据类型1个字节 //MessageTypeID
unsigned int m_MessgageStreamID; //流ID 4字节 “小”端模式
unsigned int m_ExtendTimeStamp; //扩展时间戳4字节
//则m_MessageLenth== 100,m_BytesRead == 50;
unsigned int m_hasAbsTimestamp; //11字节的完整ChunkMsgHeader的TimeStamp是绝对值
char * m_PacketData; //包数据内容
}RtmpPacket;
//chunk头
typedef struct ChunkHeader
{
unsigned char m_F0mt; //块类型2位
unsigned int m_CsID/m_ChunkStreamId; //编码块流ID 6位或字节位或字节位 大端模式
}ChunkHeader;
Rtmp可以衍生出21种packetheader,即ChunkHeader一个字节,没有扩展时间戳,常用的4种分别为:
类型0
0类型的块长度为11字节。在一个块流的开始和时间戳返回的时候必须有这种块。
时间戳:3字节
对于0类型的块。消息的绝对时间戳在这里发送。如果时间戳大于或等于16777215(16进制0x00ffffff),该值必须为16777215,并且扩展时间戳必须出现。否则该值就是整个的时间戳。
类型1
类型1的块占7个字节长。消息流 ID不包含在本块中。块的消息流ID与先前的块相同。具有可变大小消息的流,在第一个消息之后的每个消息的第一个块应该使用这个格式。
类型2
类型2的块占3个字节。既不包含流ID也不包含消息长度。本块使用的流ID和消息长度与先前的块相同。具有固定大小消息的流,在第一个消息之后的每个消息的第一个块应该使用这个格式。
类型3
类型3的块没有头。流ID,消息长度,时间戳都不出现。这种类型的块使用与先前块相同的数据。当一个消息被分成多个块,除了第一块以外,所有的块都应使用这种类型。由相同大小,流ID,和时间间隔的流在类型2的块之后应使用这种块。
如果第一个消息和第二个消息的时间增量与第一个消息的时间戳相同,那么0类型的块之后必须是3类型的块而,不需要类型2的块来注册时间增量。如果类型3的块在类型0的块之后,那么类型3的时间戳增量与0类型的块的时间戳相同。
时间戳增量:3字节
对于类型1的块和类型2的块,本字段表示先前块的时间戳与当前块的时间戳的差值。如果增量大于等于1677215(16