Linux
分类: LINUX
2015-10-20 20:47:39
块流是一种应用层协议,主要用于通过一种合适的传输层协议复用、打包多媒体数据流(音频/视频和交互数据)。
分块为更高层的多媒体流协议提供复用和分组服务。
RTMP块流是为协同RTMP协议工作而设计的,但可以处理任何发送消息流的协议。每个消息包含时间戳和负载类型标志。RTMP块流和RTMP共同适用于各种形式的音视频应用,从点到点、点到多的实时直播,到vod服务,到交互视频会议。当配合TCP等可靠传输层协议时,RTMP块流保证跨流的所有消息按时间戳序列一个接一个的传输。RTMP块流不提供优先级或者类似的控制,但可以通过更高层的协议提供类似的服务。比如视频直播服务可以基于每个消息的发送时间和答复时间选择性的丢弃视频消息,使慢的客户端能及时接受到音频消息。
RTMP块流包含自己的带内协议控制消息,并且提供了让更高层的协议嵌入用户控制消息的机制。
相关的几个术语:
负载:分组中所包含的数据,如音频样本和压缩视频数据
分组:由固定的头部和负载数据构成
消息流:允许消息流动的逻辑上的通讯通道
消息流ID:每个消息关联的ID,用于区分其所在的消息流
块:消息片段,确保跨流的消息按时间戳顺序不断的传输
块流:允许按照某一方向流动的逻辑上通讯通道,可以从客户端到服务端,可以从服务端到客户端
块流ID:每个块所关联的用于区分其所在块流的ID
复用:把分开的音视频数据整合到一个数据流,让多个音视频流可以同步的传输的过程
解复用:复用的反过程
消息格式依赖于上层实现,可以分成多个块以支持复用,但消息格式必须包含:
1. 时间戳:消息时间戳,占4个字节
2. 长度:消息负载的长度,如果消息头无法消减的话,应该包含在长度中,该字段在块头中占3个字节
3. 类型ID:部分类型ID为消息控制协议保留,其他ID用于更高层协议,本字段占用1个字节。
4. 消息流ID:可以是任何值,被复用到相同块流的消息流依靠其消息ID来解复用,在块头中占4字节,主机序
客户端同时发送C0,C1块
服务端收到C0或者C0+C1后,同时发送S0,S1块
客户端必须收到S1后,可以发送C2
服务端必须收到C1后,可以发送S2
服务端必须收到C2后,可以发送数据
客户端必须收到S2后,可以发送数据
C0和S0消息
C0和S0是单独的一个字节,
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Version |
版本:8位
C0中该字段表示客户端要求的RTMP版本,S0中该字段表示服务器选择的RTMP版本。当前规范中定义的版本是3。0-2是早期产品使用的,已被丢弃。4-31保留在未来使用。32-255不允许使用。如果服务器无法识别客户端请求的版本,应该返回3,客户端可以选择减到3或者选择取消握手。
C1和S1消息
C1和S1消息有1536字节长,由以下字段构成:
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
0 |
1 |
2 |
………… |
Time (4字节) |
|||||||||||
Zero (4字节) |
|||||||||||
Random ………………………… |
|||||||||||
…………………………………………. |
时间:4字节
该字段包含时间戳。该时间戳应该是发送这个数据块的端点的后续块的时间起始点。可以是0或者其他值。为了同步多个流,端点可能发送其块流的当前值。
Zero:4字节
该字段必须全为0。
随机数据:1528字节
可以包含任何值,由于每个端点必须用自己初始化的握手和对端初始化的握手来区分身份,所以这个数据需要充分的随机性。但不需要加密等处理。
C2和S2消息
C2和S2消息有1536字节长,由以下字段构成
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
0 |
1 |
2 |
………… |
Time (4字节) |
|||||||||||
Time2 (4字节) |
|||||||||||
Zero (4字节) |
|||||||||||
Random echo |
|||||||||||
…………………………………………. |
时间:4字节
该字段必须包含对端发送的时间,比如C2包含S1的时间,S2包含C1的时间
时间2:4字节
该字段必须包含先前发送的并被对端读取的包的时间戳
随机回复:1528字节
该字段必须包含对端发送的随机数据字段,比如C2包含S1的随机数,S2包含C1的随机数
握手之后,该连接开始复用一个或者多个块流。每个块流承载来自一个消息流的一类消息,每个被创建的块都关联到一个唯一的块流ID。所有块都通过网络传输,传输过程中,必须逐一按序发送。接收端根据块ID搜集消息,分块使高层协议的大消息分割成小的消息,保证大的低优先级消息不阻塞小的高优先级消息。分块把原本应该在消息中包含的信息压缩在块头中,减少了小块消息发送的开销。块大小可以配置,最大65535字节,最小128字节,块越大,CPU利用率越低,也导致大的写入,低带宽下产生其他内容的延迟。块大小在每个方向都独立。
块由块头和数据组成,块头由三部分组成:
Basic Header |
Chunk Msg Header |
Extended Time Stamp |
Chunk Data |
块基本头:1-3字节
含块流ID和块类型,块类型决定编码的消息头格式,长度取决于块流ID,块流ID为可变长度,支持65597种流
块消息头:0、3、7或者11字节
该字段编码要发送的消息的信息,长度取决于块头中指定的块类型,有4种格式的块消息ID。
扩展时间戳:0或4个字节
块消息头中的时间戳为0x00ffffff时发送,其他时候不需要,该字段在块消息头之后,块时间之前。
RTMP支持一些协议控制消息,包含rtmp块流协议需要的信息,并且不能传播到更高层的协议。当前有两种控制消息,一个协议消息用于设置块大小,另一个用于由于余下的块不可得而取消一个消息。协议控制消息应该包含消息流ID 0(控制流)和块流ID 2,并且有最高的发送优先级。每个协议控制消息有一个固定大小的负载,并作为一个独立的块发送。
协议控制消息1,设置块大小,用于通知对端新的最大块大小,可以使用默认值,客户端和服务端也可以设置。
协议控制消息-取消消息,用于通知对端,不用再等待接收块来完成消息,而可以丢弃以前通过块流接收到的信息。