前面我分享了一篇视频从Android端采集到编码发送模块的博客,对于平滑发送模块只是代码略过,这篇博客我具体来分析一下webrtc中的pasedsender发送到底是如何调控的:
首先抛出一个问题,为什么需要平滑发送?
对于camera采集的数据,经过编码器编码之后,会经过rtp组装,可能切片为多个rtp包,此时下一步就应该是送入发送模块,发送到远端了,但是由于网络是不断变化的,假如网络本来有点拥塞了,而此时一帧视频,比如说I帧编码后的数据很大,立马全部发送到发送模块进行发送的话,这样无疑会加大网络拥塞,影响通信质量,若视频质量相对较低,编码出来的码率相对较低,视频较为流畅,而此时提高质量,也有可能导致网络利用率不够而导致的丢包和拥塞,所以webrtc用到了pasedsender平滑发送,那么我们直接开始研究代码模块:
发送模块在process_thread_impl.cc中ProcessThreadImpl::Process()函数中进行处理
--> GetNextCallbackTime() //获取下一次发送时间
--> PasedSender::TimeUntilNextProcess() 获取下次Process()调用的时间
--> BitrateProber::TimeUntiNextProbe() 获取下次Process()调用的时间间隔 在Process() 实现wake_up->Wait()
-->PasedSender::Process() 平滑发送核心 主要功能是SendPacket即更新预算,我写出几个重要流程
{1.UpdateBugetWithElapsedTime() 根据延时和码率,结合发送队列大小,更新预算
2.BitrateProber::RecommendedMinProbeSize() 计算出此次发送的数据总量
3.if(!packets->Empty()){//发送数据} else{setpadding() 发送padding数据以保持码率的准确}}
然后根据计算出的wait时间循环从packets取数据,取多少数据由码率,延时实时计算得到
上面是PasedSender发送的核心代码解释,这里我还想说明一下码率的关系
我们这里的发送码率是上行带宽的码率,是音视频共同发送的码率,这个在测试中其实是很重要的:
上行带宽码率 = 音频上行码率 + 视频上行码率 + rtcpSender码率 + padding码率
音频上行码率 = 音频编码码率 + fec码率
视频上行码率 = 视频编码码率 + fec码率
后面我在专门分享一篇关于fec和音视频包的组合模块,看在rtp组包时候,如何根据丢包率,延时和码率来设置fec冗余度范围,降低延时和丢包率,提高音视频流畅