rtp 用于实时传输数据
rtcp 用于监控服务质量和传达关于在一个正在进行的会议中的参与者的信息
==================================================================
应用场景:
简单多播音频会议
单频和视频会议
混频器和转换器
分层编码
===================================================================
RTP负载(RTP playload): 通过RTP传输的包中的数据
RTP包(RTP packet): 一个数据包,(一个固定的RTP报头,一个可能为空的作用源,负载数据)
TRCP包(RTCP package): 一种控制包,(一个固定报头,一个结构化的部分)
端口(port):同一主机区分不同目的地
传输地址(transport address):是网络地址和端口的结合(一个ip地址和一个udp端口)
rtp媒体类型(RTP media Type):是一个单独RTP会话所载有的负载类型的集合
多媒体会话(RTP session):一群参与者通过RTP进行通信时所产生的关联 (一个地址+一对分别用于RTP和RTCP的端口)
同步源(SSRC,):RTP包流的源,用RTP报头中32位数值的ssrc标识符进行标识.使其不依赖于网络地址
作用源(CSRC):若一个RTP包流的源,对由RTP混频器生成的组合流起了作用,它就是一个作用源
终端系统(End system):一种应用程序,产生发送出的RTP包内容,或者使用RTP包中的内容
混频器(mixer): 一种中间系统,从一个或多个源中接收rtp包,可能改变其数据格式,再按某种方式把这些包组合成一个新包,转发出去
转换器(translator): 一种中间系统,转发RTP包而不改变各包的同步源标识符
监视器(monitor):一种应用程序,它接收RTP会话参与者所发送的RTCP包,特别是接收报告,对当前服务进行评估,结果用于分配监视器,故障诊断和长期统计
非RTP途径(non-rtp means): 为提供一个可用的服务,可能需要其他的协义机制
====================================================================
RTP数据传输协议
RTP固定头中的各字段
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
版本(v) 2bit 定义RTP版本
填充(P) 1bit 若填料比特被设置,则此包包含一到多个附加在末端的填充比特,填充比特不算作负载的一部分
扩展(X) 1bit 若设置扩展比特,固定头(仅)后面跟随一个头扩展
CSRC计数(CC): 4bit CSRC计数包含了跟在固定头后面CSRC识别符的数目
标志(M): 1bit 标志的解释由具体协议规定
负载类型(playload type PT): 7bit 此域定义了负载的格式,由具体应用决定其解释
序列号(sequence number): 16bit 每发送一个RTP数据包,序列号加1,接收端可以据此检测丢包和重建包序列
时间戳(timestamp): 32bit 反映了RTP数据包中第一个字节的采样时间 (实现不同媒体流的同步)
SSRC:32bit 用以识别同步源
CSRC列表: 0到15项 每项32比特 ? CSRC列表识别在此包中负载的所有贡献源
注:h.264允许解码顺序可以和显示顺序不同
RTP头扩展
实现附加信息在RTP数据包中传输
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| defined by profile | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| header extension |
| .... |
如果RTP头中的扩展比特位(x),设置为1,则一个长度可变的头扩展添加到RTP固定头之后
包含16比特的长度域
指示扩展项中32比特的字的个数
=========================================================================
RTP控制协议RTCP
会向会议中所有成员周期性发送控制包,它使用与数据包相同的传输机制
功能如下:
提供数据传输质量的反馈
为每个RTP源传输一个固定的标识符
前两个要求所有成员都发送RTCP包,因此必须控制速率以使RTP成员数可以逐级增长
传输最少的会议控制信息
RTCP的包格式:
包类型和传送的不同控制信息
SR: 发送报告者
RR: 接收报告者
SDES: 源描述项
BYE: 表明参与者将结束会话
APP: 应用描述功能
固定部分+一块结构化单元,总是以32比特终止
限制如下:
接收数据统计信息,带宽允许的情况下,就尽可能多的发送
新的参与者应尽快接收一个源的规范名,以识别数据源与媒体建立会话
限制首次在复合包中出现的包类型的数目,以增加在第一个字中常数比特的数目
所有RTCP包都是以复合包的形式发送,至少有两个单个的rtcp包,具体格式如下:
1 加密前缀: 如果加密,会添加32比特的前缀
2 sr或rr: 复合包中的第一个包,必须是报告包
3 附加的rr: 如果被报告的接收统计源数目,超过最大允许的31个,附加的rr跟在报告 包后
4 源描述符sdes:
5 bye或app包:
每个rtp参与者在一个报告间隔内应只发送一个rtcp复合包,来估计参与者rtcp带宽
rtcp复合包的格式:
每个rtcp 复合包都必须以SR或RR开头
|
|[--------- packet --------][---------- packet ----------][-packet-]
|
| receiver chunk chunk
V reports item item item item
--------------------------------------------------------------------
R[SR #sendinfo #site1#site2][SDES #CNAME PHONE #CNAME LOC][BYE##why]
--------------------------------------------------------------------
| |
|<----------------------- compound packet ----------------------->|
|<-------------------------- UDP packet ------------------------->|
#: SSRC/CSRC identifier
图1: RTCP复合包举例
rtcp的传输时间间隔--------------------------------------------
数据传输的上限:会话带宽
会话带宽的参数最好由一个会话控制应用提供
由单个发送者选择的编码方式的数据带宽算出
所有的参与者应使用相同的会话带宽,确定RTCP间隔相同
rtcp控制传输带宽应控制在RTCP会话带宽的5%,其中四分之一分配给发送者
固定的时间间隔建议为5秒
1 RTCP包的时间间隔与组中参与者的人数成正比
2 最小时间间隔建议:360/sb(秒)
3 RTCP包的真实时间间隔是计算出的时间间隔的0.5-1.5倍的随机数,
4 rtcp复合包的平均大小会被动态估计
5 由于时间间隔依赖于组中的人数,时间间隔会跟据人数的变化作出调整
人数增多时"时间重估",人数减少时"逆向重估"
6 bye包的处理与其他rtcp包的处理不同,"放弃支持算法"
rtcp包的发送和接收规则-----------------------------------------------------------
tp: RTCP包发送的最后时间
tc: 当前时间
tn: 估计的下一个rtcp包要发送的时间
pmembers:tn最后被重新计算时,统计的会话成员的人数
members: 会话成员人数的当前估计
senders: 会话成员中发送者人数的估计
rtcp_bw: 目标rtcp带宽
we_sent:自当前第二个前面的rtcp发送后,应用程序又发送了数据,则方该值为true
avg_rtcp_size:收到和发送的复合包的平均大小
initial: 如果应用程序还未发送RTCP包,该值为true
计算rtcp传输的时间间隔--------------------------------------------------------------
1 如果发送者人数<=会话总人数的25%,则 T取决是此参与者是否是发送者(we_sent的值),否则发送者和接收者将统一处理
>=25%的情况:
c=avg_rtcp_size/rtcp_bw;
n=members
<=25%的情况:
根据we_sent的值分为:
发送者:
c=avg_rtcp_size/(0.25*rtcp_bw)
n=senders
接收者: c=avg_rtcp_size/(0.75*rtcp_bw)
n=members-senders;
2 如果initial为true(未发送过),tmin=2.5s 否则为tmin=5s
3 决定性的计算时间间隔td=max(tmin,n*c);
4 t=td*(人),(人)服从于0.5-1.5之间
5 被尝时间重估算法T=T/(E-0.5)约等于T/1.21828 ,补尝时间重估算法
初始化-------------------------------------------------------------------
参与者的参量初始化为:
tp: 0
tc: 0
tn: T
pmembers: 1
members: 1
senders: 0
rtcp_bw: 由会话参数的相应部分得到
we_sent: false
avg_rtcp_size: 稍后发送的RTCP包的可能大小
initial: true
参与者把它自已的SSRC加到成员列表
接收到的tp包或一个非BYE的RTCP包----------------------------------------------
当收到一个参与者的RTP或RTCP包时,若其SSRC不在成员列表中,将其加列表
对csrc执行相同的操作
当收到一个参与者的RTP包时,若其SSRC不在发送者列表中,更新值
每收到一个rtcp复合包,avg_rtcp_size=1/16*packet_size+15/16*avg_rtcp_size, 其中package_size是RTCP复合包的大小
接收RTCP BYE包-----------------------------------------------------------
1 检测成员列表,若ssrc存在,先移除,并更新成员的值
2 收到bye包后,要执行逆向重估算法
tn(下一个rtcp包要发送的时间)的更新:tn=tc+(member/pmembers)*(tn-tc)
tp(发送的最后时间)tp=tc-(member/pmember)*(tc-tp)
pmembers的更新pmembers=members
SSRC超时-----------------------------------------------------------------------------------
接收者(we_sent为false)如果从时刻tc-m*td开始,未发送过rtp或rtcp包,则超时,从ssrc将从列表中移除,更新成员
发送者,如果从时间tc-2t(在最后两个RTCP报告时间间隔内)未发送包,从ssrc将从列表中移除,更新成员
发送时钟到时-----------------------------------------------------------------------------
当包传输的发送时钟到时,参与者执行以下操作:
1 重新计算t
2 更新发送时钟的定时时间,判断是否发送rtcp包,更新pmember
tp(最后发送时间)+T(发送时间间隔)<=tc(当前时间),执行以下操作
发送rtcp包
tp=tc;
tn=tc+t;initial=false;
avg_rtcp_size=1/16*packet_size+15/16*avg_rtcp_size
pmembers=members
tp(最后发送时间)+T(发送时间间隔)>=tc(当前时间)
tn=tp+t;
不发送rtcp包
pmembers=members
发送一个BYE包----------------------------------------------------------
应执行以下步骤:
1 tp=tc; members=1;pmembers=1;sinitial=1;we_sent=false;senders=0;rtcp_size=将要发送的包大小;T(最小时间间隔)
tn=tc+T;
2 每当从一个参与者接收到bye包时,成员人数加1 .只有收到bye包时avg_rtcp_size才更新,
3 bye包的传输同一般RTCP包
注:参与者可以直接离开,其他人会超时面删除
总人数小于50可直接发送bye包
如果从未发送过RTP或RTCP包,不能发送bye包
更新we_sent变量-------------------------------------------
如果发送过rtp包,则设置其we_sent变量为true
源描述带宽的分配
强制性的规范名cname
发送者和接收者报告-----------------------------------------------------------
RTP 接收者通过RTCP报告提供接收质量反馈
SP和RR的区别: 包类型码 ,sr中包括20字节的发送者信息
都包括零到多个接收报告块,最多31个报告块
SR:发送者报告RTCP包 ? ?
? 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
header |V=2|P| RC | PT=SR=200 | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of sender |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
sender | NTP timestamp, most significant word |
info +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NTP timestamp, least significant word |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RTP timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| sender's packet count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| sender's octet count |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
report | SSRC_1 (SSRC of first source) |
block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1 | fraction lost | cumulative number of packets lost |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| extended highest sequence number received |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| interarrival jitter |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| last SR (LSR) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| delay since last SR (DLSR) |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
report | SSRC_2 (SSRC of second source) |
block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2 : ... :
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| profile-specific extensions |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
发送者报告由以下三部分级成:
1 头部 8个字节长
版本(v) 2bit RTP版本标识符
填充(p) 1bit 若设置,则会在包的末端包含一些附加填充比特
接收报告块计数(rc) 5bit 该包所含接收报告块的数目
包类型(pt) 8bit 包含常数200,用以识别为SR
长度 16bit rtcp包长度减一
ssrc 32bit sr包发送者的同步源识别符
2 发送者信息 20字节长
NTP时间戳:64bit 指示发送时的背景时钟时刻,与返回中的时间标志结合,计算往返时间
RTP时间戳: 32bit 与ntp时间标志对应同一时刻 ,与数据包中rtp时间戳具有相同的单位和偏移量
发送的报文数:32bit 从开始传输到此sr包产生时,发送者发送的rtp数据包总数,若改变ssrc识别符,计数器重设
发送的字节总数:32bit 从开始传输到此sr包产生时发送者在rtp数据包发送的字节总数(不包含头和填充)
3 零到多个接收报告块
ssrc_n(同步源标识符) 32bit 信息所属源的ssrc标识符
丢包率: 8bit 从前一sr包或rr包发送以来,从ssrc_n传来的RTP数据包丢失的比例 (损失包数/期望接收的包数)
累计包丢失数:24bit 从开始到现在,从源ssrc_n发到本源的RTP数据包的丢包总数
接收到的扩展的最高序列号:32bit 低16bit包含从源ssrc_n来的最高接收序列号,高16bit用相应的序列号周期计数扩展该序列号
到达间隔抖动:32bit rtp数据包到达时刻统计方差的估计值
上一sr的文(LSR):32bit 接收到的来自源ssrc_n的最新rtcp发送者报告(sr)的64位NTP时间标志的中间32位
自上一sr的时间(DLSR):32bit 是从收到来自ssrc_n的sr包到发送此接收报告块之间的延时
如下图所示。
[10 Nov 1995 11:33:25.125 UTC] [10 Nov 1995 11:33:36.5 UTC]
n SR(n) A=b710:8000 (46864.500 s)
---------------------------------------------------------------->
v ^
ntp_sec =0xb44db705 v ^ dlsr=0x0005:4000 ( 5.250s)
ntp_frac=0x20000000 v ^ lsr =0xb705:2000 (46853.125s)
(3024992005.125 s) v ^
r v ^ RR(n)
---------------------------------------------------------------->
|<-DLSR->|
(5.250 s)
A 0xb710:8000 (46864.500 s)
DLSR -0x0005:4000 ( 5.250 s)
LSR -0xb705:2000 (46853.125 s)
-------------------------------
delay 0x0006:2000 ( 6.125 s)
图2: 往返路程时间的计算举例
RR:接收者报告包 ? ?
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
header |V=2|P| RC | PT=RR=201 | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of packet sender |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
report | SSRC_1 (SSRC of first source) |
block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1 | fraction lost | cumulative number of packets lost |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| extended highest sequence number received |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| interarrival jitter |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| last SR (LSR) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| delay since last SR (DLSR) |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
report | SSRC_2 (SSRC of second source) |
block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2 : ... :
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| profile-specific extensions |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
发送者和接收者报告扩展
紧跟在接收报告块的后面,也应该记录到rc字段中
分析发送者和接收者报告
略
源描述rtcp包
源描述(sdes)包由一个头及0个或多个块组成
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
header |V=2|P| SC | PT=SDES=202 | length |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
chunk | SSRC/CSRC_1 |
1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SDES items |
| ... |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
chunk | SSRC/CSRC_2 |
2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SDES items |
| ... |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
bye包
表进一个源或多个源要离开
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P| SC | PT=BYE=203 | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC/CSRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: ... :
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
(opt) | length | reason for leaving ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
安全性
略
拥塞控制
拥塞控制应该在描述文件中定义
基于RTCP反馈的自适应数据传输率