一,前言
码率分配器,当 gcc 评估出一个可用带宽,由 BitrateAllocator 分配其所包含的 observer,它的 observer 有 AudioSendStream 和 VideoSendStreamImpl 两个,关系图如下:
AudioSendStream 需要满足一下条件才能加入 observer 列表中
二,辅助工具函数
介绍 3 种策略之前先介绍下两个函数 DistributeBitrateRelatively 和 DistributeBitrateEvenly(它们都是对剩余带宽进行分配)。
1),DistributeBitrateRelatively(按需分配)
capacity_bps: observer 所需码率最大码率与最小码率的差值,我的理解为需求量。
bitrate_priority: observer 权重,默认为 1.
1),对所有的 observer 根据 capacity_bps/bitrate_priority 进行从小到大排序
2),优先对需求量小的进行码率分配
3),如果还有剩余,继续分配,bitrate_priority 越大分的的带宽越多
2),DistributeBitrateEvenly(均等分配)
原理比较简单,按 observer 数量均分,见函数
void DistributeBitrateEvenly(
const std::vector<AllocatableTrack>& allocatable_tracks,
uint32_t bitrate,
bool include_zero_allocations,
int max_multiplier,
std::map<BitrateAllocatorObserver*, int>* allocation) {
// 1,先过滤掉非活动的 observer
std::multimap<uint32_t, const AllocatableTrack*> list_max_bitrates;
for (const auto& observer_config : allocatable_tracks) {
if (include_zero_allocations ||
allocation->at(observer_config.observer) != 0) {
list_max_bitrates.insert(
{observer_config.config.max_bitrate_bps, &observer_config});
}
}
auto it = list_max_bitrates.begin();
while (it != list_max_bitrates.end()) {
RTC_DCHECK_GT(bitrate, 0);
//2, 按数量进行均分
uint32_t extra_allocation =
bitrate / static_cast<uint32_t>(list_max_bitrates.size());
// 3,直接追加
uint32_t total_allocation =
extra_allocation + allocation->at(it->second->observer);
bitrate -= extra_allocation;
// 4,当带宽毕竟充足,满足MaxRateAllocation,max_multiplier 为1.5
// 当LowRateAllocation max_multiplier 为1
if (total_allocation > max_multiplier * it->first) {
// There is more than we can fit for this observer, carry over to the
// remaining observers.
bitrate += total_allocation - max_multiplier * it->first;
total_allocation = max_multiplier * it->first;
}
// 5, 为每个observer更新最新的值
allocation->at(it->second->observer) = total_allocation;
it = list_max_bitrates.erase(it);
}
}
复制代码
三,3 种分配策略
1),当 bitrate 不能满足 sum_min_bitrates,执 LowRateAllocation
std::map<BitrateAllocatorObserver*, int> LowRateAllocation(
const std::vector<AllocatableTrack>& allocatable_tracks,
uint32_t bitrate) {
std::map<BitrateAllocatorObserver*, int> allocation;
// 1,为每个observer 赋一个初始值,enforce_min_bitrate 默认为0.
int64_t remaining_bitrate = bitrate;
for (const auto& observer_config : allocatable_tracks) {
int32_t allocated_bitrate = 0;
if (observer_config.config.enforce_min_bitrate)
allocated_bitrate = observer_config.config.min_bitrate_bps;
allocation[observer_config.observer] = allocated_bitrate;
remaining_bitrate -= allocated_bitrate;
}
// 2,有些observer 可能为非活动的,剔除掉 ?
.......
// 3, 如何带宽还有剩余则执行均等分配
if (remaining_bitrate > 0)
DistributeBitrateEvenly(allocatable_tracks, remaining_bitrate, false, 1,
&allocation);
RTC_DCHECK_EQ(allocation.size(), allocatable_tracks.size());
return allocation;
}
复制代码
2),bitrate 介于 sum_min_bitrates 和 sum_max_bitrates 之间,执行 NormalRateAllocation
std::map<BitrateAllocatorObserver*, int> NormalRateAllocation(
const std::vector<AllocatableTrack>& allocatable_tracks,
uint32_t bitrate,
uint32_t sum_min_bitrates) {
std::map<BitrateAllocatorObserver*, int> allocation;
std::map<BitrateAllocatorObserver*, int> observers_capacities;
// 1, 为每个observer 根据配置赋
for (const auto& observer_config : allocatable_tracks) {
allocation[observer_config.observer] =
observer_config.config.min_bitrate_bps;
observers_capacities[observer_config.observer] =
observer_config.config.max_bitrate_bps -
observer_config.config.min_bitrate_bps;
}
bitrate -= sum_min_bitrates;
// 2, 当 priority_margin 大于0 时,observer 优先级较高,需要先满足其预设值priority_bitrate_bps,
// priority_bitrate_bps 默认为0,
for (const auto& observer_config : allocatable_tracks) {
int64_t priority_margin = observer_config.config.priority_bitrate_bps -
allocation[observer_config.observer];
if (priority_margin > 0 && bitrate > 0) {
int64_t extra_bitrate = std::min<int64_t>(priority_margin, bitrate);
allocation[observer_config.observer] +=
rtc::dchecked_cast<int>(extra_bitrate);
observers_capacities[observer_config.observer] -= extra_bitrate;
bitrate -= extra_bitrate;
}
}
// 3,执行按需分配
if (bitrate > 0)
DistributeBitrateRelatively(allocatable_tracks, bitrate,
observers_capacities, &allocation);
return allocation;
}
复制代码
3),大于 sum_max_bitrates ,执行 MaxRateAllocation,这个函数比较简单
std::map<BitrateAllocatorObserver*, int> MaxRateAllocation(
const std::vector<AllocatableTrack>& allocatable_tracks,
uint32_t bitrate,
uint32_t sum_max_bitrates) {
std::map<BitrateAllocatorObserver*, int> allocation;
// 1, 先满足每个observer 对带宽的最大需求量
for (const auto& observer_config : allocatable_tracks) {
allocation[observer_config.observer] =
observer_config.config.max_bitrate_bps;
bitrate -= observer_config.config.max_bitrate_bps;
}
// 2,对剩余执行均等分配,kTransmissionMaxBitrateMultiplier 为1.5
DistributeBitrateEvenly(allocatable_tracks, bitrate, true,
kTransmissionMaxBitrateMultiplier, &allocation);
return allocation;
}
复制代码
评论