WebRTC 音视频同步原理与实现
所有的基于网络传输的音视频采集播放系统都会存在音视频同步的问题,作为现代互联网实时音视频通信系统的代表,WebRTC 也不例外。本文将对音视频同步的原理以及 WebRTC 的实现做深入分析。作者:良逸、审核:泰一
时间戳 (timestamp)
时间戳的生成
音频帧时间戳的生成
视频帧时间戳的生成
timestamp_us_
,然后算出此系统时间对应的 ntp_time_ms_
,再根据此 ntp 时间算出原始视频帧的时间戳 timestamp_rtp_
,参看下面的代码,计算逻辑也在 OnFrame
这个函数中。音视频同步核心依据
SR 包的生成
RTCPSender::BuildSR(const RtcpContext& ctx)
函数里面,老版本里面有 bug,写死了采样率为 8K,新版本已经修复,下面截图是老版本的代码:last_rtp_timestamp_
和它的采集时刻的系统时间 last_frame_capture_time_ms_
,和当前媒体流的时间戳的每 ms 增长速率 rtp_rate
,以及从 last_frame_capture_time_ms_
到当前时刻的时间流逝,就可以算出来。注意,last_rtp_timestamp_
是媒体流的原始时间戳,不是经过随机偏移的 RTP 包时间戳,所以最后又累加了偏移量 timestamp_offset_
。其中最后一个发送的 RTP 包的时间信息是通过下面的函数进行更新的:音视频同步的计算
StreamSynchronization::ComputeRelativeDelay()
函数中,之后又经过了 StreamSynchronization::ComputeDelays()
函数对其进行了指数平滑等一系列的处理和判断,得出最终控制音频和视频的最小延时时间,分别通过 syncable_audio_->SetMinimumPlayoutDelay(target_audio_delay_ms)
和 syncable_video_->SetMinimumPlayoutDelay(target_video_delay_ms)
应用到了音视频的播放缓冲区。RtpStreamsSynchronizer::Process()
函数来处理的。WebRTC 中实现音视频同步的手段就是 SR 包,核心的依据就是 SR 包中的 NTP 时间和 RTP 时间戳。最后的两张 NTP 时间-RTP 时间戳
坐标图如果你能看明白(其实很简单,就是求解出直线方程来计算 NTP),那么也就真正的理解了 WebRTC 中音视频同步的原理。如果有什么遗漏或者错误,欢迎大家一起交流!
END
评论