github:https://github.com/bigonelby/webrtcUml/tree/master/latest
这个图展示了webrtc中的应用带宽估算模块决策出的码率
这里的起点是RtpTransportControllerSend,前文已经提到,最终的带宽决策的值,将通过RtpTransportControllerSend的CongestionControlHandler记录,每次SetTargetRate的时候,都会更新类成员last_incoming_,如果有变化,则同时更新last_reported_
RtpTransportControllerSend模块在更新后,执行UpdateControlStat方法,这个方法,将从CongestionControlHandler中取出记录,即last_reported_,同时触发回调给observer_,这个observer就是TargetTransferRateObserver
这个Observer正是Call,原来Call在EnsureStarted的时候,就把自己注册给RtpTransportControllerSend了,理所应当,Call得到了这些数据。
接下来就是码率分配了。这里决策出的码率是带宽码率,是所有stream所共享的,因此自然要分配到人。谁来负责分配这个工作的?就是Call的成员BitrateAllocator,Call会调用其OnNetworkEstimateChanged方法,告知其网络发生改变了。BitrateAllocator需要重新分配带宽资源。
分配带宽资源的主要就是AllocateBitrates方法。有几种模式,如果带宽不足,则执行LowRateAllocation;正常的是NormalRateAllocation;如果带宽非常充裕,则执行MaxRateAllocation,这些分配函数,会具体的将码率分配给注册的AllocatableTrack,为每一个track都构建了一个结构体BitrateAllocationUpdate,然后通过BitrateAllocatorObserver将数据反馈给上层
究竟谁是observer呢?实际上就是每个VideoSendStreamImpl,这些stream在其StartupVideoSendStream的时候,通过BitrateAllocator的AddObserver,将自己注册至BitrateAllocator模块中,每一个对应一个AllocatableTrack
至此,VideoSendStreamImpl得到了分配好的码率,他需要将这些码率再进行计算交给编码器。因为发送还有overhead的数据,因此encoder显然不能独享这些码率。通过RtpVideoSenderInterface的OnBitrateUpdated,告知发送模块码率发送了变化,RtpVideoSender会通过所有RtpStreamSender的ModuleRtpRtcpImpl2模块拿到overhead的数据,即通过方法ExpectedPerpacketOverhead,最终VideoSendStreamImpl通过RtpVideoSenderInterface得到编码器应分得的码率,即GetPayloadBitrateBps
最后,就是给encoder设置了,通过VideoStreamEncoderInterface的OnBitrateUpdated方法进行设置,在其实现类VideoStreamEncoder中,再通过SetEncoderRates将码率设置给具体的编码器