Index: webrtc/video/stats_counter.h |
diff --git a/webrtc/video/stats_counter.h b/webrtc/video/stats_counter.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a4d561261f41615fabb4fe3ac73a6139bb22135a |
--- /dev/null |
+++ b/webrtc/video/stats_counter.h |
@@ -0,0 +1,242 @@ |
+/* |
+ * 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 WEBRTC_VIDEO_STATS_COUNTER_H_ |
+#define WEBRTC_VIDEO_STATS_COUNTER_H_ |
+ |
+#include <memory> |
+ |
+#include "webrtc/base/constructormagic.h" |
+#include "webrtc/typedefs.h" |
+ |
+namespace webrtc { |
+ |
+class Clock; |
+ |
+// |StatsCounterObserver| is called periodically when a metric is updated. |
+class StatsCounterObserver { |
+ public: |
+ virtual void OnMetricUpdated(int sample) = 0; |
+ |
+ virtual ~StatsCounterObserver() {} |
+}; |
+ |
+struct AggregatedStats { |
+ int64_t num_samples = 0; |
+ int min = -1; |
+ int max = -1; |
+ int average = -1; |
+ // TODO(asapersson): Consider adding median/percentiles. |
+}; |
+ |
+// Class holding periodically computed metrics. |
+class AggregatedCounter { |
mflodman
2016/05/17 11:56:18
To make the header even simpler, wdyt of moving th
åsapersson
2016/05/18 12:01:34
Done.
|
+ public: |
+ AggregatedCounter(); |
+ ~AggregatedCounter() {} |
+ |
+ void Add(int sample); |
+ |
+ AggregatedStats ComputeStats(); |
+ |
+ private: |
+ void Compute(); |
+ int64_t sum_; |
+ AggregatedStats stats_; |
+}; |
+ |
+// 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() {} |
+ |
+ virtual bool GetMetric(int* metric) const = 0; |
+ |
+ AggregatedStats GetStats(); |
+ |
+ protected: |
+ StatsCounter(Clock* clock, |
+ bool include_empty_intervals, |
+ StatsCounterObserver* observer); |
+ |
+ void Add(int sample); |
+ void Set(int sample); |
+ |
+ int max_; |
+ int64_t sum_; |
+ int64_t num_samples_; |
+ int64_t last_sum_; |
+ |
+ private: |
+ bool TimeToProcess(); |
+ void TryProcess(); |
+ |
+ Clock* const clock_; |
+ const bool include_empty_intervals_; |
+ const std::unique_ptr<StatsCounterObserver> observer_; |
+ int64_t last_process_time_ms_; |
+ AggregatedCounter aggregated_counter_; |
+}; |
+ |
+// AvgCounter: average of samples |
+// |
+// | * * * | * * | ... |
+// | Add(5) Add(1) Add(6) | Add(5) Add(5) | |
+// GetMetric | (5 + 1 + 6) / 3 | (5 + 5) / 2 | |
+// |
+class AvgCounter : public StatsCounter { |
+ public: |
+ AvgCounter(Clock* clock, StatsCounterObserver* observer); |
+ ~AvgCounter() override {} |
+ |
+ void Add(int sample); |
+ |
+ private: |
+ bool GetMetric(int* metric) const override; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(AvgCounter); |
+}; |
+ |
+// 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); |
+ ~MaxCounter() override {} |
+ |
+ void Add(int sample); |
+ |
+ private: |
+ bool GetMetric(int* metric) const override; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(MaxCounter); |
+}; |
+ |
+// 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 {} |
+ |
+ void Add(bool sample); |
+ |
+ private: |
+ bool GetMetric(int* metric) const override; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(PercentCounter); |
+}; |
+ |
+// 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 {} |
+ |
+ void Add(bool sample); |
+ |
+ private: |
+ bool GetMetric(int* metric) const override; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(PermilleCounter); |
+}; |
+ |
+// RateCounter: units per second |
+// |
+// | * * * | * * | ... |
+// | Add(5) Add(1) Add(6) | Add(5) Add(5) | |
+// |<------ 2 sec ------->| | |
+// GetMetric | (5 + 1 + 6) / 2 | (5 + 5) / 2 | |
+// |
+class RateCounter : public StatsCounter { |
+ public: |
+ RateCounter(Clock* clock, StatsCounterObserver* observer); |
+ ~RateCounter() override {} |
+ |
+ void Add(int sample); |
+ |
+ private: |
+ bool GetMetric(int* metric) const override; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(RateCounter); |
+}; |
+ |
+// RateAccCounter: units per second (used for counters) |
+// |
+// | * * * | * * | ... |
+// | Set(5) Set(6) Set(8) | Set(11) Set(13) | |
+// |<------ 2 sec ------->| | |
+// GetMetric | 8 / 2 | (13 - 8) / 2 | |
+// |
+class RateAccCounter : public StatsCounter { |
+ public: |
+ RateAccCounter(Clock* clock, StatsCounterObserver* observer); |
+ ~RateAccCounter() override {} |
+ |
+ void Set(int sample); |
+ |
+ private: |
+ bool GetMetric(int* metric) const override; |
+ |
+ RTC_DISALLOW_COPY_AND_ASSIGN(RateAccCounter); |
+}; |
+ |
+} // namespace webrtc |
+ |
+#endif // WEBRTC_VIDEO_STATS_COUNTER_H_ |