webrtc的音视频同步处理一
webrtc内部的音视频同步是怎么处理的?
几个主要词:
capture time,render time,rtp的 timestamp,sr,计算ntp
先看视频的
采集过程
1、调用堆栈
2、采集
video_capture_impl.cc的 VideoCaptureImpl::IncomingFrame中
调用set_timestamp_ms() 设置时间
rtc::TimeMillis() 这个时间获取
CLOCK_MONOTONIC:从系统启动这一刻起开始计时,不受系统时间被用户改变的影响
这个值被赋值到timestamp_us_ 中
3、继续执行,进入video_stream_encoder.cc
4、可以看到ntp是在这里设置了
incoming_frame.set_ntp_time_ms(capture_ntp_time_ms);
前面有三个分支计算capture_ntp_time_ms
断点调试走了第二个,为何?
因为video_frame.render_time_ms()获取的就是timestamp_us_,前面设置的时间,从开机时间开始计算的
但是又加了delta_ntp_internal_ms_,这个值是怎么来的呢?
5、接下来生成rtp里面的timestamp,还是在video_stream_encoder.cc
设置了ntp,生成了timestamp,接下来就是放入编码队列,编码线程进行编码
6、总结一下:
delta_ntp_internal_ms_ = 绝对时间 - 开机到现在的时间
timestamp_us_ = render_time_ms() = set_timestamp_ms() = 开机到现在的时间
ntp_time_ms_ = 绝对时间 = timestamp_us_ + delta_ntp_internal_ms_
timestamp = 90*ntp_time_ms_
7、编码后调用堆栈
8、rtp_video_sender.cc 函数 RtpVideoSender::OnEncodedImage()
可以看到 rtp_timestamp 又加了一个偏移值rtp_rtcp->StartTimestamp()。原来是个随机值,为了安全性加密。
9、这段代码是重头戏,设置rtcp timestamp和ntp的对应关系,用于生成sr
这个capture_time_ms 中间绕了好几次,还是开机时间到现在的时间。
10、每发送一帧数据都会向rtcp刷新一次timestap对应的ntp
11、接下来看看 sr是怎么组包
rtp_timestamp = 初始的偏移+发送帧的tm+上次发送帧到现在逝去的tm
ntp 是拿当前时间,不过需要转换一下
report->SetNtp(TimeMicrosToNtp(ctx.now_us_));
sr中的NTP分两部分:
秒就是正常标识
秒后的是被分成了2的32次方份
12、总结一下:
过程还隐藏了一些环节,总体来说:
ntp 计算产生timestamp
rtcp 发送sr。包含timestamp和ntp的对应关系
注意sr中ntp的表示,秒后面是被分成2的32次方,并不是ms