github:https://github.com/bigonelby/webrtcUml/tree/master/latest
這個圖展示了webrtc中的帶寬檢測模塊
這里的起點是RtpTransportControllerSend坦敌,前文已經(jīng)提到完箩,RTCP最終接收到的包,最終回到了RtcpBandwidthObserver這個接口中镐侯,而實現(xiàn)這個接口的正是RtpTransportControllerSend
繼續(xù)介紹之前首先看看webrtc中優(yōu)秀的架構(gòu)設(shè)計。在webrtc中荷腊,基本都是基于接口開發(fā)溉潭,這使得整個架子非常有彈性弄兜,很容易擴展。比如網(wǎng)絡(luò)擁塞控制模塊正压,核心作用的就是NetworkControllerInterface這個接口欣福,這個接口是由其工廠創(chuàng)建出來的,即NetworkControllerFactoryInterface焦履,同樣也是一個接口拓劝。這是一個典型的工廠模式。webrtc為我們提供了一個默認(rèn)的工廠嘉裤,即controller_factory_fallback_郑临,其實體是GoogCcNetworkControllerFactory,即默認(rèn)采用GCC屑宠。當(dāng)然我們也可以覆蓋這整個的邏輯厢洞,只要傳入一個自定義的工廠就可以了,如果傳入了典奉,則會賦值給變量controller_factory_override_躺翻,這樣我們就可以創(chuàng)建出自定義的NetworkControllerInterface,從而構(gòu)建自定義的CC模塊了
繼續(xù)看數(shù)據(jù)流秋柄,輸入就是RtcpBandwidthObserver中的兩個方法:OnReceivedEstimatedBitrate和OnReceivedRtcpReceiverReport获枝,這兩個方法分別對應(yīng)了REMB和RR包的解析。那么這兩個方法所提供的信息骇笔,被傳遞到NetworkControllerInterface中省店,即OnRemoteBitrateReport,OnRoundTripTimeUpdate以及OnTransportLossReport笨触。在GCC中懦傍,這些信息最終傳遞給SendSideBandwidthEstimation,同樣通過三個Update方法傳入芦劣,分別是UpdateReceiverEstimate粗俱,UpdatePacketsLost以及UpdateRtt。后面SendSideBandwidthEstimation模塊決策碼率時依賴這些輸入的參數(shù)虚吟。
再來看看如何獲取決策出的碼率寸认。起點還是RtpTransportControllerSend签财,其內(nèi)部會啟動一個周期任務(wù),即StartProcessPeriodicTasks偏塞,這個任務(wù)用到了工具類RepeatingTaskHandle唱蒸。這個周期任務(wù)的主要工作就是UpdateControllerWithTimeInterval,這個方法會調(diào)用NetworkControllerInterface中的OnProcessInterval方法灸叼。這個方法會返回決策出的目標(biāo)碼率神汹,即結(jié)構(gòu)體NetworkControlUpdate,這個結(jié)構(gòu)體里的成員TargetTransferRate中有兩個關(guān)鍵的成員古今,即target_rate和stable_target_rate屁魏,就是最終決策出的碼率。
以上可以看出RtpTransportControllerSend模塊捉腥,會周期性的向NetworkControllerInterface模塊獲取決策出的碼率氓拼。這些碼率是怎樣決策出來的呢?實際上就是SendSideBandwidthEstimation模塊了但狭。上面提到周期性的調(diào)用OnProcessInterval方法披诗,這個方法進一步調(diào)用到SendSideBandwidthEstimation中的UpdateEstimate方法,在這個方法中會決策出目標(biāo)碼率立磁,并調(diào)用UpdateTargetBitrate進行目標(biāo)碼率的更新呈队。這里的決策算法大致就是按照丟包率決策,丟包小于2%唱歧,則碼率變?yōu)樵瓉淼?.08宪摧;如果在2%-10%則保持上一次不變;如果大于10%颅崩,則新碼率為:上次碼率 * (1 - 0.5 * loss)
以前webrtc的版本几于,只有這一種決策方式,決策好的target_bitrate就返回給上層了沿后。不過現(xiàn)在似乎增加了新的機制沿彭,即AcknowledgeBitrateEstimatorInterface,這個機制的具體算法還不太清楚尖滚,每次收到TransportCC包的時候喉刘,會輸入到這個模塊,通過IncomingPacketFeedbackVector輸入漆弄,底層決策的是BitrateEstimator睦裳。通過接口bitrate可以返回決策出的bitrate值。因此webrtc現(xiàn)在除了之前決策出的target_rate撼唾,還有這個決策出的值廉邑,即AcknowledgedRate,通過SendSideBandwidthEstimation的SetAcknowledgedRate接口,將此參數(shù)輸入蛛蒙。
最終交由LinkCapacityTracker模塊糙箍,對決策出的target_rate以及acknowledgedrate共同加權(quán)平均決策出一個值,這個值通過LinkCapacityTracker的estimate可以得到牵祟,通過SendSideBandwidthEstimation的GetEstimatedLinkCapacity亦可以得到倍靡,此值作為TargetTransferRate的stable_target_rate返回
這實際上給我們一個啟示,如果我們想引入另一個算法课舍,是否可以和AckknowledgeBitrateEstimatorInterface平行呢?完全采用類似的方式他挎,對需要的輸入?yún)?shù)進行解析筝尾,決策出bitrate值,然后再LinkCapacityTracker中办桨,增加這個值得加權(quán)平均筹淫,這樣可能是比較好的方式
以上NetworkControllerInterface得到了決策出的bitrate,并返回給RtpTransportControllerSend呢撞,之后處理的模塊就是CongestionControlHandler了损姜,那么決策出的碼率又將進行怎么樣的分配,以及最后如何設(shè)置到各發(fā)送流的編碼殊霞,發(fā)送模塊呢摧阅?后面繼續(xù)聊