分类: 嵌入式
2012-08-31 18:13:36
转载地址http://ticktick.blog.51cto.com/823160/462746
一提到流媒体传输、一谈到什么视频监控、视频会议、语音电话(VOIP),都离不开RTP协议的应用,但当大家都根据经验或者别人的应用而选择RTP协议的时候,你可曾想过,为什么我们要使用RTP来进行流媒体的传输呢?为什么我们一定要用RTP?难道TCP、UDP或者其他的网络协议不能达到我们的要求么?
本文就是根据我在RTP协议的学习和应用过程中整理出来的思考,希望对大家有所启发,同时,也欢迎大家留言探讨,提出自己的想法和思考。
1. 维基百科的相关解释
Reliable protocols, such as the Transmission Control Protocol (TCP), guarantee correct delivery of each bit in the media stream. However, they accomplish this with a system of timeouts and retries, which makes them more complex to implement. It also means that when there is data loss on the network, the media stream stalls while the protocol handlers detect the loss and retransmit the missing data. Clients can minimize this effect by buffering data for display. While delay due to buffering is acceptable in video on demand scenarios, users of interactive applications such as video conferencing will experience a loss of fidelity if the delay that buffering contributes to exceeds 200 ms.
像TCP这样的可靠传输协议,通过超时和重传机制来保证传输数据流中的每一个bit的正确性,但这样会使得无论从协议的实现还是传输的过程都变得非常的复杂。而且,当传输过程中有数据丢失的时候,由于对数据丢失的检测(超时检测)和重传,会数据流的传输被迫暂停和延时。
或许你会说,我们可以利用客户端构造一个足够大的缓冲区来保证显示的正常,这种方法对于从网络播放音视频来说是可以接受的,但是对于一些需要实时交互的场合(如视频聊天、视频会议等),如果这种缓冲超过了200ms,将会产生难以接受的实时性体验。
2. 为什么RTP可以解决上述时延问题
RTP协议是一种基于UDP的传输协议,RTP本身并不能为按顺序传送数据包提供可靠的传送机制,也不提供流量控制或拥塞控制,它依靠RTCP提供这些服务。这样,对于那些丢失的数据包,不存在由于超时检测而带来的延时,同时,对于那些丢弃的包,也可以由上层根据其重要性来选择性的重传。比如,对于I帧、P帧、B帧数据,由于其重要性依次降低,故在网络状况不好的情况下,可以考虑在B帧丢失甚至P帧丢失的情况下不进行重传,这样,在客户端方面,虽然可能会有短暂的不清晰画面,但却保证了实时性的体验和要求。
3. 多播功能
多播在网络视频会议方面有着很广泛的应用,它主要应用于这样一种环境,即:
假设红色的圆为存放有视频数据的流媒体服务器,其他的圆为连接到该服务器的各个客户端,当所有的绿色的客户端要求同时观看红色服务器上的某一个视频时,如果服务器为每一路客户端单独建立连接进行数据的传输,这样明显不太合理浪费带宽,因此,多播技术可以很好地解决这种问题,即同一份数据,由服务器发送到公共的多播地址,各个客户端均监听同一个多播地址来获取数据,这样,既节省了带宽,同时也保证了各个客户端所观看的视频的同步。
这样的多播应用TCP协议是不支持的,而RTP协议在最初就是为了实现类似的视频会议的应用而诞生的,对其有非常好的支持。
4. RTP包头中的流媒体特性
首先,我们看看RTP的包头。
V ― 版本。识别 RTP 版本。
P ― 填充。设置1时,数据包包含一个或多个附加填充比特,填充比特不属于有效载荷。
X ― 扩展位。设置1时,在固定头后面,跟随一个头扩展。
CSRC Count ― 包含 CSRC 标识符(在固定头后)的数目。
M ― 标志。标志由描述文件(profile)文件定义。允许在比特流中标记重要的事件,如帧边界。
Payload Type ― 负载类型。由具体的应用决定其解释。某些profile 文件规定了从 Payload 编码到 Payload格式的缺省静态映射。另外的 Payload Type 编码也可以通过非 RTP 方法实现动态定义。
Sequence Number ― 序列号。每发送一个 RTP 数据包,序列号增加1。接收端可以据此检测丢包和重建包序列。
Timestamp ―时间戳。反映了RTP 数据包中第一个字节的采样时间。时钟频率依赖于负载数据格式,并在描述文件(profile)中进行描述。
SSRC ― 同步源。该标识符随机生成,旨在确保在同一个 RTP 会话中不存在两个同步源具有相同的 SSRC 标识符。
CSRC ― 贡献源标识符。识别该数据包中的有效载荷的贡献源。
从RTP包头的规定中,我们可以非常清晰地看出,在RTP协议中,添加了非常多专为流媒体传输所使用的特性,更加有助于应用于流媒体的传输。
比如用于帧边界标记的M标志位,方便接收端快速定位帧边界;比如负载类型字段,用来告诉接收端(或者播放器)传输的是哪种类型的媒体(例如G.729,H.264,MPEG-4等),这样接收端(或者播放器)就知道数据流是什么格式,然后使用对应的解码器去解码或者播放;比如时间戳字段,标识了数据流的时间戳,接收端可以利用这个时间戳来去除由网络引起的信息包的抖动,并且在接收端为播放提供同步功能,等等。
因此,相比于直接使用TCP或者UDP来进行流媒体传输,这样一个专门为传输音视频而诞生的网络协议更加合适。
5. RTP的profile机制
RTP为具体的应用提供了非常大的灵活性,它将传输协议与具体的应用环境、具体的控制策略分开,传输协议本身只提供完成实时传输的机制,开发者可以根据不同的应用环境,自主选择合适的配置环境、以及合适的控制策略。
这里所说的控制策略指的是你可以根据自己特定的应用需求,来实现特定的一些RTCP控制算法,比如前面提到的丢包的检测算法、丢包的重传策略、一些视频会议应用中的控制方案等等(这些策略我可能将在后续的文章中进行描述)。
对于上面说的合适的配置环境,主要是指RTP的相关配置和负载格式的定义。RTP协议为了广泛地支持各种多媒体格式(如 H.264, MPEG-4, MJPEG, MPEG),没有在协议中体现出具体的应用配置,而是通过profile配置文件以及负载类型格式说明文件的形式来提供。对于任何一种特定的应用,RTP定义了一个profile文件以及相关的负载格式说明,相关的文件如下所示:
《RTP Profile for Audio and Video Conferences with Minimal Control》(RFC3551)
《RTP Payload Format for H.264 Video》(RFC3984)
《RTP Payload Format for MPEG-4 Audio/Visual Streams》(RFC3016)
等等,想了解更多可以点击这里:
说明,如果应用程序不使用专有的方案来提供有效载荷类型(payload type)、顺序号或者时间戳,而是使用标准的RTP协议,应用程序就更容易与其他的网络应用程序配合运行,这是大家都希望的事情。例如,如果有两个不同的公司都在开发因特网电话软件,他们都把RTP合并到他们的产品中,这样就有希望:使用不同公司电话软件的用户之间能够进行通信。
6. RTP其他的一些良好特性
(1)RTP协议在设计上考虑到安全功能,支持加密数据和身份验证功能。
(2)有较少的首部开销
TCP和XTP相对RTP来说具有过多的首部开销(TCP和XTP3.6是40字节,XTP4.0是32字节,而RTP只有12字节)
(3)……(等待补充)
7. 相关资源列表
这里有些相关的RTP资源,希望对大家有所帮助。
(1)维基百科对RTP的介绍:
(2)维基百科对流媒体的介绍:
(3)stackoverflows论坛关于RTP vs TCP的讨论
(4)关于RTP的负载类型和时间戳的讲解
http://ticktick.blog.51cto.com/823160/350142
(5) RTP FAQ