rfc3550-自己翻译的rtp协议

热度 2已有 753 次阅读2012-8-10 17:32 |个人分类:技术| rtp, rfc3550

2.  RTP 使用场景(RTP Use Scenarios

      2.1  简单多播音频会议( Simple Multicast Audio Conference

      2.2  音频和视频会议(Audio and Video Conference

      2.3  混频器和转换器(Mixers and Translators

      2.4  分层编码(Layered Encodings

    以下章节描述了用到 RTP 的一些方面。所举例子用来说明 RTP 应用的基本操作,但 RTP的用途不限于此。在这些例子中,RTP运行于IP UDP 之上,并且遵循 RFC3551 所描述的音频和视频的配置文件中的约定。

2.1 简单多播音频会议(Simple Multicast Audio Conference

    IETF的一个工作组开会讨论最新协议草案时,使用InternetIP多播服务来进行语音通讯。工作组中心分配到一个多播的组地址和一对端口。一个端口用于音频数据,另一个端口用于控制(RTCP)数据包。该地址和端口信息发布给预定的参与者。如果有私密性要求,则可用章节 9.1 中说明的方法,对数据和控制包进行加密,这时就需要生成和发布加密密钥。分配和发布机制的精确细节不在 RTP 的讨论范围之内。

    每个与会者所使用的音频会议应用程序,都以小块形式(比方说持续20秒时间)来发送音频数据。每个音频数据块都前导 RTP 报头;RTP 报头和数据依次包含在UDP 包里。RTP 报头指明了各个包里音频编码的类型(如 PCM,ADPCM,LPC),这样发送方可以在会议过程中改变编码方式,以适应状况的变化,例如,要加进一个低带宽接入的参与者,或是要应付网络拥塞。 

    Internet,像其他的报文分组网络一样,偶尔会丢失和重排包,造成时长不等的延迟。为弥补这个不足,RTP 报头里包含计时信息和一个序列号,允许接收方重建来自源的计时信息,比如前文例子中音频块以 20s 的间隔在扬声器中连续播放。会议中,对每个 RTP包的源,单独地实施计时重建。序列号还被接收方用来评估丢失包数目。

    由于会议期间不断有工作组成员加入或离开,因此有必要知道任一时刻的实际参与者及他们接收音频数据的状况好坏。出于这个目的,会议中每个音频应用程序的实例,都在 RTCP(控制)端口上周期性地多播一个附加用户名的接收报告。接收报告指明了当前说话者被收听到的状况,可用于控制自适应性编码。除了用户名外,通过控制带宽限度,可以包含其他标识信息。一个站点在离开会议时发送 RTCP BYE 包(章节 6.5)。

2.2  音频和视频会议(Audio and Video Conference

    一个会议如果同时使用音频和视频媒体,则二者传输时使用不同的 RTP 会话。也就是说,两种媒体中 RTP 包和 RTCP 包的传输,是使用两个不同的UDP 端口对和(或)多播地址。RTP 层次,音频和视频会话没有直接的耦合,下面这种情况除外:一个同时参加两个会话的参与者,在两个会话的 RTCP 包中,使用了相同的规范名,这样两个会话就发生关联(耦合)了。 

    这样区隔开来的目的之一,是允许一些会议参与者只接受自己选择的单一媒体(或者音频,或者视频)。更进一步的说明在章节 5.2 给出。尽管两种媒体区分开来了,但通过两个会话 RTCP包内载有的计时信息,同源的音频与视频还是能够同步回放。

2.3  混频器和转换器(Mixers and Translators

    到目前为止,我们皆假设所有站点都收到相同格式的媒体数据。然而这并不总是行得通。考虑一下这种情况,一个地方的参与者只能低速接入会议,而其他大部分参与者都能享受高速连接。与其让强迫大家都忍受低带宽,不如在只能低速接入的地方,放置一个减质量音频编码的 RTP层次的中继(称作混频器)。混频器将重新同步输入的音频包,重建发送方产生的20ms 固定间隔,混频已重建过的音频流为单一的流,转换音频编码为低带宽格式,最后通过低带宽连接转发数据包流(package stream)。这些包可能被单播到一个接收方,也可能多播到另一个的地址而发给多个接收方。RTP 报头为混频器提供了一种方法,使其能辨识出对混频后的包有用的源,从而保证提供给接收方正确的说话者指示。

    在音频会议中,一些预定参与者尽管有高带宽连接,但不能通过IP多播直接接入会议。例如,他们可能位于一个不允许任何IP 包通过的应用层防火墙后面。对这些站点,可能就不需要混频,而需要另一种称为转换器 RTP层次中继。可以在防火墙两侧分别安装一个转换器,外侧转换器将所有多播包通过安全连接转入内侧转换器,内侧转换器再转发给内部网的一个多播组(multicast group)

    混频器和转换器可以设计成用于各种目的。比如,一个视频混频器在测量多个不同视频流中各人的单独影像后,将它们组合成一个单一视频流来模拟群组场景。又如,在只用IP/UDP 和只用 ST_II 的两个主机群之间通过转换建立连接。再如,在没有重新同步或混频时,用packet-by-packet编码转换来自各个独立源的视频流。混频器和转换器的操作细节见章节 7  2.4 分层编码(Layered Encodings

    为了匹配接收方的能力(容量)以及适应网络拥塞,多媒体应用程序应当能够调整其传输速率。许多应用实现把调适传输速率的责任放在源端。这种做法在多播传输中并不好,因为不同接收方对带宽存在着冲突性需求。这经常导致最小公分母的场景,网格中最小的管道支配了全部实况多媒体―广播‖的质量和保真度。

    相反地,可以把分层编码和分层传输系统组合起来,从而把调适速率的责任放在接收端。在IP 多播之上的 RTP 上下文中,对一个横跨多个 RTP会话(每个会话在独自多播组上开展)的分级表示信号(a hierarchically represented signal),源能够把它的分层(layers)分割成条。  接收方仅需合并适当的多播组子集,就能适应异种网络和控制接收带宽。

RTP 分层编码的细节在章节6.3.98.3 11 中给出。

 

3.  定义(definitions)

    RTP 负载(RTP payload):通过 RTP 传输的包中的数据,例如,音频样本或压缩好的视频数据。负载格式与解释不在本文讨论范围。

    RTP 包(RTP packet):一种数据包,其组成部分有:一个固定RTP 报头,一个可能为空的作用源(contributing sources)列表(见下文),以及负载数据。一些下层协议可能要求对 RTP 包的封装进行定义。一般地,下层协议的一个包包含一个 RTP 包,但若封装方法允许,也可包含数个 RTP包(见章节11)。

    RTCP 包(RTCP packet):一种控制包,其组成部分有:一个类似 RTP 包的固定报头,后跟一个结构化的部分,该部分具体元素依不同 RTCP包的类型而定。格式的定义见章节6。一般地,多个 RTCP 包将在一个下层协议的包中以合成 RTCP 包的形式传输;这依靠RTCP 包的固定报头中的长度字段来实现。

    端口(Port):―传输协议用来在同一主机中区分不同目的地的一种抽象。TCP/IP 协议使用正整数来标识不同端口。[12] OSI 传输层使用的传输选择器(TSEL,the transport selectors)等同于这里的端口。RTP 需依靠低层协议提供的多种机制,如―端口用以多路复用会话中的 RTP RTCP

    传输地址(Transport address):是网络地址与端口的结合,用来标识一个传输层次的终端,例如一个IP 地址与一个 UDP端口。包是从源传输地址发送到目的传输地址。

    RTP 媒体类型(RTP media type):一个 RTP 媒体类型是一个单独 RTP 会话所载有的负载类型的集合。RTP 配置文件把 RTP 媒体类型指派给 RTP 负载类型。

    多媒体会话(Multimedia session):在一个参与者公共组中,并发的 RTP会话的集合。例如,一个视频会议(为多媒体会话)可能包含一个音频 RTP 会话和一个视频 RTP会话。

    RTP 会话(RTP session):一群参与者通过 RTP 进行通信时所产生的关联。一个参与者可能同时参与多个 RTP 会话。在一个多媒体会话中,除非编码方式把多种媒体多路复用到一个单一数据流中,否则每种媒体都将使用各自的 RTCP 包,通过单独的 RTP 会话来传送。通过使用不同的目的传输地址对(一个网络地址加上一对分别用于 RTP RTCP 的端口,构成了一个传输地址对)来接收不同的会话,参与者能把多个 RTP 会话区隔开来。单个 RTP 会话中的所有参与者,可能共享一个公用目的传输地址对,比如IP 多播的情况;也可能各自使用不同的目的传输地址对,比如个体单播网络地址加上一个端口对。对于单播的情况,参与者可能使用相同端口对来收听其他所有参与者,也可能对来其他每个参与者使用不同的端口对来收听。

    RTP 会话间相互区别的特征,在于每个 RTP会话都维护一个用于 SSRC 标识符的独立完整的空间。RTP 会话所包含的参与者组,由能接收 SSRC 标识符的参与者组成,这些SSRC 标识符由 RTP(同步源或作用源)或 RTCP中的任意参与者传递。例如,考虑下述情况,用单播 UDP实现的三方会议,每方都用不同的端口对来收听其他两方。如果收到一方的数据,就只把 RTCP反馈发送给那一方,则会议就相当于由三个单独的点到点 RTP 会话构成;如果收到一方的数据,却把 RTCP 反馈发送另两方,则会议就是由一个多方(multi-party)RTP 会话构成。后者模拟了三方间进行IP 多播通信时的行为。

    RTP 框架允许上述规定发生变化,但一个特定的控制协议或者应用程序在设计时常常对变化作出约束。

    同步源(SSRCSynchronization source)RTP 包流的源,用 RTP 报头中 32 位数值的SSRC 标识符进行标识,使其不依赖于网络地址。一个同步源的所有包构成了相同计时和序列号空间的一部分,这样接收方就可以把一个同步源的包放在一起,来进行重放。举些同步源的例子,像来自同一信号源的包流的发送方,如麦克风、摄影机、RTP 混频器(见下文)就是同步源。一个同步源可能随着时间变化而改变其数据格式,如音频编码。SSRC 标识符是一个随机选取的值,它在特定的 RTP 会话中是全局唯一globally unique)的(见章节 8)。参与者并不需要在一个多媒体会议的所有 RTP 会话中,使用相同的 SSRC 标识符;SSRC 标识符的绑定通过RTCP(见章节6.5.1)。如果参与者在一个 RTP 会话中生成了多个流,例如来自多个摄影机,则每个摄影机都必须标识成单独的同步源。

         作用源(CSRCContributing source ):若一个 RTP 包流的源,对由 RTP 混频器生成的组合流起了作用,则它就是一个作用源。对特定包的生成起作用的源,其 SSRC标识符组成的列表,被混频器插入到包的 RTP 报头中。这个列表叫做CSRC表。相关应用的例子如,在音频会议中,混频器向所有的说话人(talker)指出,谁的话语(speech)将被组合到即将发出的包中,即便所有的包都包含在同一个(混频器的)SSRC 标识符中,也可让听者(接收者)可以清楚谁是当前说话人。

    终端系统(End system):一种应用程序,它产生发送出的 RTP 包中内容,或者使用接收到的 RTP 包中内容。在一个特定的 RTP 会话中,一个终端系统可以扮演一个或多个同步源角色,但通常是一个。

    混频器(Mixer):一种中间系统,它从一个或多个源中接收 RTP 包,可能改变其数据格式,再按某种方式把这些包组合成一个新的包,然后转发出去。由于多个输入源的计时一般不会同步,所以混频器会对各个流的计时作出调整,并为组合流生成一个新的计时。因此,混频器将被标识成它所产生所有数据包的同步源。

    转换器(Translator):一种中间系统,它转发 RTP 包而不改变各包的同步源标识符。转换器的例子如下:不作混频地转变编码的设备,把多播复制到单播的重复装置,以及防火墙里应用层次的过滤器。

    监视器(Monitor):一种应用程序,它接收 RTP 会话参与者所发送的 RTCP包,特别是接收报告(reception report),而且对当前服务质量进行评估,评估结果用于分配监视任务,故障诊断和长期统计。监视器常常被内建到参与会话的应用程序中,但也可以是一个的独立的应用程序——不参加会话、也不发送或接收 RTP 数据包(因为它们在不同的端口上)。这些被称作第三方监视器。还有一种情况也是可以接受的,第三方监视器只接收但不发送数据包,或者另外地算入到会话中。

    RTP 途径(Non-RTP means):为提供一个可用的服务,可能还需要其他的协议和机制。特别地,对多媒体会议来说,一个控制协议可以发布多播地址,发布加密密钥,协商所用的加密算法,以及为没有预定义负载类型值的格式,建立负载类型值和其所代表的负载格式之间的动态映射。其他协议的例子如下:会话初始化协议(SIRFC3261[13]),ITU 推荐的 H.323[14],还有使用 SDP(RFC2327[15])的应用程序,如 RTSP(RFC 2326[16]).  对于简单的应用程序,电子邮件或者会议数据库也可能用到。对这些协议和机制的详细说明已经超出了本文档的讨论范围。

 

5  RTP 数据传输协议

5.1 RTP 固定头中的各字段

RTP头有以下格式:   

   

        RTP包头格式        

    12个字节出现在每个 RTP 包中,仅仅在被混合器插入时,才出现CSRC识别符列表。这些域有以下意义:        

    版本(V)2比特 此域定义了 RTP 的版本。此协议定义的版本是 2(1 RTP 草案版本使用,值 0用在最初"vat"语音工具使用的协议中。)        

    填充(P)1 比特 若填料比特被设置,则此包包含一到多个附加在末端的填充比特,填充比特不算作负载的一部分。填充的最后一个字节指明可以忽略多少个填充比特。填充可能用于某些具有固定长度的加密算法,或者用于在底层数据单元中传输多个 RTP包。        

    扩展(X)1比特 若设置扩展比特,固定头()后面跟随一个头扩展。        

    CSRC计数(CC)4 比特    CSRC计数包含了跟在固定头后面CSRC 识别符的数目。        

    标志(M)1 比特 标志的解释由具体协议规定。它用来允许在比特流中标记重要的事件如帧边界。

    负载类型(PT)7 比特 此域定义了负载的格式,由具体应用决定其解释。协议可以规定负载类型码和负载格式之间一个默认的匹配。其他的负载类型码可以通过非 RTP 方法动态定义。 RTP发送端在任意给定时间发出一个单独的 RTP 负载类型;此域不用来复用不同的媒体流。        

    序列号(sequence number):16 比特 每发送一个 RTP 数据包,序列号加 1,接收端可以据此检测丢包和重建包序列。序列号的初始值是随机的(不可预测),以使即便在源本身不加密时(有时包要通过翻译器,它会这样做),对加密算法泛知的普通文本攻击也会更加困难。        

    时间戳(timestamp 32 比特时间戳反映了 RTP 数据包中第一个字节的采样时间。时钟频率依赖于负载数据格式,并在描述文件(profile)中进行描述。也可以通过 RTP 方法对负载格式动态描述。 如果 RTP 包是周期性产生的,那么将使用由采样时钟决定的名义上的采样时刻,而不是读取系统时间。例如,对一个固定速率的音频,采样时钟将在每个周期内增加 1。如果一个音频从输入设备中读取含有 160 个采样周期的块,那么对每个块,时间戳的值增加160 时间戳的初始值应当是随机的,就像序号一样。几个连续的 RTP 包如果是同时产生的。如:属于同一个视频帧的 RTP 包,将有相同的序列号。 不同媒体流的 RTP时间戳可能以不同的速率增长。而且会有独立的随机偏移量。因此,虽然这些时间戳足以重构一个单独的流的时间,但直接比较不同的媒体流的时间戳不能进行同步。对于每一个媒体,我们把与采样时刻相关联的 RTP时间戳与来自于参考时钟上的时间戳(NTP)相关联。因此参考时钟的时间戳就确定了数据的采样时间。(即:RTP 时间戳可用来实现不同媒体流的同步,NTP时间戳解决了 RTP 时间戳有随机偏移量的问题。)参考时钟用于同步所有媒体的共同时间。这一时间戳对(RTP 时间戳和 NTP 时间戳),用于判断 RTP 时间戳和 NTP 时间戳的对应关系,以进行媒体流的同步。它们不是在每一个数据包中都被发送,而在发送速率更低的 RTCP SR(发送者报告)中 如果传输的数据是存贮好的,而不是实时采样等到的,那么会使用从参考时钟得到的虚的表示时间线(virtual presentation timeline)。以确定存贮数据中的每个媒体下一帧或下一个单元应该呈现的时间。此种情况下 RTP 时间戳反映了每一个单元应当回放的时间。真正的回放将由接收者决定。

    SSRC32比特 用以识别同步源。标识符被随机生成,以使在同一个 RTP 会话期中没有任何两个同步源有相同的 SSRC 识别符。尽管多个源选择同一个 SSRC 识别符的概率很低,所有 RTP 实现工具都必须准备检测和解决冲突。若一个源改变本身的源传输地址,必须选择新的SSRC 识别符,以避免被当作一个环路源。

    CSRC 列表:0 15 项,每项 32 比特    CSRC列表识别在此包中负载的所有贡献源。识别符的数目在CC 域中给定。若有贡献源多于15 个,仅识别15 个。CSRC 识别符由混合器插入,并列出所有贡献源的 SSRC 识别符。例如语音包,混合产生新包的所有源的 SSRC 标识符都被列出,以在接收端处正确指示参与者。        

 5.3.1 RTP 头扩展        

    RTP 提供扩展机制以允许实现个性化:某些新的与负载格式独立的功能要求的附加信息在RTP 数据包头中传输。设计此方法可以使其它没有扩展的交互忽略此头扩展。RTP头扩展的格式如下图所示。        

        RTP 头中的扩展比特位置1,则一个长度可变的头扩展部分被加到 RTP 固定头之后。头扩展包含 16比特的长度域,指示扩展项中32 比特字的个数,不包括 4 个字节扩展头(因此零是有效值) RTP固定头之后只允许有一个头扩展。为允许多个互操作实现独立生成不同的头扩展,或某种特定实现有多种不同的头扩展,扩展项的前16 比特用以识别标识符或参数。这 16 比特的格式由具体实现的上层协议定义。基本的 RTP 说明并不定义任何头扩展本身。        

 

 6. RTP 控制协议 RTCP        

RTP 控制协议(RTCP)向会议中所有成员周期性发送控制包。它使用与数据包相同的传输机制。底层协议必须提供数据包和控制包的复用,例如用不同的UDP 端口。

四个功能:

1.       基本功能是提供数据传输质量的反馈,通过 RTCP 发送者和接收者报告实现。

2.       RTCP为每个 RTP 源传输一个固定的识别符,称为CNAME。由于当发生冲突或程序重时 SSRC 可能改变,接收者要用CNAME 来跟踪每个成员。接收者还要用CNAME 来关联一系列相关 RTP 会话中来自同一个成员的多个数据流,例如同步语音和图像。

3.       前两个功能要求所有成员都发送 RTCP 包,因此必须控制速率以使 RTP 成员数可以逐级增长。通过让每个成员向所有成员发送控制包,各个成员都可以独立地观察会议中所有成员的数目。此数目可以用来估计发包速率。

4.       第四个可选的功能是传输最少的会议控制信息。

 

RTP 用于IP 多点广播时,功能 1-3 是强制的,在所有情况下都推荐使用。建议 RTP

用开发商避免使用只能用于单向广播而不能扩充到多用户的方法。RTCP的传输应该分离地使用发送者方和接受者放,因为在如单向链接的情况下,从接受者方式不能发送反馈的。

 

 

6.1 RTCP包格式        

这部分定义了几个 RTCP包类型,可以传送不同的控制信息:

SR:发送者报告,描述作为活跃发送者成员的发送和接收统计数字;  

RR:接收者报告,描述非活跃发送者成员的接收统计数字;

SDES:源描述项,其中包括规范名CNAME

BYE:表明参与者将结束会话。

APP:应用描述功能。

 

    每个RTCP 包的开始部分是与 RTP数据包相类似的固定部分,随后是一块结构化单元,它随负载类型不同长度发生变化,但是总以 32 比特终止。对齐要求和长度域使 RTCP包可"堆栈",即可以将多个 RTCP 包形成一个复合 RTCP 包,在底层协议(UDP)中,通常都是将复合包作为一个包传输的。在复合包中,没有记录RTCP包数量的机制,因为底层协议会提供复合包总长度的值来确定复合包的边界。

复合包中的每个 RTCP 单包可以单独处理,而无需考虑包复合的顺序。然而,为了实现

协议功能,添加以下限制:

                接收数据的统计信息( SR RR)。只要带宽允许应尽可能经常的发送,以达到统计数字的最大分辨率。因此每个周期发送的 RTCP 包必须包含一个报告包。

                新的参与者需要尽快接收一个源的规范名以识别数据源并与媒体建立会话。因此,每个复合包中必须包含源描述项中的规范名。除非复合包进行了分割以进行部分加密(见 9.1节的描述)。

                   必须限制首次在复合包中出现的包类型的数目,以增加在第一个字中常数比特的数目,这样可以增加 RTCP包的有效性,以区分误传的 RTP 包和其他无关的包。因此,所有 RTCP 包必须以复合包的形式发送。复合包中至少有两个单个的 RTCP 包。具有以下格式:  

1.       加密前缀:当且仅当复合包被加密时,对每个 RTCP复合包加32 比特的前缀。如果填充也要加密,它必须被加到最复合包的最后一个包。

2.       SR RR复合包中的第一个 RTCP 包必须是一个报告包来保证头检验(附录A.2)。即使没有数据发送和接收,此时发送空的 RR包,或者复合包中其他的唯一包是 BYE 包,也必须发送报告包。

3.       附加的 RR:若被报告的接收统计的源的数目超过 SR/RR包中最大允许的 31,附加的 RR必须跟在最初的报告包后面。

4.       源描述 SDES:每个复合的RTCP包中必须都包含有CNAME项的SDES包,除非(&9.1)的情况。其他描述项信息可以选择性地包含,根据不同的应用,还有就是带宽(见&6.3.9

5.       BYE APP 包:其他RTCP包类型,包括那些还未定义的,可以是任意顺序,但是BYE

应该是最后与给出的SSRC/CSRC一起发出。包类型可以出现不止一次。

 

每个RTP 参与者在一个报告间隔内应只发送一个 RTCP 复合包,以便正确估计每个参与者的 RTCP 带宽。除非像9.1 节描述的情况——把一个 RTCP 复合包分割以进行加密。如果数据源的个数太多,以至于不能把所有的 RR包都放到同一个 RTCP包中而不超过网络路径的最大传输单元(maximum transport unit  MTU),那么可在每个间隔中发送其中的一部分包。在多个发送间隔中,所有的包应该被等概率的选中。这样就可以报告所有数据源的接收数据的情况。

如果一个 RTCP复合包的长度超过了网络路径的 MTU,则它应当被分割为多个更短的 RTCP 包来传输。这不会影响对 RTCP 带宽的估计,因为每一个复合包至少代表了一个参与者。要注意的是每个 RTCP复合包必须以 SR RR包开头。。。。。。。

 

6.2 RTCP传输时间间隔

         RTP 被设计为允许应用自动适应不同的规模的会话――从几个参与者到几千个参与者的会话。

         对每一个会话,我们假定数据传输受到一个上限――会话带宽的限制。会话带宽分配给所有的参与者。这个带宽会被预留,并由网络所限制。如果没有预留,基于环境的其他约束将会确定合理的最大带宽供会话使用,这就是会话带宽。会话带宽在一定程度上独立于媒体编码,但媒体编码却依赖于会话带宽。

         在涉及媒体应用时,会话带宽参数最好由一个会话控制应用提供。但媒体应用可能设置一个默认参数。此参数由单个发送者选择的编码方式的数据带宽算出。会话管理可能会基于多播范围的规则或其他标准确定带宽限制。所有的参与者应使用相同的会话带宽值以保证计算出相同的RTCP 间隔。

       控制传输带宽应当是会话带宽的一小部分,这部分所占总的会话带宽的百分比应是已知的。一小部分:传输协议的首要功能是传输数据;已知:控制传输带宽可以被放进带宽描述中提供给资源预留协议,并且使每个参与者都可以独立的计算出他所占有的带宽份额。

        控制传输带宽作为额外的一部分加入到会话带宽中。建议 RTCP 控制传输带宽为 RTCP 会话带宽的 5%。其中的1/4分配给发送者,即使发送者人数小于1/4,这样新加入的参加者将会更快的得到发送者的CNAME;当发送者的比例超过所有参与者的1/4时,其RTCP控制带宽相应增加。所有的会话参与者必须使用相同的常数(以上提到的百分比),以便计算出相同的发送时间间隔。这些常数应在一个特殊的描述文件中确定。

       特殊文件中用SR分别表示发送和接收带宽,推荐的默认值是1.25%3.75%。将R值设为零,而S设为非零,可以关闭某个回话的接收报告,而发送报告依然可以发送。但最好不要这么做,因为第六节开始列出的几个功能,尤其是接收质量反馈和拥塞控制都需要用到RTCP接收报告。

        计算出的 RTCP复合包的发送时间间隔应该有一个下限,以免参与者数量较少时大量发送RTCP 包。这也使网络暂时断开时,发送间隔不会太小。在应用开始时,一个延迟应加到第一个的 RTCP 复合包发送之前,以便从其他参与者接收 RTCP 复合包。这样,发送时间间隔能更快的收敛到正确的值。这个延迟可以设为最小时间间隔的一半。固定的时间间隔建议为5 秒。

       一个实现可能使 RTCP 最小发送时间间隔与会话带宽参数成比例。则应满足下列约束:

    对多播会话,只有活动的数据发送者使用减小的最小化的值计算 RTCP 复合包的发送时间间隔。

    对单播会话,减小的值也可能被不是活动的数据发送者使用,发送初始的 RTCP 复合包之前的延迟可能是 0

    对所有会话,在计算参与者的超时时间时,这个固定最小值会被用到(&6.3.5)。因此,不使用减小的值进行 RTCP包的发送,就不会被其他参与者提前宣布超时。

减小的最小时间间隔建议为: 360/带宽(),会话带宽单位是kb/s。当会话带宽大于72kb/s时,最小时间间隔将小于 5s

6.3 节所描述的算法和附录 A.7 将实现本节列出的目标:

        

 

         计算出的 RTCP 包的时间间隔与组中参与者的人数成正比。(参与者越多,发送时间间隔越长,每个参与者占有的 RTCP 带宽越小)。

         RTCP 包的(真实)时间间隔是计算出的时间间隔的0.51.5倍之间某个随机的值,以避免所有的参与者意外的同步。第一个RTCP包发送前也有一个长度为最小时间间隔的一半乘以一个随机值的延迟。

         RTCP 复合包的平均大小将会被动态估计,包括所有发送的包和接收的包。以自动适应携带的控制信息数量的变化。

         由于计算出的时间间隔依赖于观察组中的人数。因此,当一个的用户加入一个已经存在的会话或者大量的用户几乎同时加入一个新的会话时,就会有意外的初始化效应。这些新用户将在开始时错误的估计组中的人数(估计太小)。因此他们的 RTCP 包的发送时间间隔就会太短。如果许多用户同时加入一个会话,这个问题就很重要了。为了处理这处问题考虑了一种叫作时间重估的算法。这个算法实现了简单的退避机制,使得组中人数增加时,用户能够抑制 RTCP 包的传输。

         当有用户离开会话,不管是发送 BYE 包还是超时,组中的人数会减少。计算出的时间间隔也应当减少。因此,应用逆向重估算法,使组中的成员更快的减少他们的时间间隔,以对组中的人数减少快速做出响应。

         BYE 包的处理和其他 RTCP 包的处理不同。BYE 包的发送用到一个―放弃支持算法。以避免大量的 BYE 包同时发送,使大量参与者同时离开会话。

         这个算法适用于所有参与者都允许发送的情况。此时,会话带宽=每个发送者的带宽×会话中参与者的总人数。RTCP的带宽是会话带宽的5%。详细算法见随后小节,附录 A.7 给出了算法的一个实现。

 

6.2.1 维持会话成员的人数

RTCP包的时间间隔的计算依赖于会话中参与者的数量。当侦听到新的站点的时候,应当把他们加入计数。每一个登录都应在表中创建一条记录,并以 SSRC CSRC 进行索引(见&8.2)。新的登录直到接收到含有 SSRC 的包或含有与此 SSRC 相联系的CNAME SDES包才视为有效(见附录 A.1)。当一个与 SSRC 标识符相对 RTCP  BYE包收到时,登录会被从表中删除。除非一个掉队的数据包到达,使登录重新创建。

如果在几个 RTCP 报告时间间隔内(一个时间间隔推荐为5秒)没有 RTP RTCP包收到,一个参与者可能标记另外一个站点静止,并删除它。这是针对丢包提供的一个很强健的机制。所有站点对这个超时时间间隔乘子应大体相同,以使这种超时机制正常工作。因此这个乘子应在特别的描述文件中确定。

对于一个有大量参与者的会话,维持并存贮一个有所有参与者的 SSRC 及各项信息的表几乎是不可能的因此,可以只存贮 SSRC。关键的问题就是,任何算法都不应当低估组的规模,虽然它有可能被高估。

 

 

6.3  RTCP包的发送和接收规则

下面列出了如何发送 RTCP 包,当接收到的 TCP 包时该干什么的规则。

为执行规则,一个会话参与者就维持下列变量:

tp:  最近的RTCP 包发送的时间。

tc: 当前时间。

tn: 估计的下一个 RTCP 包要发送的时间。

pmembers: tn 最后被重新计算时,会计的会话成员的人数。

members: 会话成员人数的当前估计。

senders: 会话成员中发送者人数的估计。

rtcp_bw: 目标 RTCP 带宽。例如用于会话中所有成员的 RTCP 带宽。单位bit/s。这将是

程序开始时,指定给会话带宽参数的一部分。

we_sent: 自当前第二个前面的 RTCP 发送后,应用程序又发送了数据,则此项为true

avg_rtcp_size: 此参与者收到的和发送的 RTCP 复合包的平均大小。单位:bit。按 6.2

节,此大小包括底层传输层和网络层协议头。

initial: 如果应用程序还未发送 RTCP 包,则标记为 true

许多规则都用到了 RTCP包传输的计算时间间隔。此时间间隔将在随后的小节描述。

 

6.3.1 计算 RTCP 传输时间间隔

    一个会话参与者包的平均发送时间间隔应当和所在会话组中人数成正比。这个间隔称为计算时间间隔。它由上面提到的各个状态参量结合起来计算得出。计算时间间隔 T的计算如下:

    1.(1)如果发送者人数≤会话总人数×25%。则 T取决于此参与者是否是发送者(we_sent的值);否则,发送者和接收者将统一处理。

senders<=25%*members

we_sent  true

c=avg_rtcp_size / (0.25*rtcp_bw);

n=senders;

 

we_sent  false

c=avg_rtcp_size / (0.75*rtcp_bw);

n=members-senders;

 

 

senders>25%*members

c=avg_rtcp_size/rtcp_bw;

n=members;

 

6.2 节所述,RTP 描述文件可能用两个独立的参数(SR)确定发送者与非发送者。此

时,25% 75%只要相应的换成 S/(S+R),R/(S+R)即可。注意 R0的情况。

2.如果initial true(则未发送过 RTCP ),则设 Tmin=2.5s;否则设 Tmin=5s

3.决定性的计算时间间隔(deterministic calculated intervalTd=max(Tmin ,n*c) 

4. T=Td*λ;其中 λ~U(0.5,1.5)。即 λ服从0.5 1.5之间的均匀分布。

5. T=T/(e-0.5)T/1.21828补偿时间重估算法,使之收敛到比计算出的平均 RTCP

宽小的一个值。

这个算法产生了一个随机的计算时间间隔,并把至少25% RTCP 带宽分配给发送者,其

余的分给接收者。若发送者超过会话总人数的 25%,此算法将把带宽平均分给所有的参与者。

6.3.2 初始化

    一加入会话,参与者的各状态参量初始化为: tp=0   tc=0  senders=0  pmembers=1  members=1 we_sent=false  rtcp_bw:由会话带宽参数的相应部分得到;initial=trueavg_rtcp_size:初始化为应用程序稍后将发送的 RTCP 包的可能大小;T:如 6.3.1 节;tn=T(这意味着,一个计时器将经 T时间后被唤醒);应用程序可以用任何它需要的方式实现计时器。

参与者把它自己的 SSRC 加到成员列表中。

 

6.3.3 接收到的 RTP 包或一个非 BYE RTCP

当收到一个参与者的 RTP RTCP 包时,若其 SSRC不在成员列表中,将其 SSRC 加入

列表;若此参与者被确认有效(如6.2.1节描述),就把列表中成员的值更新。对每个有效的

RTP 包中的 CSRC 执行相同的过程。

当收到一个参与者的 RTP 包时,若其 SSRC 不在发送者列表中,则将其 SSRC 加入发送

者列表,更新相应的值。

每收到一个 RTCP 复合包,avg_rtcp_size 更新为 avg_rtcp_size  =  1/16  * packet_size  +  15/16  *  avg_rtcp_size  ;其中 packet_size是刚收到的RTCP 复合包的大小。

 

6.3.4 接收 RTCP  BYE

   6.3.7 小节描述的发送 RTCP BYE 包之外,如果收到一个 RTCP  BYE 包,则检测成员列表。若 SSRC 存在于成员列表;先移除之,并更新members的值;若 SSRC 存在于发送者列表;先移除之,并更新senders的值。 另外,为使 RTCP 包的发送速率与组中人数变化更加协调,当收到一个 BYE包使得

members的值 pmembers 时,下面的逆向重估算法应当执行:

1tn的更新:tn = tc  +  ( members / pmembers ) * ( tn tc )//下一次发送间隔变短

2tp的更新:tp = tc ( members / pmembers ) * ( tc tp )//上一次发送间隔变短

         下一个 RTCP 包将在时刻 tn 被发送,比更新前更早一些。  

3pmembers 的更新:pmembers=members

这个算法并没有防止组的大小被错误的在短时间内估计为 0 的情况。如:在一个较多人数

的会话中,多数参与者几乎同时离开而少数几个参与者没有离开的情况。这个算法并没有使估计迅速返回正确的值。因为这种情况较罕见,且影响不大。

 

6.3.5 SSRC超时

在随机的时间间隔中,一个参与者必须检测其他参与者是否已经超时。为此,对接收者

we_sent false),要计算决定性时间间隔 Td,如果从时刻 Tc-M*TdM为超时因子,默

认为 5 秒)开始,未发送过 RTP RTCP 包,则超时。其 SSRC 将被从列表中移除,members被更新。在发送者列表中也要进行类似的检测。发送者列表中,任何从时间 tc-2T(在最后两个 RTCP报告时间间隔内)未发送 RTP 包的发送者,其 SSRC 从发送者列表中移除,senders更新。

如果有成员超时,应该执行 6.3.4 节中的逆向重估算法。

每个参与者在一个 RTCP包发送时间间隔内至少要进行一次这样的检测

 

6.3.6 发送时钟到时了

当包传输的发送时钟到时,参与者执行下列操作:

1)按 6.3.1 节的办法计算 T

2)更新发送时钟的定时时间,判断是否发送 RTCP包,更新 pmembers

         tp+T<=tc时:

                   发送 RTCP

                   tp=tc;

                   再次计算T; tn=tc+T;设置transmission timer;

         tp+T>=tc时:

                   tn=tc+T;设置transmission timer;

         Pmemvers=members;

         如果RTCP包发送了,initial=false; 并且更新:

                   avg_rtcp_size=1/16  *  packet_size  +  15/16  *  avg_rtcp_size 

                            // packet_size是刚刚发送的RTCP包的大小

 

6.3.7 发送一个 BYE

    当一个参与者离开会话时,应发送 BYE 包,通知其他参与者。为避免大量参与者同时离开系统时,大量 BYE 包的发送,若会话人数超过50,则参与者在要离开会话时,应执行下面的算法。这个算法实际上―篡夺了一般可变成员的角色来统计 BYE

   1tp=tc tc=1members=1 pmembers=1 sinitial=1 we_sent=false senders=0  avg_rtcp_size:设置为将要发送的 BYE 包大小;计算时间间隔T tn=tc+T(BYE 包预计在时刻 tn 被发送)

   2每当从另外一个参与者接收到 BYE包时,成员人数加1。不管此成员是否存在于成员列表中,也不管 SSRC 采样何时使用及 BYE 包的 SSRC 是否包含在采样之中。如果收到 RTP 包或者RTCP 包(除 BYE包之外的 RTCP 包),成员人数不增加。类似,只有在收到 BYE 包时,avg_rtcp_size 才更新。当 RTP 包到达时,发送者人数senders 不更新,保持为 0

   3)在此基础上,BYE包的传输服从上面规定的一般的 RTCP 包的传输。

         BYE 包的传输,是专注于统计会话中发送 BYE 包的人数的。)

这允许 BYE 包被立即发送,并控制总的带宽使用。在最坏情况下上,这可能会使 RTCP 控制包使用两倍于正常水平的带宽,达到 10%――其中 5%给非BYE 包的RTCP 包,其余 5%BYE 包。

         一个参与者若不想用上面的机制进行 RTCP 包的发送,可以直接离开会话,而根本不发送BYE 包。他会被其他参与者因超时而删除。

         一个参与者想离开会话时,如果组中的人数会计数目小于 50,则参与者可以直接发送 BYE包,或者执行上面的篡夺算法。

         另外,一个从未发送过 RTP RTCP 包的参与者,在离开会话时,不能发送 BYE

 

6.3.8 更新we_sent 变量

    如果一个参与者最近发过 RTP 包,则变量 we_sent值为 true,否则为 false。相同的机制可以管理发送者中的其他参与者。如果参与者发送了RTP包时,其对应的 we_sent 变量值为false,则就把它自己加到发送者列表中,并设置其 we_sent 变量为 true6.3.4 节中描述的逆向重估算法reverse reconsideration algorithm)应当被执行。以可能减少发送 SR包前的延迟。每次发送一个 RTP 包,其相应的传输时间都会记录在表中。一般发送者的超时算法应用到参与者自身:从 tc-2T时开始,一直没有发送 RTP 包,则此参与者就从发送者列表中将其自身移除,减少发送者总数,并设置we_sent 变量值为 false

 

6.3.9 源描述带宽的分配

    这里定义了几种源描述项,强制性的规范名(CNAME)除外。例如,个人姓名(NAME)和电子邮件地址(EMAIL)。它也提供了方法定义新的 RTCP 包的类型。应用程序在给这些额外信息分配带宽时应额外小心。因为这会降低接收报告及 CNAME 的发送速率,可能破坏协议发挥作用。建议分配给一个参与者用于传输这些额外信息的带宽不超过总的RTCP带宽的20%。另外,并非所有的源描述项都将包含进每一个应用程序中。包含进应用程序的源描述项应根据其用途分配给相应的带宽百分比。建议不要动态会计这些百分比,而应根据一个源描述项的典型长度将所占带宽的百分比的转化为报告间隔。

    例如,一个应用程序可能仅发送CNAMENAME EMAIL,而不需要其他项。NAME 可能会比 EMAIL 给予更高的优先级。因为 NAME 可能会在应用程序的用户界面上持续显示,但EMAIL可能仅仅在需要时才会显示。在每一个 RTCP 时间间隔内,一个包含CNAME项的 SDES包和一个 RR包将会被发送。最小的会话时间间隔平均为5 秒。每经过3 个时间间隔(15 秒),一个额外的项将会包含进这个 SDES包中。7/8 的时间是 NAME 项,每经过8 个这样的间隔(15s*8=2min,将会是EMAIL项。

    当多个会话考虑使用一个通用的规范名为每个参与者进行绑定时,如在一个 RTP 会话组成的多媒体会议中,额外的 SDES信息可能只在一次 RTP 会话中被发送。其余的会话将只发送CNAME。特别,这个办法也应该用在分层编码的多个会话中。

 

 

6.4  发送者和接收者报告

    RTP 接收者利用 RTCP报告包提供接收质量反馈。根据接收者是否同时还是发送者,RTCP包采取两种不同的形式。发送者报告(SR)和接收者报告(RR)格式中唯一的不同,除包类型码之外,在于发送者报告包括 20字节的发送者信息        

    SR包和 RR包都包括零到多个接收报告块。针对该接收者发出上一个报告块后接收到 RTP包的起始同步源,每个源一个块。报告不发送给 CSRC 列表中的贡献源。每个接收报告块提供从特定数据源接收到数据的统计信息。由于 SR/RR包最多允许 31 个接收报告块,故可以在最初的 SR RR包之后附加 RR包,以包含从上一个报告以来的间隔内收听到的所有源的接收报告。如果数据源太多,致使若把所有的 RR包放到同一个 RTCP 复合包中会超出网络的 MTU。那么就在一个周期内选择上面 RR包的一部分以不超过 MTU。这些 RR包的选取应让各个包都有同等的几率被取到。这样在几个发送周期间隔中,对所有的数据源就都发送接收报告了。

以下部分定义了两种报告的格式。如果应用程序需要其他信息,他们可以被扩展。

(见&7  

6.4.1 SR:发送者报告 RTCP         

发送者报告包由 3部分组成,若定义,可能跟随第 4 个面向协议的扩展部分。        

 第一部分,头部,8字节长。该域有以下意义:        

   版本(V)2 比特    RTP 版本识别符,在 RTCP 包内的意义与 RTP包中的相同。此协议中定义的版本号为 2        

   填充(P)1 比特 若设置填充比特,该 RTCP包在末端包含一些附加填充比特,并不是控制信息的基本部分。填充的最后一个比特统计了多少个字节必须被忽略。填充可能会用于需要固定长度块的加密算法。在复合 RTCP 包中,复合包作为一个整体加密,填料比特只能加在最后一个单个 RTCP 包的后面。        

   接收报告块计数(RC)5 比特 该包中所含接收报告块的数目。零值有效。        

   包类型(PT)8比特 包含常数 200,用以识别这个为 SR包。        

   长度:16 比特 RTCP 包的长度减 1。其单位是 32 比特字,包括头和任何填充字节。(偏移量 1 保证零值有效,避免了在扫描 RTCP 包长度时可能发生的无限循环,同时以 32 比特为单位避免了对以4 为倍数的有效性检测。)        

   SSRC32 比特    SR包发送者的同步源标识符。

 

第二部分,发送者信息,20字节长。在每个发送者报告包中出现。它概括了从此发送者发

出的数据传输情况。此域有以下意义:        

   NTP 时间戳:64 比特 指示了此报告发送时的背景时钟(wallclock)时刻,它可以与从其它接收者返回的接收报告块中的时间标志结合起来,计算往返每个接收者所花的时间。接收者应让 NTP 时间戳的精度远大于其他时间戳的精度。时间戳测量的不确定性不可知,因此也无需指示。一个系统可能没有背景时钟的概念,而只有系统指定的时钟,如系统时间(system uptime)。在这样的系统中,此时钟可以作为参考计算相对 NTP 时间戳。选择一个公用的时名是非常重要的。这样多个独立的应用都可以使用相同的时钟。到2036 年,相对和绝对NTP 时间戳会产生大的差异。到那时,我们希望不再需要相对时钟。一个发送者,如果不用背景时钟时间或逝去时间,可以设置此项为零。        

    RTP 时间戳:32 比特 与以上的 NTP 时间标志对应同一时刻。与数据包中的 RTP时间戳具有相同的单位和偏移量。 这个一致性可以用来让 NTP时间标志已经同步的源之间进行媒体内间同步,还可以让与媒体无关的接收者估计名义 RTP 时钟频率。注意在大多数情况下此时间戳不等于任何临近的 RTP 包中的时间戳。RTP 时间戳可以由相应的NTP 时间戳计算得到。依据的是―RTP 时间戳计数器和―在采样时通过周期性检测背景时钟时间得到的实际时间两者之间的关系。

(在 RTCP  SR包中有 NTP时间戳、RTP 时间戳,它们可以计算背景时钟和 RTP 时钟之间的对应关系,通过这个关系,可以由 RTP 数据包中的 RTP 时间戳计算相应的回放时刻。这样就可以进行多个流的同步了。之所以要有NTP 时间戳,是因为不同流的 RTP 时间戳有不同的随机偏移量,无法直接进行同步  

    发送的报文数:32 比特 从开始传输到此 SR包产生时该发送者发送的 RTP 数据包总数。若发送者改变 SSRC 识别符,该计数器重设。

发送的字节文数:32 比特 从开始传输到此 SR包产生时该发送者在 RTP 数据包发送的字节总数(不包括头和填充)。若发送者改变 SSRC 识别符,该计数器重设。此域可以用来估计平均的负载数据发送速率。        

 

第三部分:零到多个接收报告块。块数等于从上一个报告以来该发送者侦听到的其它源(不包括自身)的数目。每个接收报告块传输从某个同步源来的数据包的接收统计信息。若数据源因冲突而改变其 SSRC 标识符,接收者重新设置统计信息。这些统计信息有:        

   SSRC_n(同步源标识符)32 比特 在此接收报告块中信息所属源的 SSRC 标识符。        

   丢包率:8比特 自从前一 SR包或 RR包发送以来,从 SSRC_n传来的 RTP 数据包的丢失比例。以定点小数的形式表示。该值定义为损失包数/期望接收的包数。若由于包重复而导致包丢失数为负值,丢包率设为零。注意在收到上一个包后,接收者无法知道以后的包是否丢失。如:若在上一个接收报告间隔内从某个源发出的所有数据包都丢失,那么将不为此数据源发送接收报告块。

   累计包丢失数:24 比特 从开始接收到现在,从源 SSRC_n 发到本源的 RTP 数据包的丢包总数。该值定义为:期望接收的包数-实际接收的包数。接收的包括复制的或迟到的。由于迟到的包不算作损失,在发生复制时丢包数可能为负值。期望接收的包数定义为:扩展的上一接收序号(随后定义)减去最初接收序号。        

   接收到的扩展的最高序列号:32 比特 16 比特包含从源 SSRC_n来的最高接收序列号,高 16 比特用相应的序列号周期计数器扩展该序列号。注意在同一会议中的不同接收者,若启动时间明显不同,将产生不同的扩展项。        

   到达间隔抖动: 32 比特    RTP 数据包到达时刻统计方差的估计值。测量单位同时间戳单位,用无符号整数表达。到达时间抖动定义为一对包中接收者相对发送者的时间间隔差值的平均偏差(平滑后的绝对值)该值等于两个包相对传输时间的差值。相对传输时间是指:包的 RTP 时间戳和到达时刻接收者时钟时间的差值。若 Si 是包i 中的 RTP 时间戳,Ri i到达时刻(单位为:RTP 时间戳单位)。对于两个包i jD 可以表示为

                                               D(i,j) = (Rj - Ri) - (Sj - Si) = (Rj - Sj) - (Ri - Si)

到达时刻抖动可以在收到从源 SSRC_n来的每个数据包i 后连续计算。利用该包和前一包i-1 的偏差D(按到达顺序,而非序号顺序),根据公式

                                               J(i) = J(i-1) + (|D(i-1,i)| - J(i-1))/16

计算。无论何时发送接收报告,都用当前的 J值。 此处描述的抖动计算允许与协议独立的监视器对来自不同实现的报告进行有效的解释。        

    上一SR报文(LSR) 32 比特 接收到的来自 SSRC_n 的最新RTCP 发送者报告(SR) 64 NTP 时间标志的中间32 。若还没有接收到 SR,该域值为零。

    自上一 SR的时延(DLSR)32 比特 从收到来自 SSRC_n SR包到发送此接收报告块之间的延时,以 1/65536 秒为单位。若还未收到来自 SSRC_n SR包,该域值为零。        

    假设SSRC_r 为发出此接收报告块的接收者。源 SSRC_n可以通过记录收到此接收报告块的时刻 A来计算到 SSRC_r 的环路传输时延。可以利用最新的 SR时间标志(LSR)计算整个路时间 A-LSR,然后减去此 DLSR域得到环路传输的时延。 

     如下图所示。

 

6.4.2 RR:接收者报告RTCP

 

    接收者报告包(RR)与发送者报告包基本相同,除了包类型域包含常数 201 和没有发送者信息的 5 个字(NTP RTP 时间标志和发送者包和字节计数)。余下区域与 SR包意义相同。若没有发送和接收据报告,在 RTCP 复合包头部加入空的 RR(RC=0)

 

6.4.3 发送者和接收者报告扩展

    如果有额外的关于发送者和接收者的信息要周期性的,描述文件(profile)应该定义接收者报告和发送者报告描述文件扩展。此时,应采用这里的办法,而不是定义另外的 RTCP 包。因为这种办法需要的头部信息更少。

    扩展部分是发送报告包和接收报告包的第四部分。如果有的话,应紧跟在接收报告块的后面。如果需要更多的发送者信息,它应当跟在发送者报告的开关,而不应在报告中出现。如果要包含进接收者的信息,它应该以块数组的方式放到接收报告块的后面。即这些块也应被计入 RC 字段中。

6.4.4 分析发送者和接收者报告  

    接收质量反馈不仅对发送者有用,而且对于其它接收者和第三方监视器也有作用。发送者可以基于反馈修正发送信息量;接收者可以判断问题是本地的,区域内的还是全局的;网络管理者可以利用与协议无关的监视器(只接收 RTCP 包而不接收相应的 RTP)去评估多点传送网络的性能。

    在发送者信息和接收者报告块中都连续统计丢包数,因此可以计算任何两个报告块中的差别。在短时间和长时间内都可以进行测算。最近收到的两个包之间差值可以评估当前传输质量。包中有 NTP 时间戳,可以用两个报告间隔的差值计算传输速率。由于此时间间隔与数据编码速率独立,因此可以实现与编码及协议独立的质量监视。

    一个例子是计算两个报告间隔时间内的丢包率。丢包率=此间隔内丢失的包/此间隔内期望收到的包。如果此值与―丢失比例字段中的值相同,说明包是连续的;否则,说明包不是连续的。间隔时间内的丢包率/间隔时间=每秒的丢包率。

从发送者信息中,第三方监视器可以在一个时间间隔内计算平均负载数据发送速率和平均发包速率,而无需考虑数据接收。两个值的比就是平均负载大小(平均每个包的负载大小)。(即:平均负载大小=平均负载数据发送速率/平均发包率。)若能假定丢包与包的大小无关,那么某个特定接收者收到的包数乘以平均负载大小(或相应的包大小)就得出接收者可得到的外在吞吐量。 除了累计计数允许利用报告间差值进行长期包损测量外单个报告的“丢包比例”字段提供一个短时测量数据。当会话规模增加到无法为所有接收者保存接收状态信息,或者报告间隔变得足够长以至于从一个特定接收者只能收到一个报告时,短时测量数据变得更重要。

到达间隔抖动字段提供另一个有关网络阻塞的短时测量量。丢包反映了长期阻塞,抖动测量反映出短时间的阻塞。抖动测量可以在导致丢包前预示阻塞。由于到达间隔抖动字段仅仅是发送报告时刻抖动的一个快照,因此需要在一个网络内的一段时间内,分析来自某个接收者的报告,或者分析来自多个接收者的报告。

 

6.5 源描述 RTCP

    源描述(SDES)包由一个头及0 个或多个块组成。每个块都由块中所标识的数据源的标识符及其后的各个描述构成。

6.5.1 CNAME

CNAME有如下特点:

1.在应用重启或者发生冲突时,CNAME提供了SSRC与源之间的绑定。

2.SSRC一样,CNAME在一个RTP对话中,对每个参与者都是唯一的。

3.跨多个媒体工具使用的一组相关的 RTP 会话中的一个参与者提供一个绑定。

4. CNAME 应适用于程序或确定源的人。

 

    CNAME如果可能的话应该是用算法生成的,而不是用手动输入的。除非配置文件列出了另外的有如下要求,CNAME有如下格式:”user@host”或者用户名在单用户系统上不可用时用”host”Host可以是一个绝对域名,也可以是一个IPV4IPV6的准ASCII表示。

    在这样的语法规则下,如果一个应用允许一个生成多个源,CNAME无法提供为每个源提供唯一的标示符。这样的应用需要用SSRC更进一步的确定源,或者在这个应用的配置文件中为CNAME指明额外的语法规则。

 

6.6 BYEBYE 包)

    BYE 包表明一个或多个源将要离开。

    什么时候发送一个BYE包的规则参见&6.3.7&8.2

    如果混合器收到 BYE包,混合器应当发送这个 BYE 包,并保持 SSRC/CSRC不变。如果混合器关闭,应向贡献源列表中的所有 SSRC,包括它自己的SSRC 发送 BYE 包。BYE包可能会有选择的包含 8 个字节的统计字段,其后跟上几个字节的文本表明离开的原因。文本字符串编码格式和 SDES中描述的相同。

 

7. RTP转换器和混合器

    对于终端系统,RTP支持转换器和混合器的概念,可以把它想象为RTP层的“中间系统”。尽管这个支持给协议增加了一定的复杂性,但对于因特网中的多播的音频和视频应用,这些功能都是有必要的。

 

7.1 总体概述

一个RTP的转换/翻译器连接了两个或多个传输层的“云”。每朵云一般都是被一个网络层和传输层协议(例如IP/UDP加上一个多播地址和传输层地址端口或一对单播地址和端口所定义的。(网络层协议的转换器,例如IPV4,IPV6可能在云中,但对RTP不可见)。一个系统作为一个转换器或混合器服务于许多的RTP会话,但对每个会话,都可以看做是逻辑上独立的实体。

为了避免安装转换器和混合器是造成环路,以下的规则必须遵守:

1.RTP会话中有转换器和混合器连接的云要么必须有一个参数(参数包括:协议,地址,端口)区别于其他的云,要么必须在网络层与其他云隔离。

    2.第一条规则的衍生是,那里不必须有多个并行连接的转换器或者混合器,除非由它们安排分区的源的集要发送。

    类似的,所有通过一或多个RTP转换器或混合器传递信息的RTP终端系统共享同一个SSRC空间,就是说,SSRC标示符在所有这些终端系统中必须唯一。&8.2描述了冲突解决算法,这个算法可以用来保持SSRC标示符的唯一和检测环路。

    根据不同的目的和应用,有许多不同的转换器和混合器。一些是为了增加和去除加密,

一些可以改变数据或下层协议的编码,还有在多播地址和一个或多个单播地址间的复制。它们之间的区别是,转换器传递来自不同源的数据流,而混合器将来自不同数据源的数据流合成一个新的流。

转换器:转发RTP包并且保证它们的SSRC标示符无损。它可以让接收者识别不同的流,即使来自所有源的包经过了同样的转换器并且携带了转换器的网络层源地址。一些转换器不会接触数据,但有一些可能会改变数据的编码还有RTP数据的负载类型和时间戳。如果多个数据包被二次编码为一个,或者是相反的情况,那转换器必须分配新的序列号给发出的包。进入转换器的包流中丢包会导致相应的发出的序列号的缺失。接收者无法感觉到转换器的存在,除非它们通过其他方法知道最初的源使用的负载类型或者传输地址是什么。

混合器:一个或多个源的的RTP数据包流的接收者,可能改变数据格式,用同样的方式合并了流,并且转发合并后的流。由于多个输入员的时间一般是不同步的,混合器会对流进行校准,并且为合并后的流产生新的时间,所以它是同步的源。并且,所有被混合器转发的数据包必须标上混合器自己的SSRC标示符。为了维持原来的作用于混合包的源的SSRC不变,转换器应该将它自己的SSRC标示符插入到跟在固定RTP数据头后面的CSRC标示符列表。当混合器同时也是一些包的作用源是,应该在那个包的CSRC列表中显式地包含它自己的SSRC标示符。

         对某些应用,不把混合器的SSRC列入CSRC表示可以接受的。然而,这就造成了包含这些源的循环无法被检测到的危险。

         对某些应用来说,例如音频应用,混合器对于转换器的优势在于,即使输入一边有多个源活跃,输出的带宽也只有一个源的带宽。这对于低带宽的连接是重要的。缺点是在混合器的输出一边的接收者无法控制哪个源通过或静音,除非有某种远程控制混合器的机制。混合器再生成了同步信息,这意味着接收者无法为原始流做中间同步。一个多媒体混合器可以做到。

 

 

 

 

 

 

 

 

 

 

 

 

 

8SSRC标示符的分配和使用

9. 安全性

10. 拥塞控制

         所有在因特网上的传输协议都需要拥塞控制。RTP也不例外,但由于在RTP上传输的数据没有弹性(一定的或者是控制的速率生成数据),所以它的拥塞控制和其他传输层如TCP上的控制方式不同。从某种意义上说,无弹性减少了拥塞的危险性,因为RTP流不会像TCP流那样膨胀从而消耗掉可用的带宽。然而,无弹性也意味着RTP流无法任意地减少它的负载从而限制网络拥塞的发生。

         由于RTP在许多应用中都有广泛的使用,所以它没有一个单一的机制来解决所有问题。因此,拥塞控制应该在每个RTP配置文件中用恰当的方法定义。对一些配置文件,在避免拥塞的情况下,限制使用该配置文件的适用性声明就够了。对其它一些配置文件,一些特定的方法,譬如基于RTCP反馈的数据传输速率适应可能是需要的。

11. 网络层和传输层协议上的RTP

 

 

 

 

 

 

 

 

 

 

 

 

附录

A.1 RTP数据头的有效性检验

    RTP接收者应该检测收到的包中RTP头的有效性,因为它们可能被加密或者它们可能来自一个不同的应该程序。类似的,如果允许加密(& 9),头的有效性检测是必要的,因为要证明接收的包已经被正确地解码了。虽然RTP数据头的有效性检测(例如,未知负载类型)的失败不一定代表了解码的失败。

对于第一次接收的源的数据包的检验比较简单:

         1.RTP的版本域为2

         2.负载类型必须已知

         3.如果填充位被设为1,那么包的最后一个字节代表的数,必须小于总的包长度减去头  的长度

         4.如果配置文件没有指出头扩展机制可用,扩展位必须为0。否则,扩展长度域必须小  于总的包长度减去头的长度减去填充的长度

         5.包的长度必须复合CC的值和负载的类型

    后三个检验相对复杂且不总是可以检测,前两个检测只有几个比特位。如果包中的SSRC标示符是以前接收过的,这个包可能是有效的,检测序列号是否在期望区间内。如果SSRC标示符以前没有见过,包含这个SSRC的包可能是无效的,除非他们的一部分序列号是连续的。那些无效的包可能被丢弃,或者它们由于结果延迟可接收,造成有效性检测通过,从而被存储传送。

下面的update_seq例程确保了只有在MIN_SEQUENTIAL(宏定义,值为2)包按顺序收到后,一个源才被声明为有效。它还验证了新收到的包的序列号seq的有效性并且为包的源更新了用指针s指向的结构体变量中的序列号状态。

当一个新的源被第一次接收到,即它的SSRC标示符不在表中时(见& 8.2),为这个源分配源状态,在声明这个源有效前,s->probation被设为随后所需要的包的连续的序列号的个数 MIN_SEQUENIAL),并且其他变量也被初始化:

         init_seq(s, seq);

    s->max_seq = seq - 1;

    s->probation = MIN_SEQUENTIAL;

非零变量s->probation表示源还无效,状态将会在一个很短的时间内被丢弃,而不是在一个较长的时间后,正如& 6.2.1中所说。

当一个源被认定有效后,如果序列号在(s->max_seq- MAX_MISORDER)和(s->max_seq+ MAX_DROPOUT)之间,那么序列号被认定是有效的。如果新的序列号在超过了max_seq的低16位的值,但是小于max_seq,说明它绕了序列号数一圈。返回一个1表示一个有效的序列号。

否则,返回0表示序列号无效,并且保存无效序列号加1后的值。如果接收的下一个包带来了更后的序列号,就认为这是一个新的包序列的开始。这个可能是一个扩展的遗漏或者一个源的重读。因为多个完成的序列数循环可能被错过,包的丢失统计被重置了。

参数的典型取值列出了,当传输速度为50/秒时,顺序错乱等待时间为两秒,丢失的等待时间为1分钟。所MAX_DROPOUT3000MAX_MISORDER100

 

 

A.2 RTCP头部的有效性检测

         以下检测应该被应用在RTCP的包中:

1.       RTP版本为2

2.       复合包中第一个RTCP包的负载类型域一定是SRRR

3.       复合包中的第一个RTCP包的填充域应该是0,因为即使是需要,填充域也只在最后一个包中被使用。

4.       单个RTCP包的长度域相加等于接收到的复合RTCP包的长度。这是一个相当强健的检查。

         下面是这些检查的简单代码,包类型没有被检查,因为未知的包类型可能出现以及被忽略:

           #define RTCP_VALID_MASK (0xc000 | 0x2000 | 0xfe)                  //1110 0000 1111 1110

           #define RTCP_VALID_VALUE  ((RTP_VERSION << 14) | RTCP_SR)//1000 0000 1100 1000

           //1000 0000 0000 0000|0000 0000 1100 1000

           u_int32 len;        /* length of compound RTCP packet in words */

      rtcp_t *r;          /* RTCP  packet*/

      rtcp_t *end;        /* end of compound RTCP packet */

        

      if ((*(u_int16 *)r & RTCP_VALID_MASK) != RTCP_VALID_VALUE) {

          /* something wrong with packet format */

      }

 

 

      end = (rtcp_t *)((u_int32 *)r + len);

      do r = (rtcp_t *)((u_int32 *)r + r->common.length + 1);     

                   /*length16 比特 RTCP 包的长度减 1。其单位是 32 比特字,包括头和任何填充字节。(偏移量 1 保证零值有效,避免了在扫描 RTCP 包长度时可能发生的无限循环,同时以 32 比特为单位避免了对以4 为倍数的有效性检测。*/

      while (r < end && r->common.version == 2);

      if (r != end) {

          /* something wrong with packet format */

      }

 

A.3 确定期望收到的包和丢失的包的数量

为了计算丢包率,要知道从每个源中期望收到的RTP包和实际收到的RTP包的数量,可以使用每个源状态信息得到,源状态信息用指向struct source类型引用的指针来获得。收到的包的数量就是到达的包的数量,包括任何迟到或者复制的包。期望收到的包的数量可以用接收方收到的最大序列号(s->max_seq)和最低序列号(s->base_seq)的差计算。因为序列号只有16位,会溢出,有必要用s->cycles来扩展序列号的高位。收到的包和循环的数量由A.1RTP数据头有效性检验来保持。

                   extended_max = s->cycles + s->max_seq;

                   expected = extended_max - s->base_seq + 1;

丢包数:

                   lost = expected - s->received;

因为这个值使用24比特传播的,所以在等于0x7fffff时是正的丢失,在等于0x800000是负的丢失而不是越界。

在最后一个报告间隔(自前一个SRRR报告被发送)以来,丢失的包是用在这个间隔内期望收到的包和实际收到的包的差计算的,这个间隔内的expected_prior received_prior的值在前一个接收报告生成的时候就被保存了。

                   expected_interval = expected - s->expected_prior;

                   s->expected_prior = expected;

                   received_interval = s->received - s->received_prior;

                   s->received_prior = s->received;

                   lost_interval = expected_interval - received_interval;

                   if (expected_interval == 0 || lost_interval <= 0) fraction = 0;

                   else fraction = (lost_interval << 8) / expected_interval;

结果是一个八位定点数。

 

 

A.4 生成RTCPSDES

这个函数在缓冲区b中构造了一个SDES块,这个SDES由用数组类型提供的参数项,值和长度构成。它用指针b返回下一个可用的位置。

#define RTP_MAX_SDES 255      /* maximum text length for SDES */

typedef enum {

       RTCP_SDES_END   = 0,

       RTCP_SDES_CNAME = 1,

       RTCP_SDES_NAME  = 2,

       RTCP_SDES_EMAIL = 3,

       RTCP_SDES_PHONE = 4,

       RTCP_SDES_LOC   = 5,

       RTCP_SDES_TOOL  = 6,

       RTCP_SDES_NOTE  = 7,

       RTCP_SDES_PRIV  = 8

   } rtcp_sdes_type_t;

struct rtcp_sdes {

               u_int32 src;      /* first SSRC/CSRC */

               rtcp_sdes_item_t item[1]; /* list of SDES items */

           } sdes;

typedef struct rtcp_sdes rtcp_sdes_t;

typedef struct {

       u_int8 type;              /* type of item (rtcp_sdes_type_t) */

       u_int8 length;            /* length of item (in octets) */

       char data[1];             /* text, not null-terminated */

   } rtcp_sdes_item_t;

 

 

char *rtp_write_sdes(char *b, u_int32 src, int argc,

                        rtcp_sdes_type_t type[], char *value[],

                        int length[])

   {

       rtcp_sdes_t *s = (rtcp_sdes_t *)b;

       rtcp_sdes_item_t *rsp;

       int i;

       int len;

       int pad;

 

       /* SSRC header */

       s->src = src;

       rsp = &s->item[0];

 

       /* SDES items */

       for (i = 0; i < argc; i++) {

           rsp->type = type[i];

           len = length[i];

           if (len > RTP_MAX_SDES) {

               /* invalid length, may want to take other action */

               len = RTP_MAX_SDES;

           }

           rsp->length = len;

           memcpy(rsp->data, value[i], len);

           rsp = (rtcp_sdes_item_t *)&rsp->data[len];

       }

 

       /* terminate with end marker and pad to next 4-octet boundary */

       len = ((char *) rsp) - b;

       pad = 4 - (len & 0x3);

       b = (char *) rsp;

       while (pad--) *b++ = RTCP_SDES_END;

       return b;

   }

 

A.7 计算RTCP的传输间隔

         下面的函数按照& 6.2所描述的完成了RTCP的传输和接收规则。这些规则用一些函数进行编码:

         rtcp_interval() 计算了决定性的计算时间间隔,以秒为单位。

         OnExpire() RTCP传输时钟期满是被调用。

         OnReceive() 只要收到一个RTCP包,就调用。

OnExpire() OnReceive()都有一个事件e作为参数。e是参与者下一个预定事件,这个参与者是一个RTCP报告或者RTP包。假设一下的函数式可用的:

         Schedule(time t, event e) 计划一个事件e在时刻t时发生。当时刻t到来时,函数                       OnExpire作为一个参数和e一起被调用。

         Reschedule(time t, event e)

 

 

 

 

 

 

 

 

 

 

 

 

 


路过

鸡蛋
1

鲜花

握手

雷人

刚表态过的朋友 (1 人)

发表评论 评论 (2 个评论)

回复 Anthony 2012-8-10 21:29
不错啊,我们还真是用到rtp了,有空看看
回复 肖斐 2012-9-10 10:15
Anthony: 不错啊,我们还真是用到rtp了,有空看看
嗯,感谢同学的关注~~

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

返回顶部