流媒体|时间戳分析

好了,再说说RTP的时间戳吧。
首先,了解几个基本概念:

时间戳单位:时间戳计算的单位不是秒之类的单位,而是由采样频率所代替的单位,这样做的目的就是为了是时间戳单位更为精准。比如说一个音频的采样频率为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

在Jrtplib中好像不需要自己管理时间戳的递增,由库内部管理。但在ORTP中每次数据的发送都需要自己传入时间戳的值,即自己需要每次发完一个RTP包后,累加时间戳增量,不是很方便,这就需要自己对RTP的时间戳有比较深刻地理解,我刚开始就是因为没搞清楚,随时设置时间戳增量导致传输一直有问题,困扰我好久。
【流媒体|时间戳分析】好了,关于RTP的负载类型和时间戳的介绍就到这里了,这次通过解决RTP传输中的问题学到了不少知识,在此分享希望对大家有用。有说得不正确的地方欢迎高手指教,也可以来信交流:lujun.hust@gmail.com

    推荐阅读