tor-browser

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

remote_estimate.cc (4718B)


      1 /*
      2 *  Copyright (c) 2019 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 #include "modules/rtp_rtcp/source/rtcp_packet/remote_estimate.h"
     11 
     12 #include <cstddef>
     13 #include <cstdint>
     14 #include <functional>
     15 #include <utility>
     16 #include <vector>
     17 
     18 #include "api/array_view.h"
     19 #include "api/transport/network_types.h"
     20 #include "api/units/data_rate.h"
     21 #include "modules/rtp_rtcp/source/byte_io.h"
     22 #include "modules/rtp_rtcp/source/rtcp_packet/app.h"
     23 #include "rtc_base/buffer.h"
     24 #include "rtc_base/checks.h"
     25 #include "rtc_base/logging.h"
     26 
     27 namespace webrtc {
     28 namespace rtcp {
     29 namespace {
     30 
     31 constexpr int kFieldValueSize = 3;
     32 constexpr int kFieldSize = 1 + kFieldValueSize;
     33 constexpr DataRate kDataRateResolution = DataRate::KilobitsPerSec(1);
     34 constexpr int64_t kMaxEncoded = (1 << (kFieldValueSize * 8)) - 1;
     35 
     36 class DataRateSerializer {
     37 public:
     38  DataRateSerializer(
     39      uint8_t id,
     40      std::function<DataRate*(NetworkStateEstimate*)> field_getter)
     41      : id_(id), field_getter_(field_getter) {}
     42 
     43  uint8_t id() const { return id_; }
     44 
     45  void Read(const uint8_t* src, NetworkStateEstimate* target) const {
     46    int64_t scaled = ByteReader<uint32_t, kFieldValueSize>::ReadBigEndian(src);
     47    if (scaled == kMaxEncoded) {
     48      *field_getter_(target) = DataRate::PlusInfinity();
     49    } else {
     50      *field_getter_(target) = kDataRateResolution * scaled;
     51    }
     52  }
     53 
     54  bool Write(const NetworkStateEstimate& src, uint8_t* target) const {
     55    auto value = *field_getter_(const_cast<NetworkStateEstimate*>(&src));
     56    if (value.IsMinusInfinity()) {
     57      RTC_LOG(LS_WARNING) << "Trying to serialize MinusInfinity";
     58      return false;
     59    }
     60    ByteWriter<uint8_t>::WriteBigEndian(target++, id_);
     61    int64_t scaled;
     62    if (value.IsPlusInfinity()) {
     63      scaled = kMaxEncoded;
     64    } else {
     65      scaled = value / kDataRateResolution;
     66      if (scaled >= kMaxEncoded) {
     67        scaled = kMaxEncoded;
     68        RTC_LOG(LS_WARNING) << ToString(value) << " is larger than max ("
     69                            << ToString(kMaxEncoded * kDataRateResolution)
     70                            << "), encoded as PlusInfinity.";
     71      }
     72    }
     73    ByteWriter<uint32_t, kFieldValueSize>::WriteBigEndian(target, scaled);
     74    return true;
     75  }
     76 
     77 private:
     78  const uint8_t id_;
     79  const std::function<DataRate*(NetworkStateEstimate*)> field_getter_;
     80 };
     81 
     82 class RemoteEstimateSerializerImpl : public RemoteEstimateSerializer {
     83 public:
     84  explicit RemoteEstimateSerializerImpl(std::vector<DataRateSerializer> fields)
     85      : fields_(fields) {}
     86 
     87  Buffer Serialize(const NetworkStateEstimate& src) const override {
     88    size_t max_size = fields_.size() * kFieldSize;
     89    size_t size = 0;
     90    Buffer buf(max_size);
     91    for (const auto& field : fields_) {
     92      if (field.Write(src, buf.data() + size)) {
     93        size += kFieldSize;
     94      }
     95    }
     96    buf.SetSize(size);
     97    return buf;
     98  }
     99 
    100  bool Parse(ArrayView<const uint8_t> src,
    101             NetworkStateEstimate* target) const override {
    102    if (src.size() % kFieldSize != 0)
    103      return false;
    104    RTC_DCHECK_EQ(src.size() % kFieldSize, 0);
    105    for (const uint8_t* data_ptr = src.data(); data_ptr < src.end();
    106         data_ptr += kFieldSize) {
    107      uint8_t field_id = ByteReader<uint8_t>::ReadBigEndian(data_ptr);
    108      for (const auto& field : fields_) {
    109        if (field.id() == field_id) {
    110          field.Read(data_ptr + 1, target);
    111          break;
    112        }
    113      }
    114    }
    115    return true;
    116  }
    117 
    118 private:
    119  const std::vector<DataRateSerializer> fields_;
    120 };
    121 
    122 }  // namespace
    123 
    124 const RemoteEstimateSerializer* GetRemoteEstimateSerializer() {
    125  using E = NetworkStateEstimate;
    126  static auto* serializer = new RemoteEstimateSerializerImpl({
    127      {1, [](E* e) { return &e->link_capacity_lower; }},
    128      {2, [](E* e) { return &e->link_capacity_upper; }},
    129  });
    130  return serializer;
    131 }
    132 
    133 RemoteEstimate::RemoteEstimate() : serializer_(GetRemoteEstimateSerializer()) {
    134  SetSubType(kSubType);
    135  SetName(kName);
    136  SetSenderSsrc(0);
    137 }
    138 
    139 RemoteEstimate::RemoteEstimate(App&& app)
    140    : App(std::move(app)), serializer_(GetRemoteEstimateSerializer()) {}
    141 
    142 bool RemoteEstimate::ParseData() {
    143  return serializer_->Parse({data(), data_size()}, &estimate_);
    144 }
    145 
    146 void RemoteEstimate::SetEstimate(NetworkStateEstimate estimate) {
    147  estimate_ = estimate;
    148  auto buf = serializer_->Serialize(estimate);
    149  SetData(buf.data(), buf.size());
    150 }
    151 
    152 }  // namespace rtcp
    153 }  // namespace webrtc