返回文章
音视频

音视频同步:时间戳与缓冲区

画面与声音为什么会渐渐走散?从 PTS、时钟选择和缓冲策略,理解播放器里的时间。

我们习惯把视频理解成连续播放的一组图片,但播放器真正处理的是带有时间信息的流。声音和画面各有节奏,解码耗时也会变化。如果简单地“解出一帧就画一帧”,在某些输入上看似正常,在另一些输入上却会越播越不同步。理解时间戳,是建立正确同步策略的起点。

时间戳不是帧编号

PTS 表示展示时间,DTS 表示解码时间。在存在帧重排序的编码中,两者可能不同。时间戳还需要结合 time base 才有实际意义:一个数值并不天然表示毫秒。跨流比较时间之前,应当先换算到统一的时间单位,避免整数精度与舍入带来逐渐积累的偏差。

不要用固定帧率乘帧编号去替代真实 PTS,尤其是在可变帧率内容中。跳转后也不能沿用上一次的展示基准,应当等待新的有效时间戳并重新建立时钟关系。把“媒体时间”和“系统单调时间”分别命名,能减少很多隐蔽的单位错误。

先选一只可信的主时钟

常见策略以音频时钟为主,因为音频设备按照稳定的采样节奏消耗数据,而视频帧可以适度延迟或丢弃。没有音频时,可以使用外部单调时钟作为基准。音频时钟并不等于“已经送到设备的采样数量”,还需要扣除尚在设备缓冲区中的数据。

音频时钟 = 已提交音频的结束时间 - 设备中尚未播放的时长 视频偏差 = 当前视频帧 PTS - 音频时钟 偏差较小:按正常节奏展示 视频领先:稍后展示,等待主时钟 视频落后:根据阈值丢弃过期画面

缓冲区是在用延迟交换稳定

更大的缓冲区能吸收解码与网络波动,但也增加了响应延迟。点播、实时通话和本地预览的目标不同,不能套用同一组容量。最好按时间预算而不是仅按帧数量限制队列,因为不同内容的帧率、分辨率和解码成本可能相差很大。

把同步问题变成可观察的数据

记录音视频偏差分布、丢帧数量、队列时长和音频欠载次数,比只观察一段视频更有帮助。测试时覆盖可变帧率、长时间播放、暂停恢复、倍速与多次跳转。缓慢增加的偏差常与时间单位或时钟估计有关,突然跳变则可能来自队列未清理或时间戳不连续。

先统一时间单位,再明确主时钟,最后按预算设计缓冲。这几个看起来朴素的选择,往往比不断调整延迟常量更能解决真正的问题。

感谢阅读,希望这些思考对你有所启发。