1. RTP时间戳基础:协议、作用与时钟频率
各位同学好,我是老周。做流媒体这行十几年了,今天咱们聊聊RTP时间戳。说实话,音画同步这个坑,我踩过不少。很多新手上来就写代码,结果画面和声音对不上,急得直挠头。其实问题的根子,往往就在时间戳上。
这一章,我们先打地基。把RTP协议、时间戳的作用、时钟频率这几个概念彻底搞明白。后面再讲实战,你才不会慌。
1.1 RTP协议到底是什么?
RTP,全称Real-time Transport Protocol,实时传输协议。它跑在UDP上面,专门用来传音视频数据。你想想看,直播、视频通话、IP电话,底层基本都是它。
RTP本身不保证传输质量,它只负责把数据包从A点送到B点,并且带上时间信息。至于丢包了怎么办、乱序了怎么排,那是RTCP和上层应用的事。
我刚开始做流媒体时,总觉得RTP和RTCP是一回事。后来被坑过一次——只发了RTP没配RTCP,结果接收端根本不知道网络状况,画面卡成幻灯片。嗯,这里要注意:RTP是数据通道,RTCP是控制通道,两者配合才能干活。
一个标准的RTP包长这样:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
这里面,timestamp字段就是我们的主角。它占32位,单位不是秒,而是采样时钟的tick数。这个后面会细讲。
1.2 时间戳在RTP中的作用
时间戳是RTP的灵魂。没有它,接收端根本不知道什么时候该播放这个包。
具体来说,时间戳干三件事:
- 播放时序控制:告诉接收端,这个包应该在哪个时间点被播放出来。
- 音画同步:音频和视频各自有自己的时间戳,接收端通过比对它们,让声音和画面对齐。
- 抖动消除:网络有延迟抖动,接收端靠时间戳把乱序的包重新排好,再平滑播放。
我记得有一次做视频会议项目,音频和视频总是差个几百毫秒。查了两天,发现是音频时间戳的时钟频率配错了。音频用8kHz采样,时间戳增量算出来是160,结果代码里写成了320。画面和声音直接错位,像看译制片。从那以后,我对时间戳的计算就格外小心。
核心要点:RTP时间戳不是绝对时间,而是相对时间。它表示的是采样时刻的序号,不是墙上时钟的秒数。
1.3 时钟频率的概念
时钟频率,说白了就是时间戳的“刻度”有多细。单位是Hz,表示每秒有多少个tick。
举个例子:
- 音频用8kHz采样率,时钟频率就是8000 Hz。每秒钟时间戳增加8000。
- 视频用90kHz时钟频率,每秒钟时间戳增加90000。
为什么视频要用90kHz?这是历史原因。早期的MPEG标准定了这个值,后来大家就都跟着用了。我个人习惯,视频一律用90kHz,音频根据采样率来定。
时钟频率和时间戳的关系,可以用一个公式表示:
时间戳增量 = 时钟频率 × 帧间隔(秒)
举例:
音频:48kHz采样率,每帧20ms
时间戳增量 = 48000 × 0.02 = 960
视频:90kHz时钟频率,每帧33.33ms(30fps)
时间戳增量 = 90000 × 0.03333 ≈ 3000
你想想看,如果时钟频率设错了,时间戳增量就会算错。接收端拿到错误的时间戳,播放节奏全乱套。我曾经见过一个项目,视频时间戳增量算出来是3003,结果代码里写成了3000。30fps的视频,每帧差3个tick,一分钟下来就差了5400个tick,相当于60ms的偏移。肉眼看不出来,但音频对不上,用户直接投诉。
避坑指南:时钟频率一旦确定,整个会话期间不能改变。如果中途改了,接收端的时间戳计算会全部乱掉。我曾经在切换码率时忘了保持时钟频率一致,结果画面直接卡死。从那以后,我都在SDP里明确声明时钟频率,并在代码里做校验。
1.4 常见媒体类型的时钟频率
不同媒体类型,时钟频率不一样。下面这个表是我平时查得最多的:
| 媒体类型 | 常见时钟频率 | 说明 |
|---|---|---|
| PCM音频 | 8000、16000、32000、48000 | 等于采样率 |
| AAC音频 | 48000、44100、32000 | 等于采样率 |
| G.711音频 | 8000 | 固定值 |
| H.264视频 | 90000 | 标准规定 |
| H.265视频 | 90000 | 同H.264 |
| MPEG-4视频 | 90000 | 标准规定 |
音频的时钟频率一般就等于采样率。视频则统一用90kHz。为什么视频不直接用帧率?因为帧率不固定。30fps、60fps、可变帧率,如果用帧率做时钟频率,时间戳计算会非常麻烦。90kHz是30fps的3000倍,精度足够高,能支持到小数点后好几位。
小技巧:如果你不确定视频的时钟频率,直接用90000准没错。这是行业惯例,几乎所有解码器都认。
1.5 知识体系总览
下面这张图,把这一章的核心逻辑串起来了。你看一遍,心里就有谱了。
这张图把RTP时间戳拆成了三块:协议基础、作用、时钟频率。你顺着箭头看,就能理解它们之间的关系。RTP协议提供了传输载体,时间戳在里面扮演调度角色,而时钟频率决定了时间戳的精度。三者缺一不可。