手撕RTSP协议系列(13)——RTCP协议

时间:2024-04-04 18:16:19

 

RTCP简介  

之前的文章,介绍了RTSP和RTP协议,RTSP用于建立连接及发送请求等,RTP用于实际的媒体数据传输。整个RTSP的流程中,还有一种不可或缺的协议, 那就是RTCP。RTCP的全称是RTP Control Protocol,从英文名称可以看出,其是针对RTP的控制协议!RTCP主要用于提供数据分发质量反馈信息,本文详细介绍一下RTCP协议!

 

数据包格式 

首先,让我们来看一下RTCP的数据包格式,如下图:

 

手撕RTSP协议系列(13)——RTCP协议

对照示意图,可以看到如下字段,下面做详细解释:

V(2bit):Version,表示RTCP版本号,当前规范定义的版本号为2,需要注意的是RTP数据包中的版本号与RTCP数据包的中的版本号是一致的

P(1bit):填充位,表示是否需要填充,0表示不填充,其不属于控制信息。在某些情况下(如加密)需要进行填充,在填充的情况下,Padding的最后一个字节用于计算应该忽略多少个字节!

RC(5bit)  : 接收方报告计数,表示在该数据包中的接收方报告块的数量,该字段0值是有效的,但没有实际意义!

PT(8bit) : RTCP的数据包的分组类型,RTCP包含的分组类型如下:

类型

缩写表示

意义

200

SR(Sender Report)

发送端报告

201

RR(Receiver Roport)

接收端报告

202

SDES(Source Descripition Items)

源点

203

BYE

结束

204

APP(Application)

特定应用

    • BYE分组为结束分组,表示关闭一个数据流;

    • APP分组为特定应用分组,使应用程序能够自定义新的分组类型;

    • SDES分组为源描述分组,其作用是给出参加会话者的描述;

    • SR分组为发送端报告分组:发送端每发送一个RTP数据包,就要发送个一个发送端报告分组SR;

    • RR为接收端分组报告,接收端分组报告 ,每收到一个RTP流,就产生一个RR分组。

 

length(16bit):RTCP数据包的大小。该字段中大小的表示比较有意思,使用4个字节为1组,长度共有几个4个字节的组,然后用该长度减去1,即为RTCP包中的长度!举个栗子:假设RTCP数据包的长度为32个字节,32/4=8,总共有8组4个字节,8-1=7,此时RTCP数据包中length的值为7。

SSRC(32bit):   同步源标识

RR:Recevier Report,接受端报告。

SS:Source Description,源描述。

这样,我们对RTCP报文的整体结构就比较了解了!上一个抓包文件,我们就会更直观的感受了!

 

手撕RTSP协议系列(13)——RTCP协议

通过抓包文件我们可以看到,RTCP包是应用层协议,截图中的RTCP包是基于UDP协议的!抓包中红色部分为RTCP数据包的头部分,蓝色部分为Receive Report的具体内容,绿色部分为源描述的具体内容!

 


下面,我们来详细看一下Send Report,Recive Report和Source Description的结构,首先来看Send Report!

 

SS(Send Report) 

手撕RTSP协议系列(13)——RTCP协议

通过结构图,可以看到Sender Report有以下字段:

NTP时标:NTP时间戳

RTP时标:RTP时间戳

发送者包计数:从开始传输到当前SR包生成的时间段内,发送端发送的RTP数据包的总个数!如果发送者更改其SSRC,则该计数要被重置

发送者数据8位组计数:从开始传输到当前SR包生成的时间段内,发送端发送的总的数据的大小的八位组计数,不包含头信息以及填充信息!如果发送者更改可SSRC,需要重置该值!该字段可以用来估计平均码率!

 

来看一个抓包

手撕RTSP协议系列(13)——RTCP协议


 

RR(Receiver report)

继续看一下Receiver Report的结构:

手撕RTSP协议系列(13)——RTCP协议

通过结构,可以看到如下信息:

SSRC(32bit): 发送端的信源标识符,与发送端的SSRC一致。

丢包数8(8bit):前一个SR或RR包发送后,到当前的SR包或RR包的间隔内,来自源(用源SSRC标识)发送的数据包的丢失个数

累积丢包数(24bit): 自开始接受源(用源SSRC标识)发送的数据开始,累积丢失的数据包的个数

扩展包序号(32bit):低16位为当前接收到的来自源的(用源SSRC标识)数据包的最大***;高16位表示RT包***的循环计数!我们都知道RTP数据包中,表示***的长度为2个字节,即最大的RTP***为65536,如果***超了65536,假设为655537,这个时候RTCP在扩展包序号中对其说明,如果没有超过65536,则高16位为0,如果超过65536,则为1,如果再来一圈,则为3。做个不恰当的比喻,我们跑步一圈为65536,高16位表示我们当前正在跑第几圈,从0开始计数!

间隔抖动(32bit):RTP数据包间隔时间的统计估计,以时间戳为单位,用无符号整数表示!

LSR(32bit):last SR timestamp,表示上一个SR数据包的NTP时间戳!由于NTP时间戳为64bit,LSR为32bit,LSR取上一个SR的NTP时间戳的中间32位:如上一个SR数据包的NTP时间戳为“0x 00 01 7d 6e 3b 64 5a 1c ”,则LSR为0x  7d 6e 3b 64! 

DLSR(32bit):发送当前RR包的时间与上一个SR之间的时间间隔,以1/65536为单位,如,本次RR包与上一次SR的时间间隔为264ms,则本字段的值为0.264*65536=17301.54。

 

来看一个抓包文件:

手撕RTSP协议系列(13)——RTCP协议

该抓包文件中的丢包数为0,累积丢包数为57,扩展的包序号为7070,间隔抖动为26,SR和DLSR均为0。


 

SS(source description) 

接下来,我们看下Source Description:

手撕RTSP协议系列(13)——RTCP协议

通过结构图,我们可以看到Source Description分组,也可以叫做SDES的组织结构是按照KLV的格式组织的,key表示具体的类型,length为长度,value为具体的值, key占用1个字节, length占用1个字节!RTCP中可选的KEY如结构图中所列,有如下几种:

CNAME(值为1):  规范终端标识,像SSRC标识,CNAME标识在RTP连接的所有参加者中应是唯一的;

NAME(值为2): 用户名称,用于描述源的用户名;

E-mail(值为3): 电子邮件地址,用于描述源的邮件地址,格式如 [email protected]

PHONE(值为4): 用于描述源的电话号码;

LOC(值为5): 用于描述源的地理位置;

TOOL(值为6): 用于描述应用或工具的名称,表示产生流的应用的名称与版本,如"videotool 1.2";

NOTE(值为7): 用于描述源当前状态的过渡信息;

PRIV(值为8): 用于描述针对源的扩展项;

 

看一个抓包:

手撕RTSP协议系列(13)——RTCP协议

通过抓包,我们可以看到该描述中包含一个CNAME的字段,长度为7,值为“DELL-PC”。


RTCP中通过Sender Report和Receive Report在RTP数据传输中提供当前连接中RTP包发送的情况,RTP包接收的情况,RTP包丢失的情况,通过这些信息反馈,我们可以实现对网络传输做一些调整和控制!这就是RTCP的主要功能!

 

结语 

写到这里,关于RTSP传输的三大协议就都熟悉了!RTSP发起或停止连接,以及在连接的过程中控制流媒体数据的行为,如play,scale等,RTP负责数据传输,RTCP负责信息反馈!如此,基于RTSP的流媒体传输就完整建立起来了!那么关于rtsp的专题也可以告一段落了!期待下一个专题吧!感谢朋友们的支持!

 

 

手撕RTSP协议系列(13)——RTCP协议

扫码关注了解更多,还有交流群哦

手撕RTSP协议系列(1)——Rtsp基本流程

手撕RTSP协议系列(2)——Rtsp消息格式

手撕RTSP协议系列(3)——sdp格式详解

手撕RTSP协议系列(4)——OPTION

手撕RTSP协议系列(5)——DESCRIBE

手撕RTSP协议系列(6)——SETUP

手撕RTSP协议系列(7)——PLAY

手撕RTSP协议系列(8)——PAUSE

手撕RTSP协议系列(9)——TEARDOWN

手撕RTSP协议系列(10)——GET_PARAMETER

手撕RTSP协议系列(11)——RTSP_SET_PARAMETER

手撕RTSP协议系列(12)——RTP包格式