1、RTP协议分析html
RTP全名是Real-time Transport Protocol(实时传输协议)。它是IETF提出的一个标准,对应的RFC文档为RFC3550(RFC1889为其过时版本)。RFC3550不只定义了RTP,并且定义了配套的相关协议RTCP(Real-time Transport Control Protocol,即实时传输控制协议)。RTP用来为IP网上的语音、图像、传真等多种须要实时传输的多媒体数据提供端到端的实时传输服务。RTP为Internet上端到端的实时传输提供时间信息和流同步,但并不保证服务质量,服务质量由RTCP来提供。算法
RTP用于在单播或多播网络中传送实时数据。它们典型的应用场合有以下几个。缓存
简单的多播音频会议。语音通讯经过一个多播地址和一对端口来实现。一个用于音频数据(RTP),另外一个用于控制包(RTCP)。网络
音频和视频会议。若是在一次会议中同时使用了音频和视频会议,这两种媒体将分别在不一样的RTP会话中传送,每个会话使用不一样的传输地址(IP地址+端口)。若是一个用户同时使用了两个会话,则每一个会话对应的RTCP包都使用规范化名字CNAME(Canonical Name)。与会者能够根据RTCP包中的CNAME来获取相关联的音频和视频,而后根据RTCP包中的计时信息(Network time protocol)来实现音频和视频的同步。session
翻译器和混合器。翻译器和混合器都是RTP级的中继系统。翻译器用在经过IP多 播不能直接到达的用户区,例如发送者和接收者之间存在防火墙。当与会者能接收的音频编码格式不同,好比有一个与会者经过一条低速链路接入到高速会议,这 时就要使用混合器。在进入音频数据格式须要变化的网络前,混合器未来自一个源或多个源的音频包进行重构,并把重构后的多个音频合并,采用另外一种音频编码进 行编码后,再转发这个新的RTP包。从一个混合器出来的全部数据包要用混合器做为它们的同步源(SSRC,见RTP的封装)来识别,能够经过贡献源列表(CSRC表,见RTP的封装)能够确认谈话者。ide
流媒体是指Internet上使用流式传输技术的连续时基媒体。当前在Internet上传输音频和视频等信息主要有两种方式:下载和流式传输两种方式。函数
下载状况下,用户须要先下载整个媒体文件到本地,而后才能播放媒体文件。在视频直播等应用场合,因为生成整个媒体文件要等直播结束,也就是用户至少要在直播结束后才能看到直播节目,因此用下载方式不能实现直播。工具
流式传输是实现流媒体的关键技术。使用流式传输能够边下载边观看流媒体节目。因为Internet是基于分组传输的,因此接收端收到的数据包每每有延迟和乱序(流式传输构建在UDP上)。要实现流式传输,就是要从下降延迟和恢复数据包时序入手。在发送端,为下降延迟,每每对传输数据进行预处理(下降质量和高效压缩)。在接收端为了恢复时序,采用了接收缓冲;而为了实现媒体的流畅播放,则采用了播放缓冲。post
使用接收缓冲,能够将接收到的数据包缓存起来,而后根据数据包的封装信息(如包序号和时戳等),将乱序的包从新排序,最后将从新排序了的数据包放入播放缓冲播放。ui
为何须要播放缓冲呢?容易想到,因为网络不可能很理想,而且对数据包排序须要处理时耗,咱们获得排序好的数据包的时间间隔是不等的。若是不用播放缓冲,那么播放节目会很卡,这叫时延抖动。相反,使用播放缓冲,在开始播放时,花费几十秒钟先将播放缓冲填满(例如PPLIVE),能够有效地消除时延抖动,从而在不太损失实时性的前提下实现流媒体的顺畅播放。
到目前为止,Internet 上使用较多的流式视频格式主要有如下三种:RealNetworks 公司的RealMedia ,Apple 公司的QuickTime 以及Microsoft 公司的Advanced Streaming Format (ASF) 。
上面在谈接收缓冲时,说到了流媒体数据包的封装信息(包序号和时戳等),这在后面的RTP封装中会有体现。另外,RealMedia这些流式媒体格式只是编解码有不一样,但对于RTP来讲,它们都是待封装传输的流媒体数据而没有什么不一样。
RTP(实时传输协议),顾名思义它是用来提供实时传输的,于是能够当作是传输层的一个子层。图 1给出了流媒体应用中的一个典型的协议体系结构。
图 1 流媒体体系结构
从图中能够看出,RTP被划分在传输层,它创建在UDP上。同UDP协议同样,为了实现其实时传输功能,RTP也有固定的封装形式。RTP用来为端到端的实时传输提供时间信息和流同步,但并不保证服务质量。服务质量由RTCP来提供。这些特色,在第4章能够看到。
很多人也把RTP归为应用层的一部分,这是从应用开发者的角度来讲的。操做系统中的TCP/IP等协议栈所提供的是咱们最经常使用的服务,而RTP的实现仍是要靠开发者本身。所以从开发的角度来讲,RTP的实现和应用层协议的实现没不一样,因此可将RTP当作应用层协议。
RTP实现者在发送RTP数据时,需先将数据封装成RTP包,而在接收到RTP数据包,须要将数据从RTP包中提取出来。
一个协议的封装是为了知足协议的功能需求的。从前面提出的功能需求,能够推测出RTP封装中应该有同步源和时戳等字段,但更为完整的封装是什么样子呢?请看图2。
图 2 RTP的头部格式
版本号(V):2比特,用来标志使用的RTP版本。
填充位(P):1比特,若是该位置位,则该RTP包的尾部就包含附加的填充字节。
扩展位(X):1比特,若是该位置位的话,RTP固定头部后面就跟有一个扩展头部。
CSRC计数器(CC):4比特,含有固定头部后面跟着的CSRC的数目。
标记位(M):1比特,该位的解释由配置文档(Profile)来承担.
载荷类型(PT):7比特,标识了RTP载荷的类型。
序列号(SN):16比特,发送方在每发送完一个RTP包后就将该域的值增长1,接收方能够由该域检测包的丢失及恢复包序列。序列号的初始值是随机的。
时间戳:32比特,记录了该包中数据的第一个字节的采样时刻。在一次会话开始时,时间戳初始化成一个初始值。即便在没有信号发送时,时间戳的数值也要随时间而不断地增长(时间在流逝嘛)。时间戳是去除抖动和实现同步不可缺乏的。
同步源标识符(SSRC):32比特,同步源就是指RTP包流的来源。在同一个RTP会话中不能有两个相同的SSRC值。该标识符是随机选取的 RFC1889推荐了MD5随机算法。
贡献源列表(CSRC List):0~15项,每项32比特,用来标志对一个RTP混合器产生的新包有贡献的全部RTP包的源。由混合器将这些有贡献的SSRC标识符插入表中。SSRC标识符都被列出来,以便接收端能正确指出交谈双方的身份。
RTP须要RTCP为其服务质量提供保证,所以下面介绍一下RTCP的相关知识。
RTCP的主要功能是:服务质量的监视与反馈、媒体间的同步,以及多播组中成员的标识。在RTP会话期间,各参与者周期性地传送RTCP包。RTCP包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,所以,各参与者能够利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,于是特别适合传送网上的实时数据。
从图 1能够看到,RTCP也是用UDP来传送的,但RTCP封装的仅仅是一些控制信息,于是分组很短,因此能够将多个RTCP分组封装在一个UDP包中。RTCP有以下五种分组类型。
类型 |
缩写表示 |
用途 |
200 |
SR(Sender Report) |
发送端报告 |
201 |
RR(Receiver Report) |
接收端报告 |
202 |
SDES(Source Description Items) |
源点描述 |
203 |
BYE |
结束传输 |
204 |
APP |
特定应用 |
表 1 RTCP的5种分组类型
上述五种分组的封装大同小异,下面只讲述SR类型,而其它类型请参考RFC3550。
发送端报告分组SR(Sender Report)用来使发送端以多播方式向全部接收端报告发送状况。SR分组的主要内容有:相应的RTP流的SSRC,RTP流中最新产生的RTP分组的时间戳和NTP,RTP流包含的分组数,RTP流包含的字节数。SR包的封装如图3所示。
图 3 RTCP头部的格式
版本(V):同RTP包头域。
填充(P):同RTP包头域。
接收报告计数器(RC):5比特,该SR包中的接收报告块的数目,能够为零。
包类型(PT):8比特,SR包是200。
长度域(Length):16比特,其中存放的是该SR包以32比特为单位的总长度减一。
同步源(SSRC):SR包发送者的同步源标识符。与对应RTP包中的SSRC同样。
NTP Timestamp(Network time protocol)SR包发送时的绝对时间值。NTP的做用是同步不一样的RTP媒体流。
RTP Timestamp:与NTP时间戳对应,与RTP数据包中的RTP时间戳具备相同的单位和随机初始值。
Sender’s packet count:从开始发送包到产生这个SR包这段时间里,发送者发送的RTP数据包的总数. SSRC改变时,这个域清零。
Sender`s octet count:从开始发送包到产生这个SR包这段时间里,发送者发送的净荷数据的总字节数(不包括头部和填充)。发送者改变其SSRC时,这个域要清零。
同步源n的SSRC标识符:该报告块中包含的是从该源接收到的包的统计信息。
丢失率(Fraction Lost):代表从上一个SR或RR包发出以来从同步源n(SSRC_n)来的RTP数据包的丢失率。
累计的包丢失数目:从开始接收到SSRC_n的包到发送SR,从SSRC_n传过来的RTP数据包的丢失总数。
收到的扩展最大序列号:从SSRC_n收到的RTP数据包中最大的序列号,
接收抖动(Interarrival jitter):RTP数据包接受时间的统计方差估计
上次SR时间戳(Last SR,LSR):取最近从SSRC_n收到的SR包中的NTP时间戳的中间32比特。若是目前还没收到SR包,则该域清零。
上次SR以来的延时(Delay since last SR,DLSR):上次从SSRC_n收到SR包到发送本报告的延时。
当应用程序创建一个RTP会话时,应用程序将肯定一对目的传输地址。目的传输地址由一个网络地址和一对端口组成,有两个端口:一个给RTP包,一个给RTCP包,使得RTP/RTCP数据可以正确发送。RTP数据发向偶数的UDP端口,而对应的控制信号RTCP数据发向相邻的奇数UDP端口(偶数的UDP端口+1),这样就构成一个UDP端口对。 RTP的发送过程以下,接收过程则相反。
1) RTP协议从上层接收流媒体信息码流(如H.263),封装成RTP数据包;RTCP从上层接收控制信息,封装成RTCP控制包。
2) RTP将RTP 数据包发往UDP端口对中偶数端口;RTCP将RTCP控制包发往UDP端口对中的接收端口。
实时流协议RTSP(Real-Time Streaming Protocol)是IETF提出的协议,对应的RFC文档为RFC2362。
从图 1能够看出,RTSP是一个应用层协议(TCP/IP网络体系中)。它以C/S模式工做,它是一个多媒体播放控制协议,主要用来使用户在播放流媒体时能够像操做本地的影碟机同样进行控制,便可以对流媒体进行暂停/继续、后退和前进等控制。
资源预约协议RSVP(Resource Reservation Protocol)是IETF提出的协议,对应的RFC文档为RFC2208。
从图 1能够看出,RSVP工做在IP层之上传输层之下,是一个网络控制协议。RSVP经过在路由器上预留必定的带宽,能在必定程度上为流媒体的传输提供服务质量。在某些试验性的系统如网络视频会议工具vic中就集成了RSVP。
能够根据RTP包的序列号来排序。
能够根据RTP包的时间戳来得到数据包的时序。
根据声音流和图像流的相对时间(即RTP包的时间戳),以及它们的绝对时间(即对应的RTCP包中的RTCP),能够实现声音和图像的同步。
如1.3.1所述,接收缓冲用来排序乱序了的数据包;播放缓冲用来消除播放的抖动,实现等时播放。
ID |
Protocol |
Captured contents |
||||||
Account |
password |
Local telephone number |
Opponents Telephone Number |
audio |
login |
logout |
||
36 |
Rtp |
|
|
|
|
√ |
|
|
表 2 协议分析要求
表 2给出了协议分析要求。容易看出要获取RTP音频包中的音频信息很容易,直接将RTP包的包头去掉便可。固然,要成功地播放解码获取到的音频流,须要知道其编码,这可从RTP包包头的有效载荷类型字段(PT)得到。
[1] RFC文档:RFC3550对应RTP/RTCP,RFC2362对应RTSP,RFC2208对应RSVP
[2] http://www.faqs.org/rfcs/,上面有全面的英文RFC文档
[3] http://www.cnpaf.net/,有很多协议分析文档,也有中文RFC文档,但质量不是特别高。
2、RTP与RTCP解释.含同步时间戳
RTP协议是real-time transport protocol的缩写,被设计来传输流媒体数据,有着普遍的应用,其它相关介绍本身去看RFC,我不打算讨论这些无聊的概念性的东西。
RTP
能够说,RTP协议不依赖于底层协议,也就是说,它是独立的协议。而通常的,因为UDP包的快速、时实性高的特色,它一般和UDP结合在一块儿,做为UDP的上层载体数据的形式传播。
typedef struct {
IN OUT UINT32 timestamp;
IN OUT BOOL marker;
IN OUT BYTE payload;
OUT UINT32 sSrc;
OUT UINT16 sequenceNumber;
OUT int sByte;
OUT int len;
} rtpParam;
这是一个RTP头,很简单,并无你想象的那么复杂,对不对?咱们来看几个主要的参数,他们也是RTP的灵魂:
(1)payload。payload表示了此RTP包的数据是那种类型的数据,不一样的数值表示不一样的类型。如0是PCMU,8是723,24是视频263等等。
(2)SSRC,这个东西并不经常使用,实际上它是一个随即生成的ID,表示了一个RTP链接。在应用的时候,确保这个ID惟一就能够了。
(3)sequence number。也就是序列号,它表示了当前包是第几个包。发送方每发送一个包,就把这个数值加一。接受放能够根据这个数值来从新组合包顺序,判断包是否丢失等操做。注意:它只是表示了包的前后顺序,它不能表示时间上的任何其它信息。这个请和后面的时间戳比较。
(4)timestamp。时间戳,它的概念稍微有点复杂,我用稍微通俗点的理解去解释它,虽然这样有点不太正确。时间戳顾名思义,它表示了一个数据产生的时间,和咱们邮递的邮戳同样,它是个时间标记(至于这个时间干什么用,我后面会详细的说),一般表示RTP数据包中,第一个字节数据产生的时间(至于你是否是这么用就是你写程序的问题了)。
若是你上面理解了,那么咱们更进一步:实际上,时间戳增长一并非咱们一般意义上的过了一个微秒,而是增长了一个采样间隔那么长的时间。举个例子来讲。不一样的采集有不一样的采样频率,好比通常的音频是8K的采样频率,也就是一毫秒采集8次数据,也就是每次采样间隔是1/8MS,而timestamp增长1也就意味着增长了一个采样间隔。也就是过了1/8MS。换个例子,若是令一种编码的采样频率是16K,那么timestamp增长1也就意味着系统过了1/16MS。也就是说,再同一个系统中,对不一样编码,虽然使用同一个时钟,但timestamp的增加速度是不一样的,在这个例子中,采样频率是16K的编码要比8K的快两倍,请记住这个区别。
RTCP
RTCP协议是real-time transport control protocol的缩写,被设计来作RTP的控制,这个相对来讲你们不怎么关心,我只介绍下它基本的东西。
RTCP其实是RTP传输状况的反馈,通俗的说,它告诉另一方,在一端时间内(5秒),它发送多少数据包给对方,接收到了多少对方的包。
另外,在RTCP中,还有两个比较重要的东西,一个64位的绝对时间戳和一个32位的相对时间戳。64 位时间戳也叫NTP时间戳,它的前32位是从1900 年1 月1 日0 时开始到如今的以秒为单位的整数部分,后32 位是此时间的小数部,所以,它能够确定的表示了数据发送出去的绝对时间。32位的时间戳和RTP中的时间戳是同样的,没有任何区别。
)你们感兴趣的时间戳的使用和同步的一些话题。
一、SSRC的做用。
SSRC至关于一个RTP传输session的ID,就象每一个人都有一个名字同样,每个RTP传输也都有一个名字。这个数字是随机产生,而且要保证惟一。当RTP session改变(如IP等)时,这个ID也要改变。
二、序列号字段是否能够做为流内的同步标时?
我在上面已经说过,序列号只表示了包发出的前后顺序,它表示不了任什么时候间上的其它概念,全部严格的说,序列号并不能做为流内的同步标志。可是,因为通常来讲,包的发送时间都会有严格限制,好比音频包是每秒种发送30个数据包,也就是说,每一个包间隔1000/30MS,而这个时间就能够做为一个同步时间来播放。也就是说,按照序列号,每1000/30MS间隔播放一个数据包,这样也能保证同步,可是这时候请考虑丢包问题。
三、绝对时间戳和相对时间戳在进行同步处理时有什么不一样
当咱们取得绝对时间后,咱们就能够根据这个绝对时间来播放这些数据包。这个绝对时间,加上咱们须要的延时(用于数据传输,解码等等的时间)就是咱们的播放时间,这样咱们能够保证时间的严格同步(至关于把对方的动做延时一段时间后原本来本的再现出来)。目前,在RTP中,能获得这个绝对时间的办法只有RTCP。
对于相对时间戳,咱们更关心的是两个时间戳之间的时间间隔,依靠这个时间间隔,来肯定两个包的播放时间间隔。
四、单个媒体内的同步和不一样媒体流之间的同步在处理方式上有什么不一样
应该说,不一样媒体之间同步比单媒体同步要复杂得多,除了要保证自己的播放要和时间同步外,还要保证两个或多个媒体间同步(好比音视频的同步)。这种不一样更关心的两个时间戳时间的换算统一,前面我已经说过,不一样编码有不一样的采样频率,那么时间戳的增加速度就不一样。另外,两个时间戳也须要有一个标准时间来表示时间戳的同步。最简单的方法是两个媒体的第一个时间戳相同,表示两个流的采集开始时间统一。另外还能够经过RTCP来作不一样流之间的同步,这在下个问题中会提到。
五、时间戳字段如何用于做为流间同步标识
在RTP协议中,咱们取得时间戳的方法有两个:一个是RTP包中的时间戳,另一个是RTCP包中的绝对时间戳和相对时间戳。绝对时间戳的概念上面我已经说了,它能够表示系统的绝对时间。而RTCP包中的相对时间就是RTP包中的时间。根据这两个时间,不一样流均可以纠正本身播放时间和真正时间的误差以达到和绝对时间同步的目的。反过来讲,若是咱们没有办法拿到这个绝对时间,只有RTP包中的相对时间,那怎咱们须要肯定两个流在某一时间点的时间戳的数值。通俗的说,就是在某个时间点,流A的timestamp是多少,B是多少,而后根据这个时间两个流播放的延时时间,以达到同步的目的。实现这个目的最简单的办法是在两个流开始的时候,使用相同的stamp,拿音视频来讲,在某一绝对时刻,采集相应的数据,并打上相同的时间戳,之后的播放,都以这个时间作基准时间,以保证同步
3、RTP时间戳相关
经过RTSP创建好会话以后,就能够开始传输RTP数据和RTCP SR包了(用来同步音视频)。
这二者涉及到很重要的问题:时间戳。下面是《rtp_audio_and_video_for_the_internet》上的一个时间图。
TimeStamp的初始值是随即生成的,而后每一帧数据固定增长一 个增量,客户端在接收到数据时,根据这个时间戳就能以正确的时间恢复(其中被分包的视频桢是没有时间戳增长的)。RTCP的SR包里面除了这个时间戳,还 有一个NTP时间,这是距1900年1月1日的秒数,容许每一个系统存在差别,只要同一个系统不一样流的该值的生成方式相同就行。以时钟频率为90KHz的视 频为例,若其帧率为30帧,则每一帧的时间戳增量为90000/30=3000;RTCP的SR包的时间戳也能够相应计算出来:增量=(如今时间-上一次 RTP包发送时间)*单位时间增量,其中单位时间增量=90000*1000000/(2^32),由于SR包中的微秒时间形式是NTP_frac,所以 要作“/(2^32)”这样一个转化。
RFC中说时间戳增量须要知足线性增加,实际上不必严格按照诸如3000增量来增加,我是按照实际的帧的时间间隔来打的这个时间戳:
时间戳 = 上一次时间戳 + 采样频率(典型值为90000)*0.000001 * 两帧时间差(单位毫秒)来计算的
--------------------------------------------------------------------------
---------------------------------------------------------------------------
时间戳(timestamp) 32比特 时间戳反映了RTP数据包中第一个字节的采样时间。(采样时钟必须来源于一个及时的单调、线性递增时钟,以便容许同步和去除网络引发的数据包抖动。该时钟的分辨率必须知足理想的同步精度和测量数据包到来时的抖动的须要(一种典型的时钟分辨率不知足状况是每一个视频帧仅一个时钟周期)时钟 频率依赖于负载数据的格式,并在描述文件(profile)中或者是在负载格式描述中(payload format speci_cation)进行静态描述。也能够经过非RTP方法(non-RTP means)对负载格式动态描述。
若是RTP包是周期性产生的,那么将使用由采样时钟决定的名义上的采样时刻,而不是读取系统时间。例如,对一个固定速率的音频,采样时钟(时间戳时钟)将 在每一个周期内增长1。若是一个音频从输入设备中读取含有160个采样周期的块,那么对每一个块,时间戳的值增长160,而不考虑该块是否用一个包传递或是被 丢弃。
时间戳的初始值应当是随机的,就像序号同样。几个连续的RTP包若是(逻辑上)是同时产生的,如:属于同一个视频帧的RTP包,将有相同的序列号。若是数 据并非以它采样的顺序进行传输,那么连续的RTP包能够包含不是单调递增(或递减)的时间戳(RTP包的序列号仍然是单调变化的)。
根据一些文章我本身推敲了一下几个概念以下:
时间戳单位:时间戳计算的单位不为秒之类的单位,而是由采样频率所代替的单位,这样作的目的就是为了是时间戳单位更为精准。好比说一个音频的采样频率为8000HZ,那么咱们能够把时间戳单位设为1/8000。
时间戳增量:相邻两个RTP包之间的时间差(以时间戳单位为基准)。
如何设定时间戳之间的增量呢?
按照刚才时间戳单位来看,1秒钟按照时间戳单位就是8000,那么一秒钟若是能够播放20帧,也就是发送30帧(帧率),那么能够求出相邻两帧之间的时间差,也就是时间戳增量,那么显而易见是用8000/20,那么这个时间戳增量就为400.
网上大多数列举的一个例子是: 例如MPEG,每帧20ms,采样频率8000Hz,设定时间戳单位1/8000,而每一个包之间就是160的增量
这里又该如何理解呢?能够轻易地看出增量是直接8000与20ms相乘的结果,咱们能够知道这里两帧之间的时间为20ms,也就是0.02s,这个单位是以秒来衡量的,那么咱们要用时间戳单位来表示那么就是8000*0.02=160.因此时间戳增量为160.
还有一点为何通常都用90000做为视频采样频率呢?
90k是用于视频同步的时间尺度(TimeScale),就是每秒90k个时钟tick。为何采用90k呢?目前视频的帧速率主要有25fps、29.97fps、30fps等,而90k恰好是它们的倍数,因此就采用了90k。
--------------------------------------------------------------------------
---------------------------------------------------------------------------
10~16 Bit为PT域,指的就是负载类型(PayLoad),负载类型定义了RTP负载的格式,协议原文说该域由具体应用决定其解释。
目前,负载类型主要用来告诉接收端(或者播放器)传输的是哪一种类型的媒体(例如G.729,H.264,MPEG-4等),这样接收端(或者播放器)才知道了数据流的格式,才会调用适当的编解码器去解码或者播放,这就是负载类型的主要做用。
时间戳单位:时间戳计算的单位不是秒之类的单位,而是由采样频率所代替的单位,这样作的目的就是为了是时间戳单位更为精准。好比说一个音频的采样频率为8000Hz,那么咱们能够把时间戳单位设为1 / 8000。
时间戳增量:相邻两个RTP包之间的时间差(以时间戳单位为基准)。
采样频率: 每秒钟抽取样本的次数,例如音频的采样率通常为8000Hz
帧率: 每秒传输或者显示帧数,例如25f/s
再看看RTP时间戳课本中的定义:
RTP包头的第2个32Bit即为RTP包的时间戳,Time Stamp ,占32位。
时间戳反映了RTP分组中的数据的第一个字节的采样时刻。在一次会话开始时的时间戳初值也是随机选择的。即便是没有信号发送时,时间戳的数值也要随时间不 断的增长。接收端使用时间戳可准确知道应当在什么时间还原哪个数据块,从而消除传输中的抖动。时间戳还可用来使视频应用中声音和图像同步。
在RTP协议中并无规定时间戳的粒度,这取决于有效载荷的类型。所以RTP的时间戳又称为媒体时间戳,以强调这种时间戳的粒度取决于信号的类型。例如, 对于8kHz采样的话音信号,若每隔20ms构成一个数据块,则一个数据块中包含有160个样本(0.02×8000=160)。因 此每发送一个RTP分组,其时间戳的值就增长160。
官方的解释看懂没?没看懂?不要紧,我刚开始也没看懂,那就听个人解释吧。
首先,时间戳就是一个值,用来反映某个数据块的产生(采集)时间点的,后采集的数据块的时间戳确定是大于先采集的数据块的。有了这样一个时间戳,就能够标记数据块的前后顺序。
第二,在实时流传输中,数据采集后马上传递到RTP模块进行发送,那么,其实,数据块的采集时间戳就直接做为RTP包的时间戳。
第三,若是用RTP来传输固定的文件,则这个时间戳就是读文件的时间点,依次递增。这个再也不咱们当前的讨论范围内,暂时不考虑。
第四,时间戳的单位采用的是采样频率的倒数,例如采样频率为8000Hz时,时间戳的单位为1 / 8000 ,在Jrtplib库中,有设置时间戳单位的函数接口,而ORTP库中根据负载类型直接给定了时间戳的单位(音频负载1/8000,视频负载1/90000)
第五,时间戳增量是指两个RTP包之间的时间间隔,详细点说,就是发送第二个RTP包相距发送第一个RTP包时的时间间隔(单位是时间戳单位)。
若是采样频率为90000Hz,则由上面讨论可知,时间戳单位为1/90000,咱们就假设1s钟被划分了90000个时间块,那么,若是每秒发送25 帧,那么,每个帧的发送占多少个时间块呢?固然是 90000/25 = 3600。所以,咱们根据定义“时间戳增量是发送第二个RTP包相距发送第一个RTP包时的时间间隔”,故时间 戳增量应该为3600。
【补充】:最近思考了一下,又有了新的体会和解释,可能对你们更容易地去理解这个时间戳增量会有所帮助,补充在下面吧:
其实,网络发送重点关注的是流量的平衡,即均匀地利用网络带宽,为了实现这一点,须要知足:数据采集的速率与数据网络传输的速率尽可能保持一致。时间戳增量的设置影响的是RTP包的网络传输的速率,时间戳增量越小,发送速度越快。
下面再进一步解释一下时间戳增量是怎么计算出来的:
对于PAL制式的视频而言,每秒摄像头会采集 25 帧 数据,那么,每采集到 1帧 耗时 1/25 s ,若是咱们设计为1个RTP包只包含1帧数据,而且一次发送1帧,那么,要想网络流量均匀,则时间戳增量应该设计为 1/25 s . 而在通常的RTP协议的实现中,时间戳单位不是 秒(s),而约定为采样频率的倒数,因为通常视频的采样频率是 90000,故时间戳单位为 1/90000 s,所以,实际的时间戳增量 = 时间戳增量 ( 1/25 s ) / 时间戳单位(1/90000 s) = 3600