summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/video/stats_counter.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/video/stats_counter.h')
-rw-r--r--third_party/libwebrtc/video/stats_counter.h296
1 files changed, 296 insertions, 0 deletions
diff --git a/third_party/libwebrtc/video/stats_counter.h b/third_party/libwebrtc/video/stats_counter.h
new file mode 100644
index 0000000000..9e2b8702d6
--- /dev/null
+++ b/third_party/libwebrtc/video/stats_counter.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2016 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 VIDEO_STATS_COUNTER_H_
+#define VIDEO_STATS_COUNTER_H_
+
+#include <memory>
+#include <string>
+
+namespace webrtc {
+
+class AggregatedCounter;
+class Clock;
+class Samples;
+
+// `StatsCounterObserver` is called periodically when a metric is updated.
+class StatsCounterObserver {
+ public:
+ virtual void OnMetricUpdated(int sample) = 0;
+
+ virtual ~StatsCounterObserver() {}
+};
+
+struct AggregatedStats {
+ std::string ToString() const;
+ std::string ToStringWithMultiplier(int multiplier) const;
+
+ int64_t num_samples = 0;
+ int min = -1;
+ int max = -1;
+ int average = -1;
+ // TODO(asapersson): Consider adding median/percentiles.
+};
+
+// Classes which periodically computes a metric.
+//
+// During a period, `kProcessIntervalMs`, different metrics can be computed e.g:
+// - `AvgCounter`: average of samples
+// - `PercentCounter`: percentage of samples
+// - `PermilleCounter`: permille of samples
+//
+// Each periodic metric can be either:
+// - reported to an `observer` each period
+// - aggregated during the call (e.g. min, max, average)
+//
+// periodically computed
+// GetMetric() GetMetric() => AggregatedStats
+// ^ ^ (e.g. min/max/avg)
+// | |
+// | * * * * | ** * * * * | ...
+// |<- process interval ->|
+//
+// (*) - samples
+//
+//
+// Example usage:
+//
+// AvgCounter counter(&clock, nullptr);
+// counter.Add(5);
+// counter.Add(1);
+// counter.Add(6); // process interval passed -> GetMetric() avg:4
+// counter.Add(7);
+// counter.Add(3); // process interval passed -> GetMetric() avg:5
+// counter.Add(10);
+// counter.Add(20); // process interval passed -> GetMetric() avg:15
+// AggregatedStats stats = counter.GetStats();
+// stats: {min:4, max:15, avg:8}
+//
+
+// Note: StatsCounter takes ownership of `observer`.
+
+class StatsCounter {
+ public:
+ virtual ~StatsCounter();
+
+ // Gets metric within an interval. Returns true on success false otherwise.
+ virtual bool GetMetric(int* metric) const = 0;
+
+ // Gets the value to use for an interval without samples.
+ virtual int GetValueForEmptyInterval() const = 0;
+
+ // Gets aggregated stats (i.e. aggregate of periodically computed metrics).
+ AggregatedStats GetStats();
+
+ // Reports metrics for elapsed intervals to AggregatedCounter and GetStats.
+ AggregatedStats ProcessAndGetStats();
+
+ // Reports metrics for elapsed intervals to AggregatedCounter and pauses stats
+ // (i.e. empty intervals will be discarded until next sample is added).
+ void ProcessAndPause();
+
+ // As above with a minimum pause time. Added samples within this interval will
+ // not resume the stats (i.e. stop the pause).
+ void ProcessAndPauseForDuration(int64_t min_pause_time_ms);
+
+ // Reports metrics for elapsed intervals to AggregatedCounter and stops pause.
+ void ProcessAndStopPause();
+
+ // Checks if a sample has been added (i.e. Add or Set called).
+ bool HasSample() const;
+
+ protected:
+ StatsCounter(Clock* clock,
+ int64_t process_intervals_ms,
+ bool include_empty_intervals,
+ StatsCounterObserver* observer);
+
+ void Add(int sample);
+ void Set(int64_t sample, uint32_t stream_id);
+ void SetLast(int64_t sample, uint32_t stream_id);
+
+ const bool include_empty_intervals_;
+ const int64_t process_intervals_ms_;
+ const std::unique_ptr<AggregatedCounter> aggregated_counter_;
+ const std::unique_ptr<Samples> samples_;
+
+ private:
+ bool TimeToProcess(int* num_elapsed_intervals);
+ void TryProcess();
+ void ReportMetricToAggregatedCounter(int value, int num_values_to_add) const;
+ bool IncludeEmptyIntervals() const;
+ void Resume();
+ void ResumeIfMinTimePassed();
+
+ Clock* const clock_;
+ const std::unique_ptr<StatsCounterObserver> observer_;
+ int64_t last_process_time_ms_;
+ bool paused_;
+ int64_t pause_time_ms_;
+ int64_t min_pause_time_ms_;
+};
+
+// AvgCounter: average of samples
+//
+// | * * * | * * | ...
+// | Add(5) Add(1) Add(6) | Add(5) Add(5) |
+// GetMetric | (5 + 1 + 6) / 3 | (5 + 5) / 2 |
+//
+// `include_empty_intervals`: If set, intervals without samples will be included
+// in the stats. The value for an interval is
+// determined by GetValueForEmptyInterval().
+//
+class AvgCounter : public StatsCounter {
+ public:
+ AvgCounter(Clock* clock,
+ StatsCounterObserver* observer,
+ bool include_empty_intervals);
+ ~AvgCounter() override {}
+
+ AvgCounter(const AvgCounter&) = delete;
+ AvgCounter& operator=(const AvgCounter&) = delete;
+
+ void Add(int sample);
+
+ private:
+ bool GetMetric(int* metric) const override;
+
+ // Returns the last computed metric (i.e. from GetMetric).
+ int GetValueForEmptyInterval() const override;
+};
+
+// MaxCounter: maximum of samples
+//
+// | * * * | * * | ...
+// | Add(5) Add(1) Add(6) | Add(5) Add(5) |
+// GetMetric | max: (5, 1, 6) | max: (5, 5) |
+//
+class MaxCounter : public StatsCounter {
+ public:
+ MaxCounter(Clock* clock,
+ StatsCounterObserver* observer,
+ int64_t process_intervals_ms);
+ ~MaxCounter() override {}
+
+ MaxCounter(const MaxCounter&) = delete;
+ MaxCounter& operator=(const MaxCounter&) = delete;
+
+ void Add(int sample);
+
+ private:
+ bool GetMetric(int* metric) const override;
+ int GetValueForEmptyInterval() const override;
+};
+
+// PercentCounter: percentage of samples
+//
+// | * * * | * * | ...
+// | Add(T) Add(F) Add(T) | Add(F) Add(T) |
+// GetMetric | 100 * 2 / 3 | 100 * 1 / 2 |
+//
+class PercentCounter : public StatsCounter {
+ public:
+ PercentCounter(Clock* clock, StatsCounterObserver* observer);
+ ~PercentCounter() override {}
+
+ PercentCounter(const PercentCounter&) = delete;
+ PercentCounter& operator=(const PercentCounter&) = delete;
+
+ void Add(bool sample);
+
+ private:
+ bool GetMetric(int* metric) const override;
+ int GetValueForEmptyInterval() const override;
+};
+
+// PermilleCounter: permille of samples
+//
+// | * * * | * * | ...
+// | Add(T) Add(F) Add(T) | Add(F) Add(T) |
+// GetMetric | 1000 * 2 / 3 | 1000 * 1 / 2 |
+//
+class PermilleCounter : public StatsCounter {
+ public:
+ PermilleCounter(Clock* clock, StatsCounterObserver* observer);
+ ~PermilleCounter() override {}
+
+ PermilleCounter(const PermilleCounter&) = delete;
+ PermilleCounter& operator=(const PermilleCounter&) = delete;
+
+ void Add(bool sample);
+
+ private:
+ bool GetMetric(int* metric) const override;
+ int GetValueForEmptyInterval() const override;
+};
+
+// RateCounter: units per second
+//
+// | * * * | * * | ...
+// | Add(5) Add(1) Add(6) | Add(5) Add(5) |
+// |<------ 2 sec ------->| |
+// GetMetric | (5 + 1 + 6) / 2 | (5 + 5) / 2 |
+//
+// `include_empty_intervals`: If set, intervals without samples will be included
+// in the stats. The value for an interval is
+// determined by GetValueForEmptyInterval().
+//
+class RateCounter : public StatsCounter {
+ public:
+ RateCounter(Clock* clock,
+ StatsCounterObserver* observer,
+ bool include_empty_intervals);
+ ~RateCounter() override {}
+
+ RateCounter(const RateCounter&) = delete;
+ RateCounter& operator=(const RateCounter&) = delete;
+
+ void Add(int sample);
+
+ private:
+ bool GetMetric(int* metric) const override;
+ int GetValueForEmptyInterval() const override; // Returns zero.
+};
+
+// RateAccCounter: units per second (used for counters)
+//
+// | * * * | * * | ...
+// | Set(5) Set(6) Set(8) | Set(11) Set(13) |
+// |<------ 2 sec ------->| |
+// GetMetric | (8 - 0) / 2 | (13 - 8) / 2 |
+//
+// `include_empty_intervals`: If set, intervals without samples will be included
+// in the stats. The value for an interval is
+// determined by GetValueForEmptyInterval().
+//
+class RateAccCounter : public StatsCounter {
+ public:
+ RateAccCounter(Clock* clock,
+ StatsCounterObserver* observer,
+ bool include_empty_intervals);
+ ~RateAccCounter() override {}
+
+ RateAccCounter(const RateAccCounter&) = delete;
+ RateAccCounter& operator=(const RateAccCounter&) = delete;
+
+ void Set(int64_t sample, uint32_t stream_id);
+
+ // Sets the value for previous interval.
+ // To be used if a value other than zero is initially required.
+ void SetLast(int64_t sample, uint32_t stream_id);
+
+ private:
+ bool GetMetric(int* metric) const override;
+ int GetValueForEmptyInterval() const override; // Returns zero.
+};
+
+} // namespace webrtc
+
+#endif // VIDEO_STATS_COUNTER_H_