xref: /aosp_15_r20/external/webrtc/modules/audio_coding/neteq/statistics_calculator.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_
12 #define MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_
13 
14 #include <deque>
15 #include <string>
16 
17 #include "absl/strings/string_view.h"
18 #include "api/neteq/neteq.h"
19 
20 namespace webrtc {
21 
22 class DelayManager;
23 
24 // This class handles various network statistics in NetEq.
25 class StatisticsCalculator {
26  public:
27   StatisticsCalculator();
28 
29   virtual ~StatisticsCalculator();
30 
31   StatisticsCalculator(const StatisticsCalculator&) = delete;
32   StatisticsCalculator& operator=(const StatisticsCalculator&) = delete;
33 
34   // Resets most of the counters.
35   void Reset();
36 
37   // Resets the counters that are not handled by Reset().
38   void ResetMcu();
39 
40   // Reports that `num_samples` samples were produced through expansion, and
41   // that the expansion produced other than just noise samples.
42   void ExpandedVoiceSamples(size_t num_samples, bool is_new_concealment_event);
43 
44   // Reports that `num_samples` samples were produced through expansion, and
45   // that the expansion produced only noise samples.
46   void ExpandedNoiseSamples(size_t num_samples, bool is_new_concealment_event);
47 
48   // Corrects the statistics for number of samples produced through non-noise
49   // expansion by adding `num_samples` (negative or positive) to the current
50   // value. The result is capped to zero to avoid negative values.
51   void ExpandedVoiceSamplesCorrection(int num_samples);
52 
53   // Same as ExpandedVoiceSamplesCorrection but for noise samples.
54   void ExpandedNoiseSamplesCorrection(int num_samples);
55 
56   void DecodedOutputPlayed();
57 
58   // Mark end of expand event; triggers some stats to be reported.
59   void EndExpandEvent(int fs_hz);
60 
61   // Reports that `num_samples` samples were produced through preemptive
62   // expansion.
63   void PreemptiveExpandedSamples(size_t num_samples);
64 
65   // Reports that `num_samples` samples were removed through accelerate.
66   void AcceleratedSamples(size_t num_samples);
67 
68   // Reports that `num_samples` comfort noise samples were generated.
69   void GeneratedNoiseSamples(size_t num_samples);
70 
71   // Reports that `num_packets` packets were discarded.
72   virtual void PacketsDiscarded(size_t num_packets);
73 
74   // Reports that `num_packets` secondary (FEC) packets were discarded.
75   virtual void SecondaryPacketsDiscarded(size_t num_packets);
76 
77   // Reports that `num_packets` secondary (FEC) packets were received.
78   virtual void SecondaryPacketsReceived(size_t num_packets);
79 
80   // Increases the report interval counter with `num_samples` at a sample rate
81   // of `fs_hz`. This is how the StatisticsCalculator gets notified that current
82   // time is increasing.
83   void IncreaseCounter(size_t num_samples, int fs_hz);
84 
85   // Update jitter buffer delay counter.
86   void JitterBufferDelay(size_t num_samples,
87                          uint64_t waiting_time_ms,
88                          uint64_t target_delay_ms,
89                          uint64_t unlimited_target_delay_ms);
90 
91   // Stores new packet waiting time in waiting time statistics.
92   void StoreWaitingTime(int waiting_time_ms);
93 
94   // Reports that `num_samples` samples were decoded from secondary packets.
95   void SecondaryDecodedSamples(int num_samples);
96 
97   // Reports that the packet buffer was flushed.
98   void FlushedPacketBuffer();
99 
100   // Reports that the jitter buffer received a packet.
101   void ReceivedPacket();
102 
103   // Reports that a received packet was delayed by `delay_ms` milliseconds.
104   virtual void RelativePacketArrivalDelay(size_t delay_ms);
105 
106   // Logs a delayed packet outage event of `num_samples` expanded at a sample
107   // rate of `fs_hz`. A delayed packet outage event is defined as an expand
108   // period caused not by an actual packet loss, but by a delayed packet.
109   virtual void LogDelayedPacketOutageEvent(int num_samples, int fs_hz);
110 
111   // Returns the current network statistics in `stats`. The number of samples
112   // per packet is `samples_per_packet`. The method does not populate
113   // `preferred_buffer_size_ms`, `jitter_peaks_found` or `clockdrift_ppm`; use
114   // the PopulateDelayManagerStats method for those.
115   void GetNetworkStatistics(size_t samples_per_packet,
116                             NetEqNetworkStatistics* stats);
117 
118   // Returns a copy of this class's lifetime statistics. These statistics are
119   // never reset.
120   NetEqLifetimeStatistics GetLifetimeStatistics() const;
121 
122   NetEqOperationsAndState GetOperationsAndState() const;
123 
124  private:
125   static const int kMaxReportPeriod = 60;  // Seconds before auto-reset.
126   static const size_t kLenWaitingTimes = 100;
127 
128   class PeriodicUmaLogger {
129    public:
130     PeriodicUmaLogger(absl::string_view uma_name,
131                       int report_interval_ms,
132                       int max_value);
133     virtual ~PeriodicUmaLogger();
134     void AdvanceClock(int step_ms);
135 
136    protected:
137     void LogToUma(int value) const;
138     virtual int Metric() const = 0;
139     virtual void Reset() = 0;
140 
141     const std::string uma_name_;
142     const int report_interval_ms_;
143     const int max_value_;
144     int timer_ = 0;
145   };
146 
147   class PeriodicUmaCount final : public PeriodicUmaLogger {
148    public:
149     PeriodicUmaCount(absl::string_view uma_name,
150                      int report_interval_ms,
151                      int max_value);
152     ~PeriodicUmaCount() override;
153     void RegisterSample();
154 
155    protected:
156     int Metric() const override;
157     void Reset() override;
158 
159    private:
160     int counter_ = 0;
161   };
162 
163   class PeriodicUmaAverage final : public PeriodicUmaLogger {
164    public:
165     PeriodicUmaAverage(absl::string_view uma_name,
166                        int report_interval_ms,
167                        int max_value);
168     ~PeriodicUmaAverage() override;
169     void RegisterSample(int value);
170 
171    protected:
172     int Metric() const override;
173     void Reset() override;
174 
175    private:
176     double sum_ = 0.0;
177     int counter_ = 0;
178   };
179 
180   // Corrects the concealed samples counter in lifetime_stats_. The value of
181   // num_samples_ is added directly to the stat if the correction is positive.
182   // If the correction is negative, it is cached and will be subtracted against
183   // future additions to the counter. This is meant to be called from
184   // Expanded{Voice,Noise}Samples{Correction}.
185   void ConcealedSamplesCorrection(int num_samples, bool is_voice);
186 
187   // Calculates numerator / denominator, and returns the value in Q14.
188   static uint16_t CalculateQ14Ratio(size_t numerator, uint32_t denominator);
189 
190   NetEqLifetimeStatistics lifetime_stats_;
191   NetEqOperationsAndState operations_and_state_;
192   size_t concealed_samples_correction_ = 0;
193   size_t silent_concealed_samples_correction_ = 0;
194   size_t preemptive_samples_;
195   size_t accelerate_samples_;
196   size_t expanded_speech_samples_;
197   size_t expanded_noise_samples_;
198   size_t concealed_samples_at_event_end_ = 0;
199   uint32_t timestamps_since_last_report_;
200   std::deque<int> waiting_times_;
201   uint32_t secondary_decoded_samples_;
202   size_t discarded_secondary_packets_;
203   PeriodicUmaCount delayed_packet_outage_counter_;
204   PeriodicUmaAverage excess_buffer_delay_;
205   PeriodicUmaCount buffer_full_counter_;
206   bool decoded_output_played_ = false;
207 };
208 
209 }  // namespace webrtc
210 #endif  // MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_
211