Splits network units into separate headers.
This CL moves the network units files into a separate folder with a separate BUILD file. It also splits the units into separate files. This prepares for moving all or some of the units to somewhere that can be accessed by more components. Bug: None Change-Id: I4ebbc19088b024ba920b0b3c64e5f57431f4f955 Reviewed-on: https://webrtc-review.googlesource.com/68660 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Björn Terelius <terelius@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22861}
This commit is contained in:

committed by
Commit Bot

parent
8cbb1c9162
commit
30bd4038cf
@ -36,6 +36,7 @@ rtc_source_set("bbr_controller") {
|
||||
"../../../rtc_base/experiments:congestion_controller_experiment",
|
||||
"../../../rtc_base/system:fallthrough",
|
||||
"../network_control",
|
||||
"../network_control/units",
|
||||
]
|
||||
}
|
||||
rtc_source_set("data_transfer_tracker") {
|
||||
@ -47,7 +48,7 @@ rtc_source_set("data_transfer_tracker") {
|
||||
deps = [
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../network_control",
|
||||
"../network_control/units",
|
||||
]
|
||||
}
|
||||
rtc_source_set("rtt_stats") {
|
||||
@ -58,7 +59,7 @@ rtc_source_set("rtt_stats") {
|
||||
]
|
||||
deps = [
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../network_control",
|
||||
"../network_control/units",
|
||||
]
|
||||
}
|
||||
rtc_source_set("windowed_filter") {
|
||||
@ -83,8 +84,8 @@ if (rtc_include_tests) {
|
||||
":rtt_stats",
|
||||
":windowed_filter",
|
||||
"../../../test:test_support",
|
||||
"../network_control",
|
||||
"../network_control:network_control_test",
|
||||
"../network_control/units",
|
||||
]
|
||||
if (!build_with_chromium && is_clang) {
|
||||
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_units_to_string.h"
|
||||
#include "modules/congestion_controller/network_control/units/network_units.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/experiments/congestion_controller_experiment.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "modules/congestion_controller/bbr/windowed_filter.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_control.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_types.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
|
||||
#include "api/optional.h"
|
||||
#include "rtc_base/random.h"
|
||||
|
@ -11,7 +11,7 @@
|
||||
#define MODULES_CONGESTION_CONTROLLER_BBR_DATA_TRANSFER_TRACKER_H_
|
||||
|
||||
#include <deque>
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "modules/congestion_controller/network_control/units/network_units.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace bbr {
|
||||
|
@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/bbr/data_transfer_tracker.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "modules/congestion_controller/network_control/units/network_units.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
@ -12,8 +12,7 @@
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_units_to_string.h"
|
||||
#include "modules/congestion_controller/network_control/units/network_units.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "modules/congestion_controller/network_control/units/network_units.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "modules/congestion_controller/bbr/windowed_filter.h"
|
||||
|
||||
#include "modules/congestion_controller/bbr/rtt_stats.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_units_to_string.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
@ -12,11 +12,7 @@ rtc_static_library("network_control") {
|
||||
sources = [
|
||||
"include/network_control.h",
|
||||
"include/network_types.h",
|
||||
"include/network_units.h",
|
||||
"include/network_units_to_string.h",
|
||||
"network_types.cc",
|
||||
"network_units.cc",
|
||||
"network_units_to_string.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
@ -24,6 +20,7 @@ rtc_static_library("network_control") {
|
||||
"../../../api:optional",
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"units",
|
||||
]
|
||||
}
|
||||
|
||||
@ -41,16 +38,16 @@ if (rtc_include_tests) {
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../test:test_support",
|
||||
"units",
|
||||
]
|
||||
}
|
||||
rtc_source_set("network_control_unittests") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"network_units_unittest.cc",
|
||||
]
|
||||
sources = []
|
||||
deps = [
|
||||
":network_control",
|
||||
"../../../test:test_support",
|
||||
"units:units_unittests",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "modules/congestion_controller/network_control/include/network_types.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "modules/congestion_controller/network_control/units/network_units.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_TYPES_H_
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "modules/congestion_controller/network_control/units/network_units.h"
|
||||
#include "modules/include/module_common_types.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
|
||||
|
@ -1,395 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_UNITS_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_UNITS_H_
|
||||
#include <stdint.h>
|
||||
#include <limits>
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace units_internal {
|
||||
constexpr int64_t kPlusInfinityVal = std::numeric_limits<int64_t>::max();
|
||||
constexpr int64_t kMinusInfinityVal = std::numeric_limits<int64_t>::min();
|
||||
constexpr int64_t kSignedNotInitializedVal = kMinusInfinityVal + 1;
|
||||
constexpr int64_t kNotInitializedVal = -1;
|
||||
|
||||
inline int64_t DivideAndRound(int64_t numerator, int64_t denominators) {
|
||||
if (numerator >= 0) {
|
||||
return (numerator + (denominators / 2)) / denominators;
|
||||
} else {
|
||||
return (numerator + (denominators / 2)) / denominators - 1;
|
||||
}
|
||||
}
|
||||
} // namespace units_internal
|
||||
|
||||
// TimeDelta represents the difference between two timestamps. Commonly this can
|
||||
// be a duration. However since two Timestamps are not guaranteed to have the
|
||||
// same epoch (they might come from different computers, making exact
|
||||
// synchronisation infeasible), the duration covered by a TimeDelta can be
|
||||
// undefined. To simplify usage, it can be constructed and converted to
|
||||
// different units, specifically seconds (s), milliseconds (ms) and
|
||||
// microseconds (us).
|
||||
class TimeDelta {
|
||||
public:
|
||||
TimeDelta() : TimeDelta(units_internal::kSignedNotInitializedVal) {}
|
||||
static TimeDelta Zero() { return TimeDelta(0); }
|
||||
static TimeDelta PlusInfinity() {
|
||||
return TimeDelta(units_internal::kPlusInfinityVal);
|
||||
}
|
||||
static TimeDelta MinusInfinity() {
|
||||
return TimeDelta(units_internal::kMinusInfinityVal);
|
||||
}
|
||||
static TimeDelta seconds(int64_t seconds) { return TimeDelta::s(seconds); }
|
||||
static TimeDelta s(int64_t seconds) {
|
||||
return TimeDelta::us(seconds * 1000000);
|
||||
}
|
||||
static TimeDelta ms(int64_t milliseconds) {
|
||||
return TimeDelta::us(milliseconds * 1000);
|
||||
}
|
||||
static TimeDelta us(int64_t microseconds) {
|
||||
// Infinities only allowed via use of explicit constants.
|
||||
RTC_DCHECK(microseconds > std::numeric_limits<int64_t>::min());
|
||||
RTC_DCHECK(microseconds < std::numeric_limits<int64_t>::max());
|
||||
return TimeDelta(microseconds);
|
||||
}
|
||||
int64_t s() const { return units_internal::DivideAndRound(us(), 1000000); }
|
||||
int64_t ms() const { return units_internal::DivideAndRound(us(), 1000); }
|
||||
int64_t us() const {
|
||||
RTC_DCHECK(IsFinite());
|
||||
return microseconds_;
|
||||
}
|
||||
TimeDelta Abs() const { return TimeDelta::us(std::abs(us())); }
|
||||
|
||||
double SecondsAsDouble() const;
|
||||
|
||||
bool IsZero() const { return microseconds_ == 0; }
|
||||
bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
|
||||
bool IsInitialized() const {
|
||||
return microseconds_ != units_internal::kSignedNotInitializedVal;
|
||||
}
|
||||
bool IsInfinite() const {
|
||||
return microseconds_ == units_internal::kPlusInfinityVal ||
|
||||
microseconds_ == units_internal::kMinusInfinityVal;
|
||||
}
|
||||
bool IsPlusInfinity() const {
|
||||
return microseconds_ == units_internal::kPlusInfinityVal;
|
||||
}
|
||||
bool IsMinusInfinity() const {
|
||||
return microseconds_ == units_internal::kMinusInfinityVal;
|
||||
}
|
||||
TimeDelta operator+(const TimeDelta& other) const {
|
||||
return TimeDelta::us(us() + other.us());
|
||||
}
|
||||
TimeDelta operator-(const TimeDelta& other) const {
|
||||
return TimeDelta::us(us() - other.us());
|
||||
}
|
||||
TimeDelta& operator-=(const TimeDelta& other) {
|
||||
microseconds_ -= other.us();
|
||||
return *this;
|
||||
}
|
||||
TimeDelta& operator+=(const TimeDelta& other) {
|
||||
microseconds_ += other.us();
|
||||
return *this;
|
||||
}
|
||||
TimeDelta operator*(double scalar) const;
|
||||
TimeDelta operator*(int64_t scalar) const {
|
||||
return TimeDelta::us(us() * scalar);
|
||||
}
|
||||
TimeDelta operator*(int32_t scalar) const {
|
||||
return TimeDelta::us(us() * scalar);
|
||||
}
|
||||
TimeDelta operator/(int64_t scalar) const {
|
||||
return TimeDelta::us(us() / scalar);
|
||||
}
|
||||
bool operator==(const TimeDelta& other) const {
|
||||
return microseconds_ == other.microseconds_;
|
||||
}
|
||||
bool operator!=(const TimeDelta& other) const {
|
||||
return microseconds_ != other.microseconds_;
|
||||
}
|
||||
bool operator<=(const TimeDelta& other) const {
|
||||
return microseconds_ <= other.microseconds_;
|
||||
}
|
||||
bool operator>=(const TimeDelta& other) const {
|
||||
return microseconds_ >= other.microseconds_;
|
||||
}
|
||||
bool operator>(const TimeDelta& other) const {
|
||||
return microseconds_ > other.microseconds_;
|
||||
}
|
||||
bool operator<(const TimeDelta& other) const {
|
||||
return microseconds_ < other.microseconds_;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit TimeDelta(int64_t us) : microseconds_(us) {}
|
||||
int64_t microseconds_;
|
||||
};
|
||||
inline TimeDelta operator*(const double& scalar, const TimeDelta& delta) {
|
||||
return delta * scalar;
|
||||
}
|
||||
inline TimeDelta operator*(const int64_t& scalar, const TimeDelta& delta) {
|
||||
return delta * scalar;
|
||||
}
|
||||
inline TimeDelta operator*(const int32_t& scalar, const TimeDelta& delta) {
|
||||
return delta * scalar;
|
||||
}
|
||||
|
||||
// Timestamp represents the time that has passed since some unspecified epoch.
|
||||
// The epoch is assumed to be before any represented timestamps, this means that
|
||||
// negative values are not valid. The most notable feature is that the
|
||||
// difference of two Timestamps results in a TimeDelta.
|
||||
class Timestamp {
|
||||
public:
|
||||
Timestamp() : Timestamp(units_internal::kNotInitializedVal) {}
|
||||
static Timestamp Infinity() {
|
||||
return Timestamp(units_internal::kPlusInfinityVal);
|
||||
}
|
||||
static Timestamp seconds(int64_t seconds) { return Timestamp::s(seconds); }
|
||||
static Timestamp s(int64_t seconds) {
|
||||
return Timestamp::us(seconds * 1000000);
|
||||
}
|
||||
static Timestamp ms(int64_t millis) { return Timestamp::us(millis * 1000); }
|
||||
static Timestamp us(int64_t micros) {
|
||||
RTC_DCHECK_GE(micros, 0);
|
||||
return Timestamp(micros);
|
||||
}
|
||||
int64_t s() const { return units_internal::DivideAndRound(us(), 1000000); }
|
||||
int64_t ms() const { return units_internal::DivideAndRound(us(), 1000); }
|
||||
int64_t us() const {
|
||||
RTC_DCHECK(IsFinite());
|
||||
return microseconds_;
|
||||
}
|
||||
bool IsInfinite() const {
|
||||
return microseconds_ == units_internal::kPlusInfinityVal;
|
||||
}
|
||||
bool IsInitialized() const {
|
||||
return microseconds_ != units_internal::kNotInitializedVal;
|
||||
}
|
||||
bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
|
||||
TimeDelta operator-(const Timestamp& other) const {
|
||||
return TimeDelta::us(us() - other.us());
|
||||
}
|
||||
Timestamp operator-(const TimeDelta& delta) const {
|
||||
return Timestamp::us(us() - delta.us());
|
||||
}
|
||||
Timestamp operator+(const TimeDelta& delta) const {
|
||||
return Timestamp::us(us() + delta.us());
|
||||
}
|
||||
Timestamp& operator-=(const TimeDelta& other) {
|
||||
microseconds_ -= other.us();
|
||||
return *this;
|
||||
}
|
||||
Timestamp& operator+=(const TimeDelta& other) {
|
||||
microseconds_ += other.us();
|
||||
return *this;
|
||||
}
|
||||
|
||||
double SecondsAsDouble() const;
|
||||
bool operator==(const Timestamp& other) const {
|
||||
return microseconds_ == other.microseconds_;
|
||||
}
|
||||
bool operator!=(const Timestamp& other) const {
|
||||
return microseconds_ != other.microseconds_;
|
||||
}
|
||||
bool operator<=(const Timestamp& other) const { return us() <= other.us(); }
|
||||
bool operator>=(const Timestamp& other) const { return us() >= other.us(); }
|
||||
bool operator>(const Timestamp& other) const { return us() > other.us(); }
|
||||
bool operator<(const Timestamp& other) const { return us() < other.us(); }
|
||||
|
||||
private:
|
||||
explicit Timestamp(int64_t us) : microseconds_(us) {}
|
||||
int64_t microseconds_;
|
||||
};
|
||||
|
||||
// DataSize is a class represeting a count of bytes. Note that while it can be
|
||||
// initialized by a number of bits, it does not guarantee that the resolution is
|
||||
// kept and the internal storage is in bytes. The number of bits will be
|
||||
// truncated to fit.
|
||||
class DataSize {
|
||||
public:
|
||||
DataSize() : DataSize(units_internal::kNotInitializedVal) {}
|
||||
static DataSize Zero() { return DataSize(0); }
|
||||
static DataSize Infinity() {
|
||||
return DataSize(units_internal::kPlusInfinityVal);
|
||||
}
|
||||
static DataSize bytes(int64_t bytes) {
|
||||
RTC_DCHECK_GE(bytes, 0);
|
||||
return DataSize(bytes);
|
||||
}
|
||||
static DataSize bits(int64_t bits) {
|
||||
RTC_DCHECK_GE(bits, 0);
|
||||
return DataSize(bits / 8);
|
||||
}
|
||||
int64_t bytes() const {
|
||||
RTC_DCHECK(IsFinite());
|
||||
return bytes_;
|
||||
}
|
||||
int64_t kilobytes() const {
|
||||
return units_internal::DivideAndRound(bytes(), 1000);
|
||||
}
|
||||
int64_t bits() const { return bytes() * 8; }
|
||||
int64_t kilobits() const {
|
||||
return units_internal::DivideAndRound(bits(), 1000);
|
||||
}
|
||||
bool IsZero() const { return bytes_ == 0; }
|
||||
bool IsInfinite() const { return bytes_ == units_internal::kPlusInfinityVal; }
|
||||
bool IsInitialized() const {
|
||||
return bytes_ != units_internal::kNotInitializedVal;
|
||||
}
|
||||
bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
|
||||
DataSize operator-(const DataSize& other) const {
|
||||
return DataSize::bytes(bytes() - other.bytes());
|
||||
}
|
||||
DataSize operator+(const DataSize& other) const {
|
||||
return DataSize::bytes(bytes() + other.bytes());
|
||||
}
|
||||
DataSize operator*(double scalar) const;
|
||||
DataSize operator*(int64_t scalar) const {
|
||||
return DataSize::bytes(bytes() * scalar);
|
||||
}
|
||||
DataSize operator*(int32_t scalar) const {
|
||||
return DataSize::bytes(bytes() * scalar);
|
||||
}
|
||||
DataSize operator/(int64_t scalar) const {
|
||||
return DataSize::bytes(bytes() / scalar);
|
||||
}
|
||||
DataSize& operator-=(const DataSize& other) {
|
||||
bytes_ -= other.bytes();
|
||||
return *this;
|
||||
}
|
||||
DataSize& operator+=(const DataSize& other) {
|
||||
bytes_ += other.bytes();
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const DataSize& other) const {
|
||||
return bytes_ == other.bytes_;
|
||||
}
|
||||
bool operator!=(const DataSize& other) const {
|
||||
return bytes_ != other.bytes_;
|
||||
}
|
||||
bool operator<=(const DataSize& other) const {
|
||||
return bytes_ <= other.bytes_;
|
||||
}
|
||||
bool operator>=(const DataSize& other) const {
|
||||
return bytes_ >= other.bytes_;
|
||||
}
|
||||
bool operator>(const DataSize& other) const { return bytes_ > other.bytes_; }
|
||||
bool operator<(const DataSize& other) const { return bytes_ < other.bytes_; }
|
||||
|
||||
private:
|
||||
explicit DataSize(int64_t bytes) : bytes_(bytes) {}
|
||||
int64_t bytes_;
|
||||
};
|
||||
inline DataSize operator*(const double& scalar, const DataSize& size) {
|
||||
return size * scalar;
|
||||
}
|
||||
inline DataSize operator*(const int64_t& scalar, const DataSize& size) {
|
||||
return size * scalar;
|
||||
}
|
||||
inline DataSize operator*(const int32_t& scalar, const DataSize& size) {
|
||||
return size * scalar;
|
||||
}
|
||||
|
||||
// DataRate is a class that represents a given data rate. This can be used to
|
||||
// represent bandwidth, encoding bitrate, etc. The internal storage is currently
|
||||
// bits per second (bps) since this makes it easier to intepret the raw value
|
||||
// when debugging. The promised precision, however is only that it will
|
||||
// represent bytes per second accurately. Any implementation depending on bps
|
||||
// resolution should document this by changing this comment.
|
||||
class DataRate {
|
||||
public:
|
||||
DataRate() : DataRate(units_internal::kNotInitializedVal) {}
|
||||
static DataRate Zero() { return DataRate(0); }
|
||||
static DataRate Infinity() {
|
||||
return DataRate(units_internal::kPlusInfinityVal);
|
||||
}
|
||||
static DataRate bytes_per_second(int64_t bytes_per_sec) {
|
||||
RTC_DCHECK_GE(bytes_per_sec, 0);
|
||||
return DataRate(bytes_per_sec * 8);
|
||||
}
|
||||
static DataRate bits_per_second(int64_t bits_per_sec) {
|
||||
RTC_DCHECK_GE(bits_per_sec, 0);
|
||||
return DataRate(bits_per_sec);
|
||||
}
|
||||
static DataRate bps(int64_t bits_per_sec) {
|
||||
return DataRate::bits_per_second(bits_per_sec);
|
||||
}
|
||||
static DataRate kbps(int64_t kilobits_per_sec) {
|
||||
return DataRate::bits_per_second(kilobits_per_sec * 1000);
|
||||
}
|
||||
int64_t bits_per_second() const {
|
||||
RTC_DCHECK(IsFinite());
|
||||
return bits_per_sec_;
|
||||
}
|
||||
int64_t bytes_per_second() const { return bits_per_second() / 8; }
|
||||
int64_t bps() const { return bits_per_second(); }
|
||||
int64_t bps_or(int64_t fallback) const {
|
||||
return IsFinite() ? bits_per_second() : fallback;
|
||||
}
|
||||
int64_t kbps() const { return units_internal::DivideAndRound(bps(), 1000); }
|
||||
bool IsZero() const { return bits_per_sec_ == 0; }
|
||||
bool IsInfinite() const {
|
||||
return bits_per_sec_ == units_internal::kPlusInfinityVal;
|
||||
}
|
||||
bool IsInitialized() const {
|
||||
return bits_per_sec_ != units_internal::kNotInitializedVal;
|
||||
}
|
||||
bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
|
||||
DataRate operator*(double scalar) const;
|
||||
DataRate operator*(int64_t scalar) const {
|
||||
return DataRate::bytes_per_second(bytes_per_second() * scalar);
|
||||
}
|
||||
DataRate operator*(int32_t scalar) const {
|
||||
return DataRate::bytes_per_second(bytes_per_second() * scalar);
|
||||
}
|
||||
bool operator==(const DataRate& other) const {
|
||||
return bits_per_sec_ == other.bits_per_sec_;
|
||||
}
|
||||
bool operator!=(const DataRate& other) const {
|
||||
return bits_per_sec_ != other.bits_per_sec_;
|
||||
}
|
||||
bool operator<=(const DataRate& other) const {
|
||||
return bits_per_sec_ <= other.bits_per_sec_;
|
||||
}
|
||||
bool operator>=(const DataRate& other) const {
|
||||
return bits_per_sec_ >= other.bits_per_sec_;
|
||||
}
|
||||
bool operator>(const DataRate& other) const {
|
||||
return bits_per_sec_ > other.bits_per_sec_;
|
||||
}
|
||||
bool operator<(const DataRate& other) const {
|
||||
return bits_per_sec_ < other.bits_per_sec_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Bits per second used internally to simplify debugging by making the value
|
||||
// more recognizable.
|
||||
explicit DataRate(int64_t bits_per_second) : bits_per_sec_(bits_per_second) {}
|
||||
int64_t bits_per_sec_;
|
||||
};
|
||||
inline DataRate operator*(const double& scalar, const DataRate& rate) {
|
||||
return rate * scalar;
|
||||
}
|
||||
inline DataRate operator*(const int64_t& scalar, const DataRate& rate) {
|
||||
return rate * scalar;
|
||||
}
|
||||
inline DataRate operator*(const int32_t& scalar, const DataRate& rate) {
|
||||
return rate * scalar;
|
||||
}
|
||||
|
||||
DataRate operator/(const DataSize& size, const TimeDelta& duration);
|
||||
TimeDelta operator/(const DataSize& size, const DataRate& rate);
|
||||
DataSize operator*(const DataRate& rate, const TimeDelta& duration);
|
||||
DataSize operator*(const TimeDelta& duration, const DataRate& rate);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_UNITS_H_
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_UNITS_TO_STRING_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_UNITS_TO_STRING_H_
|
||||
|
||||
#include <string>
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
|
||||
namespace webrtc {
|
||||
std::string ToString(const DataRate& datarate);
|
||||
std::string ToString(const DataSize& datarate);
|
||||
std::string ToString(const Timestamp& datarate);
|
||||
std::string ToString(const TimeDelta& datarate);
|
||||
} // namespace webrtc
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_INCLUDE_NETWORK_UNITS_TO_STRING_H_
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace webrtc {
|
||||
TimeDelta TimeDelta::operator*(double scalar) const {
|
||||
return TimeDelta::us(std::round(us() * scalar));
|
||||
}
|
||||
|
||||
DataSize DataSize::operator*(double scalar) const {
|
||||
return DataSize::bytes(std::round(bytes() * scalar));
|
||||
}
|
||||
double TimeDelta::SecondsAsDouble() const {
|
||||
if (IsPlusInfinity()) {
|
||||
return std::numeric_limits<double>::infinity();
|
||||
} else if (IsMinusInfinity()) {
|
||||
return -std::numeric_limits<double>::infinity();
|
||||
} else if (!IsInitialized()) {
|
||||
return std::numeric_limits<double>::signaling_NaN();
|
||||
} else {
|
||||
return us() * 1e-6;
|
||||
}
|
||||
}
|
||||
|
||||
double Timestamp::SecondsAsDouble() const {
|
||||
if (IsInfinite()) {
|
||||
return std::numeric_limits<double>::infinity();
|
||||
} else if (!IsInitialized()) {
|
||||
return std::numeric_limits<double>::signaling_NaN();
|
||||
} else {
|
||||
return us() * 1e-6;
|
||||
}
|
||||
}
|
||||
|
||||
DataRate DataRate::operator*(double scalar) const {
|
||||
return DataRate::bytes_per_second(std::round(bytes_per_second() * scalar));
|
||||
}
|
||||
|
||||
DataRate operator/(const DataSize& size, const TimeDelta& duration) {
|
||||
RTC_DCHECK(size.bytes() < std::numeric_limits<int64_t>::max() / 1000000)
|
||||
<< "size is too large, size: " << size.bytes() << " is not less than "
|
||||
<< std::numeric_limits<int64_t>::max() / 1000000;
|
||||
auto bytes_per_sec = size.bytes() * 1000000 / duration.us();
|
||||
return DataRate::bytes_per_second(bytes_per_sec);
|
||||
}
|
||||
|
||||
TimeDelta operator/(const DataSize& size, const DataRate& rate) {
|
||||
RTC_DCHECK(size.bytes() < std::numeric_limits<int64_t>::max() / 1000000)
|
||||
<< "size is too large, size: " << size.bytes() << " is not less than "
|
||||
<< std::numeric_limits<int64_t>::max() / 1000000;
|
||||
auto microseconds = size.bytes() * 1000000 / rate.bytes_per_second();
|
||||
return TimeDelta::us(microseconds);
|
||||
}
|
||||
|
||||
DataSize operator*(const DataRate& rate, const TimeDelta& duration) {
|
||||
auto micro_bytes = rate.bytes_per_second() * duration.us();
|
||||
auto bytes = units_internal::DivideAndRound(micro_bytes, 1000000);
|
||||
return DataSize::bytes(bytes);
|
||||
}
|
||||
|
||||
DataSize operator*(const TimeDelta& duration, const DataRate& rate) {
|
||||
return rate * duration;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "modules/congestion_controller/network_control/include/network_units_to_string.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace webrtc {
|
||||
std::string ToString(const DataRate& value) {
|
||||
char buf[64];
|
||||
rtc::SimpleStringBuilder sb(buf);
|
||||
if (value.IsInfinite()) {
|
||||
sb << "inf bps";
|
||||
} else if (!value.IsInitialized()) {
|
||||
sb << "? bps";
|
||||
} else {
|
||||
sb << value.bps() << " bps";
|
||||
}
|
||||
return sb.str();
|
||||
}
|
||||
std::string ToString(const DataSize& value) {
|
||||
char buf[64];
|
||||
rtc::SimpleStringBuilder sb(buf);
|
||||
if (value.IsInfinite()) {
|
||||
sb << "inf bytes";
|
||||
} else if (!value.IsInitialized()) {
|
||||
sb << "? bytes";
|
||||
} else {
|
||||
sb << value.bytes() << " bytes";
|
||||
}
|
||||
return sb.str();
|
||||
}
|
||||
std::string ToString(const Timestamp& value) {
|
||||
char buf[64];
|
||||
rtc::SimpleStringBuilder sb(buf);
|
||||
if (value.IsInfinite()) {
|
||||
sb << "inf ms";
|
||||
} else if (!value.IsInitialized()) {
|
||||
sb << "? ms";
|
||||
} else {
|
||||
sb << value.ms() << " ms";
|
||||
}
|
||||
return sb.str();
|
||||
}
|
||||
std::string ToString(const TimeDelta& value) {
|
||||
char buf[64];
|
||||
rtc::SimpleStringBuilder sb(buf);
|
||||
if (value.IsPlusInfinity()) {
|
||||
sb << "+inf ms";
|
||||
} else if (value.IsMinusInfinity()) {
|
||||
sb << "-inf ms";
|
||||
} else if (!value.IsInitialized()) {
|
||||
sb << "? ms";
|
||||
} else {
|
||||
sb << value.ms() << " ms";
|
||||
}
|
||||
return sb.str();
|
||||
}
|
||||
} // namespace webrtc
|
@ -1,300 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
TEST(TimeDeltaTest, GetBackSameValues) {
|
||||
const int64_t kValue = 499;
|
||||
for (int sign = -1; sign <= 1; ++sign) {
|
||||
int64_t value = kValue * sign;
|
||||
EXPECT_EQ(TimeDelta::ms(value).ms(), value);
|
||||
EXPECT_EQ(TimeDelta::us(value).us(), value);
|
||||
EXPECT_EQ(TimeDelta::s(value).s(), value);
|
||||
EXPECT_EQ(TimeDelta::seconds(value).s(), value);
|
||||
}
|
||||
EXPECT_EQ(TimeDelta::Zero().us(), 0);
|
||||
}
|
||||
|
||||
TEST(TimeDeltaTest, GetDifferentPrefix) {
|
||||
const int64_t kValue = 3000000;
|
||||
EXPECT_EQ(TimeDelta::us(kValue).s(), kValue / 1000000);
|
||||
EXPECT_EQ(TimeDelta::ms(kValue).s(), kValue / 1000);
|
||||
EXPECT_EQ(TimeDelta::us(kValue).ms(), kValue / 1000);
|
||||
|
||||
EXPECT_EQ(TimeDelta::ms(kValue).us(), kValue * 1000);
|
||||
EXPECT_EQ(TimeDelta::s(kValue).ms(), kValue * 1000);
|
||||
EXPECT_EQ(TimeDelta::s(kValue).us(), kValue * 1000000);
|
||||
}
|
||||
|
||||
TEST(TimeDeltaTest, IdentityChecks) {
|
||||
const int64_t kValue = 3000;
|
||||
EXPECT_TRUE(TimeDelta::Zero().IsZero());
|
||||
EXPECT_FALSE(TimeDelta::ms(kValue).IsZero());
|
||||
|
||||
EXPECT_TRUE(TimeDelta::PlusInfinity().IsInfinite());
|
||||
EXPECT_TRUE(TimeDelta::MinusInfinity().IsInfinite());
|
||||
EXPECT_FALSE(TimeDelta::Zero().IsInfinite());
|
||||
EXPECT_FALSE(TimeDelta::ms(-kValue).IsInfinite());
|
||||
EXPECT_FALSE(TimeDelta::ms(kValue).IsInfinite());
|
||||
|
||||
EXPECT_FALSE(TimeDelta::PlusInfinity().IsFinite());
|
||||
EXPECT_FALSE(TimeDelta::MinusInfinity().IsFinite());
|
||||
EXPECT_TRUE(TimeDelta::ms(-kValue).IsFinite());
|
||||
EXPECT_TRUE(TimeDelta::ms(kValue).IsFinite());
|
||||
EXPECT_TRUE(TimeDelta::Zero().IsFinite());
|
||||
}
|
||||
|
||||
TEST(TimeDeltaTest, ComparisonOperators) {
|
||||
const int64_t kSmall = 450;
|
||||
const int64_t kLarge = 451;
|
||||
const TimeDelta small = TimeDelta::ms(kSmall);
|
||||
const TimeDelta large = TimeDelta::ms(kLarge);
|
||||
|
||||
EXPECT_EQ(TimeDelta::Zero(), TimeDelta::ms(0));
|
||||
EXPECT_EQ(TimeDelta::PlusInfinity(), TimeDelta::PlusInfinity());
|
||||
EXPECT_EQ(small, TimeDelta::ms(kSmall));
|
||||
EXPECT_LE(small, TimeDelta::ms(kSmall));
|
||||
EXPECT_GE(small, TimeDelta::ms(kSmall));
|
||||
EXPECT_NE(small, TimeDelta::ms(kLarge));
|
||||
EXPECT_LE(small, TimeDelta::ms(kLarge));
|
||||
EXPECT_LT(small, TimeDelta::ms(kLarge));
|
||||
EXPECT_GE(large, TimeDelta::ms(kSmall));
|
||||
EXPECT_GT(large, TimeDelta::ms(kSmall));
|
||||
EXPECT_LT(TimeDelta::Zero(), small);
|
||||
EXPECT_GT(TimeDelta::Zero(), TimeDelta::ms(-kSmall));
|
||||
EXPECT_GT(TimeDelta::Zero(), TimeDelta::ms(-kSmall));
|
||||
|
||||
EXPECT_GT(TimeDelta::PlusInfinity(), large);
|
||||
EXPECT_LT(TimeDelta::MinusInfinity(), TimeDelta::Zero());
|
||||
}
|
||||
|
||||
TEST(TimeDeltaTest, MathOperations) {
|
||||
const int64_t kValueA = 267;
|
||||
const int64_t kValueB = 450;
|
||||
const TimeDelta delta_a = TimeDelta::ms(kValueA);
|
||||
const TimeDelta delta_b = TimeDelta::ms(kValueB);
|
||||
EXPECT_EQ((delta_a + delta_b).ms(), kValueA + kValueB);
|
||||
EXPECT_EQ((delta_a - delta_b).ms(), kValueA - kValueB);
|
||||
|
||||
const int32_t kInt32Value = 123;
|
||||
const double kFloatValue = 123.0;
|
||||
EXPECT_EQ((TimeDelta::us(kValueA) * kValueB).us(), kValueA * kValueB);
|
||||
EXPECT_EQ((TimeDelta::us(kValueA) * kInt32Value).us(), kValueA * kInt32Value);
|
||||
EXPECT_EQ((TimeDelta::us(kValueA) * kFloatValue).us(), kValueA * kFloatValue);
|
||||
|
||||
EXPECT_EQ(TimeDelta::us(-kValueA).Abs().us(), kValueA);
|
||||
EXPECT_EQ(TimeDelta::us(kValueA).Abs().us(), kValueA);
|
||||
}
|
||||
|
||||
TEST(TimestampTest, GetBackSameValues) {
|
||||
const int64_t kValue = 499;
|
||||
EXPECT_EQ(Timestamp::ms(kValue).ms(), kValue);
|
||||
EXPECT_EQ(Timestamp::us(kValue).us(), kValue);
|
||||
EXPECT_EQ(Timestamp::s(kValue).s(), kValue);
|
||||
}
|
||||
|
||||
TEST(TimestampTest, GetDifferentPrefix) {
|
||||
const int64_t kValue = 3000000;
|
||||
EXPECT_EQ(Timestamp::us(kValue).s(), kValue / 1000000);
|
||||
EXPECT_EQ(Timestamp::ms(kValue).s(), kValue / 1000);
|
||||
EXPECT_EQ(Timestamp::us(kValue).ms(), kValue / 1000);
|
||||
|
||||
EXPECT_EQ(Timestamp::ms(kValue).us(), kValue * 1000);
|
||||
EXPECT_EQ(Timestamp::s(kValue).ms(), kValue * 1000);
|
||||
EXPECT_EQ(Timestamp::s(kValue).us(), kValue * 1000000);
|
||||
}
|
||||
|
||||
TEST(TimestampTest, IdentityChecks) {
|
||||
const int64_t kValue = 3000;
|
||||
|
||||
EXPECT_TRUE(Timestamp::Infinity().IsInfinite());
|
||||
EXPECT_FALSE(Timestamp::ms(kValue).IsInfinite());
|
||||
|
||||
EXPECT_FALSE(Timestamp().IsFinite());
|
||||
EXPECT_FALSE(Timestamp::Infinity().IsFinite());
|
||||
EXPECT_TRUE(Timestamp::ms(kValue).IsFinite());
|
||||
}
|
||||
|
||||
TEST(TimestampTest, ComparisonOperators) {
|
||||
const int64_t kSmall = 450;
|
||||
const int64_t kLarge = 451;
|
||||
|
||||
EXPECT_EQ(Timestamp::Infinity(), Timestamp::Infinity());
|
||||
EXPECT_EQ(Timestamp::ms(kSmall), Timestamp::ms(kSmall));
|
||||
EXPECT_LE(Timestamp::ms(kSmall), Timestamp::ms(kSmall));
|
||||
EXPECT_GE(Timestamp::ms(kSmall), Timestamp::ms(kSmall));
|
||||
EXPECT_NE(Timestamp::ms(kSmall), Timestamp::ms(kLarge));
|
||||
EXPECT_LE(Timestamp::ms(kSmall), Timestamp::ms(kLarge));
|
||||
EXPECT_LT(Timestamp::ms(kSmall), Timestamp::ms(kLarge));
|
||||
EXPECT_GE(Timestamp::ms(kLarge), Timestamp::ms(kSmall));
|
||||
EXPECT_GT(Timestamp::ms(kLarge), Timestamp::ms(kSmall));
|
||||
}
|
||||
|
||||
TEST(UnitConversionTest, TimestampAndTimeDeltaMath) {
|
||||
const int64_t kValueA = 267;
|
||||
const int64_t kValueB = 450;
|
||||
const Timestamp time_a = Timestamp::ms(kValueA);
|
||||
const Timestamp time_b = Timestamp::ms(kValueB);
|
||||
const TimeDelta delta_a = TimeDelta::ms(kValueA);
|
||||
|
||||
EXPECT_EQ((time_a - time_b), TimeDelta::ms(kValueA - kValueB));
|
||||
EXPECT_EQ((time_b - delta_a), Timestamp::ms(kValueB - kValueA));
|
||||
EXPECT_EQ((time_b + delta_a), Timestamp::ms(kValueB + kValueA));
|
||||
}
|
||||
|
||||
TEST(DataSizeTest, GetBackSameValues) {
|
||||
const int64_t kValue = 123 * 8;
|
||||
EXPECT_EQ(DataSize::bytes(kValue).bytes(), kValue);
|
||||
EXPECT_EQ(DataSize::bits(kValue).bits(), kValue);
|
||||
}
|
||||
|
||||
TEST(DataSizeTest, GetDifferentPrefix) {
|
||||
const int64_t kValue = 123 * 8000;
|
||||
EXPECT_EQ(DataSize::bytes(kValue).bits(), kValue * 8);
|
||||
EXPECT_EQ(DataSize::bits(kValue).bytes(), kValue / 8);
|
||||
EXPECT_EQ(DataSize::bits(kValue).kilobits(), kValue / 1000);
|
||||
EXPECT_EQ(DataSize::bytes(kValue).kilobytes(), kValue / 1000);
|
||||
}
|
||||
|
||||
TEST(DataSizeTest, IdentityChecks) {
|
||||
const int64_t kValue = 3000;
|
||||
EXPECT_TRUE(DataSize::Zero().IsZero());
|
||||
EXPECT_FALSE(DataSize::bytes(kValue).IsZero());
|
||||
|
||||
EXPECT_TRUE(DataSize::Infinity().IsInfinite());
|
||||
EXPECT_FALSE(DataSize::Zero().IsInfinite());
|
||||
EXPECT_FALSE(DataSize::bytes(kValue).IsInfinite());
|
||||
|
||||
EXPECT_FALSE(DataSize::Infinity().IsFinite());
|
||||
EXPECT_TRUE(DataSize::bytes(kValue).IsFinite());
|
||||
EXPECT_TRUE(DataSize::Zero().IsFinite());
|
||||
}
|
||||
|
||||
TEST(DataSizeTest, ComparisonOperators) {
|
||||
const int64_t kSmall = 450;
|
||||
const int64_t kLarge = 451;
|
||||
const DataSize small = DataSize::bytes(kSmall);
|
||||
const DataSize large = DataSize::bytes(kLarge);
|
||||
|
||||
EXPECT_EQ(DataSize::Zero(), DataSize::bytes(0));
|
||||
EXPECT_EQ(DataSize::Infinity(), DataSize::Infinity());
|
||||
EXPECT_EQ(small, small);
|
||||
EXPECT_LE(small, small);
|
||||
EXPECT_GE(small, small);
|
||||
EXPECT_NE(small, large);
|
||||
EXPECT_LE(small, large);
|
||||
EXPECT_LT(small, large);
|
||||
EXPECT_GE(large, small);
|
||||
EXPECT_GT(large, small);
|
||||
EXPECT_LT(DataSize::Zero(), small);
|
||||
EXPECT_GT(DataSize::Infinity(), large);
|
||||
}
|
||||
|
||||
TEST(DataSizeTest, MathOperations) {
|
||||
const int64_t kValueA = 450;
|
||||
const int64_t kValueB = 267;
|
||||
const DataSize size_a = DataSize::bytes(kValueA);
|
||||
const DataSize size_b = DataSize::bytes(kValueB);
|
||||
EXPECT_EQ((size_a + size_b).bytes(), kValueA + kValueB);
|
||||
EXPECT_EQ((size_a - size_b).bytes(), kValueA - kValueB);
|
||||
|
||||
const int32_t kInt32Value = 123;
|
||||
const double kFloatValue = 123.0;
|
||||
EXPECT_EQ((size_a * kValueB).bytes(), kValueA * kValueB);
|
||||
EXPECT_EQ((size_a * kInt32Value).bytes(), kValueA * kInt32Value);
|
||||
EXPECT_EQ((size_a * kFloatValue).bytes(), kValueA * kFloatValue);
|
||||
|
||||
EXPECT_EQ((size_a / 10).bytes(), kValueA / 10);
|
||||
|
||||
DataSize mutable_size = DataSize::bytes(kValueA);
|
||||
mutable_size += size_b;
|
||||
EXPECT_EQ(mutable_size.bytes(), kValueA + kValueB);
|
||||
mutable_size -= size_a;
|
||||
EXPECT_EQ(mutable_size.bytes(), kValueB);
|
||||
}
|
||||
|
||||
TEST(DataRateTest, GetBackSameValues) {
|
||||
const int64_t kValue = 123 * 8;
|
||||
EXPECT_EQ(DataRate::bytes_per_second(kValue).bytes_per_second(), kValue);
|
||||
EXPECT_EQ(DataRate::bits_per_second(kValue).bits_per_second(), kValue);
|
||||
EXPECT_EQ(DataRate::bps(kValue).bps(), kValue);
|
||||
EXPECT_EQ(DataRate::kbps(kValue).kbps(), kValue);
|
||||
}
|
||||
|
||||
TEST(DataRateTest, GetDifferentPrefix) {
|
||||
const int64_t kValue = 123 * 8000;
|
||||
EXPECT_EQ(DataRate::bytes_per_second(kValue).bps(), kValue * 8);
|
||||
EXPECT_EQ(DataRate::bits_per_second(kValue).bytes_per_second(), kValue / 8);
|
||||
EXPECT_EQ(DataRate::bps(kValue).kbps(), kValue / 1000);
|
||||
}
|
||||
|
||||
TEST(DataRateTest, IdentityChecks) {
|
||||
const int64_t kValue = 3000;
|
||||
EXPECT_TRUE(DataRate::Zero().IsZero());
|
||||
EXPECT_FALSE(DataRate::bytes_per_second(kValue).IsZero());
|
||||
|
||||
EXPECT_TRUE(DataRate::Infinity().IsInfinite());
|
||||
EXPECT_FALSE(DataRate::Zero().IsInfinite());
|
||||
EXPECT_FALSE(DataRate::bytes_per_second(kValue).IsInfinite());
|
||||
|
||||
EXPECT_FALSE(DataRate::Infinity().IsFinite());
|
||||
EXPECT_TRUE(DataRate::bytes_per_second(kValue).IsFinite());
|
||||
EXPECT_TRUE(DataRate::Zero().IsFinite());
|
||||
}
|
||||
|
||||
TEST(DataRateTest, ComparisonOperators) {
|
||||
const int64_t kSmall = 450;
|
||||
const int64_t kLarge = 451;
|
||||
const DataRate small = DataRate::bytes_per_second(kSmall);
|
||||
const DataRate large = DataRate::bytes_per_second(kLarge);
|
||||
|
||||
EXPECT_EQ(DataRate::Zero(), DataRate::bps(0));
|
||||
EXPECT_EQ(DataRate::Infinity(), DataRate::Infinity());
|
||||
EXPECT_EQ(small, small);
|
||||
EXPECT_LE(small, small);
|
||||
EXPECT_GE(small, small);
|
||||
EXPECT_NE(small, large);
|
||||
EXPECT_LE(small, large);
|
||||
EXPECT_LT(small, large);
|
||||
EXPECT_GE(large, small);
|
||||
EXPECT_GT(large, small);
|
||||
EXPECT_LT(DataRate::Zero(), small);
|
||||
EXPECT_GT(DataRate::Infinity(), large);
|
||||
}
|
||||
|
||||
TEST(DataRateTest, MathOperations) {
|
||||
const int64_t kValueA = 450;
|
||||
const int64_t kValueB = 267;
|
||||
const DataRate size_a = DataRate::bytes_per_second(kValueA);
|
||||
const int32_t kInt32Value = 123;
|
||||
const double kFloatValue = 123.0;
|
||||
EXPECT_EQ((size_a * kValueB).bytes_per_second(), kValueA * kValueB);
|
||||
EXPECT_EQ((size_a * kInt32Value).bytes_per_second(), kValueA * kInt32Value);
|
||||
EXPECT_EQ((size_a * kFloatValue).bytes_per_second(), kValueA * kFloatValue);
|
||||
}
|
||||
|
||||
TEST(UnitConversionTest, DataRateAndDataSizeAndTimeDelta) {
|
||||
const int64_t kValueA = 5;
|
||||
const int64_t kValueB = 450;
|
||||
const int64_t kValueC = 45000;
|
||||
const TimeDelta delta_a = TimeDelta::seconds(kValueA);
|
||||
const DataRate rate_b = DataRate::bytes_per_second(kValueB);
|
||||
const DataSize size_c = DataSize::bytes(kValueC);
|
||||
EXPECT_EQ((delta_a * rate_b).bytes(), kValueA * kValueB);
|
||||
EXPECT_EQ((size_c / delta_a).bytes_per_second(), kValueC / kValueA);
|
||||
EXPECT_EQ((size_c / rate_b).s(), kValueC / kValueB);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
@ -9,12 +9,12 @@
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/test/network_control_tester.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_units_to_string.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "modules/congestion_controller/network_control/include/network_control.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
101
modules/congestion_controller/network_control/units/BUILD.gn
Normal file
101
modules/congestion_controller/network_control/units/BUILD.gn
Normal file
@ -0,0 +1,101 @@
|
||||
# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
import("../../../../webrtc.gni")
|
||||
|
||||
rtc_static_library("units") {
|
||||
sources = [
|
||||
"network_units.h",
|
||||
"unit_operators.cc",
|
||||
"unit_operators.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":data_rate",
|
||||
":data_size",
|
||||
":time_delta",
|
||||
":timestamp",
|
||||
"../../../../api:optional",
|
||||
"../../../../rtc_base:checks",
|
||||
"../../../../rtc_base:rtc_base_approved",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("data_rate") {
|
||||
sources = [
|
||||
"data_rate.cc",
|
||||
"data_rate.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"../../../../api:optional",
|
||||
"../../../../rtc_base:checks",
|
||||
"../../../../rtc_base:rtc_base_approved",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("data_size") {
|
||||
sources = [
|
||||
"data_size.cc",
|
||||
"data_size.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":data_rate",
|
||||
"../../../../api:optional",
|
||||
"../../../../rtc_base:checks",
|
||||
"../../../../rtc_base:rtc_base_approved",
|
||||
]
|
||||
}
|
||||
rtc_source_set("time_delta") {
|
||||
sources = [
|
||||
"time_delta.cc",
|
||||
"time_delta.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"../../../../api:optional",
|
||||
"../../../../rtc_base:checks",
|
||||
"../../../../rtc_base:rtc_base_approved",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("timestamp") {
|
||||
sources = [
|
||||
"timestamp.cc",
|
||||
"timestamp.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":time_delta",
|
||||
"../../../../api:optional",
|
||||
"../../../../rtc_base:checks",
|
||||
"../../../../rtc_base:rtc_base_approved",
|
||||
]
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
rtc_source_set("units_unittests") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"data_rate_unittest.cc",
|
||||
"data_size_unittest.cc",
|
||||
"time_delta_unittest.cc",
|
||||
"timestamp_unittest.cc",
|
||||
"unit_operators_unittest.cc",
|
||||
]
|
||||
deps = [
|
||||
":data_rate",
|
||||
":data_size",
|
||||
":time_delta",
|
||||
":timestamp",
|
||||
":units",
|
||||
"../../../../test:test_support",
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/data_rate.h"
|
||||
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string ToString(const DataRate& value) {
|
||||
char buf[64];
|
||||
rtc::SimpleStringBuilder sb(buf);
|
||||
if (value.IsInfinite()) {
|
||||
sb << "inf bps";
|
||||
} else if (!value.IsInitialized()) {
|
||||
sb << "? bps";
|
||||
} else {
|
||||
sb << value.bps() << " bps";
|
||||
}
|
||||
return sb.str();
|
||||
}
|
||||
} // namespace webrtc
|
119
modules/congestion_controller/network_control/units/data_rate.h
Normal file
119
modules/congestion_controller/network_control/units/data_rate.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_DATA_RATE_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_DATA_RATE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace data_rate_impl {
|
||||
constexpr int64_t kPlusInfinityVal = std::numeric_limits<int64_t>::max();
|
||||
constexpr int64_t kNotInitializedVal = -1;
|
||||
} // namespace data_rate_impl
|
||||
|
||||
// DataRate is a class that represents a given data rate. This can be used to
|
||||
// represent bandwidth, encoding bitrate, etc. The internal storage is currently
|
||||
// bits per second (bps) since this makes it easier to intepret the raw value
|
||||
// when debugging. The promised precision, however is only that it will
|
||||
// represent bytes per second accurately. Any implementation depending on bps
|
||||
// resolution should document this by changing this comment.
|
||||
class DataRate {
|
||||
public:
|
||||
DataRate() : DataRate(data_rate_impl::kNotInitializedVal) {}
|
||||
static DataRate Zero() { return DataRate(0); }
|
||||
static DataRate Infinity() {
|
||||
return DataRate(data_rate_impl::kPlusInfinityVal);
|
||||
}
|
||||
static DataRate bytes_per_second(int64_t bytes_per_sec) {
|
||||
RTC_DCHECK_GE(bytes_per_sec, 0);
|
||||
return DataRate(bytes_per_sec * 8);
|
||||
}
|
||||
static DataRate bits_per_second(int64_t bits_per_sec) {
|
||||
RTC_DCHECK_GE(bits_per_sec, 0);
|
||||
return DataRate(bits_per_sec);
|
||||
}
|
||||
static DataRate bps(int64_t bits_per_sec) {
|
||||
return DataRate::bits_per_second(bits_per_sec);
|
||||
}
|
||||
static DataRate kbps(int64_t kilobits_per_sec) {
|
||||
return DataRate::bits_per_second(kilobits_per_sec * 1000);
|
||||
}
|
||||
int64_t bits_per_second() const {
|
||||
RTC_DCHECK(IsFinite());
|
||||
return bits_per_sec_;
|
||||
}
|
||||
int64_t bytes_per_second() const { return bits_per_second() / 8; }
|
||||
int64_t bps() const { return bits_per_second(); }
|
||||
int64_t bps_or(int64_t fallback) const {
|
||||
return IsFinite() ? bits_per_second() : fallback;
|
||||
}
|
||||
int64_t kbps() const { return (bps() + 500) / 1000; }
|
||||
bool IsZero() const { return bits_per_sec_ == 0; }
|
||||
bool IsInfinite() const {
|
||||
return bits_per_sec_ == data_rate_impl::kPlusInfinityVal;
|
||||
}
|
||||
bool IsInitialized() const {
|
||||
return bits_per_sec_ != data_rate_impl::kNotInitializedVal;
|
||||
}
|
||||
bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
|
||||
DataRate operator*(double scalar) const {
|
||||
return DataRate::bytes_per_second(std::round(bytes_per_second() * scalar));
|
||||
}
|
||||
DataRate operator*(int64_t scalar) const {
|
||||
return DataRate::bytes_per_second(bytes_per_second() * scalar);
|
||||
}
|
||||
DataRate operator*(int32_t scalar) const {
|
||||
return DataRate::bytes_per_second(bytes_per_second() * scalar);
|
||||
}
|
||||
bool operator==(const DataRate& other) const {
|
||||
return bits_per_sec_ == other.bits_per_sec_;
|
||||
}
|
||||
bool operator!=(const DataRate& other) const {
|
||||
return bits_per_sec_ != other.bits_per_sec_;
|
||||
}
|
||||
bool operator<=(const DataRate& other) const {
|
||||
return bits_per_sec_ <= other.bits_per_sec_;
|
||||
}
|
||||
bool operator>=(const DataRate& other) const {
|
||||
return bits_per_sec_ >= other.bits_per_sec_;
|
||||
}
|
||||
bool operator>(const DataRate& other) const {
|
||||
return bits_per_sec_ > other.bits_per_sec_;
|
||||
}
|
||||
bool operator<(const DataRate& other) const {
|
||||
return bits_per_sec_ < other.bits_per_sec_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Bits per second used internally to simplify debugging by making the value
|
||||
// more recognizable.
|
||||
explicit DataRate(int64_t bits_per_second) : bits_per_sec_(bits_per_second) {}
|
||||
int64_t bits_per_sec_;
|
||||
};
|
||||
inline DataRate operator*(const double& scalar, const DataRate& rate) {
|
||||
return rate * scalar;
|
||||
}
|
||||
inline DataRate operator*(const int64_t& scalar, const DataRate& rate) {
|
||||
return rate * scalar;
|
||||
}
|
||||
inline DataRate operator*(const int32_t& scalar, const DataRate& rate) {
|
||||
return rate * scalar;
|
||||
}
|
||||
|
||||
std::string ToString(const DataRate& value);
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_DATA_RATE_H_
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/data_rate.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
TEST(DataRateTest, GetBackSameValues) {
|
||||
const int64_t kValue = 123 * 8;
|
||||
EXPECT_EQ(DataRate::bytes_per_second(kValue).bytes_per_second(), kValue);
|
||||
EXPECT_EQ(DataRate::bits_per_second(kValue).bits_per_second(), kValue);
|
||||
EXPECT_EQ(DataRate::bps(kValue).bps(), kValue);
|
||||
EXPECT_EQ(DataRate::kbps(kValue).kbps(), kValue);
|
||||
}
|
||||
|
||||
TEST(DataRateTest, GetDifferentPrefix) {
|
||||
const int64_t kValue = 123 * 8000;
|
||||
EXPECT_EQ(DataRate::bytes_per_second(kValue).bps(), kValue * 8);
|
||||
EXPECT_EQ(DataRate::bits_per_second(kValue).bytes_per_second(), kValue / 8);
|
||||
EXPECT_EQ(DataRate::bps(kValue).kbps(), kValue / 1000);
|
||||
}
|
||||
|
||||
TEST(DataRateTest, IdentityChecks) {
|
||||
const int64_t kValue = 3000;
|
||||
EXPECT_TRUE(DataRate::Zero().IsZero());
|
||||
EXPECT_FALSE(DataRate::bytes_per_second(kValue).IsZero());
|
||||
|
||||
EXPECT_TRUE(DataRate::Infinity().IsInfinite());
|
||||
EXPECT_FALSE(DataRate::Zero().IsInfinite());
|
||||
EXPECT_FALSE(DataRate::bytes_per_second(kValue).IsInfinite());
|
||||
|
||||
EXPECT_FALSE(DataRate::Infinity().IsFinite());
|
||||
EXPECT_TRUE(DataRate::bytes_per_second(kValue).IsFinite());
|
||||
EXPECT_TRUE(DataRate::Zero().IsFinite());
|
||||
}
|
||||
|
||||
TEST(DataRateTest, ComparisonOperators) {
|
||||
const int64_t kSmall = 450;
|
||||
const int64_t kLarge = 451;
|
||||
const DataRate small = DataRate::bytes_per_second(kSmall);
|
||||
const DataRate large = DataRate::bytes_per_second(kLarge);
|
||||
|
||||
EXPECT_EQ(DataRate::Zero(), DataRate::bps(0));
|
||||
EXPECT_EQ(DataRate::Infinity(), DataRate::Infinity());
|
||||
EXPECT_EQ(small, small);
|
||||
EXPECT_LE(small, small);
|
||||
EXPECT_GE(small, small);
|
||||
EXPECT_NE(small, large);
|
||||
EXPECT_LE(small, large);
|
||||
EXPECT_LT(small, large);
|
||||
EXPECT_GE(large, small);
|
||||
EXPECT_GT(large, small);
|
||||
EXPECT_LT(DataRate::Zero(), small);
|
||||
EXPECT_GT(DataRate::Infinity(), large);
|
||||
}
|
||||
|
||||
TEST(DataRateTest, MathOperations) {
|
||||
const int64_t kValueA = 450;
|
||||
const int64_t kValueB = 267;
|
||||
const DataRate size_a = DataRate::bytes_per_second(kValueA);
|
||||
const int32_t kInt32Value = 123;
|
||||
const double kFloatValue = 123.0;
|
||||
EXPECT_EQ((size_a * kValueB).bytes_per_second(), kValueA * kValueB);
|
||||
EXPECT_EQ((size_a * kInt32Value).bytes_per_second(), kValueA * kInt32Value);
|
||||
EXPECT_EQ((size_a * kFloatValue).bytes_per_second(), kValueA * kFloatValue);
|
||||
}
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/data_size.h"
|
||||
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string ToString(const DataSize& value) {
|
||||
char buf[64];
|
||||
rtc::SimpleStringBuilder sb(buf);
|
||||
if (value.IsInfinite()) {
|
||||
sb << "inf bytes";
|
||||
} else if (!value.IsInitialized()) {
|
||||
sb << "? bytes";
|
||||
} else {
|
||||
sb << value.bytes() << " bytes";
|
||||
}
|
||||
return sb.str();
|
||||
}
|
||||
} // namespace webrtc
|
118
modules/congestion_controller/network_control/units/data_size.h
Normal file
118
modules/congestion_controller/network_control/units/data_size.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_DATA_SIZE_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_DATA_SIZE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace data_size_impl {
|
||||
constexpr int64_t kPlusInfinityVal = std::numeric_limits<int64_t>::max();
|
||||
constexpr int64_t kNotInitializedVal = -1;
|
||||
} // namespace data_size_impl
|
||||
|
||||
// DataSize is a class represeting a count of bytes. Note that while it can be
|
||||
// initialized by a number of bits, it does not guarantee that the resolution is
|
||||
// kept and the internal storage is in bytes. The number of bits will be
|
||||
// truncated to fit.
|
||||
class DataSize {
|
||||
public:
|
||||
DataSize() : DataSize(data_size_impl::kNotInitializedVal) {}
|
||||
static DataSize Zero() { return DataSize(0); }
|
||||
static DataSize Infinity() {
|
||||
return DataSize(data_size_impl::kPlusInfinityVal);
|
||||
}
|
||||
static DataSize bytes(int64_t bytes) {
|
||||
RTC_DCHECK_GE(bytes, 0);
|
||||
return DataSize(bytes);
|
||||
}
|
||||
static DataSize bits(int64_t bits) {
|
||||
RTC_DCHECK_GE(bits, 0);
|
||||
return DataSize(bits / 8);
|
||||
}
|
||||
int64_t bytes() const {
|
||||
RTC_DCHECK(IsFinite());
|
||||
return bytes_;
|
||||
}
|
||||
int64_t kilobytes() const { return (bytes() + 500) / 1000; }
|
||||
int64_t bits() const { return bytes() * 8; }
|
||||
int64_t kilobits() const { return (bits() + 500) / 1000; }
|
||||
bool IsZero() const { return bytes_ == 0; }
|
||||
bool IsInfinite() const { return bytes_ == data_size_impl::kPlusInfinityVal; }
|
||||
bool IsInitialized() const {
|
||||
return bytes_ != data_size_impl::kNotInitializedVal;
|
||||
}
|
||||
bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
|
||||
DataSize operator-(const DataSize& other) const {
|
||||
return DataSize::bytes(bytes() - other.bytes());
|
||||
}
|
||||
DataSize operator+(const DataSize& other) const {
|
||||
return DataSize::bytes(bytes() + other.bytes());
|
||||
}
|
||||
DataSize operator*(double scalar) const {
|
||||
return DataSize::bytes(std::round(bytes() * scalar));
|
||||
}
|
||||
DataSize operator*(int64_t scalar) const {
|
||||
return DataSize::bytes(bytes() * scalar);
|
||||
}
|
||||
DataSize operator*(int32_t scalar) const {
|
||||
return DataSize::bytes(bytes() * scalar);
|
||||
}
|
||||
DataSize operator/(int64_t scalar) const {
|
||||
return DataSize::bytes(bytes() / scalar);
|
||||
}
|
||||
DataSize& operator-=(const DataSize& other) {
|
||||
bytes_ -= other.bytes();
|
||||
return *this;
|
||||
}
|
||||
DataSize& operator+=(const DataSize& other) {
|
||||
bytes_ += other.bytes();
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const DataSize& other) const {
|
||||
return bytes_ == other.bytes_;
|
||||
}
|
||||
bool operator!=(const DataSize& other) const {
|
||||
return bytes_ != other.bytes_;
|
||||
}
|
||||
bool operator<=(const DataSize& other) const {
|
||||
return bytes_ <= other.bytes_;
|
||||
}
|
||||
bool operator>=(const DataSize& other) const {
|
||||
return bytes_ >= other.bytes_;
|
||||
}
|
||||
bool operator>(const DataSize& other) const { return bytes_ > other.bytes_; }
|
||||
bool operator<(const DataSize& other) const { return bytes_ < other.bytes_; }
|
||||
|
||||
private:
|
||||
explicit DataSize(int64_t bytes) : bytes_(bytes) {}
|
||||
int64_t bytes_;
|
||||
};
|
||||
inline DataSize operator*(const double& scalar, const DataSize& size) {
|
||||
return size * scalar;
|
||||
}
|
||||
inline DataSize operator*(const int64_t& scalar, const DataSize& size) {
|
||||
return size * scalar;
|
||||
}
|
||||
inline DataSize operator*(const int32_t& scalar, const DataSize& size) {
|
||||
return size * scalar;
|
||||
}
|
||||
|
||||
std::string ToString(const DataSize& value);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_DATA_SIZE_H_
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/data_size.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
TEST(DataSizeTest, GetBackSameValues) {
|
||||
const int64_t kValue = 123 * 8;
|
||||
EXPECT_EQ(DataSize::bytes(kValue).bytes(), kValue);
|
||||
EXPECT_EQ(DataSize::bits(kValue).bits(), kValue);
|
||||
}
|
||||
|
||||
TEST(DataSizeTest, GetDifferentPrefix) {
|
||||
const int64_t kValue = 123 * 8000;
|
||||
EXPECT_EQ(DataSize::bytes(kValue).bits(), kValue * 8);
|
||||
EXPECT_EQ(DataSize::bits(kValue).bytes(), kValue / 8);
|
||||
EXPECT_EQ(DataSize::bits(kValue).kilobits(), kValue / 1000);
|
||||
EXPECT_EQ(DataSize::bytes(kValue).kilobytes(), kValue / 1000);
|
||||
}
|
||||
|
||||
TEST(DataSizeTest, IdentityChecks) {
|
||||
const int64_t kValue = 3000;
|
||||
EXPECT_TRUE(DataSize::Zero().IsZero());
|
||||
EXPECT_FALSE(DataSize::bytes(kValue).IsZero());
|
||||
|
||||
EXPECT_TRUE(DataSize::Infinity().IsInfinite());
|
||||
EXPECT_FALSE(DataSize::Zero().IsInfinite());
|
||||
EXPECT_FALSE(DataSize::bytes(kValue).IsInfinite());
|
||||
|
||||
EXPECT_FALSE(DataSize::Infinity().IsFinite());
|
||||
EXPECT_TRUE(DataSize::bytes(kValue).IsFinite());
|
||||
EXPECT_TRUE(DataSize::Zero().IsFinite());
|
||||
}
|
||||
|
||||
TEST(DataSizeTest, ComparisonOperators) {
|
||||
const int64_t kSmall = 450;
|
||||
const int64_t kLarge = 451;
|
||||
const DataSize small = DataSize::bytes(kSmall);
|
||||
const DataSize large = DataSize::bytes(kLarge);
|
||||
|
||||
EXPECT_EQ(DataSize::Zero(), DataSize::bytes(0));
|
||||
EXPECT_EQ(DataSize::Infinity(), DataSize::Infinity());
|
||||
EXPECT_EQ(small, small);
|
||||
EXPECT_LE(small, small);
|
||||
EXPECT_GE(small, small);
|
||||
EXPECT_NE(small, large);
|
||||
EXPECT_LE(small, large);
|
||||
EXPECT_LT(small, large);
|
||||
EXPECT_GE(large, small);
|
||||
EXPECT_GT(large, small);
|
||||
EXPECT_LT(DataSize::Zero(), small);
|
||||
EXPECT_GT(DataSize::Infinity(), large);
|
||||
}
|
||||
|
||||
TEST(DataSizeTest, MathOperations) {
|
||||
const int64_t kValueA = 450;
|
||||
const int64_t kValueB = 267;
|
||||
const DataSize size_a = DataSize::bytes(kValueA);
|
||||
const DataSize size_b = DataSize::bytes(kValueB);
|
||||
EXPECT_EQ((size_a + size_b).bytes(), kValueA + kValueB);
|
||||
EXPECT_EQ((size_a - size_b).bytes(), kValueA - kValueB);
|
||||
|
||||
const int32_t kInt32Value = 123;
|
||||
const double kFloatValue = 123.0;
|
||||
EXPECT_EQ((size_a * kValueB).bytes(), kValueA * kValueB);
|
||||
EXPECT_EQ((size_a * kInt32Value).bytes(), kValueA * kInt32Value);
|
||||
EXPECT_EQ((size_a * kFloatValue).bytes(), kValueA * kFloatValue);
|
||||
|
||||
EXPECT_EQ((size_a / 10).bytes(), kValueA / 10);
|
||||
|
||||
DataSize mutable_size = DataSize::bytes(kValueA);
|
||||
mutable_size += size_b;
|
||||
EXPECT_EQ(mutable_size.bytes(), kValueA + kValueB);
|
||||
mutable_size -= size_a;
|
||||
EXPECT_EQ(mutable_size.bytes(), kValueB);
|
||||
}
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_NETWORK_UNITS_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_NETWORK_UNITS_H_
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/data_rate.h"
|
||||
#include "modules/congestion_controller/network_control/units/data_size.h"
|
||||
#include "modules/congestion_controller/network_control/units/time_delta.h"
|
||||
#include "modules/congestion_controller/network_control/units/timestamp.h"
|
||||
#include "modules/congestion_controller/network_control/units/unit_operators.h"
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_NETWORK_UNITS_H_
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/time_delta.h"
|
||||
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string ToString(const TimeDelta& value) {
|
||||
char buf[64];
|
||||
rtc::SimpleStringBuilder sb(buf);
|
||||
if (value.IsPlusInfinity()) {
|
||||
sb << "+inf ms";
|
||||
} else if (value.IsMinusInfinity()) {
|
||||
sb << "-inf ms";
|
||||
} else if (!value.IsInitialized()) {
|
||||
sb << "? ms";
|
||||
} else {
|
||||
sb << value.ms() << " ms";
|
||||
}
|
||||
return sb.str();
|
||||
}
|
||||
} // namespace webrtc
|
149
modules/congestion_controller/network_control/units/time_delta.h
Normal file
149
modules/congestion_controller/network_control/units/time_delta.h
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_TIME_DELTA_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_TIME_DELTA_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace timedelta_impl {
|
||||
constexpr int64_t kPlusInfinityVal = std::numeric_limits<int64_t>::max();
|
||||
constexpr int64_t kMinusInfinityVal = std::numeric_limits<int64_t>::min();
|
||||
constexpr int64_t kSignedNotInitializedVal = kMinusInfinityVal + 1;
|
||||
|
||||
} // namespace timedelta_impl
|
||||
|
||||
// TimeDelta represents the difference between two timestamps. Commonly this can
|
||||
// be a duration. However since two Timestamps are not guaranteed to have the
|
||||
// same epoch (they might come from different computers, making exact
|
||||
// synchronisation infeasible), the duration covered by a TimeDelta can be
|
||||
// undefined. To simplify usage, it can be constructed and converted to
|
||||
// different units, specifically seconds (s), milliseconds (ms) and
|
||||
// microseconds (us).
|
||||
class TimeDelta {
|
||||
public:
|
||||
TimeDelta() : TimeDelta(timedelta_impl::kSignedNotInitializedVal) {}
|
||||
static TimeDelta Zero() { return TimeDelta(0); }
|
||||
static TimeDelta PlusInfinity() {
|
||||
return TimeDelta(timedelta_impl::kPlusInfinityVal);
|
||||
}
|
||||
static TimeDelta MinusInfinity() {
|
||||
return TimeDelta(timedelta_impl::kMinusInfinityVal);
|
||||
}
|
||||
static TimeDelta seconds(int64_t seconds) { return TimeDelta::s(seconds); }
|
||||
static TimeDelta s(int64_t seconds) {
|
||||
return TimeDelta::us(seconds * 1000000);
|
||||
}
|
||||
static TimeDelta ms(int64_t milliseconds) {
|
||||
return TimeDelta::us(milliseconds * 1000);
|
||||
}
|
||||
static TimeDelta us(int64_t microseconds) {
|
||||
// Infinities only allowed via use of explicit constants.
|
||||
RTC_DCHECK(microseconds > std::numeric_limits<int64_t>::min());
|
||||
RTC_DCHECK(microseconds < std::numeric_limits<int64_t>::max());
|
||||
RTC_DCHECK(microseconds != timedelta_impl::kSignedNotInitializedVal);
|
||||
return TimeDelta(microseconds);
|
||||
}
|
||||
int64_t s() const {
|
||||
return (us() + (us() >= 0 ? 500000 : -500000)) / 1000000;
|
||||
}
|
||||
int64_t ms() const { return (us() + (us() >= 0 ? 500 : -500)) / 1000; }
|
||||
int64_t us() const {
|
||||
RTC_DCHECK(IsFinite());
|
||||
return microseconds_;
|
||||
}
|
||||
|
||||
double SecondsAsDouble() const;
|
||||
|
||||
TimeDelta Abs() const { return TimeDelta::us(std::abs(us())); }
|
||||
bool IsZero() const { return microseconds_ == 0; }
|
||||
bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
|
||||
bool IsInitialized() const {
|
||||
return microseconds_ != timedelta_impl::kSignedNotInitializedVal;
|
||||
}
|
||||
bool IsInfinite() const {
|
||||
return microseconds_ == timedelta_impl::kPlusInfinityVal ||
|
||||
microseconds_ == timedelta_impl::kMinusInfinityVal;
|
||||
}
|
||||
bool IsPlusInfinity() const {
|
||||
return microseconds_ == timedelta_impl::kPlusInfinityVal;
|
||||
}
|
||||
bool IsMinusInfinity() const {
|
||||
return microseconds_ == timedelta_impl::kMinusInfinityVal;
|
||||
}
|
||||
TimeDelta operator+(const TimeDelta& other) const {
|
||||
return TimeDelta::us(us() + other.us());
|
||||
}
|
||||
TimeDelta operator-(const TimeDelta& other) const {
|
||||
return TimeDelta::us(us() - other.us());
|
||||
}
|
||||
TimeDelta& operator-=(const TimeDelta& other) {
|
||||
microseconds_ -= other.us();
|
||||
return *this;
|
||||
}
|
||||
TimeDelta& operator+=(const TimeDelta& other) {
|
||||
microseconds_ += other.us();
|
||||
return *this;
|
||||
}
|
||||
TimeDelta operator*(double scalar) const {
|
||||
return TimeDelta::us(std::round(us() * scalar));
|
||||
}
|
||||
TimeDelta operator*(int64_t scalar) const {
|
||||
return TimeDelta::us(us() * scalar);
|
||||
}
|
||||
TimeDelta operator*(int32_t scalar) const {
|
||||
return TimeDelta::us(us() * scalar);
|
||||
}
|
||||
TimeDelta operator/(int64_t scalar) const {
|
||||
return TimeDelta::us(us() / scalar);
|
||||
}
|
||||
bool operator==(const TimeDelta& other) const {
|
||||
return microseconds_ == other.microseconds_;
|
||||
}
|
||||
bool operator!=(const TimeDelta& other) const {
|
||||
return microseconds_ != other.microseconds_;
|
||||
}
|
||||
bool operator<=(const TimeDelta& other) const {
|
||||
return microseconds_ <= other.microseconds_;
|
||||
}
|
||||
bool operator>=(const TimeDelta& other) const {
|
||||
return microseconds_ >= other.microseconds_;
|
||||
}
|
||||
bool operator>(const TimeDelta& other) const {
|
||||
return microseconds_ > other.microseconds_;
|
||||
}
|
||||
bool operator<(const TimeDelta& other) const {
|
||||
return microseconds_ < other.microseconds_;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit TimeDelta(int64_t us) : microseconds_(us) {}
|
||||
int64_t microseconds_;
|
||||
};
|
||||
inline TimeDelta operator*(const double& scalar, const TimeDelta& delta) {
|
||||
return delta * scalar;
|
||||
}
|
||||
inline TimeDelta operator*(const int64_t& scalar, const TimeDelta& delta) {
|
||||
return delta * scalar;
|
||||
}
|
||||
inline TimeDelta operator*(const int32_t& scalar, const TimeDelta& delta) {
|
||||
return delta * scalar;
|
||||
}
|
||||
|
||||
std::string ToString(const TimeDelta& value);
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_TIME_DELTA_H_
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/time_delta.h"
|
||||
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
TEST(TimeDeltaTest, GetBackSameValues) {
|
||||
const int64_t kValue = 499;
|
||||
for (int sign = -1; sign <= 1; ++sign) {
|
||||
int64_t value = kValue * sign;
|
||||
EXPECT_EQ(TimeDelta::ms(value).ms(), value);
|
||||
EXPECT_EQ(TimeDelta::us(value).us(), value);
|
||||
EXPECT_EQ(TimeDelta::s(value).s(), value);
|
||||
EXPECT_EQ(TimeDelta::seconds(value).s(), value);
|
||||
}
|
||||
EXPECT_EQ(TimeDelta::Zero().us(), 0);
|
||||
}
|
||||
|
||||
TEST(TimeDeltaTest, GetDifferentPrefix) {
|
||||
const int64_t kValue = 3000000;
|
||||
EXPECT_EQ(TimeDelta::us(kValue).s(), kValue / 1000000);
|
||||
EXPECT_EQ(TimeDelta::ms(kValue).s(), kValue / 1000);
|
||||
EXPECT_EQ(TimeDelta::us(kValue).ms(), kValue / 1000);
|
||||
|
||||
EXPECT_EQ(TimeDelta::ms(kValue).us(), kValue * 1000);
|
||||
EXPECT_EQ(TimeDelta::s(kValue).ms(), kValue * 1000);
|
||||
EXPECT_EQ(TimeDelta::s(kValue).us(), kValue * 1000000);
|
||||
}
|
||||
|
||||
TEST(TimeDeltaTest, IdentityChecks) {
|
||||
const int64_t kValue = 3000;
|
||||
EXPECT_TRUE(TimeDelta::Zero().IsZero());
|
||||
EXPECT_FALSE(TimeDelta::ms(kValue).IsZero());
|
||||
|
||||
EXPECT_TRUE(TimeDelta::PlusInfinity().IsInfinite());
|
||||
EXPECT_TRUE(TimeDelta::MinusInfinity().IsInfinite());
|
||||
EXPECT_FALSE(TimeDelta::Zero().IsInfinite());
|
||||
EXPECT_FALSE(TimeDelta::ms(-kValue).IsInfinite());
|
||||
EXPECT_FALSE(TimeDelta::ms(kValue).IsInfinite());
|
||||
|
||||
EXPECT_FALSE(TimeDelta::PlusInfinity().IsFinite());
|
||||
EXPECT_FALSE(TimeDelta::MinusInfinity().IsFinite());
|
||||
EXPECT_TRUE(TimeDelta::ms(-kValue).IsFinite());
|
||||
EXPECT_TRUE(TimeDelta::ms(kValue).IsFinite());
|
||||
EXPECT_TRUE(TimeDelta::Zero().IsFinite());
|
||||
}
|
||||
|
||||
TEST(TimeDeltaTest, ComparisonOperators) {
|
||||
const int64_t kSmall = 450;
|
||||
const int64_t kLarge = 451;
|
||||
const TimeDelta small = TimeDelta::ms(kSmall);
|
||||
const TimeDelta large = TimeDelta::ms(kLarge);
|
||||
|
||||
EXPECT_EQ(TimeDelta::Zero(), TimeDelta::ms(0));
|
||||
EXPECT_EQ(TimeDelta::PlusInfinity(), TimeDelta::PlusInfinity());
|
||||
EXPECT_EQ(small, TimeDelta::ms(kSmall));
|
||||
EXPECT_LE(small, TimeDelta::ms(kSmall));
|
||||
EXPECT_GE(small, TimeDelta::ms(kSmall));
|
||||
EXPECT_NE(small, TimeDelta::ms(kLarge));
|
||||
EXPECT_LE(small, TimeDelta::ms(kLarge));
|
||||
EXPECT_LT(small, TimeDelta::ms(kLarge));
|
||||
EXPECT_GE(large, TimeDelta::ms(kSmall));
|
||||
EXPECT_GT(large, TimeDelta::ms(kSmall));
|
||||
EXPECT_LT(TimeDelta::Zero(), small);
|
||||
EXPECT_GT(TimeDelta::Zero(), TimeDelta::ms(-kSmall));
|
||||
EXPECT_GT(TimeDelta::Zero(), TimeDelta::ms(-kSmall));
|
||||
|
||||
EXPECT_GT(TimeDelta::PlusInfinity(), large);
|
||||
EXPECT_LT(TimeDelta::MinusInfinity(), TimeDelta::Zero());
|
||||
}
|
||||
|
||||
TEST(TimeDeltaTest, MathOperations) {
|
||||
const int64_t kValueA = 267;
|
||||
const int64_t kValueB = 450;
|
||||
const TimeDelta delta_a = TimeDelta::ms(kValueA);
|
||||
const TimeDelta delta_b = TimeDelta::ms(kValueB);
|
||||
EXPECT_EQ((delta_a + delta_b).ms(), kValueA + kValueB);
|
||||
EXPECT_EQ((delta_a - delta_b).ms(), kValueA - kValueB);
|
||||
|
||||
const int32_t kInt32Value = 123;
|
||||
const double kFloatValue = 123.0;
|
||||
EXPECT_EQ((TimeDelta::us(kValueA) * kValueB).us(), kValueA * kValueB);
|
||||
EXPECT_EQ((TimeDelta::us(kValueA) * kInt32Value).us(), kValueA * kInt32Value);
|
||||
EXPECT_EQ((TimeDelta::us(kValueA) * kFloatValue).us(), kValueA * kFloatValue);
|
||||
|
||||
EXPECT_EQ(TimeDelta::us(-kValueA).Abs().us(), kValueA);
|
||||
EXPECT_EQ(TimeDelta::us(kValueA).Abs().us(), kValueA);
|
||||
}
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/timestamp.h"
|
||||
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace webrtc {
|
||||
double Timestamp::SecondsAsDouble() const {
|
||||
if (IsInfinite()) {
|
||||
return std::numeric_limits<double>::infinity();
|
||||
} else if (!IsInitialized()) {
|
||||
return std::numeric_limits<double>::signaling_NaN();
|
||||
} else {
|
||||
return us() * 1e-6;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ToString(const Timestamp& value) {
|
||||
char buf[64];
|
||||
rtc::SimpleStringBuilder sb(buf);
|
||||
if (value.IsInfinite()) {
|
||||
sb << "inf ms";
|
||||
} else if (!value.IsInitialized()) {
|
||||
sb << "? ms";
|
||||
} else {
|
||||
sb << value.ms() << " ms";
|
||||
}
|
||||
return sb.str();
|
||||
}
|
||||
} // namespace webrtc
|
101
modules/congestion_controller/network_control/units/timestamp.h
Normal file
101
modules/congestion_controller/network_control/units/timestamp.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_TIMESTAMP_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_TIMESTAMP_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/time_delta.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace timestamp_impl {
|
||||
constexpr int64_t kPlusInfinityVal = std::numeric_limits<int64_t>::max();
|
||||
constexpr int64_t kMinusInfinityVal = std::numeric_limits<int64_t>::min();
|
||||
constexpr int64_t kSignedNotInitializedVal = kMinusInfinityVal + 1;
|
||||
constexpr int64_t kNotInitializedVal = -1;
|
||||
} // namespace timestamp_impl
|
||||
|
||||
// Timestamp represents the time that has passed since some unspecified epoch.
|
||||
// The epoch is assumed to be before any represented timestamps, this means that
|
||||
// negative values are not valid. The most notable feature is that the
|
||||
// difference of two Timestamps results in a TimeDelta.
|
||||
class Timestamp {
|
||||
public:
|
||||
Timestamp() : Timestamp(timestamp_impl::kNotInitializedVal) {}
|
||||
static Timestamp Infinity() {
|
||||
return Timestamp(timestamp_impl::kPlusInfinityVal);
|
||||
}
|
||||
static Timestamp seconds(int64_t seconds) { return Timestamp::s(seconds); }
|
||||
static Timestamp s(int64_t seconds) {
|
||||
return Timestamp::us(seconds * 1000000);
|
||||
}
|
||||
static Timestamp ms(int64_t millis) { return Timestamp::us(millis * 1000); }
|
||||
static Timestamp us(int64_t micros) {
|
||||
RTC_DCHECK_GE(micros, 0);
|
||||
return Timestamp(micros);
|
||||
}
|
||||
int64_t s() const { return (us() + 500000) / 1000000; }
|
||||
int64_t ms() const { return (us() + 500) / 1000; }
|
||||
int64_t us() const {
|
||||
RTC_DCHECK(IsFinite());
|
||||
return microseconds_;
|
||||
}
|
||||
|
||||
double SecondsAsDouble() const;
|
||||
|
||||
bool IsInfinite() const {
|
||||
return microseconds_ == timestamp_impl::kPlusInfinityVal;
|
||||
}
|
||||
bool IsInitialized() const {
|
||||
return microseconds_ != timestamp_impl::kNotInitializedVal;
|
||||
}
|
||||
bool IsFinite() const { return IsInitialized() && !IsInfinite(); }
|
||||
TimeDelta operator-(const Timestamp& other) const {
|
||||
return TimeDelta::us(us() - other.us());
|
||||
}
|
||||
Timestamp operator-(const TimeDelta& delta) const {
|
||||
return Timestamp::us(us() - delta.us());
|
||||
}
|
||||
Timestamp operator+(const TimeDelta& delta) const {
|
||||
return Timestamp::us(us() + delta.us());
|
||||
}
|
||||
Timestamp& operator-=(const TimeDelta& other) {
|
||||
microseconds_ -= other.us();
|
||||
return *this;
|
||||
}
|
||||
Timestamp& operator+=(const TimeDelta& other) {
|
||||
microseconds_ += other.us();
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const Timestamp& other) const {
|
||||
return microseconds_ == other.microseconds_;
|
||||
}
|
||||
bool operator!=(const Timestamp& other) const {
|
||||
return microseconds_ != other.microseconds_;
|
||||
}
|
||||
bool operator<=(const Timestamp& other) const { return us() <= other.us(); }
|
||||
bool operator>=(const Timestamp& other) const { return us() >= other.us(); }
|
||||
bool operator>(const Timestamp& other) const { return us() > other.us(); }
|
||||
bool operator<(const Timestamp& other) const { return us() < other.us(); }
|
||||
|
||||
private:
|
||||
explicit Timestamp(int64_t us) : microseconds_(us) {}
|
||||
int64_t microseconds_;
|
||||
};
|
||||
|
||||
std::string ToString(const Timestamp& value);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_TIMESTAMP_H_
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/timestamp.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
TEST(TimestampTest, GetBackSameValues) {
|
||||
const int64_t kValue = 499;
|
||||
EXPECT_EQ(Timestamp::ms(kValue).ms(), kValue);
|
||||
EXPECT_EQ(Timestamp::us(kValue).us(), kValue);
|
||||
EXPECT_EQ(Timestamp::s(kValue).s(), kValue);
|
||||
}
|
||||
|
||||
TEST(TimestampTest, GetDifferentPrefix) {
|
||||
const int64_t kValue = 3000000;
|
||||
EXPECT_EQ(Timestamp::us(kValue).s(), kValue / 1000000);
|
||||
EXPECT_EQ(Timestamp::ms(kValue).s(), kValue / 1000);
|
||||
EXPECT_EQ(Timestamp::us(kValue).ms(), kValue / 1000);
|
||||
|
||||
EXPECT_EQ(Timestamp::ms(kValue).us(), kValue * 1000);
|
||||
EXPECT_EQ(Timestamp::s(kValue).ms(), kValue * 1000);
|
||||
EXPECT_EQ(Timestamp::s(kValue).us(), kValue * 1000000);
|
||||
}
|
||||
|
||||
TEST(TimestampTest, IdentityChecks) {
|
||||
const int64_t kValue = 3000;
|
||||
|
||||
EXPECT_TRUE(Timestamp::Infinity().IsInfinite());
|
||||
EXPECT_FALSE(Timestamp::ms(kValue).IsInfinite());
|
||||
|
||||
EXPECT_FALSE(Timestamp().IsFinite());
|
||||
EXPECT_FALSE(Timestamp::Infinity().IsFinite());
|
||||
EXPECT_TRUE(Timestamp::ms(kValue).IsFinite());
|
||||
}
|
||||
|
||||
TEST(TimestampTest, ComparisonOperators) {
|
||||
const int64_t kSmall = 450;
|
||||
const int64_t kLarge = 451;
|
||||
|
||||
EXPECT_EQ(Timestamp::Infinity(), Timestamp::Infinity());
|
||||
EXPECT_EQ(Timestamp::ms(kSmall), Timestamp::ms(kSmall));
|
||||
EXPECT_LE(Timestamp::ms(kSmall), Timestamp::ms(kSmall));
|
||||
EXPECT_GE(Timestamp::ms(kSmall), Timestamp::ms(kSmall));
|
||||
EXPECT_NE(Timestamp::ms(kSmall), Timestamp::ms(kLarge));
|
||||
EXPECT_LE(Timestamp::ms(kSmall), Timestamp::ms(kLarge));
|
||||
EXPECT_LT(Timestamp::ms(kSmall), Timestamp::ms(kLarge));
|
||||
EXPECT_GE(Timestamp::ms(kLarge), Timestamp::ms(kSmall));
|
||||
EXPECT_GT(Timestamp::ms(kLarge), Timestamp::ms(kSmall));
|
||||
}
|
||||
|
||||
TEST(UnitConversionTest, TimestampAndTimeDeltaMath) {
|
||||
const int64_t kValueA = 267;
|
||||
const int64_t kValueB = 450;
|
||||
const Timestamp time_a = Timestamp::ms(kValueA);
|
||||
const Timestamp time_b = Timestamp::ms(kValueB);
|
||||
const TimeDelta delta_a = TimeDelta::ms(kValueA);
|
||||
|
||||
EXPECT_EQ((time_a - time_b), TimeDelta::ms(kValueA - kValueB));
|
||||
EXPECT_EQ((time_b - delta_a), Timestamp::ms(kValueB - kValueA));
|
||||
EXPECT_EQ((time_b + delta_a), Timestamp::ms(kValueB + kValueA));
|
||||
}
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/unit_operators.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace webrtc {
|
||||
DataRate operator/(const DataSize& size, const TimeDelta& duration) {
|
||||
RTC_DCHECK(size.bytes() < std::numeric_limits<int64_t>::max() / 1000000)
|
||||
<< "size is too large, size: " << size.bytes() << " is not less than "
|
||||
<< std::numeric_limits<int64_t>::max() / 1000000;
|
||||
int64_t bytes_per_sec = size.bytes() * 1000000 / duration.us();
|
||||
return DataRate::bytes_per_second(bytes_per_sec);
|
||||
}
|
||||
|
||||
TimeDelta operator/(const DataSize& size, const DataRate& rate) {
|
||||
RTC_DCHECK(size.bytes() < std::numeric_limits<int64_t>::max() / 1000000)
|
||||
<< "size is too large, size: " << size.bytes() << " is not less than "
|
||||
<< std::numeric_limits<int64_t>::max() / 1000000;
|
||||
int64_t microseconds = size.bytes() * 1000000 / rate.bytes_per_second();
|
||||
return TimeDelta::us(microseconds);
|
||||
}
|
||||
|
||||
DataSize operator*(const DataRate& rate, const TimeDelta& duration) {
|
||||
int64_t micro_bytes = rate.bytes_per_second() * duration.us();
|
||||
return DataSize::bytes((micro_bytes + 500000) / 1000000);
|
||||
}
|
||||
|
||||
DataSize operator*(const TimeDelta& duration, const DataRate& rate) {
|
||||
return rate * duration;
|
||||
}
|
||||
} // namespace webrtc
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_UNIT_OPERATORS_H_
|
||||
#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_UNIT_OPERATORS_H_
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/data_rate.h"
|
||||
#include "modules/congestion_controller/network_control/units/data_size.h"
|
||||
#include "modules/congestion_controller/network_control/units/time_delta.h"
|
||||
|
||||
namespace webrtc {
|
||||
DataRate operator/(const DataSize& size, const TimeDelta& duration);
|
||||
TimeDelta operator/(const DataSize& size, const DataRate& rate);
|
||||
DataSize operator*(const DataRate& rate, const TimeDelta& duration);
|
||||
DataSize operator*(const TimeDelta& duration, const DataRate& rate);
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_UNIT_OPERATORS_H_
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/congestion_controller/network_control/units/unit_operators.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
|
||||
TEST(UnitConversionTest, DataRateAndDataSizeAndTimeDelta) {
|
||||
const int64_t kValueA = 5;
|
||||
const int64_t kValueB = 450;
|
||||
const int64_t kValueC = 45000;
|
||||
const TimeDelta delta_a = TimeDelta::seconds(kValueA);
|
||||
const DataRate rate_b = DataRate::bytes_per_second(kValueB);
|
||||
const DataSize size_c = DataSize::bytes(kValueC);
|
||||
EXPECT_EQ((delta_a * rate_b).bytes(), kValueA * kValueB);
|
||||
EXPECT_EQ((rate_b * delta_a).bytes(), kValueA * kValueB);
|
||||
EXPECT_EQ((size_c / delta_a).bytes_per_second(), kValueC / kValueA);
|
||||
EXPECT_EQ((size_c / rate_b).s(), kValueC / kValueB);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "modules/congestion_controller/rtp/pacer_controller.h"
|
||||
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "modules/congestion_controller/bbr/bbr_factory.h"
|
||||
#include "modules/congestion_controller/goog_cc/include/goog_cc_factory.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_types.h"
|
||||
#include "modules/congestion_controller/network_control/include/network_units.h"
|
||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||
#include "rtc_base/bind.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
Reference in New Issue
Block a user