基础理论
关于RTP的时间戳知识点回顾
时间戳单位:时间戳计算的单位不是秒,而是采用采样频率的倒数,这样做的目的是为了使时间戳单位更为精准。比如说一个音频的采样频率为8000Hz,那么我们可以把时间戳单位设为1/8000s。
时间戳增量:相邻两个RTP包之间的时间差(以时间戳单位为基准)
采样频率: 每秒钟抽取样本的次数,例如音频的采样率一般为8000Hz,即每秒采样8000次,产生8000个样本
帧率: 每秒传输或者显示帧数,例如25f/s
小结:
时间戳反映了RTP分组中的数据的第一个字节的采样时刻。在一次会话开始时的时间戳初值也是随机选择的。即使是没有信号发送时,时间戳的数值也要随时间不 断的增加**。接收端使用时间戳可准确知道应当在什么时间还原哪一个数据块,从而消除传输中的抖动。**时间戳还可用来使视频应用中声音和图像同步。
在RTP协议中并没有规定时间戳的粒度,这取决于有效载荷的类型。因此RTP的时间戳又称为媒体时间戳,以强调这种时间戳的粒度取决于信号的类型。例如,对于8kHz采样的音频信号,若每隔20ms构成一个数据块,则一个数据块中包含有160个样本(0.02×8000=160)。因此每发送一个RTP分组,其时间戳的值就增加160。
如果采样频率为90000Hz,则时间戳单位为1/90000,我们就假设1s钟被划分了90000个时间块,那么,如果每秒发送25帧,那么,每一个帧的发送占多少个时间块呢?当然是 90000/25 = 3600。因此,我们根据定义"时间戳增量是发送第二个RTP包相距发送第一个RTP包时的时间间隔",故时间戳增量应该为3600。
1,时间戳可用来使视频应用中声音和图像同步,为什么呢?
首先,这个时间戳就是一个值且必须满足大家都来使用这个值,用来反映某个数据块的产生(采集)时间点的, 后采集的数据块的时间戳肯定是大于先采集的数据块的。有了这样一个时间戳,就可以标记数据块的先后顺序。
第二,在实时流传输中,数据采集后立刻传递到RTP 模块进行发送,那么,其实,数据块的采集时间戳就直接作为RTP包的时间戳。
第三,如果用RTP来传输固定的文件,则这个时间戳 就是读文件的时间点,依次递增。这个不再我们当前的讨论范围内,暂时不考虑。
rtsp时间戳类型
在分析音视频同步之前,我们先知道都有哪几类的时间戳。
RTP 包中的 rtptime :这是 RTP 协议中用于同步媒体流的关键字段。它表示的是分组中数据的第一个字节的采样时间。RTP 时间戳的初始值是随机的,而且即使没有数据发送,时间戳也会随着时间的推移而增加,这样可以保持媒体流的连续性。RTP 时间戳不能单独用于同步,因为它的初始值是随机的,需要通过 RTCP 协议来同步不同的 RTP 流 。
PLAY 请求的 Response 中的 rtp time 和 npt:
- npt (Normal Play Time):这是正常播放时间,它表示流相对于播放开始时的绝对位置。播放开始时的时间定义为 0.0s。这个时间用于客户端请求特定时间点的媒体流,并且可以用于在播放过程中跟踪当前播放的位置 。
- rtptime:这是发送 PLAY 请求后收到的第一个 RTP 包的时间戳值。它表示的是会话开始的相对时间,用于客户端计算当前播放时间戳 。
- npt 是影⽚开始的相对时间,⽽ rtptime 是会话开始的相对时间。
RTCP 的 SR (Sender Report) 中的 rtp 和 ntp 时间戳对:
- RTP 时间戳:与数据包中的 RTP 时间戳具有相同的单位和偏移量,但它通常不等于任何临近的 RTP 包中的时间戳 。
- NTP 时间戳 :这是一个 64 位的时间戳,用于在 RTCP 报文中表示发送者报告的绝对时间。NTP 时间戳基于协调世界时(UTC),提供了一个全局的时间参考,使得不同的 RTP 流可以通过 NTP 时间戳同步到同一个时间轴上 。
流内同步和流间同步
多媒体通信同步方法,主要有时间戳同步法、同步标记法、多路复用同步法三种。
下面主要讨论时间戳同步法,特别是RTP时间戳同步。内容包括RTP媒体间同步的实现。
1.序列号字段是否可以作为流内的同步标识?
序列号只表示了包发出的先后顺序,它表示不了任何时间上的其它概念,所以严格的说,序列号并不能作为流内的同步标志。但是,由于一般来说,包的发送时间都会有严格限制,比如音频包是每秒种发送30个数据包,也就是说,每个包间隔1000/30MS,而这个时间就可以 作为一个同步时间来播放。也就是说,按照序列号,每1000/30MS间隔播放一个数据包,这样也能保证同步,但是这时候请考虑丢包问题。
2.为什么需要RTCP的NTP时间来实现媒体间同步?没有RTCP,能实现RTP媒体间的同步吗?
仅仅使用RTP时间戳是无法实现媒体间同步的,根本的原因是音频时间轴和视频时间轴是完全独立的,通过音频帧和视频帧的时间戳,无法确定一个视频帧和一个音频帧的相对时间关系,也就是无法把它们都准确定位在绝对时间轴上。
要实现RTP媒体间同步,需要借助于RTCP,在RTCP的SR包中,包含有对,音频帧RTP时间戳和视频帧RTP时间戳通过对,都可以准确定位到绝对时间轴NTP上,音频帧和视频帧的相对时间关系就可以确定下来 了。为什么设计了sr包,主要是为了能让音频视频的rtp的时间戳可以有不同的起点,sr包的<rtp ntp>就是为了获取这个不同的起点。
本质而言:如果音频视频时间戳都是同样的起点 就不需要用到ntp。
基本上可以这么认为。例如,对于RTP实时流,在发送端媒体间就同步的很好,在接收端只需做少许处理,不需要RTCP,就可以实现媒体间同步。当然,这只是少数例外。因为RTP规范并不包括这个假设,所以我们还是按照RTP规范来做吧。
1.流内时间戳映射关系
npt 和 rtptime 的区别在于 npt 是影⽚开始的相对时间,⽽ rtptime 是会话开始的相对时间。因此在 client 端,需要对这两者进⾏ map 处理。
在 client 端计算播放时间戳的公式如下:
scale 值。在正常播放的情况下为 1 ,快速播放时⼤于 1 ,当处于反向扫描模式时⼩于 -1 .
客户端播放时间 = rtp.ts - play.rtp.ts / scale + play.ntp.ts
假设有以下情况:
视频编码格式为 30 fps
PLAY 请求的 Response 中获得:
npt=0.0
rtptime=1000
scale=1.0
现在收到一个 RTP 数据包,其 rtptime=2500
nptUs = (2500 - 1000) / 1.0 + 0.0
= 1500 / 1.0 + 0.0
= 1.5 seconds
为了消除网络延迟的影响,可以结合 RTCP SR 报文中提供的 LSR (Last Sender Report) 和 DLSR (Delay Since Last Sender Report) 信息,对 RTP 时间戳进行校正:
corrected_rtpTime = current_rtpTime - (LSR + DLSR)
2.媒体间同步⽅法(不同设备的同步)
上⾯的处理仅仅实现了媒体内的同步,在实现媒体间同步时,还需要进⾏其他的处理⼯作。这就需要⽤到 RTCP 的 SR ( Sender Report )。在 SR 中包含⼀个< rtp , ntp >时间戳对,通过这个时间戳对可以将 ⾳频和视频准确的定位到⼀个绝对时间轴上。
RTP 时间戳对应的 NTP 时间戳,从而将 RTP 流中的事件映射到全局的 NTP 时间轴上。
推导图:
同步流程:接收端收到 RTCP SR 报文,获取 <rtp, ntp> 时间戳对。
根据 <rtp, ntp> 时间戳对,将不同 RTP 流的时间戳映射到统一的时间轴上。
利用映射后的时间戳值进行媒体间的时间校准和同步播放。
音视频不是同时产生
发送端的音视频流并没有对齐,但是周期地发送SR包,接收端得到音视频SR包的RTP时间戳、NTP时间戳后通过****线性回归****得到NTP时间戳Tntp和RTP时间戳Trtp时间戳的对应关系:
- Tntp_audio = f(Trtp_audio)
- Tntp_video = f(Trtp_video)
其中Tntp = f(Trtp) = a*kTrtp + b 为线性函数,其中 a 是比例系数, b 是时间偏移量
这样接收端每收到一个RTP包,都可以将RTP时间戳换算成NTP时间戳,从而在同一时间基准下进行音视频同步。
rtp和ntp转换是线性关系:绝对时间 ntp=x+80ms,rtp=80*90=7200;
建立线性关系:则rtp=(ntp-x)*90,RTP时间戳 = (x + 80ms - x) * 90 = 80ms * 90 = 7200
这个示例是一种简单的线性关系:RTP时间戳可以通过NTP时间减去一个基准时间x,再乘以一个比例因子90来计算得出。不是所以情况都适用
实际情况如下图:
实例分析 :
问:音频采样率8k,视频帧率25. Audio从头开始,音频时间戳320会在多少ms播放呢?
答:320*1000/8000 =40ms
问:那么收到的视频帧rtp时间戳是7200应该在多少ms播放呢?
答:
因为第一个音频是从0开始播放的,但是第一个视频帧可能是在第1ms开始的,而不是从0ms开始的.
如果视频从1ms开始,rtcp第一个音视频帧 video rtp 是3600,它表示1+40 = 41ms。而audio rtp 是160表示40ms.所以先要计算audio,video的绝对时间差,倒退开始的时间差.
视频同步到音频为例:
- diff=(video ntp time)-(audio ntp time)=1ms (rtcp中NTP时间相减).
- 对应的rtp时间相减,3600-90=3510.3510就是视频ntp对应的40ms绝对时间(time base).
- 后面rtp 7200是多少ms呢?
7200-3510=7200-(3600-90)=3600+90=40ms+1=41ms;即在播放base 40ms之后的41ms播放,等于81ms的地方播放.- 或者使用线性回归 rtp=(ntp-x)*90 7200 = (ntp - 1)*90 =81ms
后续的每个audio/video rtp timestamp减去这个base就是播放时间。实现同步.音频同步到视频原理一样.
参考
使用rtcp实现音视频同步 - 知乎 (zhihu.com)
RTP、RTCP及媒体流同步 - 明明是悟空 - 博客园 (cnblogs.com)
学习资料分享