123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- /*
- * 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>
- #include "rtc_base/constructor_magic.h"
- 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 {}
- void Add(int sample);
- private:
- bool GetMetric(int* metric) const override;
- // Returns the last computed metric (i.e. from GetMetric).
- int GetValueForEmptyInterval() 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,
- int64_t process_intervals_ms);
- ~MaxCounter() override {}
- void Add(int sample);
- private:
- bool GetMetric(int* metric) const override;
- int GetValueForEmptyInterval() 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;
- int GetValueForEmptyInterval() 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;
- int GetValueForEmptyInterval() 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 |
- //
- // |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 {}
- void Add(int sample);
- private:
- bool GetMetric(int* metric) const override;
- int GetValueForEmptyInterval() const override; // Returns zero.
- 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 - 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 {}
- 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.
- RTC_DISALLOW_COPY_AND_ASSIGN(RateAccCounter);
- };
- } // namespace webrtc
- #endif // VIDEO_STATS_COUNTER_H_
|