github:https://github.com/bigonelby/webrtcUml/tree/master/latest
這個(gè)圖展示了webrtc中的transport-CC解析后的核心:trendline預(yù)測(cè)與碼率評(píng)估
上張圖介紹了杆烁,TransportFeedbackAdapter已經(jīng)將所有的原材料都準(zhǔn)備好了窃爷,在PacketResult中詳細(xì)的記錄了各個(gè)包的接收時(shí)間和發(fā)送時(shí)間耸三,這里就可以進(jìn)入到核心了,即DelayBasedBwe
DelayBasedBwe由名稱(chēng)就可以知道寥假,是基于延遲進(jìn)行的帶寬評(píng)估,這部分原本在接收端,最新的webrtc代碼改進(jìn)了這個(gè)行為,將這部分放在了發(fā)送端腔召,也方便程序員的調(diào)試。那么幀到達(dá)的時(shí)間扮惦,就通過(guò)擴(kuò)展RTCP包返回,即transport-cc亲桦。通過(guò)tranport-cc可以將包接收情況崖蜜,包接收的時(shí)間返回給發(fā)送端。這部分內(nèi)容前面已經(jīng)介紹過(guò)了客峭。因此豫领,到了DelayBasedBwe,已經(jīng)準(zhǔn)備好了各個(gè)包的發(fā)送以及接收時(shí)間舔琅。模塊將進(jìn)行下一步的核心決策
整個(gè)決策分為三個(gè)部分:分組等恐;過(guò)載檢測(cè);碼率決策
分組模塊即InterArrival备蚓,為何要分組呢课蔬?就是因?yàn)閱蝹€(gè)包的發(fā)送接收時(shí)間存在一定的偶然性,因此將相臨近的包分為一組郊尝,模型數(shù)據(jù)更加可靠二跋。分組的依據(jù)是什么呢?就是閾值kTimestampGroupLengthTicks流昏。IntervalArrival模塊記錄了上一個(gè)包組prev_timestamp_group_以及當(dāng)前包組current_timestamp_group_
記錄包組的結(jié)構(gòu)體為T(mén)imestampGroup扎即,這個(gè)結(jié)構(gòu)體中的size表示了包組的長(zhǎng)度吞获;first_timestamp,timestamp分別表示包組第一個(gè)包和最后一個(gè)包的發(fā)送時(shí)間谚鄙;first_arrival_ms各拷,complete_time_ms分別表示了包組第一個(gè)包和最后一個(gè)包的接收時(shí)間
通過(guò)InterArrival的NewTimestampGroup方法,判斷當(dāng)前packet是否屬于新的包組了闷营,判斷的依據(jù)就是當(dāng)前包的timestamp和包組的first_timestamp之差是否超過(guò)閾值kTimestampGroupLengthTicks烤黍,如果超過(guò),則認(rèn)為是新的分組粮坞,如果沒(méi)超過(guò)蚊荣,則還屬于同一個(gè)分組
通過(guò)InterArrival模塊,包被分成了包組莫杈,用包組的發(fā)送時(shí)間和接收時(shí)間互例,作為過(guò)載檢測(cè)器的輸入數(shù)據(jù)。過(guò)載檢測(cè)器的接口為DelayIncreaseDetectorInterface筝闹,繼承這個(gè)接口的就是TrendlineEstimator媳叨。接口有兩個(gè)方法,其一是Update关顷,即更新數(shù)據(jù)糊秆,即包組的發(fā)送和接收的時(shí)間;其二就是State议双,這個(gè)方法返回了當(dāng)前探測(cè)出的網(wǎng)絡(luò)狀態(tài)痘番,即BandwidthUsage,也就是kBwNormal還是kBwUnderusing亦或是kBwOverusing
如何決策出當(dāng)前網(wǎng)絡(luò)狀態(tài)是正常還是過(guò)載還是不足呢平痰?核心就是閾值比較汞舱。這里的閾值就是通過(guò)最小二乘法決策出的斜率。首先通過(guò)Update方法宗雇,出入包組相關(guān)數(shù)據(jù)昂芜,然后保存在delay_hist_中,這里保存的結(jié)構(gòu)體為PacketTiming赔蒲,有三個(gè)成員arrival_time_ms代表到達(dá)時(shí)間泌神,raw_delay_ms是原始的延遲時(shí)間,即接收時(shí)間差減去發(fā)送時(shí)間差舞虱,smoothed_delay_ms是平滑后的延遲時(shí)間欢际,是通過(guò)指數(shù)加權(quán)作用在raw_delay_ms,從而得出的數(shù)據(jù)矾兜。Trendline中的橫坐標(biāo)即為當(dāng)前包組的到達(dá)時(shí)間 - 首包組到達(dá)時(shí)間幼苛;縱坐標(biāo)為累積的平滑延遲。我們認(rèn)為這些數(shù)據(jù)的關(guān)系是線性的焕刮,因此可以通過(guò)最小二乘法算出斜率舶沿。這個(gè)計(jì)算是通過(guò)LinearFitSlope計(jì)算出來(lái)的墙杯。
計(jì)算出斜率后,接著進(jìn)入Detect方法括荡,進(jìn)行網(wǎng)絡(luò)狀態(tài)決策高镐,首先對(duì)上一步?jīng)Q策出的斜率trend進(jìn)行調(diào)整,得到modified_trend畸冲,再和閾值threshold_做比較嫉髓,如果modified_trend > threshold_ 則為kBwOverusing;如果modified_trend < - threshold_ 則為kBwUnderUsing邑闲;否則即為kBwNormal
最后算行,通過(guò)UpdateThreshold更新閾值
通過(guò)以上兩個(gè)步驟,已經(jīng)得到了當(dāng)前網(wǎng)絡(luò)的狀態(tài)是 正常 / 過(guò)載 / 不足苫耸。接下來(lái)通過(guò)碼率控制模塊rate_control_決策出具體的碼率州邢。這里的rate_control_即為AimdRateControl,所謂Aimd褪子,就是和式增加量淌,積式下降。輸入為RateControlInput嫌褪,這個(gè)參數(shù)是由DelayBasedBwe構(gòu)建出來(lái)呀枢,并出入到Aimd模塊的
首先調(diào)用Update方法,在這個(gè)方法中進(jìn)一步調(diào)用了ChangeBitrate笼痛,在這里先調(diào)用了ChangeState裙秋,即通過(guò)上一次的rate_control_state_,結(jié)合過(guò)載檢測(cè)器決策出來(lái)的BandwidthUsage缨伊,決策出當(dāng)前的rate_control_state_残吩。根據(jù)當(dāng)前的rate_control_state_,決策在當(dāng)前current_bitrate_的基礎(chǔ)上進(jìn)行和式增加或積式下降倘核。并可以通過(guò)方法LastEstimate將決策出的current_bitrate_值返回
最后小結(jié)一下:這張圖的核心就是DelayBasedBwe,入口就是IncomingPacketFeedbackVector即彪,在這個(gè)入口里首先調(diào)用了IncomingPacketFeedback紧唱,在這個(gè)函數(shù)里,通過(guò)InterArrival模塊進(jìn)行分組隶校,并通過(guò)TrendlineEstimator模塊進(jìn)行網(wǎng)絡(luò)狀態(tài)評(píng)測(cè)漏益。之后DelayBasedBwe會(huì)通過(guò)MaybeUpdateEstimate方法決策是否需要更新碼率,如果需要深胳,即調(diào)用UpdateEstimate方法绰疤,這個(gè)方法構(gòu)建了RateControlInput參數(shù),并交給AimdRateControl模塊進(jìn)行最終的碼率決策