webrtc發(fā)送端-probe

github:https://github.com/bigonelby/webrtcUml/tree/master/latest

webrtc-new-發(fā)送端-probe.drawio.png
  1. 這張圖介紹了probe的過程

  2. probe過程比較復雜,由于是對網(wǎng)絡的探測心包,因此大致的思路贱勃,就是構建probecluster丁寄;將probecluster信息分配給發(fā)送的數(shù)據(jù)包儡羔;將發(fā)送信息緩存在history中殴蹄;收到feedback的時候,從緩存中找到相應的發(fā)送信息章姓;由發(fā)送拧抖,接收的時間推算出bitrate

  3. 上面介紹了大概過程煤搜,對于cluster而言,還經(jīng)歷了合-分-合這幾個階段唧席,剛剛創(chuàng)建cluster的時候擦盾,每個cluster都是一個整體,是一個合的狀態(tài)淌哟;當需要將cluster分配給發(fā)送包時迹卢,有可能很多個包對應相同的cluster,這就相當于將分配好的cluster分解徒仓,開來了腐碱;最后收到feedback時,要將這些分解后的cluster重新合并掉弛,這又是一個合的過程

  4. 首先要看看的就是cluster的產(chǎn)生症见,這個cluster的產(chǎn)生實際上幕后的推手就是RtpTransportControllerSend,這是一個至關重要的類殃饿,他的很多行為都會導致cluster的產(chǎn)生谋作,比如當網(wǎng)絡變化時;當網(wǎng)絡路由變化時乎芳;當設置配置修改時等遵蚜,都會觸發(fā)重新probe。RtpTransportControllerSend的得力助手自然就是NetworkControllerInterface了奈惑,而其實現(xiàn)類GoogCcNetworkController也是我們的老朋友了吭净。我們以周期性的probe為例,來看看probe產(chǎn)生的過程肴甸。周期性的觸發(fā)者就是RtpTransportControllerSend寂殉,在StartProcessPeriodTasks時,開啟周期性更新雷滋,即UpdateControllerWithTimeInterval不撑,進而觸發(fā)NetworkControllerInterface的OnProcessInterval方法,然后調(diào)用ProbeController的Process方法晤斩。ProbeController焕檬,顧名思義,就是Probe的控制器澳泵,因此會根據(jù)當前的網(wǎng)絡帶寬預估值estimated_bitrate_bps_实愚,結合ProbeControllerConfig配置,決策出需要構建的ProbeClusterConfig的target_data_rate,以及id這些初始的關鍵信息腊敲』魑梗可以說ProbeController為probecluster分配了唯一的clusterid,以及對應的target_data_rate碰辅,這是cluster的起點

  5. 繼續(xù)看GooCCNetworkController的OnProcessInterval方法懂昂,這個方法返回了NetworkControllerUpdate,這個類其中的成員就是probe_cluster_configs没宾,這個vector是由ProbeController產(chǎn)生的凌彬。至此,RtpTransportControllerSend得到了助手GooCCNetworkController的決策報告循衰,即NetworkControllerUpdate铲敛,在這個報告里,有ProbeClusterConfig信息会钝,這個信息將送給下一個部門

  6. 下面我們看第二部分伐蒋,pacing模塊根據(jù)指示構建ProbeCluster。上面的介紹已經(jīng)知道迁酸,RtpTransportControllerSend已經(jīng)拿到助手的決策報告先鱼,因此已經(jīng)知道需要進行probe,以及所對應的ProbeClusterConfig胁出,緊接著型型,RtpTransportControllerSend就把這份報告交給了pacing模塊段审,其pacer()指向的正是PacedSender全蝶,這個模塊負責將rtp包發(fā)送到網(wǎng)絡,不過在此之前寺枉,他要首先看看probe的情況抑淫。當他發(fā)現(xiàn)需要probe時,就將相關的信息姥闪,交給他的助手prober_了始苇,即BitrateProber,BitrateProber的作用就是根據(jù)決策出來的ProbeClusterConfig這個配置筐喳,生產(chǎn)出ProbeCluster了催式。ProbeCluster有個關鍵的信息就是pace_info,即PacedPacketInfo避归,這可是一個核心的信息荣月!首先,send_bitrate_bps指明了這個cluster的目標探測比特率梳毙,probe_cluster_id正是每個cluster的唯一標識符哺窄,起到身份證的作用!接下來probe_cluster_min_probes和probe_cluster_min_bytes,這兩個成員也很重要萌业,他們是從BitrateProberConfig獲取到的坷襟,其作用是決策出這個cluster究竟需要多少次probe,以及最小的bytes生年,換句話說婴程,這兩個變量決定了這個cluster到哪里才算是完成了任務!

  7. 我們來看看究竟可以從BitrateProber中獲取什么抱婉,最重要的就是剛開始知道要進行probe時排抬,通過CreateProbeCluster生產(chǎn)出所有的ProbeCluster,保存在其成員clusters_中授段,創(chuàng)建的過程上面已經(jīng)說了蹲蒲,根據(jù)傳遞下來的ProbeClusterConfig。然后通過ProbeSent這個方法侵贵,告訴BitrateProber模塊究竟已經(jīng)probe發(fā)送了多少數(shù)據(jù)了届搁,這里還有一道手續(xù),就是用到了6中介紹的兩個變量窍育,根據(jù)probe_cluster_min_probes和probe_cluster_min_bytes這兩個閾值卡睦,決定了這個cluster是否已經(jīng)完成任務了,如果超過這兩個閾值漱抓,則會將這個cluster從vector中移除表锻。最后一個核心的方法就是CurrentCluster了,他會返回當前的ProbeCluster的PacedPacketInfo

  8. 一切順利的話乞娄,就就到達第三部分了瞬逊,即ProbeCluster印記送達發(fā)送模塊。什么是ProbeCluster的印記呢仪或,就是PacedPacketInfo确镊!Pacing的過程之前已經(jīng)介紹過,PacingController會通過PacketRouter的SendPacket將包發(fā)送出去范删,當然蕾域,這里要補充兩個額外的工作,就是要拿到rtppacket所分配的cluster到旦,即通過BitrateProber的CurrentCluster方法旨巷,得到當前的PacedPacketInfo印記,這個印記將隨著這個rtp包一直傳輸?shù)桨l(fā)送層添忘。當成功發(fā)送數(shù)據(jù)后采呐,要通過BitrateProber的ProbeSent方法來更新probe的數(shù)據(jù),內(nèi)部會決策當前的probecluster是否已經(jīng)達到閾值昔汉,完成任務懈万,如果確實已經(jīng)達到閾值拴清,則會從clusters_這個向量中移除出去,這樣会通,下一個包就將用之后的印記了口予。通過這個過程,我們也可以了解到涕侈,這就是上述的從合到分的過程沪停,一個cluster可以對應多個rtp包,每當發(fā)送rtp包的時候裳涛,如果處于probe狀態(tài)木张,都會從BitrateProber中拿到對應的印記PacedPacketInfo,如果處理的幾個包沒有超過兩個cluster閾值端三,則這些包使用的是相同的cluster舷礼,即他們的clusterid都相同。這樣郊闯,就將同一個cluster分配到不同的rtp包中去了妻献,完成了從合到分的過程

  9. pacing的發(fā)送過程之前已有介紹,這里不再復述团赁,總之育拨,最終rtp包到達了RtpSenderEgress模塊,隨著rtp包一同而來的欢摄,就是其印記PacedPacketInfo熬丧。RtpSenderEgress會構建RtpPacketSendInfo這個類,這個類的成員pacing_info正是這個包的印記PacedPacketInfo怀挠。構建好RtpPacketSendInfo后析蝴,RtpSenderEgress將這個信息反饋給其觀察者TransportFeedbackObserver,這個觀察者有一個接口就是OnAddPacket唆香,就是專門為了收集RtpPacketSendInfo信息的

  10. 接下來終于來到了第四部分發(fā)送模塊緩存cluster印記嫌变。前面已經(jīng)介紹,發(fā)送前躬它,每個包對應的印記將以回調(diào)的形式匯報給TransportFeedbackObserver,而實現(xiàn)這個接口的正是RtpTransportControllerSend东涡!可見RtpTransPortControllerSend就如同如來佛祖一樣冯吓,掌控著所有信息。接著疮跑,RtpTransportControllerSend將此信息轉(zhuǎn)達給TransportFeedbackAdapter组贺,他會將這些核心信息保存在其history_中,每個history_的成員都是PacketFeedback祖娘,這個類信息是由RtpPacketSendInfo生成的失尖。最終,包的印記,就被保存在PacketFeedback的SentPacket的pacing_info成員中掀潮,供后續(xù)使用

  11. 終于一路來到了第五部分菇夸,即發(fā)送模塊收到feedback后,根據(jù)緩存決策最終bitrate仪吧。前面已經(jīng)說過每個包在發(fā)送之前庄新,都會將pacing印記保存在TransportFeedbackAdapter中。接下來我們介紹一下這些保存的pacing印記究竟該如何使用薯鼠。真正的使用的地方择诈,就是在接收到這些包的feedback反饋時,此時該包已經(jīng)發(fā)送到接收端出皇,接收端整理了收到這些包的信息羞芍,通過transport-feedback的RTCP報文,反饋給發(fā)送端郊艘。關于transport-feedback報文涩金,之前已經(jīng)介紹過,這里不再重復暇仲。而接收這些報文信息的步做,依然是我們的老朋友,佛祖奈附,RtpTransportControllerSend全度。通過其OnTransportFeedback方法得到這些信息。當然斥滤,這些信息還是需要交由TransportFeedbackAdapter處理一下将鸵,因為通過transport-feedback報文,我們只能知道每個包的接收信息佑颇,那么發(fā)送信息該如何獲取呢顶掉?當然是TransportFeedbackAdapter的緩存history_中。這個history_是一個map挑胸,其key即為transport-id痒筒,這個id是每個包獨一無二的。通過這個transport-id的索引茬贵,我們可以在history_中找到對應的PacketFeedback簿透,其send成員SentPacket記錄了發(fā)送的相關信息,當然解藻,當初的pacing印記PacedPacketInfo也在這里

  12. 經(jīng)過TransportFeedbackAdapter的加工后老充,將信息匯總到TransportPacketsFeedback中,這個類由TransportFeedbackAdapter生成螟左,其維護的向量表packet_feedbacks記錄了包信息啡浊,對應的類為PacketsResult觅够。特別的PacketsResult的sent_packet成員即為SendPacket,記錄著包的發(fā)送相關信息

  13. 最終RtpTransportControllerSend會將處理好的信息TransportPacketsFeedback交給controller_巷嚣,即GoogCcNetworkController喘先,該模塊會進一步將信息交給其成員probe_bitrate_estimator_來處理。這個成員對應的類是ProbeBitrateEstimator涂籽,這個類接收所有有probe印記的包苹祟,并進一步處理。每個PacketsResult信息评雌,都會進行HandleProbeAndEstimateBitrate的處理树枫。這個處理方式將所有相同clusterid的包,合并成相同額AggregatedCluster景东,這里體現(xiàn)了從分到合的過程砂轻。整理成AggregatedCluster后斤吐,通過信息就可以決策出發(fā)送的碼率和接收的碼率了,因為信息已經(jīng)很充分庄呈,我們知道這個cluster的實際大小派阱,以及發(fā)送和接收的相關信息了贫母。當發(fā)送碼率和接收碼率比較接近時,我們選取兩者的最小值绿贞,作為評估后的帶寬值籍铁,即estimated_data_rate_寨辩。至此歼冰,整個probe過程終于可以告一段落隔嫡!

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腮恩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子秸滴,更是在濱河造成了極大的恐慌,老刑警劉巖咒唆,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件全释,死亡現(xiàn)場離奇詭異误债,居然都是意外死亡,警方通過查閱死者的電腦和手機李命,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來周叮,“玉大人界斜,你說我怎么就攤上這事各薇∏团校” “怎么了林螃?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長完残。 經(jīng)常有香客問我伏钠,道長,這世上最難降的妖魔是什么谨设? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮赴肚,結果婚禮上,老公的妹妹穿的比我還像新娘二蓝。我一直安慰自己,他們只是感情好侣夷,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布横朋。 她就那樣靜靜地躺著,像睡著了一般百拓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衙传,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天蓖捶,我揣著相機與錄音,去河邊找鬼。 笑死细睡,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的溜徙。 我是一名探鬼主播蠢壹,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼九巡!你這毒婦竟也來了图贸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎求妹,沒想到半個月后乏盐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體佳窑,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡制恍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了神凑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片净神。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖溉委,靈堂內(nèi)的尸體忽然破棺而出鹃唯,到底是詐尸還是另有隱情,我是刑警寧澤瓣喊,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布坡慌,位于F島的核電站,受9級特大地震影響藻三,放射性物質(zhì)發(fā)生泄漏洪橘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一棵帽、第九天 我趴在偏房一處隱蔽的房頂上張望熄求。 院中可真熱鬧,春花似錦逗概、人聲如沸弟晚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卿城。三九已至,卻和暖如春铅搓,著一層夾襖步出監(jiān)牢的瞬間瑟押,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工狸吞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勉耀,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓蹋偏,卻偏偏與公主長得像便斥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子威始,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容