Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1504015
  • 博文数量: 228
  • 博客积分: 1698
  • 博客等级: 上尉
  • 技术积分: 3241
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-24 21:49
个人简介

Linux

文章分类

全部博文(228)

文章存档

2017年(1)

2016年(43)

2015年(102)

2014年(44)

2013年(5)

2012年(30)

2011年(3)

分类: LINUX

2015-10-20 20:47:39

块流是一种应用层协议,主要用于通过一种合适的传输层协议复用、打包多媒体数据流(音频/视频和交互数据)。

分块为更高层的多媒体流协议提供复用和分组服务。

RTMP块流是为协同RTMP协议工作而设计的,但可以处理任何发送消息流的协议。每个消息包含时间戳和负载类型标志。RTMP块流和RTMP共同适用于各种形式的音视频应用,从点到点、点到多的实时直播,到vod服务,到交互视频会议。当配合TCP等可靠传输层协议时,RTMP块流保证跨流的所有消息按时间戳序列一个接一个的传输。RTMP块流不提供优先级或者类似的控制,但可以通过更高层的协议提供类似的服务。比如视频直播服务可以基于每个消息的发送时间和答复时间选择性的丢弃视频消息,使慢的客户端能及时接受到音频消息。

RTMP块流包含自己的带内协议控制消息,并且提供了让更高层的协议嵌入用户控制消息的机制。

相关的几个术语:

    负载:分组中所包含的数据,如音频样本和压缩视频数据

    分组:由固定的头部和负载数据构成

    消息流:允许消息流动的逻辑上的通讯通道

    消息流ID:每个消息关联的ID,用于区分其所在的消息流

    块:消息片段,确保跨流的消息按时间戳顺序不断的传输

    块流:允许按照某一方向流动的逻辑上通讯通道,可以从客户端到服务端,可以从服务端到客户端

    块流ID:每个块所关联的用于区分其所在块流的ID

    复用:把分开的音视频数据整合到一个数据流,让多个音视频流可以同步的传输的过程

    解复用:复用的反过程


RTMP块流中的所有数据按照字节进行对齐,RTMP块流中的时间戳是用整数表示的,以毫秒为单位的相对时间。起始时间是没有强制定义的,一般而言每个块流的时间戳都是从0开始,但只要通讯双方用统一的起始时间,也可以不从0开始。时间戳是单调递增的,并且线性增长,这样可以让应用程序处理同步、测量带宽、注入检测和进行流控制。时间戳为32位长,只能在50天内循环,应用程序需要处理回绕问题。时间戳增量也是以毫秒为单位无符号整数,增量可以是24位或者32位长。

消息格式依赖于上层实现,可以分成多个块以支持复用,但消息格式必须包含:

1. 时间戳:消息时间戳,占4个字节

2. 长度:消息负载的长度,如果消息头无法消减的话,应该包含在长度中,该字段在块头中占3个字节

3. 类型ID:部分类型ID为消息控制协议保留,其他ID用于更高层协议,本字段占用1个字节。

4. 消息流ID:可以是任何值,被复用到相同块流的消息流依靠其消息ID来解复用,在块头中占4字节,主机序


握手阶段
RTMP连接以握手开始,握手由三个固定大小的块组成。客户端和服务端各发送三个相同的块,客户端发出的记为C0C1C2,服务端的记为S0S1S2

    客户端同时发送C0C1

    服务端收到C0或者C0+C1后,同时发送S0S1

    客户端必须收到S1后,可以发送C2

    服务端必须收到C1后,可以发送S2

    服务端必须收到C2后,可以发送数据

    客户端必须收到S2后,可以发送数据

C0S0消息

C0和S0是单独的一个字节,

0

1

2

3

4

5

6

7

Version

版本:8

C0中该字段表示客户端要求的RTMP版本,S0中该字段表示服务器选择的RTMP版本。当前规范中定义的版本是30-2是早期产品使用的,已被丢弃。4-31保留在未来使用。32-255不允许使用。如果服务器无法识别客户端请求的版本,应该返回3,客户端可以选择减到3或者选择取消握手。


C1S1消息

C1和S1消息有1536字节长,由以下字段构成:

0

1

2

3

4

5

6

7

0

1

2

…………

Time 4字节)

Zero 4字节)

Random …………………………

………………………………………….

时间4字节

该字段包含时间戳。该时间戳应该是发送这个数据块的端点的后续块的时间起始点。可以是0或者其他值。为了同步多个流,端点可能发送其块流的当前值。

Zero4字节

该字段必须全为0

随机数据1528字节

可以包含任何值,由于每个端点必须用自己初始化的握手和对端初始化的握手来区分身份,所以这个数据需要充分的随机性。但不需要加密等处理。


C2S2消息

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的时间

时间24字节

该字段必须包含先前发送的并被对端读取的包的时间戳

随机回复: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种流

块消息头:037或者11字节

该字段编码要发送的消息的信息,长度取决于块头中指定的块类型,有4种格式的块消息ID

扩展时间戳:04个字节

块消息头中的时间戳为0x00ffffff时发送,其他时候不需要,该字段在块消息头之后,块时间之前。


协议控制消息

RTMP支持一些协议控制消息,包含rtmp块流协议需要的信息,并且不能传播到更高层的协议。当前有两种控制消息,一个协议消息用于设置块大小,另一个用于由于余下的块不可得而取消一个消息。协议控制消息应该包含消息流ID 0(控制流)和块流ID 2,并且有最高的发送优先级。每个协议控制消息有一个固定大小的负载,并作为一个独立的块发送。

协议控制消息1,设置块大小,用于通知对端新的最大块大小,可以使用默认值,客户端和服务端也可以设置。

协议控制消息-取消消息,用于通知对端,不用再等待接收块来完成消息,而可以丢弃以前通过块流接收到的信息。


参考:


阅读(2840) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~