RTP是传输层协议还是一种应用层协议?
RTP协议有传输层协议的许多特性:它运行在端到端系统中,并且提供双工服务。但是它和象TCP协议一样的传输层协议不一样,它并不提供任何的可靠性或者错误恢复和流量控制机制。但是,它却为实现这样的控制协议提供了接口,有点象应用层窗体的属性,具体参加D.Clark和D.Tennenhouse的"Architectural consideration for a new generation of protocols", SIGCOMM'90, Philadelpia。虽然现在大多数的RTP实现都是作为应用程序,但是这和它的定位无关。TCP的实现如果作为应用程序的一部分而不是操作系统内核,它还是一个传输层协议。
没有任何一种端到端协议,包括RTP,都不能提供完全的实时服务。这还需要底层的设备如路由器和交换机对资源的控制。RTP提供了一些特性以适合携带实时数据,如时间戳、同步机制等。
就现在的定义,RTP还没有提供恢复错误的机制,这样的机制依赖于所携带的数据。比如,对于语音数据,就需要对低low-bit-rate数据进行较多的缓存,而对于其他数据,则更多的需要重传(H.261 RTP载荷提供了这样的机制)。RTP可能可以提供一些可能的首部信息如序列号来实现重传的错误恢复机制。
当然可以。RTP与底层没有什么关系,除非底层提供了分帧。RTP没有网络层的地址,所以当地址改变的时候是影响不到RTP的,而其他的底层提供的服务如安全或者QoS保证则可以由使用RTP的应用程序使用。现在已经有直接运行在AAL5的RTP实现了,还有对AAL2和AAL5运载RTP载荷的规范。有一点需要指出的是,RTCP中的CNAME域现在是基于没有台主机都有一个因特网形式的域名的假设上的。
在异步传输网络中,一般来说,从用户到因特网的带宽是要明显小于从因特网到用户的带宽的。这些网络包括ADSL、Cable Modem还有卫星网络。RTP协议需要在发送者发送了RTCP控制消息以后才可以使用,RTCP消息允许媒体之间进行内容同步。
RTP没有长度域,也就是说分片是由下层协议来进行,并且一个PDU只能够携带一个RTP分组,非常典型的下层协议就是UDP或者AAL5,因为现在很多的应用程序都不需要分帧,可以想象加入这点特性对于处理和带宽是一个浪费,具体可以参阅RTP规范的RTP over Network and Transport Protocols。如果RTP使用的不是基于消息的协议或者需要携带几个RTP分组在一个PDU中,则需要定义一个16位或者32位bit的长度域,由载荷和字节对齐来共同决定。
有些实现假设语音分组有固定的封装包的间隔,如20ms,但是这是错误的,RFC1890建议可以使用固定的值作为默认参数,但是具体的实现必须能够处理所有的情况。G.711和其他基于采样协议的格式就在一个单位中有不同的时间。尽管使用123采样的G.711的RTP包是合法的,但是还需要进行适当的处理。
周期性的就有人提出一个将12字节的首部长度域缩减到"RTP lite"版本,他们的依据是在一些通信特别是语音中根本不需要这样多的域,而这些通信传递的都是小分组,对于长度的变化是非常敏感的。
一般的讲,最完美的压缩就是将IP/UDP/RTP的40字节压缩到1到2个字节,但是,这只有在单链路的时延小的连接中使用。
在大范围的互联中,如PBX互联,RTP混用更加的高效,因为它避免了IP和UDP报文头,还有RTP头的长度,此时,每个channel只需要一到两个字节,而平常需要几十个channels。
一个最小版本的RTP包括一个序列号(SN)和载荷类型(PT),两个字节。但是,这样的选择有下面一些缺点:
- 没有了SSRC域,则不能选择合适的混和器和转换器
- 对于头标的减少是有限的,如G.723.1分组,带有20字节语音分组的数据可以从60字节压缩到50字节,单这也只有因特网两个月的增长量
- 在组播中,由于没有SSRC,报文会被丢弃,H.323族中也是如此
- H.245和SDP用来对附加的RTP格式进行协商
- 不是每一个设备都支持两种长度的RTP报文,需要网关进行转换
- 由于没有时间戳,媒体中间的同步变得非常的困难,无声的丢弃报文比头标压缩更能够节省带宽
- 许多RTCP的功能需要重新定义,由于它是基于时间戳和序列号来进行抖动计算、误差统计和同步的。
对于语音来讲,时间戳是封包间隔和采样速率的乘积的递增的,比如,如果封包时间是20ms,而采样率是8000Hz,则每一块的时间戳递增是160,即使由于某些原因包被丢弃,另外要注意的是,真实的采样速率和预定的速率有一些小的变化,但是发送着一般没有可靠的办法察觉这些区别。
对于视频来说,时间戳的生成依赖于应用程序是否能够分辩其帧数。如果能够分辩帧速率,则时间戳可以使用一个固定的速率增加,如对于30f/s的视频,时间戳就每一帧增加3000,而对于25f/s的视频就增加3600f/s,如果一个帧被几个RTP包携带,则这些包应该有相同的时间戳。而如果应用程序并不能够识别帧数或者采样是变化的,现在很多编码器都是这样做的,那么时间戳就必须由系统时钟来获得,如gettimeofday()。
不,初始化的时间戳值是随即选取的,而且每一个RTP流应该无关(对于相互独立的程序生成的不同的媒体类型,不管是否在一台主机上,这都是或多或少难以避免的)。不同媒体间的同步(如嘴唇同步)是通过RTCP报告中的NTP时间戳来实现的。这个时间戳提供了一个公共的参照把媒体指定的时间戳和墙上时间联系起来。而这种同步机制并不是在RTP定义的,尽管如此,一个可能的处理是定期的交换所有的时延信息然后由应用程序来选择一个最大的时延如果没有同步的话。
时间戳是用来把接收到的语音和视频数据按照正确的时间顺序提交给上层,而序列号主要是用来检查包的丢失。序列号是递增的,而时间戳则递增一个所携带报文的时间,对于视频来说,一帧被分割成好几个RTP包,则这些包具有相同的时间戳。对于某些情况,如携带DTMF(RFC 2833)数据,RTP时间戳可能是不会变化的。
RFC 1889 定义了一个在RTP报文首部中的媒体时钟,还有一个由RTCP时间戳携带的从此时戳到全局定位时钟的映射。
SR中的NTP时戳则可以在一个会话中同步所有的每天发送者,如果来自相同的网络源,这显然不是问题,而接受者要同步发送者,唯一的方法只有广播。
经验表明:所有其他的交互媒体和交互主机之间的同步,常常要次于NTP和应用规范。
对于语音分组,标记比特可以用来指示一个语音流的开始。在开始的时候,如果发现不同的时钟或者网络延时的变化,可以比较容易检查出来。中间的分组则最好能够连续发送,而对于前面的短暂的时延是不太敏感的。
标记比特指示一个指示,如果时钟速率是已知的话,对话的开头还可以通过比较两个分组时间戳和序列号的不同来获得的。
分组可能不是按照顺序到达的,所以含有标记比特的分组比其他分组后到,只要分组延时超过重排序的时间,那么接受者就可以适应这种延时。如果不是的话,那么就只有简单的等待下一个会话了。
RTP时戳和NTP时戳结合在一起用来识别一个流中的绝对时间。比如,如果RTCP源端报告中包含RTP时戳 1234和NTP时戳 February 3, 10:14:15,就表示采样1234发生在February 3, 10:14:15。
如果有几个分组携带着同样的时间戳(如视频帧),应该使用第一个分组来计算抖动(这可能会在以后的发行中规范)。
抖动是通过时戳来计算的,如,音频流的采样率是8000Hz,到达的时间就会乘以8000。
首先,它不是链路带宽,它不是一个比例关系的,即使只有5%的带宽用于RTCP,大量的会话也会将链路占满。其次,链路带宽的定义在不同的网络中是有不同的定义的。
会话带宽是指普通的数据带宽乘以IP、UDP和RTP首部(40字节)。比如,对于一个64Kb/s的PCM编码语音,以20ms递增,则会话带宽就是(160+40)/0.02 B/s即80Kb/s,如果有多个发送端,则需要把每一个单独相加起来。
因为发送RTCP的代价需要最小(大概5秒钟一个包),即使对于端到端的连接也是有影响的:
- 使用RTCP,通信双方都知道对方接收音频和视频的情况;这是很重要的,因为,经常有由于网络丢包、延时或者抖动而造成的质量下降。一个特别的例子是在呼叫技术支持的时候,技术支持人员可以在远程获得网络的性能
- RTCP对于音频流和视频流的同步是必须的
- 对于音频的无声丢失,RTCP可以观察到并指示
- SDES信息对于用户接口是有用的
- 许多应用需要支持单播和组播,使得具体实现的附加复杂度为0。
动态载荷类型被定义在了RTP A/V配置中,不想静态的载荷类型,动态载荷类型没有被IANA所定义,它们在一个会话中将一种RTP载荷映射到音频和视频上,不同的成员可以使用不同的映射,但是一般都不常用。动态载荷类型的范围是96到127,它们没有在标准中被定义,包括:
- 会话描述象SDP(使用a:rtpmap参数),使用声明和邀请(如SIP),比如 m=audio 12345 RTP/AVP/121 a=rtpmap:121 RT24
- 其他的信令协议(尽管如此,H.245好像没有这样的机制,至少在非ITU的协议中)
因为载荷类型的空间是有限的,只有常用的编码才会定义一个静态的类型,它们是被国际标准化组织定义的音频或者视频编码标准,如ITU-T音频编码的G系列标准。RTP A/V配置定义了一组静态载荷类型。
一种应用程序不应该只是支持一种载荷类型,尽管是通过H.245或者其他协议协商的。新的机制应该有:
- 传输DTMF数据(RFC 2833)
- 适当的噪声标明
- 使用冗余的数据进行错误恢复
- 可以对网络情况进行估计
可以使用PT域来标注可能在应用中被忽略的特殊的分组,如果需要的话,需要保证兼容性。但是这个假设在应用程序忽略所有的PT域的时候是没有作用的。
另外,在组播环境中,每一个发送端使用相同的载荷类型是不好的。
建议使用没有混用的底层技术,如AAL5上的RTP,其PT域可以区分不同源发出的流,但其实这是一个不好的规范。一方面是因为不容易在一个单独的流中使用不同的PT(见前面的问题),零位一方面也没有必要,因为SSRC就是被设计成可以分别不同的源的。
RTP SSRC是用来标记不同的源的,也就是说,在一个会议中每一个发送者都有一个SSRC。对于不同的流媒体,如语音和视频,对于不同的SSRC最好使用单独的源来发送。但是在下列情况下是不合适的:
- 一个RTP混合器一般是结合所有的SSRCs,对于某些RTP会话和结合方法,这是合适的,如语音的混合。如果在一个会话中有不同的媒体,则SSRCs需要通过附加的信息来隔离不同的媒体,这将使问题变得复杂。如果不能使用相同的转换器,则对于终端接收程序来说,也是很复杂的;
- 在同一个RTP会话中携带不同的媒体阻止了使用不同的网络媒体和链路选路,对于同步的音频或者视频信号,可能并不需要选路等,但是难以想象一个媒体需要通过低速率低时延的有线线路和另外一个媒体能够容忍长时延来获得高的带宽之间结合的情况;
- 在同一个RTP会话中携带不同的媒体阻止了对于一组媒体集合的接收,如音频集合,而视频超过了可用带宽,这在单播的时候不是一个问题,因为发送者可以选择类型,而在组播当中,这是应该注意的,因为可能有许多不同类型的接受者;
- 在同一个RTP会话中携带不同的媒体组织了接收端对于不同媒体之间的单独处理;
- 如果使得SSRCs固定的话,对于组播是不合适的,因为某些组播冲突解决方案是需要更改SSRC的。
如果说只是把音频和视频下载下来回放的话,TCP是一个不错的选择。如果对于实时要求不是很高的话,具有大的缓冲和好的带宽的TCP是一个不错的选择,如通过www点播,TCP还可以运行在如X.25这样的网络上,尽管有些语音或者视频通信少量的损失都是不可接受的。
尽管如此,对于实时传输来说,象TCP或者其他的可靠性协议XTP都不适合用来做传输协议,主要有三个原因:
- 可靠性的协议并不适合用来传输对于时延很敏感的数据如实时语音或视频等,当发送者发现包丢失并且重传的时候,至少已经过了一个RTT的时间,而发送者要么必须等待重传的数据,造成声音的不连续或者不按照TCP协议而丢弃重发的数据,而标准的TCP实现都要求等待重发的数据并处理,所以延时不断增加,这对于实时传输是不利的;
- TCP不支持组播;
- TCP拥塞控制机制是在发现丢包的时候减小窗口,而对于语音或者视频来说,是不能够突然减小速率来饿死接受者的,比如对于PCM编码的语音数据来说,是不会超过64kb/s多少的。对于这些媒体的拥塞控制机制最好是更改编码的比特率,比方说根据RTCP接收报告分组。
还有一个不利的地方是TCP和XTP相对UDP来说具有过多的首部开销(TCP和XTP3.6是40字节,XTP4.0是32字节,而UDP是8字节),而且这些协议还不带有接收端所需要的时间戳,所以它们不能够代替RTP(这些协议不含有序列号,因为它假设不会发生丢包或者重复的情况)。
对于局域网来说,由于具有足够的带宽且只有极少量的错误,这个时候TCP就只是在恢复少量错误的时候有优势,这并没有什么作用,而且,TCP的竞争机制会限制源端的初始速率。
前面的小节中有许多相同的争论。关于RTP和XTP的关系有许多讨论,可能是由于它们都是属于传输层的吧,尽管如此,两者并不能够互相代替。XTP是为了可靠或者不可靠的数据通信中设计一个可配置和传输的协议,而RTP并不包含任何可靠的机制(尽管可以添加)和象XTP那样的流控机制,所以RTP不适合传输常规的需要保证可靠性的数据(TCP或XTP更加适合)。对实时传输来说,由于延时问题,重传一般是禁止的,XTP也是这样。还有,流控和拥塞控制对于实时传输来说都是不合适的,因为一般实时数据都有相对稳定的比特率,但是,要注意的是,RTP提供了对于变化比较大的比特率进行拥塞控制的机制,如调整编码率等。
RTP没有自己的承载协议,所以需要使用非面向连接的协议如UDP、TCP或者是面向连接的协议如XTP、ST-II、ATM(AAL3/4, AAL5)。一般的实时应用大多使用组播,比如一千多人的讲座、报告,而面向连接的协议如XTP是难以适应这样的规模的。
XTP不含有定时或者媒体类型信息,而这些是由RTP提供的,XTP也不含有象RTP那样的直接反馈,所以需要从其他协议中获取这些信息。看看现在使用XTP的实时传输实现,都在XTP和实时媒体之间加了一层象RTP数据一样的信息。
由于RTCP含有绝对时间信息,所以一个记录的会话是不容易直接使用移动时间的方法来重放的。一个想法就是将时间重组然后重放数据包。SDES信息和NOTE可以用来收集然后重生一个会话。NOTE SDES当它们可以修改的时候应该可以在合适的时间插入流中。
由于RTP(特别是数据部分)和应用程序是紧紧关联的,所以内核的实现没有什么意义。一些人已经实现了RTP和RTCP的库。NeVoT, rtpdump, vat, rat 和 vic都含有可以修改的RTP和RTCP处理模块,要注意的是它们还含有各自的许多代码(还有其他的一些实现是依据老版本的RTP,不要用它们来作为开发)。
Java Media Framework (JMF),一个JAVA API,也支持RTP和RTCP。
现在还没有对于RTP的标准的API。
没有。
在RTP协议规范的端口分配中这样说明的:
- RTP使用一个偶数的UDP端口,而RTCP则使用大一个端口的奇数端口;
- 应用程序可以使用任意的UDP端口对,如由应用程序分配并管理。之所以这样,是因为对于多媒体来说,需要有多个协议运行在一个端口,而这在一些操作系统中是不允许的,所以没有分配固定的端口;
- 5004和5005作为默认的端口对。如果应用程序没有这样的默认选择的话可能需要明确的指定。选择的端口超过5000是因为在UNIX系统中小于1024的端口是特权端口而1024到5000是由操作系统自动分配的。
组播实现使用下面的端口范围:
注意:当组播速率没有超过路由器的配置的组播速率限制的时候,端口是没有区别的。
当RTP使用H.323的协议框架的时候,由H.225来分配端口,如在SDP和SIP中,由会议的控制者来选择端口。
每端选择自己的源地址,也就是说,不会说Alice发送语音信息到5000端口,而Bob必须在5000端口接收数据。每端只需要简单的告诉对方是在哪个端口监听数据,如通过SDP。
RFC1889的第十章说道,在一个单播会话中,应用必须准备接收数据,控制一个端口对并且可以将数据发往另外一个节点。
注意SSRCs通常是不相同的。
许多旧的,高比特率的编解码都是不受保护的,但是,G.723,G.729和GSM都受到了各种专利限制的。如 美国 4,752,956 专利是在GSM中使用的Digital speech coder with baseband residual coding modifies coding using short term fine structure speech data produced by analysers within encoder-multiplexers是被飞利浦公司注册的。
没有,如果路由器在会话建立的时候没有对协议进行过问的话,那么是没有办法告诉路由器某个特定的包是RTP报文的。但是,如果路由器维持状态的话,当发现序列号缓慢增加(如加1),或者UDP的端口为一对的时候,路由器还是可以概率的发现的。另外,报文的前两个比特是不变的,用来标识RTP报文,还有,载荷类型一般也是不变的。
语音和视频格式和编码有:
- MPEG L3 G.711 G.722 G.723 G.723.1 G.726 G.728 G.729 H.261 H.263
- H.324 在POTS长传输Audio和Video,速率在20kb/s以下。
在ISDN上传输的标准有:
- H.221 视听设备,从64到1920kb/s
- H.320 电路交换
- H.323 H.320在LAN中的传输
对于会议的控制,管理和数据交换,还有一些建议:
- T.120 一个简单的可视化电话建议
- T.121 常用应用模板
- T.122 多点通信
- T.123 电话通信应用中的协议栈
- T.124 基本会议控制
- T.125 多点通信服务协议规范
- T.126 静态图象协议规范
- T.127 多点二进制文件传输协议
- mbus 对等媒体应用协议