当前位置:首页 > > 充电吧
[导读] 本文在文章[1]的基础上,从源代码实现角度对WebRTC的GCC算法进行分析。主要内容包括: RTCP RR的数据源、报文构造和接收,接收端基于数据包到达延迟的码率估计,发送端码率的计算以及生效于目

本文在文章[1]的基础上,从源代码实现角度对WebRTC的GCC算法进行分析。主要内容包括: RTCP RR的数据源、报文构造和接收,接收端基于数据包到达延迟的码率估计,发送端码率的计算以及生效于目标模块。

拥塞控制是实时流媒体应用的重要服务质量保证。通过本文和文章[1][2],从数学基础、算法步骤到实现细节,对WebRTC的拥塞控制GCC算法有一个全面深入的理解,为进一步学习WebRTC奠定良好基础。

1 GCC算法框架再学习


本节内容基本上是文章[1]第1节的复习,目的是再次复习GCC算法的主要框架,梳理其算法流程中的数据流和控制流,以此作为后续章节的行文提纲。GCC算法的数据流和控制流如图1所示。


图1 GCC算法数据流和控制流

对发送端来讲,GCC算法主要负责两件事:1)接收来自接收端的数据包信息反馈,包括来自RTCP RR报文的丢包率和来自RTCP REMB报文的接收端估计码率,综合本地的码率配置信息,计算得到目标码率A。2)把目标码率A生效于目标模块,包括PacedSender模块,RTPSender模块和ViEEncoder模块等。

对于接收端来讲,GCC算法主要负责两件事:1)统计RTP数据包的接收信息,包括丢包数、接收RTP数据包的最高序列号等,构造RTCP RR报文,发送回发送端。2)针对每一个到达的RTP数据包,执行基于到达时间延迟的码率估计算法,得到接收端估计码率,构造RTCP REMB报文,发送回发送端。

由此可见,GCC算法由发送端和接收端配合共同实现,接收端负责码率反馈数据的生成,发送端负责根据码率反馈数据计算目标码率,并生效于目标模块。本文接下来基于本节所述的GCC算法的四项子任务,分别详细分析之。

2 RTCP RR报文构造及收发


关于WebRTC上的RTP/RTCP协议的具体实现细节,可参考文章[3]。本节主要从RR报文的数据流角度,对其数据源、报文构造和收发进行分析。其数据源和报文构造如图2所示,报文接收和作用于码率控制模块如图3所示。

在数据接收端,RTP数据包从Network线程到达Worker线程,经过Call对象,VideoReceiveStream对象到达RtpStreamReceiver对象。在该对象中,主要执行三项任务:1)接收端码率估计;2) 转发RTP数据包到VCM模块;3)接收端数据统计。其中1)是下一节的重点,2)是RTP数据包进一步组帧和解码的地方;3)是统计RTP数据包接收信息,作为RTCP RR报文和其他数据统计模块的数据来源,是我们本节重点分析的部分。

在RtpStreamReceiver对象中,RTP数据包经过解析得到头部信息,作为输入参数调用ReceiveStatistianImpl::IncomingPacket()。该函数中分别调用UpdateCounters()和NotifyRtpCallback(),前者用来更新对象内部的统计信息,如接收数据包计数等,后者用来更新RTP回调对象的统计信息,该信息用来作为getStats调用的数据源。


图2 RTCP RR报文数据源及报文构造

RTCP发送模块在ModuleProcess线程中工作,RTCP报文周期性发送。当线程判断需要发送RTCP报文时,调用SendRTCP()进行发送。接下来调用PrepareReport()准备各类型RTCP报文的数据。对于我们关心的RR报文,会调用AddReportBlock()获取数据源并构造ReportBlock对象:该函数首先通过ReceiveStatistianImpl::GetStatistics()拿到类型为RtcpStatistics的数据源,然后以此填充ReportBlock对象。GetStatistics()会调用CalculateRtcpStatistics()计算ReportBlock的每一项数据,包括丢包数、接收数据包最高序列号等。ReportBlock对象会在接下来的报文构造环节通过BuildRR()进行序列化。RTCP报文进行序列化之后,交给Network线程进行网络层发送。


图3 RTCP RR报文接收及反馈

在发送端(即RTCP报文接收端),RTCP报文经过Network线程到达Worker线程,最后到达ModuleRtpRtcpImpl模块调用IncomingRtcpPacket()进行报文解析工作。解析完成以后,调用TriggerCallbacksFromRTCPPackets()反馈到回调模块。在码率估计方面,会反馈到BitrateController模块。ReportBlock消息最终会到达BitrateControllerImpl对象,进行下一步的目标码率确定。

至此,关于RTCP RR报文在拥塞控制中的执行流程分析完毕。

3 接收端基于延迟的码率估计


接收端基于数据包到达延迟的码率估计是整个GCC算法最复杂的部分,本节在分析WebRTC代码的基础上,阐述该部分的实现细节。

接收端基于延迟码率估计的基本思想是:RTP数据包的到达时间延迟m(i)反映网络拥塞状况。当延迟很小时,说明网络拥塞不严重,可以适当增大目标码率;当延迟变大时,说明网络拥塞变严重,需要减小目标码率;当延迟维持在一个低水平时,目标码率维持不变。其主要由三个模块组成:到达时间滤波器,过载检查器和速率控制器。

在实现上,WebRTC定义该模块为远端码率估计模块RemoteBitrateEstimator,整个模块的工作流程如图4所示。需要注意的是,该模块需要RTP报文扩展头部abs-send-time的支持,用以记录RTP数据包在发送端的绝对发送时间,详细请参考文献[4]。


图4 GCC算法基于延迟的码率估计

接收端收到RTP数据包后,经过一系列调用到RtpStreamReceiver对象,由该对象调用远端码率估计模块的总控对象RemoteBitrateEstimatorAbsSendTime,由该对象的总控函数IncomingPacketInfo()负责整个码率估计流程,如图4所示,算法从左到右依次调用子对象的功能函数。

总控函数首先调用InterArrival::ComputeDeltas()函数,用以计算相邻数据包组的到达时间相对延迟,该部分对应文章[1]的3.1节内容。在计算到达时间相对延迟时,用到了RTP报文头部扩展abs-send-time。另外,实现细节上要注意数据包组的划分,以及对乱序和突发时间的处理。

接下来算法调用OveruseEstimator::Update()函数,用以估计数据包的网络延迟,该部分对应文章[1]的3.2节内容。对网络延迟的估计用到了Kalman滤波,算法的具体细节请参考文章[2]。Kalman滤波的结果为网络延迟m(i),作为下一阶段网络状态检测的输入参数。

算法接着调用OveruseDetector::Detect(),用来检测当前网络的拥塞状况,该部分对应文章[1]的3.2节内容。网络状态检测用当前网络延迟m(i)和阈值gamma_1进行比较,判断出overuse,underuse和normal三种网络状态之一。在算法细节上,要注意overuse的判定相对复杂一些:当m(i) > gamma_1时,计算处于当前状态的持续时间t(ou),如果t(ou) > gamma_2,并且m(i) > m(i-1),则发出网络过载信号Overuse。如果m(i)小于m(i-1),即使高于阀值gamma_1也不需要发出过载信号。在判定网络拥塞状态之后,还要调用UpdateThreshold()更新阈值gamma_1。

算法接着调用AimdRateControl::Update()和UpdateBandwidthEstimate()函数,用以估计当前网络状态下的目标码率Ar,该部分对应文章[1]的3.3节。算法基于当前网络状态和码率变化趋势有限状态机,采用AIMD(Additive Increase Multiplicative Decrease)方法计算目标码率,具体计算公式请参考文章[1]。需要注意的是,当算法处于开始阶段时,会采用Multiplicative Increase方法快速增加码率,以加快码率估计速度。

此时,我们已经拿到接收端估计的目标码率Ar。接下来以Ar为参数调用VieRemb对象的OnReceiveBitrateChange()函数,发送REMB报文到发送端。REMB报文会推送到RTCP模块,并设置REMB报文发送时间为立即发送。关于REMB报文接下来的发送和接收流程,和第1节描述的RTCP报文一般处理流程是一样的,即经过序列化发送到网络,然后发送端收到以后,反序列化出描述结构,最后通过回调函数到达发送端码率控制模块BitrateControllerImpl。

至此,接收端基于延迟的码率估计过程描述完毕。

4 发送端码率计算及生效


在发送端,目标码率计算和生效是异步进行的,即Worker线程从RTCP接收模块经回调函数拿到丢包率和REMB码率之后,计算得到目标码率A;然后ModuleProcess线程异步把目标码率A生效到目标模块如PacedSender和ViEEncoder等。下面分别描述码率计算和生效过程。


图5 发送端码率计算过程

码率计算过程如图5所示:Worker线程从RTCPReceiver模块经过回调函数拿到RTCP RR报文和REMB报文的数据,到达BitrateController模块。RR报文中的丢包率会进入Update()函数中计算码率,码率计算公式如文章[1]第2节所述。然后算法流程进入CapBitrateToThreshold()函数,和配置的最大最小码率和远端估计码率进行比较后,确定最终目标码率。而REMB报文的接收端估计码率Ar则直接进入CapBitrateToThreshold()函数参与目标码率的确定。目标码率由文章[1]的3.4节所示公式进行确定。需要注意的是,RR报文和REMB报文一般不在同一个RTCP报文里。


图6 发送端码率生效过程

发送端码率生效过程如图6所示:ModuleProcess线程调用拥塞控制总控对象CongestionController周期性从码率控制模块BitrateControllerImpl中获取当前最新目标码率A,然后判断目标码率是否有变化。若是,则把最新目标码率设置到相关模块中,主要包括PacedSender模块,RTPSender模块和ViEEncoder模块。

对于PacedSender模块,设置码率主要是为了平滑RTP数据包的发送速率,尽量避免数据包Burst造成码率波动。对于RTPSender模块,设置码率是为了给NACK模块预留码率,如果预留码率过小,则在某些情况下对于NACK报文请求选择不响应。对于ViEEncoder模块,设置码率有两个用途:1)控制发送端丢帧策略,根据设定码率和漏桶算法决定是否丢弃当前帧。2)控制编码器内部码率控制,设定码率作为参数传输到编码器内部,参与内部码率控制过程。

至此,发送端码率计算和生效过程分析完毕。

5 总结

本文结合文章[1],深入WebRTC代码内部,详细分析了WebRTC的GCC算法的实现细节。通过本文,对WebRTC的代码结构和拥塞控制实现细节有了更深层次的理解,为进一步学习WebRTC奠定良好基础。

参考文献

[1] WebRTC基于GCC的拥塞控制(上) – 算法分析
http://www.jianshu.com/p/0f7ee0e0b3be
[2] WebRTC视频接收缓冲区基于KalmanFilter的延迟模型.
http://www.jianshu.com/p/bb34995c549a
[3] WebRTC中RTP/RTCP协议实现分析
http://www.jianshu.com/p/c84be6f3ddf3
[4] abs-send-time. https://webrtc.org/experiments/rtp-hdrext/abs-send-time/

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭