xref: /aosp_15_r20/external/webrtc/video/stats_counter.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef VIDEO_STATS_COUNTER_H_
12*d9f75844SAndroid Build Coastguard Worker #define VIDEO_STATS_COUNTER_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <memory>
15*d9f75844SAndroid Build Coastguard Worker #include <string>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
18*d9f75844SAndroid Build Coastguard Worker 
19*d9f75844SAndroid Build Coastguard Worker class AggregatedCounter;
20*d9f75844SAndroid Build Coastguard Worker class Clock;
21*d9f75844SAndroid Build Coastguard Worker class Samples;
22*d9f75844SAndroid Build Coastguard Worker 
23*d9f75844SAndroid Build Coastguard Worker // `StatsCounterObserver` is called periodically when a metric is updated.
24*d9f75844SAndroid Build Coastguard Worker class StatsCounterObserver {
25*d9f75844SAndroid Build Coastguard Worker  public:
26*d9f75844SAndroid Build Coastguard Worker   virtual void OnMetricUpdated(int sample) = 0;
27*d9f75844SAndroid Build Coastguard Worker 
~StatsCounterObserver()28*d9f75844SAndroid Build Coastguard Worker   virtual ~StatsCounterObserver() {}
29*d9f75844SAndroid Build Coastguard Worker };
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker struct AggregatedStats {
32*d9f75844SAndroid Build Coastguard Worker   std::string ToString() const;
33*d9f75844SAndroid Build Coastguard Worker   std::string ToStringWithMultiplier(int multiplier) const;
34*d9f75844SAndroid Build Coastguard Worker 
35*d9f75844SAndroid Build Coastguard Worker   int64_t num_samples = 0;
36*d9f75844SAndroid Build Coastguard Worker   int min = -1;
37*d9f75844SAndroid Build Coastguard Worker   int max = -1;
38*d9f75844SAndroid Build Coastguard Worker   int average = -1;
39*d9f75844SAndroid Build Coastguard Worker   // TODO(asapersson): Consider adding median/percentiles.
40*d9f75844SAndroid Build Coastguard Worker };
41*d9f75844SAndroid Build Coastguard Worker 
42*d9f75844SAndroid Build Coastguard Worker // Classes which periodically computes a metric.
43*d9f75844SAndroid Build Coastguard Worker //
44*d9f75844SAndroid Build Coastguard Worker // During a period, `kProcessIntervalMs`, different metrics can be computed e.g:
45*d9f75844SAndroid Build Coastguard Worker // - `AvgCounter`: average of samples
46*d9f75844SAndroid Build Coastguard Worker // - `PercentCounter`: percentage of samples
47*d9f75844SAndroid Build Coastguard Worker // - `PermilleCounter`: permille of samples
48*d9f75844SAndroid Build Coastguard Worker //
49*d9f75844SAndroid Build Coastguard Worker // Each periodic metric can be either:
50*d9f75844SAndroid Build Coastguard Worker // - reported to an `observer` each period
51*d9f75844SAndroid Build Coastguard Worker // - aggregated during the call (e.g. min, max, average)
52*d9f75844SAndroid Build Coastguard Worker //
53*d9f75844SAndroid Build Coastguard Worker //                 periodically computed
54*d9f75844SAndroid Build Coastguard Worker //                    GetMetric()            GetMetric()   => AggregatedStats
55*d9f75844SAndroid Build Coastguard Worker //                        ^                      ^            (e.g. min/max/avg)
56*d9f75844SAndroid Build Coastguard Worker //                        |                      |
57*d9f75844SAndroid Build Coastguard Worker // |   *    *  *       *  |  **    *   * *     * | ...
58*d9f75844SAndroid Build Coastguard Worker // |<- process interval ->|
59*d9f75844SAndroid Build Coastguard Worker //
60*d9f75844SAndroid Build Coastguard Worker // (*) - samples
61*d9f75844SAndroid Build Coastguard Worker //
62*d9f75844SAndroid Build Coastguard Worker //
63*d9f75844SAndroid Build Coastguard Worker // Example usage:
64*d9f75844SAndroid Build Coastguard Worker //
65*d9f75844SAndroid Build Coastguard Worker // AvgCounter counter(&clock, nullptr);
66*d9f75844SAndroid Build Coastguard Worker // counter.Add(5);
67*d9f75844SAndroid Build Coastguard Worker // counter.Add(1);
68*d9f75844SAndroid Build Coastguard Worker // counter.Add(6);   // process interval passed -> GetMetric() avg:4
69*d9f75844SAndroid Build Coastguard Worker // counter.Add(7);
70*d9f75844SAndroid Build Coastguard Worker // counter.Add(3);   // process interval passed -> GetMetric() avg:5
71*d9f75844SAndroid Build Coastguard Worker // counter.Add(10);
72*d9f75844SAndroid Build Coastguard Worker // counter.Add(20);  // process interval passed -> GetMetric() avg:15
73*d9f75844SAndroid Build Coastguard Worker // AggregatedStats stats = counter.GetStats();
74*d9f75844SAndroid Build Coastguard Worker // stats: {min:4, max:15, avg:8}
75*d9f75844SAndroid Build Coastguard Worker //
76*d9f75844SAndroid Build Coastguard Worker 
77*d9f75844SAndroid Build Coastguard Worker // Note: StatsCounter takes ownership of `observer`.
78*d9f75844SAndroid Build Coastguard Worker 
79*d9f75844SAndroid Build Coastguard Worker class StatsCounter {
80*d9f75844SAndroid Build Coastguard Worker  public:
81*d9f75844SAndroid Build Coastguard Worker   virtual ~StatsCounter();
82*d9f75844SAndroid Build Coastguard Worker 
83*d9f75844SAndroid Build Coastguard Worker   // Gets metric within an interval. Returns true on success false otherwise.
84*d9f75844SAndroid Build Coastguard Worker   virtual bool GetMetric(int* metric) const = 0;
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker   // Gets the value to use for an interval without samples.
87*d9f75844SAndroid Build Coastguard Worker   virtual int GetValueForEmptyInterval() const = 0;
88*d9f75844SAndroid Build Coastguard Worker 
89*d9f75844SAndroid Build Coastguard Worker   // Gets aggregated stats (i.e. aggregate of periodically computed metrics).
90*d9f75844SAndroid Build Coastguard Worker   AggregatedStats GetStats();
91*d9f75844SAndroid Build Coastguard Worker 
92*d9f75844SAndroid Build Coastguard Worker   // Reports metrics for elapsed intervals to AggregatedCounter and GetStats.
93*d9f75844SAndroid Build Coastguard Worker   AggregatedStats ProcessAndGetStats();
94*d9f75844SAndroid Build Coastguard Worker 
95*d9f75844SAndroid Build Coastguard Worker   // Reports metrics for elapsed intervals to AggregatedCounter and pauses stats
96*d9f75844SAndroid Build Coastguard Worker   // (i.e. empty intervals will be discarded until next sample is added).
97*d9f75844SAndroid Build Coastguard Worker   void ProcessAndPause();
98*d9f75844SAndroid Build Coastguard Worker 
99*d9f75844SAndroid Build Coastguard Worker   // As above with a minimum pause time. Added samples within this interval will
100*d9f75844SAndroid Build Coastguard Worker   // not resume the stats (i.e. stop the pause).
101*d9f75844SAndroid Build Coastguard Worker   void ProcessAndPauseForDuration(int64_t min_pause_time_ms);
102*d9f75844SAndroid Build Coastguard Worker 
103*d9f75844SAndroid Build Coastguard Worker   // Reports metrics for elapsed intervals to AggregatedCounter and stops pause.
104*d9f75844SAndroid Build Coastguard Worker   void ProcessAndStopPause();
105*d9f75844SAndroid Build Coastguard Worker 
106*d9f75844SAndroid Build Coastguard Worker   // Checks if a sample has been added (i.e. Add or Set called).
107*d9f75844SAndroid Build Coastguard Worker   bool HasSample() const;
108*d9f75844SAndroid Build Coastguard Worker 
109*d9f75844SAndroid Build Coastguard Worker  protected:
110*d9f75844SAndroid Build Coastguard Worker   StatsCounter(Clock* clock,
111*d9f75844SAndroid Build Coastguard Worker                int64_t process_intervals_ms,
112*d9f75844SAndroid Build Coastguard Worker                bool include_empty_intervals,
113*d9f75844SAndroid Build Coastguard Worker                StatsCounterObserver* observer);
114*d9f75844SAndroid Build Coastguard Worker 
115*d9f75844SAndroid Build Coastguard Worker   void Add(int sample);
116*d9f75844SAndroid Build Coastguard Worker   void Set(int64_t sample, uint32_t stream_id);
117*d9f75844SAndroid Build Coastguard Worker   void SetLast(int64_t sample, uint32_t stream_id);
118*d9f75844SAndroid Build Coastguard Worker 
119*d9f75844SAndroid Build Coastguard Worker   const bool include_empty_intervals_;
120*d9f75844SAndroid Build Coastguard Worker   const int64_t process_intervals_ms_;
121*d9f75844SAndroid Build Coastguard Worker   const std::unique_ptr<AggregatedCounter> aggregated_counter_;
122*d9f75844SAndroid Build Coastguard Worker   const std::unique_ptr<Samples> samples_;
123*d9f75844SAndroid Build Coastguard Worker 
124*d9f75844SAndroid Build Coastguard Worker  private:
125*d9f75844SAndroid Build Coastguard Worker   bool TimeToProcess(int* num_elapsed_intervals);
126*d9f75844SAndroid Build Coastguard Worker   void TryProcess();
127*d9f75844SAndroid Build Coastguard Worker   void ReportMetricToAggregatedCounter(int value, int num_values_to_add) const;
128*d9f75844SAndroid Build Coastguard Worker   bool IncludeEmptyIntervals() const;
129*d9f75844SAndroid Build Coastguard Worker   void Resume();
130*d9f75844SAndroid Build Coastguard Worker   void ResumeIfMinTimePassed();
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker   Clock* const clock_;
133*d9f75844SAndroid Build Coastguard Worker   const std::unique_ptr<StatsCounterObserver> observer_;
134*d9f75844SAndroid Build Coastguard Worker   int64_t last_process_time_ms_;
135*d9f75844SAndroid Build Coastguard Worker   bool paused_;
136*d9f75844SAndroid Build Coastguard Worker   int64_t pause_time_ms_;
137*d9f75844SAndroid Build Coastguard Worker   int64_t min_pause_time_ms_;
138*d9f75844SAndroid Build Coastguard Worker };
139*d9f75844SAndroid Build Coastguard Worker 
140*d9f75844SAndroid Build Coastguard Worker // AvgCounter: average of samples
141*d9f75844SAndroid Build Coastguard Worker //
142*d9f75844SAndroid Build Coastguard Worker //           | *      *      *      | *           *       | ...
143*d9f75844SAndroid Build Coastguard Worker //           | Add(5) Add(1) Add(6) | Add(5)      Add(5)  |
144*d9f75844SAndroid Build Coastguard Worker // GetMetric | (5 + 1 + 6) / 3      | (5 + 5) / 2         |
145*d9f75844SAndroid Build Coastguard Worker //
146*d9f75844SAndroid Build Coastguard Worker // `include_empty_intervals`: If set, intervals without samples will be included
147*d9f75844SAndroid Build Coastguard Worker //                            in the stats. The value for an interval is
148*d9f75844SAndroid Build Coastguard Worker //                            determined by GetValueForEmptyInterval().
149*d9f75844SAndroid Build Coastguard Worker //
150*d9f75844SAndroid Build Coastguard Worker class AvgCounter : public StatsCounter {
151*d9f75844SAndroid Build Coastguard Worker  public:
152*d9f75844SAndroid Build Coastguard Worker   AvgCounter(Clock* clock,
153*d9f75844SAndroid Build Coastguard Worker              StatsCounterObserver* observer,
154*d9f75844SAndroid Build Coastguard Worker              bool include_empty_intervals);
~AvgCounter()155*d9f75844SAndroid Build Coastguard Worker   ~AvgCounter() override {}
156*d9f75844SAndroid Build Coastguard Worker 
157*d9f75844SAndroid Build Coastguard Worker   AvgCounter(const AvgCounter&) = delete;
158*d9f75844SAndroid Build Coastguard Worker   AvgCounter& operator=(const AvgCounter&) = delete;
159*d9f75844SAndroid Build Coastguard Worker 
160*d9f75844SAndroid Build Coastguard Worker   void Add(int sample);
161*d9f75844SAndroid Build Coastguard Worker 
162*d9f75844SAndroid Build Coastguard Worker  private:
163*d9f75844SAndroid Build Coastguard Worker   bool GetMetric(int* metric) const override;
164*d9f75844SAndroid Build Coastguard Worker 
165*d9f75844SAndroid Build Coastguard Worker   // Returns the last computed metric (i.e. from GetMetric).
166*d9f75844SAndroid Build Coastguard Worker   int GetValueForEmptyInterval() const override;
167*d9f75844SAndroid Build Coastguard Worker };
168*d9f75844SAndroid Build Coastguard Worker 
169*d9f75844SAndroid Build Coastguard Worker // MaxCounter: maximum of samples
170*d9f75844SAndroid Build Coastguard Worker //
171*d9f75844SAndroid Build Coastguard Worker //           | *      *      *      | *           *       | ...
172*d9f75844SAndroid Build Coastguard Worker //           | Add(5) Add(1) Add(6) | Add(5)      Add(5)  |
173*d9f75844SAndroid Build Coastguard Worker // GetMetric | max: (5, 1, 6)       | max: (5, 5)         |
174*d9f75844SAndroid Build Coastguard Worker //
175*d9f75844SAndroid Build Coastguard Worker class MaxCounter : public StatsCounter {
176*d9f75844SAndroid Build Coastguard Worker  public:
177*d9f75844SAndroid Build Coastguard Worker   MaxCounter(Clock* clock,
178*d9f75844SAndroid Build Coastguard Worker              StatsCounterObserver* observer,
179*d9f75844SAndroid Build Coastguard Worker              int64_t process_intervals_ms);
~MaxCounter()180*d9f75844SAndroid Build Coastguard Worker   ~MaxCounter() override {}
181*d9f75844SAndroid Build Coastguard Worker 
182*d9f75844SAndroid Build Coastguard Worker   MaxCounter(const MaxCounter&) = delete;
183*d9f75844SAndroid Build Coastguard Worker   MaxCounter& operator=(const MaxCounter&) = delete;
184*d9f75844SAndroid Build Coastguard Worker 
185*d9f75844SAndroid Build Coastguard Worker   void Add(int sample);
186*d9f75844SAndroid Build Coastguard Worker 
187*d9f75844SAndroid Build Coastguard Worker  private:
188*d9f75844SAndroid Build Coastguard Worker   bool GetMetric(int* metric) const override;
189*d9f75844SAndroid Build Coastguard Worker   int GetValueForEmptyInterval() const override;
190*d9f75844SAndroid Build Coastguard Worker };
191*d9f75844SAndroid Build Coastguard Worker 
192*d9f75844SAndroid Build Coastguard Worker // PercentCounter: percentage of samples
193*d9f75844SAndroid Build Coastguard Worker //
194*d9f75844SAndroid Build Coastguard Worker //           | *      *      *      | *           *       | ...
195*d9f75844SAndroid Build Coastguard Worker //           | Add(T) Add(F) Add(T) | Add(F)      Add(T)  |
196*d9f75844SAndroid Build Coastguard Worker // GetMetric | 100 * 2 / 3          | 100 * 1 / 2         |
197*d9f75844SAndroid Build Coastguard Worker //
198*d9f75844SAndroid Build Coastguard Worker class PercentCounter : public StatsCounter {
199*d9f75844SAndroid Build Coastguard Worker  public:
200*d9f75844SAndroid Build Coastguard Worker   PercentCounter(Clock* clock, StatsCounterObserver* observer);
~PercentCounter()201*d9f75844SAndroid Build Coastguard Worker   ~PercentCounter() override {}
202*d9f75844SAndroid Build Coastguard Worker 
203*d9f75844SAndroid Build Coastguard Worker   PercentCounter(const PercentCounter&) = delete;
204*d9f75844SAndroid Build Coastguard Worker   PercentCounter& operator=(const PercentCounter&) = delete;
205*d9f75844SAndroid Build Coastguard Worker 
206*d9f75844SAndroid Build Coastguard Worker   void Add(bool sample);
207*d9f75844SAndroid Build Coastguard Worker 
208*d9f75844SAndroid Build Coastguard Worker  private:
209*d9f75844SAndroid Build Coastguard Worker   bool GetMetric(int* metric) const override;
210*d9f75844SAndroid Build Coastguard Worker   int GetValueForEmptyInterval() const override;
211*d9f75844SAndroid Build Coastguard Worker };
212*d9f75844SAndroid Build Coastguard Worker 
213*d9f75844SAndroid Build Coastguard Worker // PermilleCounter: permille of samples
214*d9f75844SAndroid Build Coastguard Worker //
215*d9f75844SAndroid Build Coastguard Worker //           | *      *      *      | *         *         | ...
216*d9f75844SAndroid Build Coastguard Worker //           | Add(T) Add(F) Add(T) | Add(F)    Add(T)    |
217*d9f75844SAndroid Build Coastguard Worker // GetMetric | 1000 *  2 / 3        | 1000 * 1 / 2        |
218*d9f75844SAndroid Build Coastguard Worker //
219*d9f75844SAndroid Build Coastguard Worker class PermilleCounter : public StatsCounter {
220*d9f75844SAndroid Build Coastguard Worker  public:
221*d9f75844SAndroid Build Coastguard Worker   PermilleCounter(Clock* clock, StatsCounterObserver* observer);
~PermilleCounter()222*d9f75844SAndroid Build Coastguard Worker   ~PermilleCounter() override {}
223*d9f75844SAndroid Build Coastguard Worker 
224*d9f75844SAndroid Build Coastguard Worker   PermilleCounter(const PermilleCounter&) = delete;
225*d9f75844SAndroid Build Coastguard Worker   PermilleCounter& operator=(const PermilleCounter&) = delete;
226*d9f75844SAndroid Build Coastguard Worker 
227*d9f75844SAndroid Build Coastguard Worker   void Add(bool sample);
228*d9f75844SAndroid Build Coastguard Worker 
229*d9f75844SAndroid Build Coastguard Worker  private:
230*d9f75844SAndroid Build Coastguard Worker   bool GetMetric(int* metric) const override;
231*d9f75844SAndroid Build Coastguard Worker   int GetValueForEmptyInterval() const override;
232*d9f75844SAndroid Build Coastguard Worker };
233*d9f75844SAndroid Build Coastguard Worker 
234*d9f75844SAndroid Build Coastguard Worker // RateCounter: units per second
235*d9f75844SAndroid Build Coastguard Worker //
236*d9f75844SAndroid Build Coastguard Worker //           | *      *      *      | *           *       | ...
237*d9f75844SAndroid Build Coastguard Worker //           | Add(5) Add(1) Add(6) | Add(5)      Add(5)  |
238*d9f75844SAndroid Build Coastguard Worker //           |<------ 2 sec ------->|                     |
239*d9f75844SAndroid Build Coastguard Worker // GetMetric | (5 + 1 + 6) / 2      | (5 + 5) / 2         |
240*d9f75844SAndroid Build Coastguard Worker //
241*d9f75844SAndroid Build Coastguard Worker // `include_empty_intervals`: If set, intervals without samples will be included
242*d9f75844SAndroid Build Coastguard Worker //                            in the stats. The value for an interval is
243*d9f75844SAndroid Build Coastguard Worker //                            determined by GetValueForEmptyInterval().
244*d9f75844SAndroid Build Coastguard Worker //
245*d9f75844SAndroid Build Coastguard Worker class RateCounter : public StatsCounter {
246*d9f75844SAndroid Build Coastguard Worker  public:
247*d9f75844SAndroid Build Coastguard Worker   RateCounter(Clock* clock,
248*d9f75844SAndroid Build Coastguard Worker               StatsCounterObserver* observer,
249*d9f75844SAndroid Build Coastguard Worker               bool include_empty_intervals);
~RateCounter()250*d9f75844SAndroid Build Coastguard Worker   ~RateCounter() override {}
251*d9f75844SAndroid Build Coastguard Worker 
252*d9f75844SAndroid Build Coastguard Worker   RateCounter(const RateCounter&) = delete;
253*d9f75844SAndroid Build Coastguard Worker   RateCounter& operator=(const RateCounter&) = delete;
254*d9f75844SAndroid Build Coastguard Worker 
255*d9f75844SAndroid Build Coastguard Worker   void Add(int sample);
256*d9f75844SAndroid Build Coastguard Worker 
257*d9f75844SAndroid Build Coastguard Worker  private:
258*d9f75844SAndroid Build Coastguard Worker   bool GetMetric(int* metric) const override;
259*d9f75844SAndroid Build Coastguard Worker   int GetValueForEmptyInterval() const override;  // Returns zero.
260*d9f75844SAndroid Build Coastguard Worker };
261*d9f75844SAndroid Build Coastguard Worker 
262*d9f75844SAndroid Build Coastguard Worker // RateAccCounter: units per second (used for counters)
263*d9f75844SAndroid Build Coastguard Worker //
264*d9f75844SAndroid Build Coastguard Worker //           | *      *      *      | *         *         | ...
265*d9f75844SAndroid Build Coastguard Worker //           | Set(5) Set(6) Set(8) | Set(11)   Set(13)   |
266*d9f75844SAndroid Build Coastguard Worker //           |<------ 2 sec ------->|                     |
267*d9f75844SAndroid Build Coastguard Worker // GetMetric | (8 - 0) / 2          | (13 - 8) / 2        |
268*d9f75844SAndroid Build Coastguard Worker //
269*d9f75844SAndroid Build Coastguard Worker // `include_empty_intervals`: If set, intervals without samples will be included
270*d9f75844SAndroid Build Coastguard Worker //                            in the stats. The value for an interval is
271*d9f75844SAndroid Build Coastguard Worker //                            determined by GetValueForEmptyInterval().
272*d9f75844SAndroid Build Coastguard Worker //
273*d9f75844SAndroid Build Coastguard Worker class RateAccCounter : public StatsCounter {
274*d9f75844SAndroid Build Coastguard Worker  public:
275*d9f75844SAndroid Build Coastguard Worker   RateAccCounter(Clock* clock,
276*d9f75844SAndroid Build Coastguard Worker                  StatsCounterObserver* observer,
277*d9f75844SAndroid Build Coastguard Worker                  bool include_empty_intervals);
~RateAccCounter()278*d9f75844SAndroid Build Coastguard Worker   ~RateAccCounter() override {}
279*d9f75844SAndroid Build Coastguard Worker 
280*d9f75844SAndroid Build Coastguard Worker   RateAccCounter(const RateAccCounter&) = delete;
281*d9f75844SAndroid Build Coastguard Worker   RateAccCounter& operator=(const RateAccCounter&) = delete;
282*d9f75844SAndroid Build Coastguard Worker 
283*d9f75844SAndroid Build Coastguard Worker   void Set(int64_t sample, uint32_t stream_id);
284*d9f75844SAndroid Build Coastguard Worker 
285*d9f75844SAndroid Build Coastguard Worker   // Sets the value for previous interval.
286*d9f75844SAndroid Build Coastguard Worker   // To be used if a value other than zero is initially required.
287*d9f75844SAndroid Build Coastguard Worker   void SetLast(int64_t sample, uint32_t stream_id);
288*d9f75844SAndroid Build Coastguard Worker 
289*d9f75844SAndroid Build Coastguard Worker  private:
290*d9f75844SAndroid Build Coastguard Worker   bool GetMetric(int* metric) const override;
291*d9f75844SAndroid Build Coastguard Worker   int GetValueForEmptyInterval() const override;  // Returns zero.
292*d9f75844SAndroid Build Coastguard Worker };
293*d9f75844SAndroid Build Coastguard Worker 
294*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
295*d9f75844SAndroid Build Coastguard Worker 
296*d9f75844SAndroid Build Coastguard Worker #endif  // VIDEO_STATS_COUNTER_H_
297