今天来聊一聊WebRTC的带宽分配(BWA,Bandwidth Allocation),带宽分配是将带宽估计(BWE,Bandwidth Estimation)的结果分配到不同的流上面。 因此带宽分配是一个peerconnection级别的工作,分配到每一路流(MediaStream)的工作就放在call模块完成。
整个带宽估计不仅仅涉及如何分配估计结果到每一路流,还涉及如何分配用于保护的冗余码率,对于视频来说还需要考虑如何分配simulcast、SVC每一层的码率,甚至是如何决策视频流的暂停。因为篇幅限制,我们将这些功能拆分成几个章节来讲解,本文主要介绍BWA如何将估计带宽分配到每一路流。
1.带宽分配流程以及定义
带宽分配由分配器BitrateAllocator完成对BWE输出带宽的分配,结果通过BitrateAllocatorObserver通知到各个流按照目标码率去编码发送。 分配需要知道各路流的先验信息才可以,不然BWA无法决定如何去分配。每一路流都会设置最小、最大码率,以及流的优先级等等,用于带宽分配,见配置结构:MediaStreamAllocationConfig:
structMediaStreamAllocationConfig {
// 最低码率需求,
uint32_tmin_bitrate_bps;
// 最大码率需求,一般码率达到最大再增加没有什么意义
uint32_tmax_bitrate_bps;
// padding码率,用于视频
uint32_tpad_up_bitrate_bps;
// 优先级码率
int64_tpriority_bitrate_bps;
// 是否强制保障最低码率,如果为true,则无法通过分配码率0使其暂停,永远会保证其有一个最低的分配码率
boolenforce_min_bitrate;
// 码率优先级,如果一路流的优先级是另外一路流两倍,那么会分配到2倍的码率
// 如果有两路流优先级分别为2/8,则分配比例为20%/80%
doublebitrate_priority;
};
因此,BitrateAllocator输入为:
BWE输出的估计带宽、稳定的估计(link capacity),loss,RTT等
各路流的先验信息,最大最小码率、优先级等
带宽分配由BitrateAllocator::OnNetworkEstimateChanged触发,或者添加流的时候触发,分配结果保存到BitrateAllocationUpdate:
structBitrateAllocationUpdate {
// 目标码率
DataRatetarget_bitrate=DataRate::Zero();
// link capacity分配的目标码率
DataRatestable_target_bitrate=DataRate::Zero();
// Predicted packet loss ratio.
doublepacket_loss_ratio=0;
// Predicted round trip time.
TimeDeltaround_trip_time=TimeDelta::PlusInfinity();
// `bwe_period` is deprecated, use `stable_target_bitrate` allocation instead.
TimeDeltabwe_period=TimeDelta::PlusInfinity();
// Congestion window pushback bitrate reduction fraction. Used in
// VideoStreamEncoder to reduce t