目录
一、概述
二、实现原理
1、实现思路
2、模块分工
3、具体实现
1)探测次数
2、探测节奏
3、pad数据
4、AlrDetector
5、探测参数
三、参考
所以需要一种快速探测算法,探测当前网络合适的带宽,保证音视频按照最佳码率值发送数据。
1、发送端以一定的速度发送数据包,同时记录这些数据包的发送时间、序列号(全局唯一)、探测组的ID。
2、接收端根据收到数据报文size和时间,计算接收端的码率。反馈给发送端。
3、发送端选取发送码率和接收端反馈码率最小值,作为当前发送码率值。
ProbeBitrateEstimator::HandleProbeAndEstimateBitrate是确定最终探测结果的函数:
里面用到的公式如下:
TimeDelta send_interval = common::TimeDelta(state.last_send - state.first_send);
TimeDelta recive_interval = common::TimeDelta(state.last_recive - state.first_recive);
size_t size_send = state.size_total_sent - state.size_last_sent;
size_t size_recive = state.size_total_recived - state.size_first_recived;
DataRate send_bps = (size_send * 8 / send_interval );
DataRate receive_bps = (size_recive * 8 / recive_interval);
实现这个过程主要由四个模块:
1、ProbeController:控制探测状态机
2、PacingController:控制数据发送节奏
3、BitrateProber:实际操作数据发送量和发送节奏
4、GoogCcNetworkController:接收接收端反馈的接收码率
5、ProbeBitrateEstimator:计算最终探测码率
RtpTransportControllerSend::OnNetworkAvailability
->RtpTransportControllerSend::MaybeCreateControllers()
->RtpTransportControllerSend::UpdateControllerWithTimeInterval()
->GoogCcNetworkController::OnProcessInterval
->GoogCcNetworkController::ResetConstraints
->ProbeController::SetBitrates
->ProbeController::InitiateExponentialProbing
RtpTransportControllerSend::OnNetworkAvailability
->RtpTransportControllerSend::MaybeCreateControllers
->GoogCcNetworkControllerFactory::Create
->GoogCcNetworkController::GoogCcNetworkController
->ProbeController::ProbeController
->ProbeControllerConfig::ProbeControllerConfig
RtpTransportControllerSend::OnNetworkAvailability
->RtpTransportControllerSend::MaybeCreateControllers()
->RtpTransportControllerSend::UpdateControllerWithTimeInterval()
->GoogCcNetworkController::OnProcessInterval
->GoogCcNetworkController::ResetConstraints
->ProbeController::SetBitrates
所以webrtc的探测次数是二次到三次。
1)PacingController::ProcessPackets函数在每次发送探测包前,都会调用BitrateProber::RecommendedMinProbeSize询问本次应该发送多少报文。
2)BitrateProber::RecommendedMinProbeSize计算发送量的根据是当前探测带宽下,min_probe_delta(默认1ms)时长,应该发送的数据量。
3)但是实际packet队列数据包,不一定完全满足RecommendedMinProbeSize计算值。所以在BitrateProber::CalculateNextProbeTime函数计算下一次的探测时间,为已经发送数据量在探测码率下可持续的时间。
4)发送端正常停止一次cluster探测的条件是,该cluster已经连续发送了5次报文并且该cluster已经发送的数据量大于15ms。
5)发送端异常终止cluster探测的条件是,一个cluster两个pace周期大于10ms。
6)两个cluster之间的探测时间,没有固定要求。只要pace模块有包发送,可直接进行下一个cluster的探测。
probe过程中,探测高码率时明显需要大量数据,会出现有效数据量不足情况,pace模块使用RTX协议重传历史数据,作为补充数据。
在webrtc根据探测发送实际数据的时候,由于一些系统原因,比方说编码器编码码率超高,码率持续超高,持续这样累计延时会比较大;对此webrtc还增加了AlrDetector(应用受限区域探测器,Application Limited Region Detector)模块,该模块利用某段时间值,以及这段时间发送的字节数判断当前输出网络流量是超标。若实际码率一直超纲,则再次启动按照当前预估码率的2倍码率探测。
AlrDetector::OnBytesSent函数持续检测实际发送码率,与预设码率之间的关系。若出现长期超标,则通知probe模块,ProbeController::Process函数被调用时,检测出ALR消息,启动按当前码率的2倍值,重新探测。
RtpTransportControllerSend::OnNetworkAvailability
->RtpTransportControllerSend::MaybeCreateControllers
->RtpTransportControllerSend::UpdateControllerWithTimeInterval
->GoogCcNetworkController::OnProcessInterval
-->AlrDetector::GetApplicationLimitedRegionStartTime
-->ProbeController::SetAlrStartTimeMs 触发ProbeController::Process函数启动probe探测
struct ProbeClusterConfig {
Timestamp at_time = Timestamp::PlusInfinity();//
DataRate target_data_rate = DataRate::Zero(); //需探测码率
TimeDelta target_duration = TimeDelta::Zero();//持续探测时间,用于计算发送数据量
int32_t target_probe_count = 0; //一次探测允许调度次数
int32_t id = 0; //探测ID标识,用于和接收端反馈信息匹配
};
https://www.jianshu.com/p/29e40d692036
https://rtcdeveloper.com/t/topic/15587
好文收藏:https://www.jianshu.com/p/55e5246f12b9