现在的位置: 首页 > 综合 > 正文

Red5源码研究二-RTMP规范(传输层Chunk Stream Protocol)

2018年03月30日 ⁄ 综合 ⁄ 共 2005字 ⁄ 字号 评论关闭

 

Chunk的目的就是在RTMP传输层将消息截成可传输的数据包,所以一个Chunk应该能够体现属于哪个逻辑流(传输层面的通道,与后面我们谈到的Message
Stream ID表示的通道是两个概念,可以用于负载均衡等)、重新组装时的顺序和具体的数据信息。


每个Chunk由数据头和数据组成,其中数据头由Basic Header、Chunk Msg
Header和Extended Time
Stamp组成,这里相对复杂的是Chunk的头是可变长度的,其可变的初衷是为了进行数据压缩,其实大家觉得压缩10几个字节好像没有什么,但对一个比较大的流的话,这种压缩还是很有效的。

BASIC
HEADER

首先一个Chunk的前两位主要用来表示后面数据的具体结构。接下来的6位如果等于1表示后面的16位是Chunk流ID的数据(范围26+28到26+28*28-1,即320到65599),如果等于0表示后面的8位是Chunk流ID的数据(范围26到28+26-1,即64到319),如果大于1,说明Chunk流ID就是(范围2到26-1,即2到63)此六位的值。
上面的计算约定伪代码如下:
如果
(第一个字节[2-7]==0){
Chunk流ID = 26+ 第二个字节的值;
} 否则 如果
(第一个字节[2-7]==1){
Chunk流ID = 26 + 第二个字节的值+ 第三个字节的值*216;
} 否则 {
Chunk流ID
=
第一个字节[2-7]的值;
}
通过上面我们基本知道理论上RTMP可以支持2到65599范围内的流ID,即支持65597个流。说实话实际应用中不会同时超过10个吧。
从上面我们直到一个Chunk的Basic
Header可能会占用1到3个字节,这些完全取决于首个字节后六位的值。
CHUNK MESSAGE
HEADER

接下来的数据在RTMP协议中被称作Chunk Message
Header,其具体的数据格式由前面提到的Chunk首个字节的前两位来决定,即把后面的数据通过此两位分成四种类型,每种类型可以适当省略一些没有必要携带的重复信息,从而达到数据压缩的目的。
类型0(即前两位的值为0):
其Chunk
Message Header长度为11个字节,如下图:

一个Chunk流的第一个Chunk必须采用该类型,换句话来说,如果有一个这样的Chunk到客户端,客户端都应该重置流,无论其传回来的时间戳在相同ID的Chunk流中的位置。例如我们在视频播放中的Seek。
类型1:
其Chunk
Message Header的长度为7个字节,如下图:

该类型其实就是省略掉了message stream
id。其省略掉的前提就是前面继承前面的类型0的信息。此类型不要求服务器端和客户端必须这么做,但这句话的意思并不是说客户端和服务器端置之不理也不会影响正常通信,而是说如果你嫌麻烦可以把该消息用类型0的方式来不压缩传递,其出了影响压缩之外还是可以正常工作的。
类型2:
其Chunk
Message Header长度为3个字节,如下图:

该类型的原理和类型1是一样的,有其自己的约定。该类型在具体的协议通信中很难出现,其出现的可能就是要服务器端和客户端有个协商,例如我们播放视频的时候,由于持续的流可能会很长,这时候一个Chunk的大小很可能把一个视频帧分成两部分,并且这个分解随着时间的推移越来越没有规则,这时候对服务器端还是客户端都造成消息切割和组装的负担,如果这时能够引入客户端和服务器端的协商机制,让一个Chunk就承载一个完整的消息并且消息大小都一样那多好啊。如果能达到这种一致,类型2就可以使用。
类型3:
Chunk
Message
Header不占用任何字节。这种消息更容易理解,例如当一个消息被分解成多个Chunk的时候,第一个遇到消息的Chunk处理之后,就等待后面的Chunk的消息补上了,直到后面的消息有新的消息ID产生为止。
EXTENDED
TIME STAMP
扩展时间戳就比较好理解的,就是当Chunk Message Header的时间戳大于等于0xffffff的时候Chunk
Message
Header后面的四个字节就代表扩展时间。

Chunk Data
数据大小默认为128。
CHUNK协议控制消息
我前面好像提到过Chunk的切分大小可以由客户端和服务器端协商着来,那如何协商就是通过控制消息来完成的。Chunk的控制消息有两个,一个是设置Chunk的大小,一个是终止持续发送Chunk。那么我们如何判断一个Chunk中传载的消息是控制消息呢?RTMP的约定是当Chunk流ID为2,消息流ID为0的时候,被认为是控制消息。当然控制消息应该一个Chunk一个消息就解决问题。
具体内容,请看后面的内容消息层(Message
Formats)。
原文:http://hi.baidu.com/janins/blog/item/94fa7dd11ae6f4ca51da4bcd.html

 

抱歉!评论已关闭.