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 WEBRTC_MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_
12 #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_
13 
14 #include <deque>
15 #include <string>
16 
17 #include "webrtc/base/constructormagic.h"
18 #include "webrtc/modules/audio_coding/neteq/include/neteq.h"
19 #include "webrtc/typedefs.h"
20 
21 namespace webrtc {
22 
23 // Forward declarations.
24 class DecisionLogic;
25 class DelayManager;
26 
27 // This class handles various network statistics in NetEq.
28 class StatisticsCalculator {
29  public:
30   StatisticsCalculator();
31 
32   virtual ~StatisticsCalculator();
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);
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);
47 
48   // Reports that |num_samples| samples were produced through preemptive
49   // expansion.
50   void PreemptiveExpandedSamples(size_t num_samples);
51 
52   // Reports that |num_samples| samples were removed through accelerate.
53   void AcceleratedSamples(size_t num_samples);
54 
55   // Reports that |num_samples| zeros were inserted into the output.
56   void AddZeros(size_t num_samples);
57 
58   // Reports that |num_packets| packets were discarded.
59   void PacketsDiscarded(size_t num_packets);
60 
61   // Reports that |num_samples| were lost.
62   void LostSamples(size_t num_samples);
63 
64   // Increases the report interval counter with |num_samples| at a sample rate
65   // of |fs_hz|. This is how the StatisticsCalculator gets notified that current
66   // time is increasing.
67   void IncreaseCounter(size_t num_samples, int fs_hz);
68 
69   // Stores new packet waiting time in waiting time statistics.
70   void StoreWaitingTime(int waiting_time_ms);
71 
72   // Reports that |num_samples| samples were decoded from secondary packets.
73   void SecondaryDecodedSamples(int num_samples);
74 
75   // Logs a delayed packet outage event of |outage_duration_ms|. A delayed
76   // packet outage event is defined as an expand period caused not by an actual
77   // packet loss, but by a delayed packet.
78   virtual void LogDelayedPacketOutageEvent(int outage_duration_ms);
79 
80   // Returns the current network statistics in |stats|. The current sample rate
81   // is |fs_hz|, the total number of samples in packet buffer and sync buffer
82   // yet to play out is |num_samples_in_buffers|, and the number of samples per
83   // packet is |samples_per_packet|.
84   void GetNetworkStatistics(int fs_hz,
85                             size_t num_samples_in_buffers,
86                             size_t samples_per_packet,
87                             const DelayManager& delay_manager,
88                             const DecisionLogic& decision_logic,
89                             NetEqNetworkStatistics *stats);
90 
91  private:
92   static const int kMaxReportPeriod = 60;  // Seconds before auto-reset.
93   static const size_t kLenWaitingTimes = 100;
94 
95   class PeriodicUmaLogger {
96    public:
97     PeriodicUmaLogger(const std::string& uma_name,
98                       int report_interval_ms,
99                       int max_value);
100     virtual ~PeriodicUmaLogger();
101     void AdvanceClock(int step_ms);
102 
103    protected:
104     void LogToUma(int value) const;
105     virtual int Metric() const = 0;
106     virtual void Reset() = 0;
107 
108     const std::string uma_name_;
109     const int report_interval_ms_;
110     const int max_value_;
111     int timer_ = 0;
112   };
113 
114   class PeriodicUmaCount final : public PeriodicUmaLogger {
115    public:
116     PeriodicUmaCount(const std::string& uma_name,
117                      int report_interval_ms,
118                      int max_value);
119     ~PeriodicUmaCount() override;
120     void RegisterSample();
121 
122    protected:
123     int Metric() const override;
124     void Reset() override;
125 
126    private:
127     int counter_ = 0;
128   };
129 
130   class PeriodicUmaAverage final : public PeriodicUmaLogger {
131    public:
132     PeriodicUmaAverage(const std::string& uma_name,
133                        int report_interval_ms,
134                        int max_value);
135     ~PeriodicUmaAverage() override;
136     void RegisterSample(int value);
137 
138    protected:
139     int Metric() const override;
140     void Reset() override;
141 
142    private:
143     double sum_ = 0.0;
144     int counter_ = 0;
145   };
146 
147   // Calculates numerator / denominator, and returns the value in Q14.
148   static uint16_t CalculateQ14Ratio(size_t numerator, uint32_t denominator);
149 
150   size_t preemptive_samples_;
151   size_t accelerate_samples_;
152   size_t added_zero_samples_;
153   size_t expanded_speech_samples_;
154   size_t expanded_noise_samples_;
155   size_t discarded_packets_;
156   size_t lost_timestamps_;
157   uint32_t timestamps_since_last_report_;
158   std::deque<int> waiting_times_;
159   uint32_t secondary_decoded_samples_;
160   PeriodicUmaCount delayed_packet_outage_counter_;
161   PeriodicUmaAverage excess_buffer_delay_;
162 
163   RTC_DISALLOW_COPY_AND_ASSIGN(StatisticsCalculator);
164 };
165 
166 }  // namespace webrtc
167 #endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_
168