描述( SDES )、成员管理( BYE )和应⽤程序定义( APP )。

SR: payload type=200

RTCP协议详解SRRRSDESBYEAPPNACKTCCPLISLI 休闲娱乐

RR:payload type=201

SDES: payload type=202

BYE:payload type=203

APP:payload type=204

RTPFB:payload type=205

PSFB:payload type=206

RTCP_RTP_FB_NACK_FMT(1): NACK重传, type-205

RTCP_RTP_FB_RTX_FMT(1):RTX重传,type-205

RTCP_RTP_FB_CC_FMT(15):Transport-cc 带宽估计,type-205

RTCP_PLI_FMT(1): picture重传, type-206

RTCP_SLI_FMT(2): Slice重传, type-206

RTCP_FIR_FMT(4): 关键帧重传, type-206

RTCP_REMB_FMT(15): 带宽估计, type-206

版本号(V):对付当前版本的RTP协议,版本号为2(截止到本书编纂为止),目前还 没有推出新版本的操持,并且之前的版本并没有广泛的被利用.

添补(P):添补位表示,所要添补的数据已经超出了目前所能容纳的位数。
如果此位 被设置为1,那么意味着包尾已经被一个或多个八位字节添补,末了一位八位所添补的 内容表示此包的总数大小。

条款计数(IC):某些包类型中包含了一个list的条款,可能作为固定的、用于特定类 型的信息的补充。
这些条款字段须要标示出包中包含的条款标总数(这个字段在不同的 包中有不同的命名方法,这取决于详细如何利用此字段)。
每个RTCP包最多包含31个 条款,同时也受到MTU(maximum transmission unit)的限定。
如果须要传输超过31 个条款标场景,那么运用程序必须天生多个RTCP包。
Item Count字段为0的时候表示此包中的条款为空(但是并不意味着包中内容为空)。
如果不须要Item count字段那么此字段可以用于其他的目的。

包类型(PT):此字段标识了传输的包中所携带的信息的类型。
在RTP的规范中定义了 五种标准数据包类型,将来可能还会定义其他的类型(例如,报告额外统计信息或者传 递其他特定源的信息)。

长度:此字段标识包头之后的内容总长度。
由于所有的RTCP的数据包的长度必须为32 位的整数倍,以是这个字段放的是32位字的个数,由于如果按照八位字节打算会涌现 此字段和总长度不同等的情形。
0是一个有效长度,表示这个包只包含4个8位字节的包 头(包头字段IC在这种情形下也是0)。

RTCP包中复合包的构造

RTCP中RR的格式:

每一个报告块(report block)都是描述单个同步源的吸收质量,而报告者(reporter)从当前报告的间隔期间,吸收从该同步源发过来的RTP包。
每一个RTCP的RR包统共有31个报告 块。
如果有超过31个激活的发送者,那么吸收者该当在一个复合数据包中发送多个RR数据包,每个报告块有7个字段,统共24个字节。

Reportee(被报告者)SSRC标识此报告块干系的参与者。
报告块中的统计数据,表示的是在天生RR数据包的参与者处,被报告方吸收到的同步源的数据包的吸收质量。

丢包率(loss fraction)的定义是在这个报告间隔中所丢失包的数量,除以预期到达的数量。
丢包率表示为一个定点数,该定点数的二进制小数点位于字段的左边缘。
即丢包率乘 以256后的整数部分(即如果传输中有1/4的包丧失落,那么丢包率该当是1/4 256 = 64). 如果吸收到的包的数量大于预期(由于存在重复包的情形),使得丢包数为负值,那么丢 包的部分设置为0.

累计丢包数是一个24位带符号的整数,它表示预期该当到达的包的数量,减去实际吸收到 的包的数量。
预期的包数的定义是,末了吸收到的扩展序列号,减去吸收到的初始序列号。
吸收到的包的总数包括任何延迟到达或者重传过来的包,因此可能会大于预期的数量,因此累计丢包数有可能是负值。
累计丢包数的打算区间是统计的全体会话期间的,而不是在每个间隔期间。
如果在会话期间丢包的总数大于0x7FFFFF,那么此字段会在0x7FFFFF处于最大饱和值。

理论打算办法, packet lost = 期待得到报文数量 - 实际收到报文的数量。

实际打算办法, packet lost = 期待收到最新sequence - 第一次收到报文的sequence。

在同步源的RTP数据包中吸收到的扩展最高序列号(extended highest sequence number) 的打算,由于可能存在包重新排序的情形,以是并不一定是吸收到的末了一个RTP包的扩展序列号。
扩展序列号是 基于会话打算的,而不是基于包间隔打算的。

extended_seq_num = seq_num + (65536 wrap_around_count)

个中wrap_around_count为sequence翻转的次数

到达间隔抖动(Interarrival jitter)是对被报告者(Reportee)同步源发送的数据包的网络传输韶光统计方差的估计。
它因此韶光戳单位衡量的,因此它像RTP韶光戳一样用32位无 符号整数表示.

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

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

末了一个发送者报告(last sender report,LSR)韶光戳是64位NTP(网络韶光协议(Network Time Protocol))格式的韶光戳中间的32位,包含在最近从被报告者的SSRC吸收到的RTCP的SR包中。
如果SR没有收到,那么此字段可以设置为0.

自上次发送者报告起的延迟(delay since last sender report,DSLR)是从被报告者SSRC吸收到末了一个SR数据包到发送此吸收报告块之间的延时,以1/65,536秒为单位。
如果没从 该被报告者收到SR,则DLSR字段设置为0.

发送方可以利用LSR和DLSR字段来打算它与每个吸收方之间的来回韶光(rtt)。
当吸收到 一个与之干系的RR包时,发送方用当前的韶光减去LSR字段,以得到发送SR到吸收此RR之 间的延迟。
发送方然后再减去DLSR字段以肃清吸收方延迟带来的偏移,从而得到网络来回韶光。

RTT=NTP-LSR-DLSR.

领取音视频开拓学习资料:音视频开拓(资料文档+视频教程+口试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

RTCP中SR包的格式

发送者报告的包类型为200,有效负载包含一个24字节的发送者信息 块,后面随着0个或多个吸收方报告块,由RC字段标识,类似于吸收方报告报。
当发送者 也是接管方的时候,吸收方报告块就涌现了.

NTP韶光戳是一个64位的无符号值,表示发送这个RTCP SR包的韶光。
它的格式是NTP韶光戳,韶光从1900年1月1日开始打算秒,低32位代表秒的小数部分(fractions of second)

(也便是64位定点值,二进制小数点位于32位之后)。
如果要将UNIX的韶光戳(从1970 年1月1日开始的秒数)转化为NTP韶光,那么须要添加2,208,988,800秒。

RTP韶光戳与NTP韶光戳的对应的韶光是相同的,但是,它因此RTP媒体时钟的基准单位表 示的。
这个值,常日与前一个数据包的RTP韶光戳不同,由于自该数据包中的数据被采样 已经经由了一段韶光了。

发送方的包计数,是这个同步源自会话开始以来,天生的数据包的总数。
发送方的字节计 数是这些数据包的有效负载(playload)中包含的字节数(不包括包头或者添补)。
如果发送方改变其SSRC(例如,由于产生冲突),则会重置发送方的包计数以及字节计数 字段。

RTCP SDES:源描述(Source Description)

RTCP也可以用来通报源描述(SDES)数据包,供应参与者认证和补充性细节,如位置、 电子邮件地址和电话号码。

运用程序有可能天生SDES项为空列表的包,在这种场景下,RTCP公共包头中的SC和length 字段都为0.在正常情形下,SC该当为1(混流器(mixers)和转换器(translators)所聚拢 的转发信息产生的包会有较大的SDES项的列表)。

每个SDES项中的条款都因此连续的办法打包到包中,没有分隔或者添补。
条款列表(list of item)以一个或者多个空的字节结束,当解析到第一个字节为0类型的时候,意味着这个列 表结束。
0类型字节后面不会跟长度字节,但是如果须要添补,则包括其他的空字节,直到 达到32-bit边界为止。
这个添补(padding)与RTCP包头中的P位表示的添补是分开的。
带 有零项的列表(四个空字节)是有效的,但是没故意义。

CNAME项(type = 1)为每个参与者供应了一个规范名称(CNAME)。
它供应了一个独立于同步源的稳定且持久的标识符(由于如果运用程序重启或发生SSRC冲突,SSRC将改 变)。
CNAME可以用于关联来自不同RTP会话的参与者的多个媒体流(例如,关联须要同 步的语音和视频),以及在媒体工具重启时命名参与者。
这是唯一的逼迫性的SDES条款, 所有实现都须要发送SDES CNAME项。

RTCP 开释连接(bye) : 成员掌握

RTCP通过RTCP的Bye包为成员供应疏松的掌握,如果收到Bye表明某些参与者已经离开了 会话。
Bye包是在参与者离开会话的时候,或者当其他参与者由于冲突而改变SSRC的时候 天生的。
Bye包有可能会在传输过程中丢失,并且有些运用程序也不能天生此包。
以是,即便没有收到Bye包,针对一段韶光没有生动的参与者,吸收方该当有超机遇制。

RTCP BYE包不会终止参与者之间的任何其他关联关系。
Bye包的标识类型为203,公共的RTCP包头中的RC字段表示SSRC标 识符的数量。
其存在为0的可能性,标识为0时无用。
在吸收到Bye包时,实现时该当假设 此源已经离开了会话,并忽略来自该源的任何后续的RTP和RTCP包。
最主要的是,当收到Bye包之后,须要为此参与者保留一段韶光的连接状态,由于要许可延迟到达的数据包被吸收到。

Bye包还可能包含了表示离开会话缘故原由的文本,适宜在用户界面中显示。
但是,这个文本是可以选填的,在实现过程中我们须要去吸收它(纵然文本可能会被忽略)。

RTCP APP:运用程序定义的RTCP包

末了一类RTCP包(APP)许可运用程序来自己定义扩展。
它的包类型为204,由4个字符组成唯一的标识,每个字符都得从ASCII字符集中选择,并区分大小写。
建议选择包名称来匹配它所代表的运用程序,并由运用程序来折衷子类型值的选 择。
包别的部分被用于运用程序的特定需求。

运用程序自定义的包用于RTCP的非标准扩展和验证新特性。
目的是,验证者首先利用APP 来验证新特性,然后如果新特性有广泛的用场,那么就注册为新的包类型。
一些运用程序 天生的包或实现方案,该当忽略识别不出来的运用程序包。

组包(Packing)问题

RTCP包不会单独发送,而是组包成一个复合数据包进行传输。
天生复合RTCP包的参与者是生动的数据发送方,那么该复合包必须以RTCP SR包开始。
否则必须从RTCP RR包开始。
纵然还没有发送或吸收数据,这也是精确的,在这种情形下,SR/RR包不会包含吸收方的报告块(包头字段RC为0)。
另一方面,如果从多个源吸收数据,并且报告太多,导致无法放入一个SR/RR包,则复合后的数据应以一个SR/RR包开始,后面在随着多个RR包。
跟在SR/RR包后面的是一个SDES包。
这个包必须包含一个CNAME条款。
它可能包含其他的 条款。
包含其他(非CNAME)SDES条款标频度由利用中的RTP配置文件决定。

Bye包必须做为末了一个数据包发送。
要发送的其他RTCP包可以按 任何顺序。
这些严格的排序规则,旨在使数据包的校验更容易,由于缺点定向的数据包, 大概率不会知足这些约束。

在天生复合RTCP包时,一个潜在的问题便是如何处理大量生动发送者的会话。
如果存在超 过31个生动的发送者,那么有必要在复合包中增加额外的RR包。
这可以根据须要重复此过 程,直到达到MTU的上限。
如果发送方太多,甚至于吸收方报告不能被MTU容纳,则必须 忽略某些发送方的吸收报告。
如果涌现这种情形,那么被忽略的报告,该当在天生的下一 个复合包中被包含(哀求吸收方跟踪每个间隔中报告的源)。

有时候须要将一个复合RTCP包添补并超出其原始大小。
在这种场景下,添补只是添加到复 合包中的末了一个RTCP包中,P位(P bit)在末了一个包中被设置。

重传NACK(RTPFB-FMT(1))

重传要求须要两个步骤:须要为重传要求定义数据包格式,并且必须修正时序规则以许可⽴立即反馈。

否定应答(NACK)的格式如图9.11所示。
NACK包含⼀一个表示丢包的包标识符和⼀一个位图,该位图显示以下16个包中的哪⼀一个丢失了了,值为1表示丢失。

反馈包作为⼀一个复合RTCP包的⼀一部分发送,其⽅办法与所有其他RTCP包相同。
它们放在复合包的末了,在SR/RR和SDES项之后。

RTX重传

PT=205,FMT=1 和 NACK 一样

1、rtx 在sdp中的表示:

a=rtpmap:97 rtx/90000

a=fmtp:97 apt=96

a=ssrc-group:FID ssrc rtxssrc

97 为rtx负载类型,90000为时钟频率,一样平常和要重传的包的时钟频率相同。

a=fmtp:97 apt=96 表示 负载类型为97的rtx包重传的是负载类型为96包。

a=ssrc-group:FID ssrc rtxssrc 将rtx包的ssrc与重传包的ssrc关联起来。

其余,97 rtx负载类型必须涌如今sdp的对应m行里。

Original Rtp Packet Payload为要重传包的负载数据,OSN为原始包的sequence number,Rtp Header除了Ssrc、负载类型和rtx的sequence number外,别的部分与原始包相同。

Rtx事理:重发的包封装到RTX包里发送,RTX包与原RTP有不同的SSRC,不同的rtpseq,但是timestamp与丢失包的韶光戳相同。

Rtx上风:rtp重传包在带宽估计时不计入运算,利用rtx比较方便,不该用rtx统计丢包率有时会涌现负值

Rtxpayload:前两个字节代表丢失包的rtp seq,因此rtx包比丢失的rtp包多2个字节

临时最大码率要求TMMBR(RTPFB-FMT(3))

webRTC中被废弃

临时最大码率关照TMMBR(RTPFB-FMT(4))

对TMMBR的相应

webRTC 中被废弃

PLI(PSFB-FMT(1))

FCI为空

PLI用于解码端关照编码端我要解码的图像的编码数据丢失了。
对付基于帧间预测的视频编码类型,编码端收到PLI就要知道视频数据丢失了,由于帧间预测须要基于前后完全的视频帧才能解码(例如H264中,存在B帧,须要参考前后帧才能解码),前面的数据丢失了,后面的视频帧不能正常解码出图像,此时编码端可以直接天生一个关键帧,然后发送给解码端。

SLI(PSFB-FMT(2))




FIR(PSFB-FMT(4))

当解码端须要刷新时,可以发送FIR给编码端,编码端此时发送关键帧,刷新解码端。
这有点类似PLI,但是PLI是用于丢包情形下的关照,而FIR却不是,在有些非丢包情形下,FIR就要用到。
举两个例子:

1)解码端须要切换到另一起不同视频时,由于须要新的解码参数,以是可通过发送FIR,关照编码端天生关键帧,获取新的解码参数,刷新视频解码器;

2)在视频会议中,新用户随机时候加入,各个编码端发送的视频不一定都是关键帧,以是新用户不一定能正常解码。
此时该新加入用户发送FIR,关照各个编码端给它发关键帧,获取关键帧后即可正常解码。

REMB(PSFB-FMT(15))

它描述了一个绝对值韶光戳选项,用于带宽估计。
该反馈用于关照一个在同一RTP会话上有多个媒体流的发送方, 关照它在该RTP会话的吸收方路径上的总的估计可用比特率。

在用于反馈的公共数据包头中(如[RFC4585]的6.1节所定义),“数据包发送者的SSRC” 字段指示关照的来源。
不该用“媒体源的SSRC”,并且应将其设置为0。
在其他RFC中也利用零值.

媒体发送方对符合此规范的REMB的吸收将导致该在RTP会话上发送的总比特率即是或低于其中的比特率。
新的比特率限定应尽快运用。
发送者可以根据自己的限定和估计自由运用其他带脱期制。

How 怎么实现 REMB?SDP 中包含如下属性

a=rtcp-fb:<payload type> goog-remba=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time

V=2 P=0 FMT=15 PT=206 SSRC of media source=0

unique identifier ='R' 'E' 'M' 'B'

同步源的个数NUM SSRC:

带宽的指数BR EXP:

带宽的底数BR Mantissa:

所反馈的SSRC 一个或多个值 SSRC feedback (32 bits) Consists of one or more SSRC entries which this feedback message applies to.

receiver-bit-rate = mantissa 2^exp

例子:

Transport-CC(RTPFB-FMT(15))

Transport-cc指的是Transport-wide Congestion Control。
WebRTC最新的拥塞掌握算法(Sendside BWE)基于Transport-cc,吸收端记录数据包到达韶光,布局干系RTCP包,然后反馈给发送端,在发送端做带宽估计,从而进行拥塞掌握.WebRTC中为了利用Transport-cc,须要用到RTP报头扩展以及增加新的RTCP类型。
这里我们先容下Transport-cc中的RTP以及RTCP。

报文格式

Transport-cc中,收流客户端通过TransportFeedback RTCP向发送端反馈收到的各个RTP包的到达韶光信息。
首先我们看下TransportFeedback包格式定义

base sequence number:2字节,TransportFeedback包中记录的第一个RTP包的transport sequence number,在反馈的各个TransportFeedback RTCP包中,这个字段不一定是递增的,也有可能比之前的RTCP包小

packet status count:2字节,表示这个TransportFeedback包记录了多少个RTP包信息,这些RTP的transport sequence number以base sequence number为基准,比如记录的第一个RTP包的transport sequence number为base sequence number,那么记录的第二个RTP包transport sequence number为base sequence number+1

reference time:3字节,表示参考韶光,以64ms为单位,RTCP包记录的RTP包到达韶光信息以这个reference time为基准进行打算

feedback packet count:1字节,用于计数发送的每个TransportFeedback包,相称于RTCP包的序列号。
可用于检测TransportFeedback包的丢包情形

packet chunk:2字节,记录RTP包的到达状态,记录的这些RTP包transport sequence number通过base sequence number打算得到

recv delta: 8bits,对付"packet received"状态的包,也便是收到的RTP包,在recv delta列表中添加对应的的到达韶光间隔信息,用于记录RTP包到达韶光信息。
通过前面的reference time以及recv delta信息,我们就可以得到RTP包到达韶光

packet chunk

首先先理解下RTP包状态,目前定义了如下四种状态,每个状态值2bits,用来标识RTP包的到达状态,以及与前面RTP包的韶光间隔大小信息:

00-Packet not received

01-Packet received, small delta

10-Packet received, large or negative delta

11-[Reserved]

packet chunk有两种类型,Run length chunk(行程长度编码数据块)与Status vector chunk(状态矢量编码数据块),对应packet chunk构造的两种编码办法。
packet chunk的第一bit标识chunk类型。

这里先来理解下Run length(行程长度)编码。
Run length编码是一种大略的数据压缩算法,其基本思想是将重复且连续涌现多次的字符利用“连续涌现次数+字符”来描述,例如:aaabbbcdddd通过Run length编码就可以压缩为3a3bc4d。
Run length chunk中就利用了Run length编码标识连续多个相同状态的包。

Run length chunk第一bit为0,后面随着packet status以及run length。
格式如下:

hunk type (T):1 bit,值为0packet status symbol (S):2 bits,标识包状态run length (L):13 bits,行程长度,标识有多少个连续包为相同状态

下面举例子解释下。

packet status为00,由前面包状态可知为"Packet not received"状态,run lengh为221(11011101),解释连续有221个包为"Packet not received"状态。

Status Vector Chunk

第一bit为1,后面随着symbol size以及symbol list。
格式如下:

chunk type (T):1 bit,值为1

symbol size(S):1 bit,为0表示只包含"packet not received" (0)以及"packet received"(1)状态,每个状态利用1bit表示,这样后面14bits的symbol list能标识14个包的状态。
为1表示利用2bits来标识包状态,这样symbol list中我们只能标识7个包的状态

symbol list:14 bits,标识一系列包的状态, 统共能标识7或14个包的状态

symbol size为0,这样能标识14个包的状态。
第一个包状态为"packet not received"(0),接着后面5个包状态为"packet received"(1),再接着三个包状态为"packet not received",再接着三个包状态为"packet received",末了两个包状态为"packet not received"。

symbol size为1,这样只能标识7个包的状态。
第一个包为"packet not received"(00)状态,第二个包为 "packet received, w/o timestamp"(11)状态,再接着三个包为"packet received"(01)状态,末了两个包为"packet not received"(00)状态。

Receive Delta

以250us(0.25ms)为单位,表示RTP包到达韶光与前面一个RTP包到达韶光的间隔,对付记录的第一个RTP包,该包的韶光间隔是相对reference time的。

如果在packet chunk记录了一个"Packet received, small delta"状态的包,那么就会在receive delta列表中添加一个无符号1字节长度receive delta,无符号1字节取值范围[0,255],由于Receive Delta以0.25ms为单位,故此时Receive Delta取值范围[0, 63.75]ms

如果在packet chunk记录了一个"Packet received, large or negative delta"状态的包,那么就会在receive delta列表中添加一个有符号2字节长度的receive delta,范围[-8192.0, 8191.75] ms

如果韶光间隔超过了最大限定,那么就会构建一个新的TransportFeedback RTCP包,由于reference time长度为3字节,以是目前的包中3字节长度能够覆盖很大范围了

以上解释总结起来便是:对付收到的RTP包在TransportFeedback RTCP receive delta列表中通过韶光间隔记录到达韶光,如果与前面包韶光间隔小,那么利用1字节表示,否则2字节,超过最大取值范围,就另起新RTCP包了。

对付"Packet received, small delta"状态的包来说,receive delta最大值63.75ms,那么一秒韶光跨度最少能标识1000/63.75~=16个包。
由于receive delta为250us的倍数,以是一秒韶光跨度最多能标识4000个包。

packet chunk以及receive delta的利用是为了尽可能减小RTCP包大小。
packet chunk用到了不同编码办法,对付收到的RTP包才添加到达韶光信息,而且是通过韶光间隔的办法记录到达韶光。