webrtc发送端-probe

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

webrtc-new-发送端-probe.drawio.png
  1. 这张图介绍了probe的过程

  2. probe过程比较复杂,由于是对网络的探测,因此大致的思路,就是构建probecluster;将probecluster信息分配给发送的数据包;将发送信息缓存在history中;收到feedback的时候,从缓存中找到相应的发送信息;由发送,接收的时间推算出bitrate

  3. 上面介绍了大概过程,对于cluster而言,还经历了合-分-合这几个阶段,刚刚创建cluster的时候,每个cluster都是一个整体,是一个合的状态;当需要将cluster分配给发送包时,有可能很多个包对应相同的cluster,这就相当于将分配好的cluster分解,开来了;最后收到feedback时,要将这些分解后的cluster重新合并,这又是一个合的过程

  4. 首先要看看的就是cluster的产生,这个cluster的产生实际上幕后的推手就是RtpTransportControllerSend,这是一个至关重要的类,他的很多行为都会导致cluster的产生,比如当网络变化时;当网络路由变化时;当设置配置修改时等,都会触发重新probe。RtpTransportControllerSend的得力助手自然就是NetworkControllerInterface了,而其实现类GoogCcNetworkController也是我们的老朋友了。我们以周期性的probe为例,来看看probe产生的过程。周期性的触发者就是RtpTransportControllerSend,在StartProcessPeriodTasks时,开启周期性更新,即UpdateControllerWithTimeInterval,进而触发NetworkControllerInterface的OnProcessInterval方法,然后调用ProbeController的Process方法。ProbeController,顾名思义,就是Probe的控制器,因此会根据当前的网络带宽预估值estimated_bitrate_bps_,结合ProbeControllerConfig配置,决策出需要构建的ProbeClusterConfig的target_data_rate,以及id这些初始的关键信息。可以说ProbeController为probecluster分配了唯一的clusterid,以及对应的target_data_rate,这是cluster的起点

  5. 继续看GooCCNetworkController的OnProcessInterval方法,这个方法返回了NetworkControllerUpdate,这个类其中的成员就是probe_cluster_configs,这个vector是由ProbeController产生的。至此,RtpTransportControllerSend得到了助手GooCCNetworkController的决策报告,即NetworkControllerUpdate,在这个报告里,有ProbeClusterConfig信息,这个信息将送给下一个部门

  6. 下面我们看第二部分,pacing模块根据指示构建ProbeCluster。上面的介绍已经知道,RtpTransportControllerSend已经拿到助手的决策报告,因此已经知道需要进行probe,以及所对应的ProbeClusterConfig,紧接着,RtpTransportControllerSend就把这份报告交给了pacing模块,其pacer()指向的正是PacedSender,这个模块负责将rtp包发送到网络,不过在此之前,他要首先看看probe的情况。当他发现需要probe时,就将相关的信息,交给他的助手prober_了,即BitrateProber,BitrateProber的作用就是根据决策出来的ProbeClusterConfig这个配置,生产出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生产出所有的ProbeCluster,保存在其成员clusters_中,创建的过程上面已经说了,根据传递下来的ProbeClusterConfig。然后通过ProbeSent这个方法,告诉BitrateProber模块究竟已经probe发送了多少数据了,这里还有一道手续,就是用到了6中介绍的两个变量,根据probe_cluster_min_probes和probe_cluster_min_bytes这两个阈值,决定了这个cluster是否已经完成任务了,如果超过这两个阈值,则会将这个cluster从vector中移除。最后一个核心的方法就是CurrentCluster了,他会返回当前的ProbeCluster的PacedPacketInfo

  8. 一切顺利的话,就就到达第三部分了,即ProbeCluster印记送达发送模块。什么是ProbeCluster的印记呢,就是PacedPacketInfo!Pacing的过程之前已经介绍过,PacingController会通过PacketRouter的SendPacket将包发送出去,当然,这里要补充两个额外的工作,就是要拿到rtppacket所分配的cluster,即通过BitrateProber的CurrentCluster方法,得到当前的PacedPacketInfo印记,这个印记将随着这个rtp包一直传输到发送层。当成功发送数据后,要通过BitrateProber的ProbeSent方法来更新probe的数据,内部会决策当前的probecluster是否已经达到阈值,完成任务,如果确实已经达到阈值,则会从clusters_这个向量中移除出去,这样,下一个包就将用之后的印记了。通过这个过程,我们也可以了解到,这就是上述的从合到分的过程,一个cluster可以对应多个rtp包,每当发送rtp包的时候,如果处于probe状态,都会从BitrateProber中拿到对应的印记PacedPacketInfo,如果处理的几个包没有超过两个cluster阈值,则这些包使用的是相同的cluster,即他们的clusterid都相同。这样,就将同一个cluster分配到不同的rtp包中去了,完成了从合到分的过程

  9. pacing的发送过程之前已有介绍,这里不再复述,总之,最终rtp包到达了RtpSenderEgress模块,随着rtp包一同而来的,就是其印记PacedPacketInfo。RtpSenderEgress会构建RtpPacketSendInfo这个类,这个类的成员pacing_info正是这个包的印记PacedPacketInfo。构建好RtpPacketSendInfo后,RtpSenderEgress将这个信息反馈给其观察者TransportFeedbackObserver,这个观察者有一个接口就是OnAddPacket,就是专门为了收集RtpPacketSendInfo信息的

  10. 接下来终于来到了第四部分发送模块缓存cluster印记。前面已经介绍,发送前,每个包对应的印记将以回调的形式汇报给TransportFeedbackObserver,而实现这个接口的正是RtpTransportControllerSend!可见RtpTransPortControllerSend就如同如来佛祖一样,掌控着所有信息。接着,RtpTransportControllerSend将此信息转达给TransportFeedbackAdapter,他会将这些核心信息保存在其history_中,每个history_的成员都是PacketFeedback,这个类信息是由RtpPacketSendInfo生成的。最终,包的印记,就被保存在PacketFeedback的SentPacket的pacing_info成员中,供后续使用

  11. 终于一路来到了第五部分,即发送模块收到feedback后,根据缓存决策最终bitrate。前面已经说过每个包在发送之前,都会将pacing印记保存在TransportFeedbackAdapter中。接下来我们介绍一下这些保存的pacing印记究竟该如何使用。真正的使用的地方,就是在接收到这些包的feedback反馈时,此时该包已经发送到接收端,接收端整理了收到这些包的信息,通过transport-feedback的RTCP报文,反馈给发送端。关于transport-feedback报文,之前已经介绍过,这里不再重复。而接收这些报文信息的,依然是我们的老朋友,佛祖,RtpTransportControllerSend。通过其OnTransportFeedback方法得到这些信息。当然,这些信息还是需要交由TransportFeedbackAdapter处理一下,因为通过transport-feedback报文,我们只能知道每个包的接收信息,那么发送信息该如何获取呢?当然是TransportFeedbackAdapter的缓存history_中。这个history_是一个map,其key即为transport-id,这个id是每个包独一无二的。通过这个transport-id的索引,我们可以在history_中找到对应的PacketFeedback,其send成员SentPacket记录了发送的相关信息,当然,当初的pacing印记PacedPacketInfo也在这里

  12. 经过TransportFeedbackAdapter的加工后,将信息汇总到TransportPacketsFeedback中,这个类由TransportFeedbackAdapter生成,其维护的向量表packet_feedbacks记录了包信息,对应的类为PacketsResult。特别的PacketsResult的sent_packet成员即为SendPacket,记录着包的发送相关信息

  13. 最终RtpTransportControllerSend会将处理好的信息TransportPacketsFeedback交给controller_,即GoogCcNetworkController,该模块会进一步将信息交给其成员probe_bitrate_estimator_来处理。这个成员对应的类是ProbeBitrateEstimator,这个类接收所有有probe印记的包,并进一步处理。每个PacketsResult信息,都会进行HandleProbeAndEstimateBitrate的处理。这个处理方式将所有相同clusterid的包,合并成相同额AggregatedCluster,这里体现了从分到合的过程。整理成AggregatedCluster后,通过信息就可以决策出发送的码率和接收的码率了,因为信息已经很充分,我们知道这个cluster的实际大小,以及发送和接收的相关信息了。当发送码率和接收码率比较接近时,我们选取两者的最小值,作为评估后的带宽值,即estimated_data_rate_。至此,整个probe过程终于可以告一段落!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容