diff options
Diffstat (limited to 'third_party/libwebrtc/system_wrappers/include')
9 files changed, 982 insertions, 0 deletions
diff --git a/third_party/libwebrtc/system_wrappers/include/clock.h b/third_party/libwebrtc/system_wrappers/include/clock.h new file mode 100644 index 0000000000..214b34c970 --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/include/clock.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013 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 SYSTEM_WRAPPERS_INCLUDE_CLOCK_H_ +#define SYSTEM_WRAPPERS_INCLUDE_CLOCK_H_ + +#include <stdint.h> + +#include <atomic> +#include <memory> + +#include "api/units/timestamp.h" +#include "rtc_base/system/rtc_export.h" +#include "system_wrappers/include/ntp_time.h" + +namespace webrtc { + +// January 1970, in NTP seconds. +const uint32_t kNtpJan1970 = 2208988800UL; + +// Magic NTP fractional unit. +const double kMagicNtpFractionalUnit = 4.294967296E+9; + +// A clock interface that allows reading of absolute and relative timestamps. +class RTC_EXPORT Clock { + public: + virtual ~Clock() {} + + // Return a timestamp relative to an unspecified epoch. + virtual Timestamp CurrentTime() = 0; + int64_t TimeInMilliseconds() { return CurrentTime().ms(); } + int64_t TimeInMicroseconds() { return CurrentTime().us(); } + + // Retrieve an NTP absolute timestamp (with an epoch of Jan 1, 1900). + NtpTime CurrentNtpTime() { return ConvertTimestampToNtpTime(CurrentTime()); } + int64_t CurrentNtpInMilliseconds() { return CurrentNtpTime().ToMs(); } + + // Converts between a relative timestamp returned by this clock, to NTP time. + virtual NtpTime ConvertTimestampToNtpTime(Timestamp timestamp) = 0; + int64_t ConvertTimestampToNtpTimeInMilliseconds(int64_t timestamp_ms) { + return ConvertTimestampToNtpTime(Timestamp::Millis(timestamp_ms)).ToMs(); + } + + // Returns an instance of the real-time system clock implementation. + static Clock* GetRealTimeClockRaw(); +}; + +class SimulatedClock : public Clock { + public: + // The constructors assume an epoch of Jan 1, 1970. + explicit SimulatedClock(int64_t initial_time_us); + explicit SimulatedClock(Timestamp initial_time); + ~SimulatedClock() override; + + // Return a timestamp with an epoch of Jan 1, 1970. + Timestamp CurrentTime() override; + + NtpTime ConvertTimestampToNtpTime(Timestamp timestamp) override; + + // Advance the simulated clock with a given number of milliseconds or + // microseconds. + void AdvanceTimeMilliseconds(int64_t milliseconds); + void AdvanceTimeMicroseconds(int64_t microseconds); + void AdvanceTime(TimeDelta delta); + + private: + // The time is read and incremented with relaxed order. Each thread will see + // monotonically increasing time, and when threads post tasks or messages to + // one another, the synchronization done as part of the message passing should + // ensure that any causual chain of events on multiple threads also + // corresponds to monotonically increasing time. + std::atomic<int64_t> time_us_; +}; + +} // namespace webrtc + +#endif // SYSTEM_WRAPPERS_INCLUDE_CLOCK_H_ diff --git a/third_party/libwebrtc/system_wrappers/include/cpu_features_wrapper.h b/third_party/libwebrtc/system_wrappers/include/cpu_features_wrapper.h new file mode 100644 index 0000000000..612b4a5d6b --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/include/cpu_features_wrapper.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 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 SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_ +#define SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_ + +#include <stdint.h> + +namespace webrtc { + +// List of features in x86. +typedef enum { kSSE2, kSSE3, kAVX2 } CPUFeature; + +// List of features in ARM. +enum { + kCPUFeatureARMv7 = (1 << 0), + kCPUFeatureVFPv3 = (1 << 1), + kCPUFeatureNEON = (1 << 2), + kCPUFeatureLDREXSTREX = (1 << 3) +}; + +// Returns true if the CPU supports the feature. +int GetCPUInfo(CPUFeature feature); + +// No CPU feature is available => straight C path. +int GetCPUInfoNoASM(CPUFeature feature); + +// Return the features in an ARM device. +// It detects the features in the hardware platform, and returns supported +// values in the above enum definition as a bitmask. +uint64_t GetCPUFeaturesARM(void); + +} // namespace webrtc + +#endif // SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_ diff --git a/third_party/libwebrtc/system_wrappers/include/cpu_info.h b/third_party/libwebrtc/system_wrappers/include/cpu_info.h new file mode 100644 index 0000000000..ab546c7214 --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/include/cpu_info.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 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 SYSTEM_WRAPPERS_INCLUDE_CPU_INFO_H_ +#define SYSTEM_WRAPPERS_INCLUDE_CPU_INFO_H_ + +#include <stdint.h> + +namespace webrtc { + +class CpuInfo { + public: + static uint32_t DetectNumberOfCores(); + + private: + CpuInfo() {} +}; + +} // namespace webrtc + +#endif // SYSTEM_WRAPPERS_INCLUDE_CPU_INFO_H_ diff --git a/third_party/libwebrtc/system_wrappers/include/denormal_disabler.h b/third_party/libwebrtc/system_wrappers/include/denormal_disabler.h new file mode 100644 index 0000000000..bd3d401327 --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/include/denormal_disabler.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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 SYSTEM_WRAPPERS_INCLUDE_DENORMAL_DISABLER_H_ +#define SYSTEM_WRAPPERS_INCLUDE_DENORMAL_DISABLER_H_ + +#include "rtc_base/system/arch.h" + +namespace webrtc { + +// Activates the hardware (HW) way to flush denormals (see [1]) to zero as they +// can very seriously impact performance. At destruction time restores the +// denormals handling state read by the ctor; hence, supports nested calls. +// Equals a no-op if the architecture is not x86 or ARM or if the compiler is +// not CLANG. +// [1] https://en.wikipedia.org/wiki/Denormal_number +// +// Example usage: +// +// void Foo() { +// DenormalDisabler d; +// ... +// } +class DenormalDisabler { + public: + // Ctor. If architecture and compiler are supported, stores the HW settings + // for denormals, disables denormals and sets `disabling_activated_` to true. + // Otherwise, only sets `disabling_activated_` to false. + DenormalDisabler(); + // Ctor. Same as above, but also requires `enabled` to be true to disable + // denormals. + explicit DenormalDisabler(bool enabled); + DenormalDisabler(const DenormalDisabler&) = delete; + DenormalDisabler& operator=(const DenormalDisabler&) = delete; + // Dtor. If `disabling_activated_` is true, restores the denormals HW settings + // read by the ctor before denormals were disabled. Otherwise it's a no-op. + ~DenormalDisabler(); + + // Returns true if architecture and compiler are supported. + static bool IsSupported(); + + private: + const int status_word_; + const bool disabling_activated_; +}; + +} // namespace webrtc + +#endif // SYSTEM_WRAPPERS_INCLUDE_DENORMAL_DISABLER_H_ diff --git a/third_party/libwebrtc/system_wrappers/include/field_trial.h b/third_party/libwebrtc/system_wrappers/include/field_trial.h new file mode 100644 index 0000000000..8d0ad258c1 --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/include/field_trial.h @@ -0,0 +1,116 @@ +// +// Copyright (c) 2014 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 SYSTEM_WRAPPERS_INCLUDE_FIELD_TRIAL_H_ +#define SYSTEM_WRAPPERS_INCLUDE_FIELD_TRIAL_H_ + +#include <string> + +#include "absl/strings/string_view.h" +#include "rtc_base/containers/flat_set.h" + +// Field trials allow webrtc clients (such as Chrome) to turn on feature code +// in binaries out in the field and gather information with that. +// +// By default WebRTC provides an implementation of field trials that can be +// found in system_wrappers/source/field_trial.cc. If clients want to provide +// a custom version, they will have to: +// +// 1. Compile WebRTC defining the preprocessor macro +// WEBRTC_EXCLUDE_FIELD_TRIAL_DEFAULT (if GN is used this can be achieved +// by setting the GN arg rtc_exclude_field_trial_default to true). +// 2. Provide an implementation of: +// std::string webrtc::field_trial::FindFullName(absl::string_view trial). +// +// They are designed to wire up directly to chrome field trials and to speed up +// developers by reducing the need to wire APIs to control whether a feature is +// on/off. E.g. to experiment with a new method that could lead to a different +// trade-off between CPU/bandwidth: +// +// 1 - Develop the feature with default behaviour off: +// +// if (FieldTrial::FindFullName("WebRTCExperimentMethod2") == "Enabled") +// method2(); +// else +// method1(); +// +// 2 - Once the changes are rolled to chrome, the new code path can be +// controlled as normal chrome field trials. +// +// 3 - Evaluate the new feature and clean the code paths. +// +// Notes: +// - NOT every feature is a candidate to be controlled by this mechanism as +// it may require negotiation between involved parties (e.g. SDP). +// +// TODO(andresp): since chrome --force-fieldtrials does not marks the trial +// as active it does not get propagated to the renderer process. For now one +// needs to push a config with start_active:true or run a local finch +// server. +// +// TODO(andresp): find out how to get bots to run tests with trials enabled. + +namespace webrtc { +namespace field_trial { + +// Returns the group name chosen for the named trial, or the empty string +// if the trial does not exists. +// +// Note: To keep things tidy append all the trial names with WebRTC. +std::string FindFullName(absl::string_view name); + +// Convenience method, returns true iff FindFullName(name) return a string that +// starts with "Enabled". +// TODO(tommi): Make sure all implementations support this. +inline bool IsEnabled(absl::string_view name) { + return FindFullName(name).find("Enabled") == 0; +} + +// Convenience method, returns true iff FindFullName(name) return a string that +// starts with "Disabled". +inline bool IsDisabled(absl::string_view name) { + return FindFullName(name).find("Disabled") == 0; +} + +// Optionally initialize field trial from a string. +// This method can be called at most once before any other call into webrtc. +// E.g. before the peer connection factory is constructed. +// Note: trials_string must never be destroyed. +void InitFieldTrialsFromString(const char* trials_string); + +const char* GetFieldTrialString(); + +// Validates the given field trial string. +bool FieldTrialsStringIsValid(absl::string_view trials_string); + +// Merges two field trial strings. +// +// If a key (trial) exists twice with conflicting values (groups), the value +// in 'second' takes precedence. +// Shall only be called with valid FieldTrial strings. +std::string MergeFieldTrialsStrings(absl::string_view first, + absl::string_view second); + +// This helper allows to temporary "register" a field trial within the current +// scope. This is only useful for tests that use the global field trial string, +// otherwise you can use `webrtc::FieldTrialsRegistry`. +// +// If you want to isolate changes to the global field trial string itself within +// the current scope you should use `webrtc::test::ScopedFieldTrials`. +class FieldTrialsAllowedInScopeForTesting { + public: + explicit FieldTrialsAllowedInScopeForTesting(flat_set<std::string> keys); + ~FieldTrialsAllowedInScopeForTesting(); +}; + +} // namespace field_trial +} // namespace webrtc + +#endif // SYSTEM_WRAPPERS_INCLUDE_FIELD_TRIAL_H_ diff --git a/third_party/libwebrtc/system_wrappers/include/metrics.h b/third_party/libwebrtc/system_wrappers/include/metrics.h new file mode 100644 index 0000000000..ca9ed6d09b --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/include/metrics.h @@ -0,0 +1,436 @@ +// +// Copyright (c) 2014 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 SYSTEM_WRAPPERS_INCLUDE_METRICS_H_ +#define SYSTEM_WRAPPERS_INCLUDE_METRICS_H_ + +#include <stddef.h> + +#include <atomic> +#include <map> +#include <memory> +#include <string> + +#include "absl/strings/string_view.h" +#include "rtc_base/checks.h" +#include "rtc_base/string_utils.h" + +#if defined(RTC_DISABLE_METRICS) +#define RTC_METRICS_ENABLED 0 +#else +#define RTC_METRICS_ENABLED 1 +#endif + +namespace webrtc { +namespace metrics_impl { +template <typename... Ts> +void NoOp(const Ts&...) {} +} +} + +#if RTC_METRICS_ENABLED +#define EXPECT_METRIC_EQ(val1, val2) EXPECT_EQ(val1, val2) +#define EXPECT_METRIC_EQ_WAIT(val1, val2, timeout) \ + EXPECT_EQ_WAIT(val1, val2, timeout) +#define EXPECT_METRIC_GT(val1, val2) EXPECT_GT(val1, val2) +#define EXPECT_METRIC_LE(val1, val2) EXPECT_LE(val1, val2) +#define EXPECT_METRIC_TRUE(conditon) EXPECT_TRUE(conditon) +#define EXPECT_METRIC_FALSE(conditon) EXPECT_FALSE(conditon) +#define EXPECT_METRIC_THAT(value, matcher) EXPECT_THAT(value, matcher) +#else +#define EXPECT_METRIC_EQ(val1, val2) webrtc::metrics_impl::NoOp(val1, val2) +#define EXPECT_METRIC_EQ_WAIT(val1, val2, timeout) webrtc::metrics_impl::NoOp(val1, val2, timeout) +#define EXPECT_METRIC_GT(val1, val2) webrtc::metrics_impl::NoOp(val1, val2) +#define EXPECT_METRIC_LE(val1, val2) webrtc::metrics_impl::NoOp(val1, val2) +#define EXPECT_METRIC_TRUE(condition) webrtc::metrics_impl::NoOp(condition || true) +#define EXPECT_METRIC_FALSE(condition) webrtc::metrics_impl::NoOp(condition && false) +#define EXPECT_METRIC_THAT(value, matcher) webrtc::metrics_impl::NoOp(value, testing::_) +#endif + +#if RTC_METRICS_ENABLED +// Macros for allowing WebRTC clients (e.g. Chrome) to gather and aggregate +// statistics. +// +// Histogram for counters. +// RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count); +// +// Histogram for enumerators. +// The boundary should be above the max enumerator sample. +// RTC_HISTOGRAM_ENUMERATION(name, sample, boundary); +// +// +// The macros use the methods HistogramFactoryGetCounts, +// HistogramFactoryGetEnumeration and HistogramAdd. +// +// By default WebRTC provides implementations of the aforementioned methods +// that can be found in system_wrappers/source/metrics.cc. If clients want to +// provide a custom version, they will have to: +// +// 1. Compile WebRTC defining the preprocessor macro +// WEBRTC_EXCLUDE_METRICS_DEFAULT (if GN is used this can be achieved +// by setting the GN arg rtc_exclude_metrics_default to true). +// 2. Provide implementations of: +// Histogram* webrtc::metrics::HistogramFactoryGetCounts( +// absl::string_view name, int sample, int min, int max, +// int bucket_count); +// Histogram* webrtc::metrics::HistogramFactoryGetEnumeration( +// absl::string_view name, int sample, int boundary); +// void webrtc::metrics::HistogramAdd( +// Histogram* histogram_pointer, absl::string_view name, int sample); +// +// Example usage: +// +// RTC_HISTOGRAM_COUNTS("WebRTC.Video.NacksSent", nacks_sent, 1, 100000, 100); +// +// enum Types { +// kTypeX, +// kTypeY, +// kBoundary, +// }; +// +// RTC_HISTOGRAM_ENUMERATION("WebRTC.Types", kTypeX, kBoundary); +// +// NOTE: It is recommended to do the Chromium review for modifications to +// histograms.xml before new metrics are committed to WebRTC. + +// Macros for adding samples to a named histogram. + +// Histogram for counters (exponentially spaced buckets). +#define RTC_HISTOGRAM_COUNTS_100(name, sample) \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 100, 50) + +#define RTC_HISTOGRAM_COUNTS_200(name, sample) \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 200, 50) + +#define RTC_HISTOGRAM_COUNTS_500(name, sample) \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 500, 50) + +#define RTC_HISTOGRAM_COUNTS_1000(name, sample) \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50) + +#define RTC_HISTOGRAM_COUNTS_10000(name, sample) \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 10000, 50) + +#define RTC_HISTOGRAM_COUNTS_100000(name, sample) \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 100000, 50) + +#define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \ + RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \ + webrtc::metrics::HistogramFactoryGetCounts( \ + name, min, max, bucket_count)) + +#define RTC_HISTOGRAM_COUNTS_LINEAR(name, sample, min, max, bucket_count) \ + RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \ + webrtc::metrics::HistogramFactoryGetCountsLinear( \ + name, min, max, bucket_count)) + +// Slow metrics: pointer to metric is acquired at each call and is not cached. +// +#define RTC_HISTOGRAM_COUNTS_SPARSE_100(name, sample) \ + RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 100, 50) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_200(name, sample) \ + RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 200, 50) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_500(name, sample) \ + RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 500, 50) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_1000(name, sample) \ + RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 1000, 50) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_10000(name, sample) \ + RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 10000, 50) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_100000(name, sample) \ + RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 100000, 50) + +#define RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, min, max, bucket_count) \ + RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, \ + webrtc::metrics::HistogramFactoryGetCounts( \ + name, min, max, bucket_count)) + +// Histogram for percentage (evenly spaced buckets). +#define RTC_HISTOGRAM_PERCENTAGE_SPARSE(name, sample) \ + RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, 101) + +// Histogram for booleans. +#define RTC_HISTOGRAM_BOOLEAN_SPARSE(name, sample) \ + RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, 2) + +// Histogram for enumerators (evenly spaced buckets). +// `boundary` should be above the max enumerator sample. +// +// TODO(qingsi): Refactor the default implementation given by RtcHistogram, +// which is already sparse, and remove the boundary argument from the macro. +#define RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, boundary) \ + RTC_HISTOGRAM_COMMON_BLOCK_SLOW( \ + name, sample, \ + webrtc::metrics::SparseHistogramFactoryGetEnumeration(name, boundary)) + +// Histogram for percentage (evenly spaced buckets). +#define RTC_HISTOGRAM_PERCENTAGE(name, sample) \ + RTC_HISTOGRAM_ENUMERATION(name, sample, 101) + +// Histogram for booleans. +#define RTC_HISTOGRAM_BOOLEAN(name, sample) \ + RTC_HISTOGRAM_ENUMERATION(name, sample, 2) + +// Histogram for enumerators (evenly spaced buckets). +// `boundary` should be above the max enumerator sample. +#define RTC_HISTOGRAM_ENUMERATION(name, sample, boundary) \ + RTC_HISTOGRAM_COMMON_BLOCK_SLOW( \ + name, sample, \ + webrtc::metrics::HistogramFactoryGetEnumeration(name, boundary)) + +// The name of the histogram should not vary. +#define RTC_HISTOGRAM_COMMON_BLOCK(constant_name, sample, \ + factory_get_invocation) \ + do { \ + static std::atomic<webrtc::metrics::Histogram*> atomic_histogram_pointer( \ + nullptr); \ + webrtc::metrics::Histogram* histogram_pointer = \ + atomic_histogram_pointer.load(std::memory_order_acquire); \ + if (!histogram_pointer) { \ + histogram_pointer = factory_get_invocation; \ + webrtc::metrics::Histogram* null_histogram = nullptr; \ + atomic_histogram_pointer.compare_exchange_strong(null_histogram, \ + histogram_pointer); \ + } \ + if (histogram_pointer) { \ + webrtc::metrics::HistogramAdd(histogram_pointer, sample); \ + } \ + } while (0) + +// The histogram is constructed/found for each call. +// May be used for histograms with infrequent updates.` +#define RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, factory_get_invocation) \ + do { \ + webrtc::metrics::Histogram* histogram_pointer = factory_get_invocation; \ + if (histogram_pointer) { \ + webrtc::metrics::HistogramAdd(histogram_pointer, sample); \ + } \ + } while (0) + +// Helper macros. +// Macros for calling a histogram with varying name (e.g. when using a metric +// in different modes such as real-time vs screenshare). Fast, because pointer +// is cached. `index` should be different for different names. Allowed `index` +// values are 0, 1, and 2. +#define RTC_HISTOGRAMS_COUNTS_100(index, name, sample) \ + RTC_HISTOGRAMS_COMMON(index, name, sample, \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 100, 50)) + +#define RTC_HISTOGRAMS_COUNTS_200(index, name, sample) \ + RTC_HISTOGRAMS_COMMON(index, name, sample, \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 200, 50)) + +#define RTC_HISTOGRAMS_COUNTS_500(index, name, sample) \ + RTC_HISTOGRAMS_COMMON(index, name, sample, \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 500, 50)) + +#define RTC_HISTOGRAMS_COUNTS_1000(index, name, sample) \ + RTC_HISTOGRAMS_COMMON(index, name, sample, \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50)) + +#define RTC_HISTOGRAMS_COUNTS_10000(index, name, sample) \ + RTC_HISTOGRAMS_COMMON(index, name, sample, \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 10000, 50)) + +#define RTC_HISTOGRAMS_COUNTS_100000(index, name, sample) \ + RTC_HISTOGRAMS_COMMON(index, name, sample, \ + RTC_HISTOGRAM_COUNTS(name, sample, 1, 100000, 50)) + +#define RTC_HISTOGRAMS_ENUMERATION(index, name, sample, boundary) \ + RTC_HISTOGRAMS_COMMON(index, name, sample, \ + RTC_HISTOGRAM_ENUMERATION(name, sample, boundary)) + +#define RTC_HISTOGRAMS_PERCENTAGE(index, name, sample) \ + RTC_HISTOGRAMS_COMMON(index, name, sample, \ + RTC_HISTOGRAM_PERCENTAGE(name, sample)) + +#define RTC_HISTOGRAMS_COMMON(index, name, sample, macro_invocation) \ + do { \ + switch (index) { \ + case 0: \ + macro_invocation; \ + break; \ + case 1: \ + macro_invocation; \ + break; \ + case 2: \ + macro_invocation; \ + break; \ + default: \ + RTC_DCHECK_NOTREACHED(); \ + } \ + } while (0) + +#else + +//////////////////////////////////////////////////////////////////////////////// +// This section defines no-op alternatives to the metrics macros when +// RTC_METRICS_ENABLED is defined. + +#define RTC_HISTOGRAM_COUNTS_100(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_200(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_500(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_1000(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_10000(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_100000(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \ + webrtc::metrics_impl::NoOp(name, sample, min, max, bucket_count) + +#define RTC_HISTOGRAM_COUNTS_LINEAR(name, sample, min, max, bucket_count) \ + webrtc::metrics_impl::NoOp(name, sample, min, max, bucket_count) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_100(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_200(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_500(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_1000(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_10000(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_SPARSE_100000(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, min, max, bucket_count) \ + webrtc::metrics_impl::NoOp(name, sample, min, max, bucket_count) + +#define RTC_HISTOGRAM_PERCENTAGE_SPARSE(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_BOOLEAN_SPARSE(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, boundary) \ + webrtc::metrics_impl::NoOp(name, sample, boundary) + +#define RTC_HISTOGRAM_PERCENTAGE(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_BOOLEAN(name, sample) webrtc::metrics_impl::NoOp(name, sample) + +#define RTC_HISTOGRAM_ENUMERATION(name, sample, boundary) \ + webrtc::metrics_impl::NoOp(name, sample, boundary) + +#define RTC_HISTOGRAM_COMMON_BLOCK(constant_name, sample, \ + factory_get_invocation) \ + webrtc::metrics_impl::NoOp(constant_name, sample, factory_get_invocation) + +#define RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, factory_get_invocation) \ + webrtc::metrics_impl::NoOp(name, sample, factory_get_invocation) + +#define RTC_HISTOGRAMS_COUNTS_100(index, name, sample) webrtc::metrics_impl::NoOp(index, name, sample) + +#define RTC_HISTOGRAMS_COUNTS_200(index, name, sample) webrtc::metrics_impl::NoOp(index, name, sample) + +#define RTC_HISTOGRAMS_COUNTS_500(index, name, sample) webrtc::metrics_impl::NoOp(index, name, sample) + +#define RTC_HISTOGRAMS_COUNTS_1000(index, name, sample) \ + webrtc::metrics_impl::NoOp(index, name, sample) + +#define RTC_HISTOGRAMS_COUNTS_10000(index, name, sample) \ + webrtc::metrics_impl::NoOp(index, name, sample) + +#define RTC_HISTOGRAMS_COUNTS_100000(index, name, sample) \ + webrtc::metrics_impl::NoOp(index, name, sample) + +#define RTC_HISTOGRAMS_ENUMERATION(index, name, sample, boundary) \ + webrtc::metrics_impl::NoOp(index, name, sample, boundary) + +#define RTC_HISTOGRAMS_PERCENTAGE(index, name, sample) webrtc::metrics_impl::NoOp(index, name, sample) + +#define RTC_HISTOGRAMS_COMMON(index, name, sample, macro_invocation) \ + webrtc::metrics_impl::NoOp(index, name, sample, macro_invocation) + +#endif // RTC_METRICS_ENABLED + +namespace webrtc { +namespace metrics { + +// Time that should have elapsed for stats that are gathered once per call. +constexpr int kMinRunTimeInSeconds = 10; + +class Histogram; + +// Functions for getting pointer to histogram (constructs or finds the named +// histogram). + +// Get histogram for counters. +Histogram* HistogramFactoryGetCounts(absl::string_view name, + int min, + int max, + int bucket_count); + +// Get histogram for counters with linear bucket spacing. +Histogram* HistogramFactoryGetCountsLinear(absl::string_view name, + int min, + int max, + int bucket_count); + +// Get histogram for enumerators. +// `boundary` should be above the max enumerator sample. +Histogram* HistogramFactoryGetEnumeration(absl::string_view name, int boundary); + +// Get sparse histogram for enumerators. +// `boundary` should be above the max enumerator sample. +Histogram* SparseHistogramFactoryGetEnumeration(absl::string_view name, + int boundary); + +// Function for adding a `sample` to a histogram. +void HistogramAdd(Histogram* histogram_pointer, int sample); + +struct SampleInfo { + SampleInfo(absl::string_view name, int min, int max, size_t bucket_count); + ~SampleInfo(); + + const std::string name; + const int min; + const int max; + const size_t bucket_count; + std::map<int, int> samples; // <value, # of events> +}; + +// Enables collection of samples. +// This method should be called before any other call into webrtc. +void Enable(); + +// Gets histograms and clears all samples. +void GetAndReset( + std::map<std::string, std::unique_ptr<SampleInfo>, rtc::AbslStringViewCmp>* + histograms); + +// Functions below are mainly for testing. + +// Clears all samples. +void Reset(); + +// Returns the number of times the `sample` has been added to the histogram. +int NumEvents(absl::string_view name, int sample); + +// Returns the total number of added samples to the histogram. +int NumSamples(absl::string_view name); + +// Returns the minimum sample value (or -1 if the histogram has no samples). +int MinSample(absl::string_view name); + +// Returns a map with keys the samples with at least one event and values the +// number of events for that sample. +std::map<int, int> Samples(absl::string_view name); + +} // namespace metrics +} // namespace webrtc + +#endif // SYSTEM_WRAPPERS_INCLUDE_METRICS_H_ diff --git a/third_party/libwebrtc/system_wrappers/include/ntp_time.h b/third_party/libwebrtc/system_wrappers/include/ntp_time.h new file mode 100644 index 0000000000..b912bc8a0c --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/include/ntp_time.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2015 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 SYSTEM_WRAPPERS_INCLUDE_NTP_TIME_H_ +#define SYSTEM_WRAPPERS_INCLUDE_NTP_TIME_H_ + +#include <cmath> +#include <cstdint> +#include <limits> + +#include "rtc_base/numerics/safe_conversions.h" + +namespace webrtc { + +class NtpTime { + public: + static constexpr uint64_t kFractionsPerSecond = 0x100000000; + NtpTime() : value_(0) {} + explicit NtpTime(uint64_t value) : value_(value) {} + NtpTime(uint32_t seconds, uint32_t fractions) + : value_(seconds * kFractionsPerSecond + fractions) {} + + NtpTime(const NtpTime&) = default; + NtpTime& operator=(const NtpTime&) = default; + explicit operator uint64_t() const { return value_; } + + void Set(uint32_t seconds, uint32_t fractions) { + value_ = seconds * kFractionsPerSecond + fractions; + } + void Reset() { value_ = 0; } + + int64_t ToMs() const { + static constexpr double kNtpFracPerMs = 4.294967296E6; // 2^32 / 1000. + const double frac_ms = static_cast<double>(fractions()) / kNtpFracPerMs; + return 1000 * static_cast<int64_t>(seconds()) + + static_cast<int64_t>(frac_ms + 0.5); + } + // NTP standard (RFC1305, section 3.1) explicitly state value 0 is invalid. + bool Valid() const { return value_ != 0; } + + uint32_t seconds() const { + return rtc::dchecked_cast<uint32_t>(value_ / kFractionsPerSecond); + } + uint32_t fractions() const { + return rtc::dchecked_cast<uint32_t>(value_ % kFractionsPerSecond); + } + + private: + uint64_t value_; +}; + +inline bool operator==(const NtpTime& n1, const NtpTime& n2) { + return static_cast<uint64_t>(n1) == static_cast<uint64_t>(n2); +} +inline bool operator!=(const NtpTime& n1, const NtpTime& n2) { + return !(n1 == n2); +} + +// Converts `int64_t` milliseconds to Q32.32-formatted fixed-point seconds. +// Performs clamping if the result overflows or underflows. +inline int64_t Int64MsToQ32x32(int64_t milliseconds) { + // TODO(bugs.webrtc.org/10893): Change to use `rtc::saturated_cast` once the + // bug has been fixed. + double result = + std::round(milliseconds * (NtpTime::kFractionsPerSecond / 1000.0)); + + // Explicitly cast values to double to avoid implicit conversion warnings + // The conversion of the std::numeric_limits<int64_t>::max() triggers + // -Wimplicit-int-float-conversion warning in clang 10.0.0 without explicit + // cast + if (result <= static_cast<double>(std::numeric_limits<int64_t>::min())) { + return std::numeric_limits<int64_t>::min(); + } + + if (result >= static_cast<double>(std::numeric_limits<int64_t>::max())) { + return std::numeric_limits<int64_t>::max(); + } + + return rtc::dchecked_cast<int64_t>(result); +} + +// Converts `int64_t` milliseconds to UQ32.32-formatted fixed-point seconds. +// Performs clamping if the result overflows or underflows. +inline uint64_t Int64MsToUQ32x32(int64_t milliseconds) { + // TODO(bugs.webrtc.org/10893): Change to use `rtc::saturated_cast` once the + // bug has been fixed. + double result = + std::round(milliseconds * (NtpTime::kFractionsPerSecond / 1000.0)); + + // Explicitly cast values to double to avoid implicit conversion warnings + // The conversion of the std::numeric_limits<int64_t>::max() triggers + // -Wimplicit-int-float-conversion warning in clang 10.0.0 without explicit + // cast + if (result <= static_cast<double>(std::numeric_limits<uint64_t>::min())) { + return std::numeric_limits<uint64_t>::min(); + } + + if (result >= static_cast<double>(std::numeric_limits<uint64_t>::max())) { + return std::numeric_limits<uint64_t>::max(); + } + + return rtc::dchecked_cast<uint64_t>(result); +} + +// Converts Q32.32-formatted fixed-point seconds to `int64_t` milliseconds. +inline int64_t Q32x32ToInt64Ms(int64_t q32x32) { + return rtc::dchecked_cast<int64_t>( + std::round(q32x32 * (1000.0 / NtpTime::kFractionsPerSecond))); +} + +// Converts UQ32.32-formatted fixed-point seconds to `int64_t` milliseconds. +inline int64_t UQ32x32ToInt64Ms(uint64_t q32x32) { + return rtc::dchecked_cast<int64_t>( + std::round(q32x32 * (1000.0 / NtpTime::kFractionsPerSecond))); +} + +} // namespace webrtc +#endif // SYSTEM_WRAPPERS_INCLUDE_NTP_TIME_H_ diff --git a/third_party/libwebrtc/system_wrappers/include/rtp_to_ntp_estimator.h b/third_party/libwebrtc/system_wrappers/include/rtp_to_ntp_estimator.h new file mode 100644 index 0000000000..a5c7a157b6 --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/include/rtp_to_ntp_estimator.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2012 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 SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_ESTIMATOR_H_ +#define SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_ESTIMATOR_H_ + +#include <stdint.h> + +#include <list> + +#include "absl/types/optional.h" +#include "rtc_base/checks.h" +#include "rtc_base/numerics/sequence_number_unwrapper.h" +#include "system_wrappers/include/ntp_time.h" + +namespace webrtc { + +// Converts an RTP timestamp to the NTP domain. +// The class needs to be trained with (at least 2) RTP/NTP timestamp pairs from +// RTCP sender reports before the convertion can be done. +class RtpToNtpEstimator { + public: + static constexpr int kMaxInvalidSamples = 3; + + RtpToNtpEstimator() = default; + RtpToNtpEstimator(const RtpToNtpEstimator&) = delete; + RtpToNtpEstimator& operator=(const RtpToNtpEstimator&) = delete; + ~RtpToNtpEstimator() = default; + + enum UpdateResult { kInvalidMeasurement, kSameMeasurement, kNewMeasurement }; + // Updates measurements with RTP/NTP timestamp pair from a RTCP sender report. + UpdateResult UpdateMeasurements(NtpTime ntp, uint32_t rtp_timestamp); + + // Converts an RTP timestamp to the NTP domain. + // Returns invalid NtpTime (i.e. NtpTime(0)) on failure. + NtpTime Estimate(uint32_t rtp_timestamp) const; + + // Returns estimated rtp_timestamp frequency, or 0 on failure. + double EstimatedFrequencyKhz() const; + + private: + // Estimated parameters from RTP and NTP timestamp pairs in `measurements_`. + // Defines linear estimation: NtpTime (in units of 1s/2^32) = + // `Parameters::slope` * rtp_timestamp + `Parameters::offset`. + struct Parameters { + double slope; + double offset; + }; + + // RTP and NTP timestamp pair from a RTCP SR report. + struct RtcpMeasurement { + NtpTime ntp_time; + int64_t unwrapped_rtp_timestamp; + }; + + void UpdateParameters(); + + int consecutive_invalid_samples_ = 0; + std::list<RtcpMeasurement> measurements_; + absl::optional<Parameters> params_; + mutable RtpTimestampUnwrapper unwrapper_; +}; +} // namespace webrtc + +#endif // SYSTEM_WRAPPERS_INCLUDE_RTP_TO_NTP_ESTIMATOR_H_ diff --git a/third_party/libwebrtc/system_wrappers/include/sleep.h b/third_party/libwebrtc/system_wrappers/include/sleep.h new file mode 100644 index 0000000000..3bf8df219f --- /dev/null +++ b/third_party/libwebrtc/system_wrappers/include/sleep.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012 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. + */ +// An OS-independent sleep function. + +#ifndef SYSTEM_WRAPPERS_INCLUDE_SLEEP_H_ +#define SYSTEM_WRAPPERS_INCLUDE_SLEEP_H_ + +namespace webrtc { + +// This function sleeps for the specified number of milliseconds. +// It may return early if the thread is woken by some other event, +// such as the delivery of a signal on Unix. +void SleepMs(int msecs); + +} // namespace webrtc + +#endif // SYSTEM_WRAPPERS_INCLUDE_SLEEP_H_ |