RTP时间映射及同步

RTP与RTCP时间戳同步解析

RTP包中的时间戳字段是说明数据包时间的同步信息,是数据能以正确的时间顺序恢复的关键。时间戳的值给出了分组中数据的第一个字节的采样时间。为了计算各个数据流的播放时间以及同步处理,仅有RTP包中的时间戳信息是不够的。

在整个播放过程中,包括这样几种时间,1)RTP包中的rtp time

                                                           2)PLAY请求的Response中的rtp time和npt

                                                           3)RTCP的SR中的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_rtptimesrart_npt分别是PLAY请求的Response中的rtptime和npt。

current_rtpTime是当前收到的RTP包头中的rtp time。

scale为PLAY请求的Response中的scale值。在正常播放的情况下为1,快速播放时大于1,当处于反向扫描模式时小于-1.

二、媒体间同步方法

上面的处理仅仅实现了媒体内的同步,在实现媒体间同步时,还需要进行其他的处理工作。这就需要用到RTCP的SR。在SR中包含一个<rtp,ntp>时间戳对,通过这个时间戳对可以将音频和视频准确的定位到一个绝对时间轴上。

<rtp,ntp>时间戳对的必要性在于不同流的 RTP 时间戳有不同的随机偏移量,因此无法直接进行同步。

<rtp,ntp>中的ntp是网络时间协议格式表示的绝对时间值。

<rtp,ntp>中的rtp与数据包中的 RTP 时间戳具有相同的单位和偏移量,但在大多数情况下此时间戳不等于任何临近的 RTP 包中的时间戳。

根据不同stream中的<rtp,ntp>时间戳对,可以将一个stream中的时间戳值映射为另一个stream的时间戳值,从而实现媒体间的同步。

在处理 RTP 和 RTCP 包时,获取绝对时间信息主要依赖于 RTCP 包中的 **SR(Sender Report)** 报告。RTP 包本身仅携带相对时间戳timestamp),该时间戳表示媒体数据的采样时刻,单位由媒体的时钟频率决定,但无法直接表示绝对时间[^4]。为了实现不同媒体流之间的同步,需要将 RTP 时间戳映射到一个统一的绝对时间基准上。 ### 从 RTCP SR 中获取绝对时间 RTCP 的 SR 报告中包含两个关键字段用于时间同步: - **NTP 时间戳**(ntp_secs 和 ntp_frac):表示发送 SR 的时刻的绝对时间,采用 NTP(Network Time Protocol)时间格式,精确到秒和分数部分。 - **RTP 时间戳**:表示与 NTP 时间戳对应的 RTP 时间戳,即在该 NTP 时间点上,媒体流的 RTP 时间戳值。 通过这两个时间戳,可以建立 RTP 时间与绝对时间之间的映射关系。例如,在某个 NTP 时间 `T_ntp`,对应的 RTP 时间戳为 `T_rtp`,之后接收到的 RTP时间戳 `t_rtp` 可以通过线性插值转换为绝对时间: $$ T_{abs} = T_{ntp} + \frac{t_{rtp} - T_{rtp}}{clock\_rate} $$ 其中,`clock_rate` 是媒体流的时钟频率,通常在 SDP 中协商确定[^2]。 ### RTP 扩展头中的绝对时间戳 在某些实现中,如 WebRTC,RTP 包可以通过扩展头携带 **绝对发送时间**(Absolute Send Time)或 **绝对采集时间**(Absolute Capture Time)[^3]。这些扩展字段直接提供与系统时间相关的绝对时间戳,有助于更精确地进行端到端延迟估算和多流同步。 例如,WebRTC 使用 `AbsoluteSendTime` 扩展头字段来记录每个 RTP 包的发送时间,单位为毫秒。该字段格式如下: ```c typedef struct { uint32_t absolute_send_time : 24; // 单位为毫秒,高位省略,只保留低24位 } AbsoluteSendTime; ``` 接收端可以根据该字段估算包的传输延迟,并进行播放时间调整。 ### 同步多流的绝对时间 在音视频同步场景中,通常的做法是在采集阶段为音频和视频打上相同的时间戳作为基准点,后续播放时依据该基准进行同步。例如,在某一绝对时刻同时采集音频和视频帧,并赋予相同的时间戳,之后根据各自的时钟频率递增。这种方式可以确保两个流在播放时保持一致的时间基准[^1]。 ### 示例:从 RTCP SR 解析 NTP 与 RTP 时间戳 以下是一个 C++ 示例,展示如何从 RTCP SR 报告中提取 NTP 时间戳和对应的 RTP 时间戳: ```cpp struct RtcpSr { uint32_t ntp_sec; uint32_t ntp_frac; uint32_t rtp_timestamp; }; void ParseRtcpSr(const uint8_t* data, RtcpSr* sr_out) { sr_out->ntp_sec = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; sr_out->ntp_frac = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; sr_out->rtp_timestamp = (data[8] << 24) | (data[9] << 16) | (data[10] << 8) | data[11]; } ``` 该函数从 RTCP SR 报告中提取 NTP 时间戳(秒和分数部分)以及 RTP 时间戳,用于后续的绝对时间计算。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值