summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/rtc_base/units
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/rtc_base/units')
-rw-r--r--third_party/libwebrtc/rtc_base/units/BUILD.gn34
-rw-r--r--third_party/libwebrtc/rtc_base/units/OWNERS1
-rw-r--r--third_party/libwebrtc/rtc_base/units/unit_base.h311
-rw-r--r--third_party/libwebrtc/rtc_base/units/unit_base_gn/moz.build209
-rw-r--r--third_party/libwebrtc/rtc_base/units/unit_base_unittest.cc251
5 files changed, 806 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/units/BUILD.gn b/third_party/libwebrtc/rtc_base/units/BUILD.gn
new file mode 100644
index 0000000000..bbb87a009a
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/units/BUILD.gn
@@ -0,0 +1,34 @@
+# 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_source_set("unit_base") {
+ visibility = [
+ ":*",
+ "../../api/units:*",
+ ]
+ sources = [ "unit_base.h" ]
+
+ deps = [
+ "../../rtc_base:checks",
+ "../../rtc_base:divide_round",
+ "../../rtc_base:safe_conversions",
+ ]
+}
+
+if (rtc_include_tests) {
+ rtc_library("units_unittests") {
+ testonly = true
+ sources = [ "unit_base_unittest.cc" ]
+ deps = [
+ ":unit_base",
+ "../../test:test_support",
+ ]
+ }
+}
diff --git a/third_party/libwebrtc/rtc_base/units/OWNERS b/third_party/libwebrtc/rtc_base/units/OWNERS
new file mode 100644
index 0000000000..53e076b20b
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/units/OWNERS
@@ -0,0 +1 @@
+srte@webrtc.org
diff --git a/third_party/libwebrtc/rtc_base/units/unit_base.h b/third_party/libwebrtc/rtc_base/units/unit_base.h
new file mode 100644
index 0000000000..a6bdbf547d
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/units/unit_base.h
@@ -0,0 +1,311 @@
+/*
+ * 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 RTC_BASE_UNITS_UNIT_BASE_H_
+#define RTC_BASE_UNITS_UNIT_BASE_H_
+
+#include <stdint.h>
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+#include <type_traits>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/numerics/divide_round.h"
+#include "rtc_base/numerics/safe_conversions.h"
+
+namespace webrtc {
+namespace rtc_units_impl {
+
+// UnitBase is a base class for implementing custom value types with a specific
+// unit. It provides type safety and commonly useful operations. The underlying
+// storage is always an int64_t, it's up to the unit implementation to choose
+// what scale it represents.
+//
+// It's used like:
+// class MyUnit: public UnitBase<MyUnit> {...};
+//
+// Unit_T is the subclass representing the specific unit.
+template <class Unit_T>
+class UnitBase {
+ public:
+ UnitBase() = delete;
+ static constexpr Unit_T Zero() { return Unit_T(0); }
+ static constexpr Unit_T PlusInfinity() { return Unit_T(PlusInfinityVal()); }
+ static constexpr Unit_T MinusInfinity() { return Unit_T(MinusInfinityVal()); }
+
+ constexpr bool IsZero() const { return value_ == 0; }
+ constexpr bool IsFinite() const { return !IsInfinite(); }
+ constexpr bool IsInfinite() const {
+ return value_ == PlusInfinityVal() || value_ == MinusInfinityVal();
+ }
+ constexpr bool IsPlusInfinity() const { return value_ == PlusInfinityVal(); }
+ constexpr bool IsMinusInfinity() const {
+ return value_ == MinusInfinityVal();
+ }
+
+ constexpr bool operator==(const UnitBase<Unit_T>& other) const {
+ return value_ == other.value_;
+ }
+ constexpr bool operator!=(const UnitBase<Unit_T>& other) const {
+ return value_ != other.value_;
+ }
+ constexpr bool operator<=(const UnitBase<Unit_T>& other) const {
+ return value_ <= other.value_;
+ }
+ constexpr bool operator>=(const UnitBase<Unit_T>& other) const {
+ return value_ >= other.value_;
+ }
+ constexpr bool operator>(const UnitBase<Unit_T>& other) const {
+ return value_ > other.value_;
+ }
+ constexpr bool operator<(const UnitBase<Unit_T>& other) const {
+ return value_ < other.value_;
+ }
+ constexpr Unit_T RoundTo(const Unit_T& resolution) const {
+ RTC_DCHECK(IsFinite());
+ RTC_DCHECK(resolution.IsFinite());
+ RTC_DCHECK_GT(resolution.value_, 0);
+ return Unit_T((value_ + resolution.value_ / 2) / resolution.value_) *
+ resolution.value_;
+ }
+ constexpr Unit_T RoundUpTo(const Unit_T& resolution) const {
+ RTC_DCHECK(IsFinite());
+ RTC_DCHECK(resolution.IsFinite());
+ RTC_DCHECK_GT(resolution.value_, 0);
+ return Unit_T((value_ + resolution.value_ - 1) / resolution.value_) *
+ resolution.value_;
+ }
+ constexpr Unit_T RoundDownTo(const Unit_T& resolution) const {
+ RTC_DCHECK(IsFinite());
+ RTC_DCHECK(resolution.IsFinite());
+ RTC_DCHECK_GT(resolution.value_, 0);
+ return Unit_T(value_ / resolution.value_) * resolution.value_;
+ }
+
+ protected:
+ template <
+ typename T,
+ typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
+ static constexpr Unit_T FromValue(T value) {
+ if (Unit_T::one_sided)
+ RTC_DCHECK_GE(value, 0);
+ RTC_DCHECK_GT(value, MinusInfinityVal());
+ RTC_DCHECK_LT(value, PlusInfinityVal());
+ return Unit_T(rtc::dchecked_cast<int64_t>(value));
+ }
+ template <typename T,
+ typename std::enable_if<std::is_floating_point<T>::value>::type* =
+ nullptr>
+ static constexpr Unit_T FromValue(T value) {
+ if (value == std::numeric_limits<T>::infinity()) {
+ return PlusInfinity();
+ } else if (value == -std::numeric_limits<T>::infinity()) {
+ return MinusInfinity();
+ } else {
+ RTC_DCHECK(!std::isnan(value));
+ return FromValue(rtc::dchecked_cast<int64_t>(value));
+ }
+ }
+
+ template <
+ typename T,
+ typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
+ static constexpr Unit_T FromFraction(int64_t denominator, T value) {
+ if (Unit_T::one_sided)
+ RTC_DCHECK_GE(value, 0);
+ RTC_DCHECK_GT(value, MinusInfinityVal() / denominator);
+ RTC_DCHECK_LT(value, PlusInfinityVal() / denominator);
+ return Unit_T(rtc::dchecked_cast<int64_t>(value * denominator));
+ }
+ template <typename T,
+ typename std::enable_if<std::is_floating_point<T>::value>::type* =
+ nullptr>
+ static constexpr Unit_T FromFraction(int64_t denominator, T value) {
+ return FromValue(value * denominator);
+ }
+
+ template <typename T = int64_t>
+ constexpr typename std::enable_if<std::is_integral<T>::value, T>::type
+ ToValue() const {
+ RTC_DCHECK(IsFinite());
+ return rtc::dchecked_cast<T>(value_);
+ }
+ template <typename T>
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ ToValue() const {
+ return IsPlusInfinity() ? std::numeric_limits<T>::infinity()
+ : IsMinusInfinity() ? -std::numeric_limits<T>::infinity()
+ : value_;
+ }
+ template <typename T>
+ constexpr T ToValueOr(T fallback_value) const {
+ return IsFinite() ? value_ : fallback_value;
+ }
+
+ template <int64_t Denominator, typename T = int64_t>
+ constexpr typename std::enable_if<std::is_integral<T>::value, T>::type
+ ToFraction() const {
+ RTC_DCHECK(IsFinite());
+ return rtc::dchecked_cast<T>(DivideRoundToNearest(value_, Denominator));
+ }
+ template <int64_t Denominator, typename T>
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ ToFraction() const {
+ return ToValue<T>() * (1 / static_cast<T>(Denominator));
+ }
+
+ template <int64_t Denominator>
+ constexpr int64_t ToFractionOr(int64_t fallback_value) const {
+ return IsFinite() ? DivideRoundToNearest(value_, Denominator)
+ : fallback_value;
+ }
+
+ template <int64_t Factor, typename T = int64_t>
+ constexpr typename std::enable_if<std::is_integral<T>::value, T>::type
+ ToMultiple() const {
+ RTC_DCHECK_GE(ToValue(), std::numeric_limits<T>::min() / Factor);
+ RTC_DCHECK_LE(ToValue(), std::numeric_limits<T>::max() / Factor);
+ return rtc::dchecked_cast<T>(ToValue() * Factor);
+ }
+ template <int64_t Factor, typename T>
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ ToMultiple() const {
+ return ToValue<T>() * Factor;
+ }
+
+ explicit constexpr UnitBase(int64_t value) : value_(value) {}
+
+ private:
+ template <class RelativeUnit_T>
+ friend class RelativeUnit;
+
+ static inline constexpr int64_t PlusInfinityVal() {
+ return std::numeric_limits<int64_t>::max();
+ }
+ static inline constexpr int64_t MinusInfinityVal() {
+ return std::numeric_limits<int64_t>::min();
+ }
+
+ constexpr Unit_T& AsSubClassRef() { return static_cast<Unit_T&>(*this); }
+ constexpr const Unit_T& AsSubClassRef() const {
+ return static_cast<const Unit_T&>(*this);
+ }
+
+ int64_t value_;
+};
+
+// Extends UnitBase to provide operations for relative units, that is, units
+// that have a meaningful relation between values such that a += b is a
+// sensible thing to do. For a,b <- same unit.
+template <class Unit_T>
+class RelativeUnit : public UnitBase<Unit_T> {
+ public:
+ constexpr Unit_T Clamped(Unit_T min_value, Unit_T max_value) const {
+ return std::max(min_value,
+ std::min(UnitBase<Unit_T>::AsSubClassRef(), max_value));
+ }
+ constexpr void Clamp(Unit_T min_value, Unit_T max_value) {
+ *this = Clamped(min_value, max_value);
+ }
+ constexpr Unit_T operator+(const Unit_T other) const {
+ if (this->IsPlusInfinity() || other.IsPlusInfinity()) {
+ RTC_DCHECK(!this->IsMinusInfinity());
+ RTC_DCHECK(!other.IsMinusInfinity());
+ return this->PlusInfinity();
+ } else if (this->IsMinusInfinity() || other.IsMinusInfinity()) {
+ RTC_DCHECK(!this->IsPlusInfinity());
+ RTC_DCHECK(!other.IsPlusInfinity());
+ return this->MinusInfinity();
+ }
+ return UnitBase<Unit_T>::FromValue(this->ToValue() + other.ToValue());
+ }
+ constexpr Unit_T operator-(const Unit_T other) const {
+ if (this->IsPlusInfinity() || other.IsMinusInfinity()) {
+ RTC_DCHECK(!this->IsMinusInfinity());
+ RTC_DCHECK(!other.IsPlusInfinity());
+ return this->PlusInfinity();
+ } else if (this->IsMinusInfinity() || other.IsPlusInfinity()) {
+ RTC_DCHECK(!this->IsPlusInfinity());
+ RTC_DCHECK(!other.IsMinusInfinity());
+ return this->MinusInfinity();
+ }
+ return UnitBase<Unit_T>::FromValue(this->ToValue() - other.ToValue());
+ }
+ constexpr Unit_T& operator+=(const Unit_T other) {
+ *this = *this + other;
+ return this->AsSubClassRef();
+ }
+ constexpr Unit_T& operator-=(const Unit_T other) {
+ *this = *this - other;
+ return this->AsSubClassRef();
+ }
+ constexpr double operator/(const Unit_T other) const {
+ return UnitBase<Unit_T>::template ToValue<double>() /
+ other.template ToValue<double>();
+ }
+ template <typename T,
+ typename std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
+ constexpr Unit_T operator/(T scalar) const {
+ return UnitBase<Unit_T>::FromValue(std::llround(this->ToValue() / scalar));
+ }
+ template <typename T,
+ typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
+ constexpr Unit_T operator/(T scalar) const {
+ return UnitBase<Unit_T>::FromValue(this->ToValue() / scalar);
+ }
+ constexpr Unit_T operator*(double scalar) const {
+ return UnitBase<Unit_T>::FromValue(std::llround(this->ToValue() * scalar));
+ }
+ constexpr Unit_T operator*(int64_t scalar) const {
+ return UnitBase<Unit_T>::FromValue(this->ToValue() * scalar);
+ }
+ constexpr Unit_T operator*(int32_t scalar) const {
+ return UnitBase<Unit_T>::FromValue(this->ToValue() * scalar);
+ }
+ constexpr Unit_T operator*(size_t scalar) const {
+ return UnitBase<Unit_T>::FromValue(this->ToValue() * scalar);
+ }
+
+ protected:
+ using UnitBase<Unit_T>::UnitBase;
+};
+
+template <class Unit_T>
+inline constexpr Unit_T operator*(double scalar, RelativeUnit<Unit_T> other) {
+ return other * scalar;
+}
+template <class Unit_T>
+inline constexpr Unit_T operator*(int64_t scalar, RelativeUnit<Unit_T> other) {
+ return other * scalar;
+}
+template <class Unit_T>
+inline constexpr Unit_T operator*(int32_t scalar, RelativeUnit<Unit_T> other) {
+ return other * scalar;
+}
+template <class Unit_T>
+inline constexpr Unit_T operator*(size_t scalar, RelativeUnit<Unit_T> other) {
+ return other * scalar;
+}
+
+template <class Unit_T>
+inline constexpr Unit_T operator-(RelativeUnit<Unit_T> other) {
+ if (other.IsPlusInfinity())
+ return UnitBase<Unit_T>::MinusInfinity();
+ if (other.IsMinusInfinity())
+ return UnitBase<Unit_T>::PlusInfinity();
+ return -1 * other;
+}
+
+} // namespace rtc_units_impl
+
+} // namespace webrtc
+
+#endif // RTC_BASE_UNITS_UNIT_BASE_H_
diff --git a/third_party/libwebrtc/rtc_base/units/unit_base_gn/moz.build b/third_party/libwebrtc/rtc_base/units/unit_base_gn/moz.build
new file mode 100644
index 0000000000..bb68c4ea3c
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/units/unit_base_gn/moz.build
@@ -0,0 +1,209 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["RTC_ENABLE_WIN_WGC"] = True
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["TARGET_CPU"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["TARGET_CPU"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["TARGET_CPU"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["TARGET_CPU"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["TARGET_CPU"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["TARGET_CPU"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android" and CONFIG["TARGET_CPU"] == "arm":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["OS_TARGET"] == "Android" and CONFIG["TARGET_CPU"] == "x86":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "aarch64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "arm":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86_64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("unit_base_gn")
diff --git a/third_party/libwebrtc/rtc_base/units/unit_base_unittest.cc b/third_party/libwebrtc/rtc_base/units/unit_base_unittest.cc
new file mode 100644
index 0000000000..258d7d1268
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/units/unit_base_unittest.cc
@@ -0,0 +1,251 @@
+/*
+ * 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 "rtc_base/units/unit_base.h"
+
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+class TestUnit final : public rtc_units_impl::RelativeUnit<TestUnit> {
+ public:
+ TestUnit() = delete;
+
+ using UnitBase::FromValue;
+ using UnitBase::ToValue;
+ using UnitBase::ToValueOr;
+
+ template <typename T>
+ static constexpr TestUnit FromKilo(T kilo) {
+ return FromFraction(1000, kilo);
+ }
+ template <typename T = int64_t>
+ T ToKilo() const {
+ return UnitBase::ToFraction<1000, T>();
+ }
+ constexpr int64_t ToKiloOr(int64_t fallback) const {
+ return UnitBase::ToFractionOr<1000>(fallback);
+ }
+ template <typename T>
+ constexpr T ToMilli() const {
+ return UnitBase::ToMultiple<1000, T>();
+ }
+
+ private:
+ friend class rtc_units_impl::UnitBase<TestUnit>;
+ static constexpr bool one_sided = false;
+ using RelativeUnit<TestUnit>::RelativeUnit;
+};
+constexpr TestUnit TestUnitAddKilo(TestUnit value, int add_kilo) {
+ value += TestUnit::FromKilo(add_kilo);
+ return value;
+}
+} // namespace
+namespace test {
+TEST(UnitBaseTest, ConstExpr) {
+ constexpr int64_t kValue = -12345;
+ constexpr TestUnit kTestUnitZero = TestUnit::Zero();
+ constexpr TestUnit kTestUnitPlusInf = TestUnit::PlusInfinity();
+ constexpr TestUnit kTestUnitMinusInf = TestUnit::MinusInfinity();
+ static_assert(kTestUnitZero.IsZero(), "");
+ static_assert(kTestUnitPlusInf.IsPlusInfinity(), "");
+ static_assert(kTestUnitMinusInf.IsMinusInfinity(), "");
+ static_assert(kTestUnitPlusInf.ToKiloOr(-1) == -1, "");
+
+ static_assert(kTestUnitPlusInf > kTestUnitZero, "");
+
+ constexpr TestUnit kTestUnitKilo = TestUnit::FromKilo(kValue);
+ constexpr TestUnit kTestUnitValue = TestUnit::FromValue(kValue);
+
+ static_assert(kTestUnitKilo.ToKiloOr(0) == kValue, "");
+ static_assert(kTestUnitValue.ToValueOr(0) == kValue, "");
+ static_assert(TestUnitAddKilo(kTestUnitValue, 2).ToValue() == kValue + 2000,
+ "");
+ static_assert(TestUnit::FromValue(500) / 2 == TestUnit::FromValue(250));
+}
+
+TEST(UnitBaseTest, GetBackSameValues) {
+ const int64_t kValue = 499;
+ for (int sign = -1; sign <= 1; ++sign) {
+ int64_t value = kValue * sign;
+ EXPECT_EQ(TestUnit::FromKilo(value).ToKilo(), value);
+ EXPECT_EQ(TestUnit::FromValue(value).ToValue<int64_t>(), value);
+ }
+ EXPECT_EQ(TestUnit::Zero().ToValue<int64_t>(), 0);
+}
+
+TEST(UnitBaseTest, GetDifferentPrefix) {
+ const int64_t kValue = 3000000;
+ EXPECT_EQ(TestUnit::FromValue(kValue).ToKilo(), kValue / 1000);
+ EXPECT_EQ(TestUnit::FromKilo(kValue).ToValue<int64_t>(), kValue * 1000);
+}
+
+TEST(UnitBaseTest, IdentityChecks) {
+ const int64_t kValue = 3000;
+ EXPECT_TRUE(TestUnit::Zero().IsZero());
+ EXPECT_FALSE(TestUnit::FromKilo(kValue).IsZero());
+
+ EXPECT_TRUE(TestUnit::PlusInfinity().IsInfinite());
+ EXPECT_TRUE(TestUnit::MinusInfinity().IsInfinite());
+ EXPECT_FALSE(TestUnit::Zero().IsInfinite());
+ EXPECT_FALSE(TestUnit::FromKilo(-kValue).IsInfinite());
+ EXPECT_FALSE(TestUnit::FromKilo(kValue).IsInfinite());
+
+ EXPECT_FALSE(TestUnit::PlusInfinity().IsFinite());
+ EXPECT_FALSE(TestUnit::MinusInfinity().IsFinite());
+ EXPECT_TRUE(TestUnit::FromKilo(-kValue).IsFinite());
+ EXPECT_TRUE(TestUnit::FromKilo(kValue).IsFinite());
+ EXPECT_TRUE(TestUnit::Zero().IsFinite());
+
+ EXPECT_TRUE(TestUnit::PlusInfinity().IsPlusInfinity());
+ EXPECT_FALSE(TestUnit::MinusInfinity().IsPlusInfinity());
+
+ EXPECT_TRUE(TestUnit::MinusInfinity().IsMinusInfinity());
+ EXPECT_FALSE(TestUnit::PlusInfinity().IsMinusInfinity());
+}
+
+TEST(UnitBaseTest, ComparisonOperators) {
+ const int64_t kSmall = 450;
+ const int64_t kLarge = 451;
+ const TestUnit small = TestUnit::FromKilo(kSmall);
+ const TestUnit large = TestUnit::FromKilo(kLarge);
+
+ EXPECT_EQ(TestUnit::Zero(), TestUnit::FromKilo(0));
+ EXPECT_EQ(TestUnit::PlusInfinity(), TestUnit::PlusInfinity());
+ EXPECT_EQ(small, TestUnit::FromKilo(kSmall));
+ EXPECT_LE(small, TestUnit::FromKilo(kSmall));
+ EXPECT_GE(small, TestUnit::FromKilo(kSmall));
+ EXPECT_NE(small, TestUnit::FromKilo(kLarge));
+ EXPECT_LE(small, TestUnit::FromKilo(kLarge));
+ EXPECT_LT(small, TestUnit::FromKilo(kLarge));
+ EXPECT_GE(large, TestUnit::FromKilo(kSmall));
+ EXPECT_GT(large, TestUnit::FromKilo(kSmall));
+ EXPECT_LT(TestUnit::Zero(), small);
+ EXPECT_GT(TestUnit::Zero(), TestUnit::FromKilo(-kSmall));
+ EXPECT_GT(TestUnit::Zero(), TestUnit::FromKilo(-kSmall));
+
+ EXPECT_GT(TestUnit::PlusInfinity(), large);
+ EXPECT_LT(TestUnit::MinusInfinity(), TestUnit::Zero());
+}
+
+TEST(UnitBaseTest, Clamping) {
+ const TestUnit upper = TestUnit::FromKilo(800);
+ const TestUnit lower = TestUnit::FromKilo(100);
+ const TestUnit under = TestUnit::FromKilo(100);
+ const TestUnit inside = TestUnit::FromKilo(500);
+ const TestUnit over = TestUnit::FromKilo(1000);
+ EXPECT_EQ(under.Clamped(lower, upper), lower);
+ EXPECT_EQ(inside.Clamped(lower, upper), inside);
+ EXPECT_EQ(over.Clamped(lower, upper), upper);
+
+ TestUnit mutable_delta = lower;
+ mutable_delta.Clamp(lower, upper);
+ EXPECT_EQ(mutable_delta, lower);
+ mutable_delta = inside;
+ mutable_delta.Clamp(lower, upper);
+ EXPECT_EQ(mutable_delta, inside);
+ mutable_delta = over;
+ mutable_delta.Clamp(lower, upper);
+ EXPECT_EQ(mutable_delta, upper);
+}
+
+TEST(UnitBaseTest, CanBeInititializedFromLargeInt) {
+ const int kMaxInt = std::numeric_limits<int>::max();
+ EXPECT_EQ(TestUnit::FromKilo(kMaxInt).ToValue<int64_t>(),
+ static_cast<int64_t>(kMaxInt) * 1000);
+}
+
+TEST(UnitBaseTest, ConvertsToAndFromDouble) {
+ const int64_t kValue = 17017;
+ const double kMilliDouble = kValue * 1e3;
+ const double kValueDouble = kValue;
+ const double kKiloDouble = kValue * 1e-3;
+
+ EXPECT_EQ(TestUnit::FromValue(kValue).ToKilo<double>(), kKiloDouble);
+ EXPECT_EQ(TestUnit::FromKilo(kKiloDouble).ToValue<int64_t>(), kValue);
+
+ EXPECT_EQ(TestUnit::FromValue(kValue).ToValue<double>(), kValueDouble);
+ EXPECT_EQ(TestUnit::FromValue(kValueDouble).ToValue<int64_t>(), kValue);
+
+ EXPECT_NEAR(TestUnit::FromValue(kValue).ToMilli<double>(), kMilliDouble, 1);
+
+ const double kPlusInfinity = std::numeric_limits<double>::infinity();
+ const double kMinusInfinity = -kPlusInfinity;
+
+ EXPECT_EQ(TestUnit::PlusInfinity().ToKilo<double>(), kPlusInfinity);
+ EXPECT_EQ(TestUnit::MinusInfinity().ToKilo<double>(), kMinusInfinity);
+ EXPECT_EQ(TestUnit::PlusInfinity().ToValue<double>(), kPlusInfinity);
+ EXPECT_EQ(TestUnit::MinusInfinity().ToValue<double>(), kMinusInfinity);
+ EXPECT_EQ(TestUnit::PlusInfinity().ToMilli<double>(), kPlusInfinity);
+ EXPECT_EQ(TestUnit::MinusInfinity().ToMilli<double>(), kMinusInfinity);
+
+ EXPECT_TRUE(TestUnit::FromKilo(kPlusInfinity).IsPlusInfinity());
+ EXPECT_TRUE(TestUnit::FromKilo(kMinusInfinity).IsMinusInfinity());
+ EXPECT_TRUE(TestUnit::FromValue(kPlusInfinity).IsPlusInfinity());
+ EXPECT_TRUE(TestUnit::FromValue(kMinusInfinity).IsMinusInfinity());
+}
+
+TEST(UnitBaseTest, MathOperations) {
+ const int64_t kValueA = 267;
+ const int64_t kValueB = 450;
+ const TestUnit delta_a = TestUnit::FromKilo(kValueA);
+ const TestUnit delta_b = TestUnit::FromKilo(kValueB);
+ EXPECT_EQ((delta_a + delta_b).ToKilo(), kValueA + kValueB);
+ EXPECT_EQ((delta_a - delta_b).ToKilo(), kValueA - kValueB);
+
+ const int32_t kInt32Value = 123;
+ const double kFloatValue = 123.0;
+ EXPECT_EQ((TestUnit::FromValue(kValueA) * kValueB).ToValue<int64_t>(),
+ kValueA * kValueB);
+ EXPECT_EQ((TestUnit::FromValue(kValueA) * kInt32Value).ToValue<int64_t>(),
+ kValueA * kInt32Value);
+ EXPECT_EQ((TestUnit::FromValue(kValueA) * kFloatValue).ToValue<int64_t>(),
+ kValueA * kFloatValue);
+
+ EXPECT_EQ((delta_b / 10).ToKilo(), kValueB / 10);
+ EXPECT_EQ(delta_b / delta_a, static_cast<double>(kValueB) / kValueA);
+
+ TestUnit mutable_delta = TestUnit::FromKilo(kValueA);
+ mutable_delta += TestUnit::FromKilo(kValueB);
+ EXPECT_EQ(mutable_delta, TestUnit::FromKilo(kValueA + kValueB));
+ mutable_delta -= TestUnit::FromKilo(kValueB);
+ EXPECT_EQ(mutable_delta, TestUnit::FromKilo(kValueA));
+
+ // Division by an int rounds towards zero to follow regular int division.
+ EXPECT_EQ(TestUnit::FromValue(789) / 10, TestUnit::FromValue(78));
+ EXPECT_EQ(TestUnit::FromValue(-789) / 10, TestUnit::FromValue(-78));
+}
+
+TEST(UnitBaseTest, InfinityOperations) {
+ const int64_t kValue = 267;
+ const TestUnit finite = TestUnit::FromKilo(kValue);
+ EXPECT_TRUE((TestUnit::PlusInfinity() + finite).IsPlusInfinity());
+ EXPECT_TRUE((TestUnit::PlusInfinity() - finite).IsPlusInfinity());
+ EXPECT_TRUE((finite + TestUnit::PlusInfinity()).IsPlusInfinity());
+ EXPECT_TRUE((finite - TestUnit::MinusInfinity()).IsPlusInfinity());
+
+ EXPECT_TRUE((TestUnit::MinusInfinity() + finite).IsMinusInfinity());
+ EXPECT_TRUE((TestUnit::MinusInfinity() - finite).IsMinusInfinity());
+ EXPECT_TRUE((finite + TestUnit::MinusInfinity()).IsMinusInfinity());
+ EXPECT_TRUE((finite - TestUnit::PlusInfinity()).IsMinusInfinity());
+}
+
+TEST(UnitBaseTest, UnaryMinus) {
+ const int64_t kValue = 1337;
+ const TestUnit unit = TestUnit::FromValue(kValue);
+ EXPECT_EQ(-unit.ToValue(), -kValue);
+
+ // Check infinity.
+ EXPECT_EQ(-TestUnit::PlusInfinity(), TestUnit::MinusInfinity());
+ EXPECT_EQ(-TestUnit::MinusInfinity(), TestUnit::PlusInfinity());
+}
+
+} // namespace test
+} // namespace webrtc