tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

video_bitrate_allocation.cc (5983B)


      1 /*
      2 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "api/video/video_bitrate_allocation.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <optional>
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "api/video/video_codec_constants.h"
     20 #include "rtc_base/checks.h"
     21 #include "rtc_base/numerics/safe_conversions.h"
     22 #include "rtc_base/strings/string_builder.h"
     23 
     24 namespace webrtc {
     25 
     26 VideoBitrateAllocation::VideoBitrateAllocation()
     27    : sum_(0), is_bw_limited_(false) {}
     28 
     29 bool VideoBitrateAllocation::SetBitrate(size_t spatial_index,
     30                                        size_t temporal_index,
     31                                        uint32_t bitrate_bps) {
     32  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
     33  RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
     34  int64_t new_bitrate_sum_bps = sum_;
     35  std::optional<uint32_t>& layer_bitrate =
     36      bitrates_[spatial_index][temporal_index];
     37  if (layer_bitrate) {
     38    RTC_DCHECK_LE(*layer_bitrate, sum_);
     39    new_bitrate_sum_bps -= *layer_bitrate;
     40  }
     41  new_bitrate_sum_bps += bitrate_bps;
     42  if (new_bitrate_sum_bps > kMaxBitrateBps)
     43    return false;
     44 
     45  layer_bitrate = bitrate_bps;
     46  sum_ = dchecked_cast<uint32_t>(new_bitrate_sum_bps);
     47  return true;
     48 }
     49 
     50 bool VideoBitrateAllocation::HasBitrate(size_t spatial_index,
     51                                        size_t temporal_index) const {
     52  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
     53  RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
     54  return bitrates_[spatial_index][temporal_index].has_value();
     55 }
     56 
     57 uint32_t VideoBitrateAllocation::GetBitrate(size_t spatial_index,
     58                                            size_t temporal_index) const {
     59  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
     60  RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
     61  return bitrates_[spatial_index][temporal_index].value_or(0);
     62 }
     63 
     64 // Whether the specific spatial layers has the bitrate set in any of its
     65 // temporal layers.
     66 bool VideoBitrateAllocation::IsSpatialLayerUsed(size_t spatial_index) const {
     67  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
     68  for (size_t i = 0; i < kMaxTemporalStreams; ++i) {
     69    if (bitrates_[spatial_index][i].has_value())
     70      return true;
     71  }
     72  return false;
     73 }
     74 
     75 // Get the sum of all the temporal layer for a specific spatial layer.
     76 uint32_t VideoBitrateAllocation::GetSpatialLayerSum(
     77    size_t spatial_index) const {
     78  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
     79  return GetTemporalLayerSum(spatial_index, kMaxTemporalStreams - 1);
     80 }
     81 
     82 uint32_t VideoBitrateAllocation::GetTemporalLayerSum(
     83    size_t spatial_index,
     84    size_t temporal_index) const {
     85  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
     86  RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
     87  uint32_t sum = 0;
     88  for (size_t i = 0; i <= temporal_index; ++i) {
     89    sum += bitrates_[spatial_index][i].value_or(0);
     90  }
     91  return sum;
     92 }
     93 
     94 std::vector<uint32_t> VideoBitrateAllocation::GetTemporalLayerAllocation(
     95    size_t spatial_index) const {
     96  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
     97  std::vector<uint32_t> temporal_rates;
     98 
     99  // Find the highest temporal layer with a defined bitrate in order to
    100  // determine the size of the temporal layer allocation.
    101  for (size_t i = kMaxTemporalStreams; i > 0; --i) {
    102    if (bitrates_[spatial_index][i - 1].has_value()) {
    103      temporal_rates.resize(i);
    104      break;
    105    }
    106  }
    107 
    108  for (size_t i = 0; i < temporal_rates.size(); ++i) {
    109    temporal_rates[i] = bitrates_[spatial_index][i].value_or(0);
    110  }
    111 
    112  return temporal_rates;
    113 }
    114 
    115 std::vector<std::optional<VideoBitrateAllocation>>
    116 VideoBitrateAllocation::GetSimulcastAllocations() const {
    117  std::vector<std::optional<VideoBitrateAllocation>> bitrates;
    118  for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
    119    std::optional<VideoBitrateAllocation> layer_bitrate;
    120    if (IsSpatialLayerUsed(si)) {
    121      layer_bitrate = VideoBitrateAllocation();
    122      for (int tl = 0; tl < kMaxTemporalStreams; ++tl) {
    123        if (HasBitrate(si, tl))
    124          layer_bitrate->SetBitrate(0, tl, GetBitrate(si, tl));
    125      }
    126    }
    127    bitrates.push_back(layer_bitrate);
    128  }
    129  return bitrates;
    130 }
    131 
    132 bool VideoBitrateAllocation::operator==(
    133    const VideoBitrateAllocation& other) const {
    134  for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
    135    for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
    136      if (bitrates_[si][ti] != other.bitrates_[si][ti])
    137        return false;
    138    }
    139  }
    140  return true;
    141 }
    142 
    143 std::string VideoBitrateAllocation::ToString() const {
    144  if (sum_ == 0)
    145    return "VideoBitrateAllocation [ [] ]";
    146 
    147  // Max string length in practice is 260, but let's have some overhead and
    148  // round up to nearest power of two.
    149  char string_buf[512];
    150  SimpleStringBuilder ssb(string_buf);
    151 
    152  ssb << "VideoBitrateAllocation [";
    153  uint32_t spatial_cumulator = 0;
    154  for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
    155    RTC_DCHECK_LE(spatial_cumulator, sum_);
    156    if (spatial_cumulator == sum_)
    157      break;
    158 
    159    const uint32_t layer_sum = GetSpatialLayerSum(si);
    160    if (layer_sum == sum_ && si == 0) {
    161      ssb << " [";
    162    } else {
    163      if (si > 0)
    164        ssb << ",";
    165      ssb << '\n' << "  [";
    166    }
    167    spatial_cumulator += layer_sum;
    168 
    169    uint32_t temporal_cumulator = 0;
    170    for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
    171      RTC_DCHECK_LE(temporal_cumulator, layer_sum);
    172      if (temporal_cumulator == layer_sum)
    173        break;
    174 
    175      if (ti > 0)
    176        ssb << ", ";
    177 
    178      uint32_t bitrate = bitrates_[si][ti].value_or(0);
    179      ssb << bitrate;
    180      temporal_cumulator += bitrate;
    181    }
    182    ssb << "]";
    183  }
    184 
    185  RTC_DCHECK_EQ(spatial_cumulator, sum_);
    186  ssb << " ]";
    187  return ssb.str();
    188 }
    189 
    190 }  // namespace webrtc