RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )

RTCP 协议规范中定义了五种类型的 RTCP 包:接收⽅报告( RR )、发送⽅报告( SR )、源
描述( SDES )、成员管理( BYE )和应⽤程序定义( APP )。
SR: payload type=200
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

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第1张图片

版本号(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协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第2张图片

RTCPRR的格式:

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第3张图片

 每一个报告块(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位无 符号整数表示.

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第4张图片

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

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

I Si Ri D(i, i-1) J(i)
1 0 10 0 0
2 20 30 0 0
3 40 49 -1 0.0625
4 60 74 5 0.3711

最后一个发送者报告(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.

RTCPSR包的格式

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

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第5张图片

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)数据包,提供参与者认证和补充性细节,如位置、    电子邮件地址和电话号码。

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第6张图片

应用程序有可能生成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协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第7张图片

RTCP 释放连接(bye) : 成员控制

RTCP通过RTCP的Bye包为成员提供松散的控制,如果收到Bye表明某些参与者已经离开了 会话。Bye包是在参与者离开会话的时候,或者当其他参与者因为冲突而改变SSRC的时候 生成的。Bye包有可能会在传输过程中丢失,并且有些应用程序也不能生成此包。所以,即便没有收到Bye包,针对一段时间没有活跃的参与者,接收方应该有超时机制。

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

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第8张图片

 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)在最后一个包中被设置。

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第9张图片

重传NACK(RTPFB-FMT(1))

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

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

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第10张图片

反馈包作为⼀一个复合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行里。 

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第11张图片

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))

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第12张图片

FCI为空

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

SLI(PSFB-FMT(2))

。。。 

FIR(PSFB-FMT(4))

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第13张图片

 当解码端需要刷新时,可以发送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?

  1. SDP 中包含如下属性
a=rtcp-fb: goog-remb
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第14张图片

 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

例子:

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第15张图片

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包格式定义

RTCP协议详解(SR、RR、SDES、BYE、APP、NACK、TCC、PLI、SLI、FIR )_第16张图片

  • base sequence number:2字节,TransportFeedback包中记录的第一个RTP包的transport sequence number,在反馈的各个TransportFeedback RTCP包中,这个字段不一定是递增的,也有可能比之前的RTCP包小
  • packet status count:2字节,表示这个TransportFeedback包记录了多少个RTP包信息,这些RTP的transport sequence numberbase sequence number为基准,比如记录的第一个RTP包的transport sequence numberbase sequence number,那么记录的第二个RTP包transport sequence numberbase 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。格式如下:

       0                   1

       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |T| S |       Run Length        |

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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

下面举例子说明下。

       0                   1

       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

      |0|0 0|0 0 0 0 0 1 1 0 1 1 1 0 1|

      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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

Status Vector Chunk

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

        0                   1

        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

       |T|S|       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个包的状态

2

3

4

5

        0                   1

        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

       |1|0|0 1 1 1 1 1 0 0 0 1 1 1 0 0|

       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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

1

2

3

4

5

        0                   1

        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

       |1|1|0 0 1 1 0 1 0 1 0 1 0 0 0 0|

       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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包才添加到达时间信息,而且是通过时间间隔的方式记录到达时间。

你可能感兴趣的:(编解码,音视频,音视频,rtcp,nack,remb,rtx)