RTP 视频时间戳单位是 时钟周期,标准频率为 90 kHz(即每秒 90000 个 tick)。 它代表帧在播放时间轴上的“相对时间”,而不是发送时间。
如果上一帧捕获时间是 t_prev,当前帧捕获时间是 t_now,单位为秒:
textΔt = t_now - t_prev timestamp_now = timestamp_prev + Δt × 90000
| 帧号 | 采集时间(秒) | 时间差 Δt | RTP ts 增量 | RTP timestamp |
|---|---|---|---|---|
| 0 | 0.000 | - | - | 1000000 |
| 1 | 0.033 | 0.033 | 2970 | 1002970 |
| 2 | 0.066 | 0.033 | 2970 | 1005940 |
| 3 | 0.100 | 0.034 | 3060 | 1009000 |
| 4 | 0.136 | 0.036 | 3240 | 1012240 |
这样生成的 RTP 时间戳完全根据真实捕获时间变化,可自然适应 VFR(可变帧率)。
cuint32_t video_ts_base = rand(); // 初始随机时间戳
uint32_t video_ts = video_ts_base;
double last_capture_time = now_seconds(); // 获取当前系统时间(秒)
while (get_next_frame(&frame)) {
double now = now_seconds();
double delta = now - last_capture_time;
uint32_t inc = (uint32_t)(delta * 90000.0);
video_ts += inc;
send_rtp_packet(frame.data, frame.size, video_ts);
last_capture_time = now;
}
不要用系统 tick 直接当 RTP 时间戳 RTP 时间戳只能反映播放时间间隔,不能是实际系统时间(否则 wraparound、同步都会出问题)。
要避免时间抖动
如果帧间隔噪声大(比如摄像头捕获不稳定),可以对 Δt 做平滑(如移动平均)以减少 jitter。
视频和音频的时钟不同
在录像/回放中保持一致的时间基
如果你的编码器输出带有 PTS/DTS(比如 ffmpeg),可以直接用帧的 pts → 转换到 90 kHz:
textrtp_ts = pts_in_seconds × 90000
| 场景 | 时间戳计算方式 |
|---|---|
| 固定帧率 | rtp_ts += 90000 / fps |
| 可变帧率 (VFR) | rtp_ts += (t_now - t_prev) * 90000 |
| 从编码器 PTS | rtp_ts = pts * 90000 |
本文作者:zion
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!