音视频流媒体开发【七十三】- RTSP流媒体8-RTCP详解
音视频流媒体开发-目录
iOS知识点-目录
Android-目录
Flutter-目录
数据结构与算法-目录
uni-pp-目录
RTCP功能
Real-time Transport Control Protocol或RTP Control Protocol或简写RTCP)是实时传输协议(RTP)的⼀个姐妹协议。RTCP由RFC 3550定义(取代作废的RFC 1889)。RTP 使⽤⼀个 偶数 UDPport ;⽽RTCP 则使⽤ RTP 的下⼀个 port,也就是⼀个奇数 port。RTCP与RTP联合⼯作,RTP实施实际数据的传输,RTCP则负责将控制包送⾄电话中的每个⼈。其主要功能是就RTP正在提供的服务质量做出反馈。
RTCP报⽂封装在UDP中进⾏传输,作⽤如下:
- 质量反馈
- 传输层标识(CNAME)
- 给参与者发送RTCP控制报⽂
- 最⼩会话控制消息(可选)
RTCP端⼝号 = RTP端⼝号 + 1
RTCP报⽂格式--报⽂类型
在RTP的规范(RFC 3550)中,⼀共定义了5种RTCP报告⽤来报告当前控制信息:
RTCP的5种报告:RR,SR,SDES,BYE和APP。他们使⽤共同的结构,但是在某些具体的地⽅有⼀些不同。
以下是RTCP报⽂基本结构:
其中⽐较重要的⼏个域及其意义如下:
header size = 2 + 1 + 5 +8 + 16 = 4个字节
SR 包,总共28字节 = header 4字节 + 4字节*6
typedef struct _rtcp_header_t{
uint32_t v:2; // version
uint32_t p:1; // padding
uint32_t rc:5; // reception report count
uint32_t pt:8; // packet type
uint32_t length:16; /* pkt len in words, w/o this word */
} rtcp_header_t;
RTCP报⽂格式-- SR报⽂格式
为了补充接收者报告,RTP协议还规定了最近发送数据的参与者发送SR,该报告提供了发送的媒体的⼀些信息。主要⽤于接收端同步多媒体流,如语⾳和视频流。
其中域及其意义如下:
typedef struct _rtcp_sr_t // sender report{
uint32_t ssrc;
uint32_t ntpmsw; // ntp timestamp MSW(in second)
uint32_t ntplsw; // ntp timestamp LSW(in picosecond)
uint32_t rtpts; // rtp timestamp
uint32_t spc; // sender packet count
uint32_t soc; // sender octet count
} rtcp_sr_t;
以下是SR报⽂的实例:
RTCP报⽂格式-- RR报⽂格式
RTCP通过RR可以很好地保证传输质量,每个接收数据的参与者都要发出RR。
其中PT定义为201。接收者报告包含发送者的SSRC,跟随在由RC指定的(0个或多个)报告块之后。
其中域及其意义如下:
typedef struct _rtcp_rr_t // receiver report
{
uint32_t ssrc;
} rtcp_rr_t;
typedef struct _rtcp_rb_t // report block
{
uint32_t ssrc;
uint32_t fraction:8; // fraction lost
uint32_t cumulative:24; // cumulative number of packets lost
uint32_t exthsn; // extended highest sequence number received
uint32_t jitter; // interarrival jitter
uint32_t lsr; // last SR
uint32_t dlsr; // delay since last SR
} rtcp_rb_t;
- 丢包率计算:表示⽅式:分⺟固定为256,分⼦是loss fraction表示的整数。所以如果想要表示1/4的报⽂丢失,那么loss fraction=64。
- 丢包数量计算:cumulative number of packets lost不是以每个周期为计算范围,⽽是以整个会话为计算范围。所以0x7fffff是cumulative number of packets lost的最⼤值,因为它是带符号整数。
- 扩展⾼位序列号:随着会话时间增⻓,16⽐特⻓度的序列号可能会不够⽤,当序列号⼜回到初始化序列号时,为了表示这个环绕,在⾼16⽐特记录环绕的次数,也就是把序列号扩展了。
RTCP报⽂格式-- RR报⽂实例
RTCP报⽂格式-- SDES报⽂格式
lRTCP还可以通过传输SDES来详细描述源,如标识和⼀些辅助信息(地理位置,电话号码以及Email地址等信息)。⼀般来说SDES数据由⽤户输⼊,显示在应⽤的图形界⾯上。
-
⼀般来说SDES列表(list of SDES items)以被描述的源的SSRC开始。跟随⼀个或者多个描述项,描述项格式如下图:
- 如果描述项的type=1,那么该描述称为CNAME item,为每个参与者提供了规范名(canonical name)。
- 这个规范名是稳固的永久的标识,独⽴于同步源标识。CNAME能同时⽤于⼀个参与者的多个会话。
- CNAME是唯⼀⼀个强制实现的SDES item,所有实现必须实现该描述。
RTCP报⽂格式-- SDES报⽂实例
SR的SDES报⽂案例
image.pngRR的SDES报⽂案例
RTCP报⽂格式-- BYE报⽂格式
RTCP协议可以通过BYE分组进⾏⾃由的成员控制,RTCP BYE标识离开会话的成员,或者成员改变SSRC。BYE分组可能在传输中丢失,⽽且应⽤实现不会再次产⽣BYE分组。所以接收者应该准备好对某些⽤户超时,⽽且没有接收到BYE分组。
以下是BYE的报⽂实例
RTCP报⽂格式-- APP报⽂格式
APP数据报⽂允许应⽤定义扩展。APP分组⽤来进⾏⼀些⾮标准RTCP扩展,或者进⾏⼀些新特性的试验,等到试验成熟,就可以注册成⼀种新的类型。应⽤实现对不认识的APP应该予以忽略。
image.pngRTCP报⽂格式-- APP报告实例
Application-defined packet name使⽤4个字符的标识符,唯⼀标识这个扩展。每个字符使⽤ASCII编码格式,区分⼤⼩写。
RTSP play同步
RTP 包中的时间戳字段是说明数据包时间的同步信息,是数据能以正确的时间顺序恢复的关键。时间戳的值给出了分组中数据的第⼀个字节的采样时间。为了计算各个数据流的播放时间以及同步处理,仅有 RTP包中的时间戳信息是不够的。
在整个播放过程中,包括这样⼏种时间:
- RTP 包中的 rtptime
- PLAY 请求的 Response 中的 rtp time 和 npt
- RTCP 的 SR ( Sender Report )中的 rtp 和 ntp 时间戳对
⼀、时间戳映射关系
⾸先介绍 PLAY 请求的 Response ⾥的两个域:
(1) npt
npt 顾名思义 Normal PLay Time ,正常播放时间,指出了流相对与播放开始时的绝对位置。播放开始时的之间定义为 0.0s 。这个特殊的常量 now 被定义为现场事件的当前时刻。" now "常数允许客户端请求接收实时反馈⽽不是存储或者延时的版本。因为对于这种情况⽽⾔,既没有绝对时间,也没有 0 时间,所以需要该参数。
(2) rtptime
rtptime 是发送 PLAY 请求后将收到的第⼀个 RTP 包的时间戳值。
npt 和 rtptime 的区别在于 npt 是影⽚开始的相对时间,⽽ rtptime 是会话开始的相对时间。因此在client 端,需要对这两者进⾏ map 处理。
在 client 端计算播放时间戳的公式如下:
nptUs = (current_rtpTime - start_rtptime) / scale + srart_npt
其中:
start_rtptime 与 start_npt 分别是 PLAY 请求的 Response 中的 rtptime 和 npt 。current_rtpTime 是当前收到的 RTP 包头中的 rtptime 。
scale 为 PLAY 请求的 Response 中的 scale 值。在正常播放的情况下为 1 ,快速播放时⼤于 1 ,当处于反向扫描模式时⼩于 -1 .
⼆、媒体间同步⽅法(不同设备的同步)
上⾯的处理仅仅实现了媒体内的同步,在实现媒体间同步时,还需要进⾏其他的处理⼯作。这就需要⽤到RTCP 的 SR ( Sender Report )。在 SR 中包含⼀个< rtp , ntp >时间戳对,通过这个时间戳对可以将⾳频和视频准确的定位到⼀个绝对时间轴上。
< rtp , ntp >时间戳对的必要性在于不同流的 RTP 时间戳有不同的随机偏移量,因此⽆法直接进⾏同步。
< rtp , ntp >中的 ntp 是⽹络时间协议格式表示的绝对时间值。
< rtp , ntp >中的 RTP 与数据包中的 RTP 时间戳具有相同的单位和偏移量,但在⼤多数情况下此时间戳不等于任何临近的 RTP 包中的时间戳。
根据不同 stream 中的< rtp , ntp >时间戳对,可以将⼀个 stream 中的时间戳值映射为另⼀个stream 的时间戳值,从⽽实现媒体间的同步。
RTCP同步
RTP⽀持传送不同codec的steaming,不同codec的clock rate的也不⼀样,不同的media之间需要依靠RTCP进⾏同步。这⾥简单介绍⼀下他们的机制。
在每个RTCP SR包中对应有⼀个RTP时间和⼀个NTP时间,它表达的意思很明确,那就是这个RTP时间对应的绝对时间, 不同media的RTP时间尽管不同,但可以通过NTP时间映射到同⼀个时间轴上,从⽽实现同步。
如下图所示,RTP session 1 send H264 使⽤90,000HZ,⽽RTP session 2 send G.711 使⽤8,000HZ:
也就是是说有3个时间轴,⾳频时间轴,视频时间轴,ntp时间轴。
⾳视频的时间轴的单位都是各⾃的采样率,需要除以采样率才能取得单位为秒的时间单位。
有两个rtcp流,分别为⾳/视频的,其中有⼀个当前的⾳频的timestamp和⼀个ntp的timestamp。这两个值是在不同轴上的相同时间点,即⾳/视频轴和ntp轴的重合点。使⽤这个值可以使⾳视频轴同步。
当拿到⾳频NTP时间 (Tan),⾳频RTP时间(Tar),视频NTP时间(Tvn),视频RTP时间(Tvr),就可以计算⾳视频时间轴的差距D:
假设使⽤⾳频为主轴,视频向⾳频对⻬。D = (Tar-Tvr) - (Tan - Tvn);
新的视频时间戳为Tar = Tar + D;
在rtcp的sr单元中有32位的MSW和32位的LSW。MSW的单位为秒,⽽LSW的单位为232
picoseconds。1⽪秒为1/1012秒。LSW转为us的公式为(LSW*1012/2^32)/1000000;