Prepares for moving units to API.
Cleanup based on review of move CL. Using separate CL to keep the move clean. Bug: webrtc:9155 Change-Id: Ie0b15c6d3efcd86e2fa5761f014d0daf72ccfa06 Reviewed-on: https://webrtc-review.googlesource.com/73367 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23068}
This commit is contained in:
parent
71a720ba16
commit
66fa535e6e
@ -13,33 +13,6 @@
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
int64_t Microbytes(const DataSize& size) {
|
||||
constexpr int64_t kMaxBeforeConversion =
|
||||
std::numeric_limits<int64_t>::max() / 1000000;
|
||||
RTC_DCHECK(size.bytes() < kMaxBeforeConversion)
|
||||
<< "size is too large to be expressed in microbytes, size: "
|
||||
<< size.bytes() << " is not less than " << kMaxBeforeConversion;
|
||||
return size.bytes() * 1000000;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
DataRate operator/(const DataSize& size, const TimeDelta& duration) {
|
||||
return DataRate::bytes_per_second(Microbytes(size) / duration.us());
|
||||
}
|
||||
|
||||
TimeDelta operator/(const DataSize& size, const DataRate& rate) {
|
||||
return TimeDelta::us(Microbytes(size) / rate.bytes_per_second());
|
||||
}
|
||||
|
||||
DataSize operator*(const DataRate& rate, const TimeDelta& duration) {
|
||||
int64_t microbytes = rate.bytes_per_second() * duration.us();
|
||||
return DataSize::bytes((microbytes + 500000) / 1000000);
|
||||
}
|
||||
|
||||
DataSize operator*(const TimeDelta& duration, const DataRate& rate) {
|
||||
return rate * duration;
|
||||
}
|
||||
|
||||
std::string ToString(const DataRate& value) {
|
||||
char buf[64];
|
||||
|
||||
@ -25,14 +25,19 @@ namespace webrtc {
|
||||
namespace data_rate_impl {
|
||||
constexpr int64_t kPlusInfinityVal = std::numeric_limits<int64_t>::max();
|
||||
constexpr int64_t kNotInitializedVal = -1;
|
||||
|
||||
inline int64_t Microbits(const DataSize& size) {
|
||||
constexpr int64_t kMaxBeforeConversion =
|
||||
std::numeric_limits<int64_t>::max() / 8000000;
|
||||
RTC_DCHECK_LE(size.bytes(), kMaxBeforeConversion)
|
||||
<< "size is too large to be expressed in microbytes";
|
||||
return size.bytes() * 8000000;
|
||||
}
|
||||
} // 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.
|
||||
// represent bandwidth, encoding bitrate, etc. The internal storage is bits per
|
||||
// second (bps).
|
||||
class DataRate {
|
||||
public:
|
||||
DataRate() : DataRate(data_rate_impl::kNotInitializedVal) {}
|
||||
@ -40,10 +45,6 @@ class DataRate {
|
||||
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);
|
||||
@ -58,7 +59,6 @@ class DataRate {
|
||||
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;
|
||||
@ -72,15 +72,7 @@ class DataRate {
|
||||
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_;
|
||||
}
|
||||
@ -106,20 +98,41 @@ class DataRate {
|
||||
explicit DataRate(int64_t bits_per_second) : bits_per_sec_(bits_per_second) {}
|
||||
int64_t bits_per_sec_;
|
||||
};
|
||||
|
||||
inline DataRate operator*(const DataRate& rate, const double& scalar) {
|
||||
return DataRate::bits_per_second(std::round(rate.bits_per_second() * scalar));
|
||||
}
|
||||
inline DataRate operator*(const double& scalar, const DataRate& rate) {
|
||||
return rate * scalar;
|
||||
}
|
||||
inline DataRate operator*(const DataRate& rate, const int64_t& scalar) {
|
||||
return DataRate::bits_per_second(rate.bits_per_second() * scalar);
|
||||
}
|
||||
inline DataRate operator*(const int64_t& scalar, const DataRate& rate) {
|
||||
return rate * scalar;
|
||||
}
|
||||
inline DataRate operator*(const DataRate& rate, const int32_t& scalar) {
|
||||
return DataRate::bits_per_second(rate.bits_per_second() * 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);
|
||||
inline DataRate operator/(const DataSize& size, const TimeDelta& duration) {
|
||||
return DataRate::bits_per_second(data_rate_impl::Microbits(size) /
|
||||
duration.us());
|
||||
}
|
||||
inline TimeDelta operator/(const DataSize& size, const DataRate& rate) {
|
||||
return TimeDelta::us(data_rate_impl::Microbits(size) /
|
||||
rate.bits_per_second());
|
||||
}
|
||||
inline DataSize operator*(const DataRate& rate, const TimeDelta& duration) {
|
||||
int64_t microbits = rate.bits_per_second() * duration.us();
|
||||
return DataSize::bytes((microbits + 4000000) / 8000000);
|
||||
}
|
||||
inline DataSize operator*(const TimeDelta& duration, const DataRate& rate) {
|
||||
return rate * duration;
|
||||
}
|
||||
|
||||
std::string ToString(const DataRate& value);
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@ 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);
|
||||
@ -23,30 +22,28 @@ TEST(DataRateTest, GetBackSameValues) {
|
||||
|
||||
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_FALSE(DataRate::bits_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::bits_per_second(kValue).IsInfinite());
|
||||
|
||||
EXPECT_FALSE(DataRate::Infinity().IsFinite());
|
||||
EXPECT_TRUE(DataRate::bytes_per_second(kValue).IsFinite());
|
||||
EXPECT_TRUE(DataRate::bits_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);
|
||||
const DataRate small = DataRate::bits_per_second(kSmall);
|
||||
const DataRate large = DataRate::bits_per_second(kLarge);
|
||||
|
||||
EXPECT_EQ(DataRate::Zero(), DataRate::bps(0));
|
||||
EXPECT_EQ(DataRate::Infinity(), DataRate::Infinity());
|
||||
@ -65,25 +62,25 @@ TEST(DataRateTest, ComparisonOperators) {
|
||||
TEST(DataRateTest, MathOperations) {
|
||||
const int64_t kValueA = 450;
|
||||
const int64_t kValueB = 267;
|
||||
const DataRate size_a = DataRate::bytes_per_second(kValueA);
|
||||
const DataRate size_a = DataRate::bits_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);
|
||||
EXPECT_EQ((size_a * kValueB).bits_per_second(), kValueA * kValueB);
|
||||
EXPECT_EQ((size_a * kInt32Value).bits_per_second(), kValueA * kInt32Value);
|
||||
EXPECT_EQ((size_a * kFloatValue).bits_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((rate_b * delta_a).bytes(), kValueA * kValueB);
|
||||
EXPECT_EQ((size_c / delta_a).bytes_per_second(), kValueC / kValueA);
|
||||
EXPECT_EQ((size_c / rate_b).seconds(), kValueC / kValueB);
|
||||
const int64_t kSeconds = 5;
|
||||
const int64_t kBitsPerSecond = 440;
|
||||
const int64_t kBytes = 44000;
|
||||
const TimeDelta delta_a = TimeDelta::seconds(kSeconds);
|
||||
const DataRate rate_b = DataRate::bits_per_second(kBitsPerSecond);
|
||||
const DataSize size_c = DataSize::bytes(kBytes);
|
||||
EXPECT_EQ((delta_a * rate_b).bytes(), kSeconds * kBitsPerSecond / 8);
|
||||
EXPECT_EQ((rate_b * delta_a).bytes(), kSeconds * kBitsPerSecond / 8);
|
||||
EXPECT_EQ((size_c / delta_a).bits_per_second(), kBytes * 8 / kSeconds);
|
||||
EXPECT_EQ((size_c / rate_b).seconds(), kBytes * 8 / kBitsPerSecond);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
||||
@ -103,9 +100,9 @@ TEST(UnitConversionTest, DivisionFailsOnLargeSize) {
|
||||
// Note that the failure is expected since the current implementation is
|
||||
// implementated in a way that does not support division of large sizes. If
|
||||
// the implementation is changed, this test can safely be removed.
|
||||
const int64_t kToolargeForDivision =
|
||||
std::numeric_limits<int64_t>::max() / 1000000;
|
||||
const int64_t kJustSmallEnoughForDivision = kToolargeForDivision - 1;
|
||||
const int64_t kJustSmallEnoughForDivision =
|
||||
std::numeric_limits<int64_t>::max() / 8000000;
|
||||
const int64_t kToolargeForDivision = kJustSmallEnoughForDivision + 1;
|
||||
const DataSize large_size = DataSize::bytes(kJustSmallEnoughForDivision);
|
||||
const DataSize too_large_size = DataSize::bytes(kToolargeForDivision);
|
||||
const DataRate data_rate = DataRate::kbps(100);
|
||||
|
||||
@ -24,10 +24,7 @@ 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.
|
||||
// DataSize is a class represeting a count of bytes.
|
||||
class DataSize {
|
||||
public:
|
||||
DataSize() : DataSize(data_size_impl::kNotInitializedVal) {}
|
||||
@ -39,17 +36,11 @@ class DataSize {
|
||||
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 {
|
||||
@ -62,18 +53,6 @@ class DataSize {
|
||||
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;
|
||||
@ -101,15 +80,27 @@ class DataSize {
|
||||
explicit DataSize(int64_t bytes) : bytes_(bytes) {}
|
||||
int64_t bytes_;
|
||||
};
|
||||
inline DataSize operator*(const DataSize& size, const double& scalar) {
|
||||
return DataSize::bytes(std::round(size.bytes() * scalar));
|
||||
}
|
||||
inline DataSize operator*(const double& scalar, const DataSize& size) {
|
||||
return size * scalar;
|
||||
}
|
||||
inline DataSize operator*(const DataSize& size, const int64_t& scalar) {
|
||||
return DataSize::bytes(size.bytes() * scalar);
|
||||
}
|
||||
inline DataSize operator*(const int64_t& scalar, const DataSize& size) {
|
||||
return size * scalar;
|
||||
}
|
||||
inline DataSize operator*(const DataSize& size, const int32_t& scalar) {
|
||||
return DataSize::bytes(size.bytes() * scalar);
|
||||
}
|
||||
inline DataSize operator*(const int32_t& scalar, const DataSize& size) {
|
||||
return size * scalar;
|
||||
}
|
||||
inline DataSize operator/(const DataSize& size, const int64_t& scalar) {
|
||||
return DataSize::bytes(size.bytes() / scalar);
|
||||
}
|
||||
|
||||
std::string ToString(const DataSize& value);
|
||||
|
||||
|
||||
@ -17,14 +17,10 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@ -97,18 +97,7 @@ class TimeDelta {
|
||||
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_;
|
||||
}
|
||||
@ -132,16 +121,30 @@ class TimeDelta {
|
||||
explicit TimeDelta(int64_t us) : microseconds_(us) {}
|
||||
int64_t microseconds_;
|
||||
};
|
||||
|
||||
inline TimeDelta operator*(const TimeDelta& delta, const double& scalar) {
|
||||
return TimeDelta::us(std::round(delta.us() * scalar));
|
||||
}
|
||||
inline TimeDelta operator*(const double& scalar, const TimeDelta& delta) {
|
||||
return delta * scalar;
|
||||
}
|
||||
inline TimeDelta operator*(const TimeDelta& delta, const int64_t& scalar) {
|
||||
return TimeDelta::us(delta.us() * scalar);
|
||||
}
|
||||
inline TimeDelta operator*(const int64_t& scalar, const TimeDelta& delta) {
|
||||
return delta * scalar;
|
||||
}
|
||||
inline TimeDelta operator*(const TimeDelta& delta, const int32_t& scalar) {
|
||||
return TimeDelta::us(delta.us() * scalar);
|
||||
}
|
||||
inline TimeDelta operator*(const int32_t& scalar, const TimeDelta& delta) {
|
||||
return delta * scalar;
|
||||
}
|
||||
|
||||
inline TimeDelta operator/(const TimeDelta& delta, const int64_t& scalar) {
|
||||
return TimeDelta::us(delta.us() / scalar);
|
||||
}
|
||||
|
||||
std::string ToString(const TimeDelta& value);
|
||||
} // namespace webrtc
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user