渲染时机 VCMTiming · 一帧该什么时候显示
帧解好了不能立刻显示——要在正确的时刻渲染,才能流畅且与音频同步。这一章读 video_coding/timing/timing.h 的 VCMTiming::RenderTime,讲清渲染时刻怎么由抖动、解码耗时、音视频同步共同决定,以及它如何把参差的到达变成匀速的画面。
渲染时机 VCMTiming · 一帧该什么时候显示
帧可解了,但不能解出来就立刻显示。显示早了、晚了都不行:早了画面跳,晚了对不上声音。每一帧都有一个正确的渲染时刻,算它的是 VCMTiming(modules/video_coding/timing/timing.h)。这一章看它。
RenderTime:算出该显示的时刻
VCMTiming 的核心方法很直白:
// modules/video_coding/timing/timing.h(节选)
Timestamp RenderTime(uint32_t rtp_timestamp, Timestamp now) const;给它一帧的 RTP 时间戳和当前时刻,它算出“这帧应该在什么时候渲染出去”。
音视频同步:视频等音频
渲染时机里,音视频同步(A/V sync) 是个专门的考量,呼应 RTCP SR 那章:
音频和视频是两条独立的流,各有各的抖动缓冲和延迟,要让它们“口型对得上”,得把两条流的播放时刻对齐到同一个绝对时间**。** 靠的是 RTCP SR 里的 RTP↔NTP 时间戳映射——它让接收端知道“这帧视频”和“这段音频”在真实世界的同一刻采集。VCMTiming 据此调整视频的渲染时刻,使之和音频的播放对齐。通常是视频等音频(音频延迟对听感影响更大、更难调,所以让视频迁就音频)。WebRTC 里 RtpStreamsSynchronizer 一类负责协调两条流的延迟,让 VCMTiming 算出的视频渲染时刻,和音频播放严丝合缝。“口型同步”这个用户最容易察觉的质量指标,就落在这里。
平滑与追赶
VCMTiming 还要处理动态变化:
- 网络突然变差,抖动变大,它会加大缓冲(渲染时刻往后推),用一点延迟换流畅。
- 网络恢复,它会慢慢把延迟收回来(逐渐提前渲染,别一下子跳),追回低延迟。
这个“缓冲深度随网络平滑调整”和抖动缓冲那章的权衡是一体两面——VCMTiming 是那个权衡在“每帧渲染时刻”上的落地。它追求的,始终是实时媒体的核心目标:在当前网络下,尽量低的延迟 + 尽量流畅的画面 + 和音频同步。
小结与下一章
VCMTiming::RenderTime 算每帧的正确渲染时刻,综合抖动缓冲延迟、解码耗时、音视频同步偏移——把参差的到达摆成匀速的显示。音视频同步靠 RTCP SR 的 RTP↔NTP 映射对齐两条流(通常视频等音频),RtpStreamsSynchronizer 协调,决定了“口型对得上”。它随网络平滑调整缓冲深度,追求低延迟 + 流畅 + 同步。
到点了,终于解码并显示。但网络丢包会让解码遇挫——最后一章看解码与丢包恢复,收尾第 6 部分。👉 解码与丢包恢复。
参考资料
- [1] libwebrtc 源码.
modules/video_coding/timing/timing.h(VCMTiming::RenderTime)、inter_frame_delay.h。 - [2] libwebrtc 源码.
video/rtp_streams_synchronizer2.h(音视频同步)。 - [3] 关联 RTCP SR 时间戳映射。