写点什么

webrtc BitrateAllocator

用户头像
糖米唐爹
关注
发布于: 2021 年 08 月 24 日
webrtc BitrateAllocator

一,前言

码率分配器,当 gcc 评估出一个可用带宽,由 BitrateAllocator 分配其所包含的 observer,它的 observer 有 AudioSendStream 和 VideoSendStreamImpl 两个,关系图如下:


AudioSendStream 需要满足一下条件才能加入 observer 列表中

  • 启用新特性“WebRTC-Audio-ABWENoTWCC”

  • sdp 含有“a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01”


二,辅助工具函数

介绍 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 种分配策略


  • sum_min_bitrates: observer 所需的最小带宽之和

    sum_max_bitrates: observer 所需的最大带宽之和

    bitrate: gcc 评估出的带宽


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;}
复制代码


用户头像

糖米唐爹

关注

还未添加个人签名 2020.08.12 加入

还未添加个人简介

评论

发布
暂无评论
webrtc BitrateAllocator