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 "api/neteq/neteq.h" 18 #include "rtc_base/constructor_magic.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 // Resets most of the counters. 32 void Reset(); 33 34 // Resets the counters that are not handled by Reset(). 35 void ResetMcu(); 36 37 // Reports that |num_samples| samples were produced through expansion, and 38 // that the expansion produced other than just noise samples. 39 void ExpandedVoiceSamples(size_t num_samples, bool is_new_concealment_event); 40 41 // Reports that |num_samples| samples were produced through expansion, and 42 // that the expansion produced only noise samples. 43 void ExpandedNoiseSamples(size_t num_samples, bool is_new_concealment_event); 44 45 // Corrects the statistics for number of samples produced through non-noise 46 // expansion by adding |num_samples| (negative or positive) to the current 47 // value. The result is capped to zero to avoid negative values. 48 void ExpandedVoiceSamplesCorrection(int num_samples); 49 50 // Same as ExpandedVoiceSamplesCorrection but for noise samples. 51 void ExpandedNoiseSamplesCorrection(int num_samples); 52 53 void DecodedOutputPlayed(); 54 55 // Mark end of expand event; triggers some stats to be reported. 56 void EndExpandEvent(int fs_hz); 57 58 // Reports that |num_samples| samples were produced through preemptive 59 // expansion. 60 void PreemptiveExpandedSamples(size_t num_samples); 61 62 // Reports that |num_samples| samples were removed through accelerate. 63 void AcceleratedSamples(size_t num_samples); 64 65 // Reports that |num_samples| zeros were inserted into the output. 66 void AddZeros(size_t num_samples); 67 68 // Reports that |num_packets| packets were discarded. 69 virtual void PacketsDiscarded(size_t num_packets); 70 71 // Reports that |num_packets| secondary (FEC) packets were discarded. 72 virtual void SecondaryPacketsDiscarded(size_t num_packets); 73 74 // Reports that |num_packets| secondary (FEC) packets were received. 75 virtual void SecondaryPacketsReceived(size_t num_packets); 76 77 // Reports that |num_samples| were lost. 78 void LostSamples(size_t num_samples); 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 90 // Stores new packet waiting time in waiting time statistics. 91 void StoreWaitingTime(int waiting_time_ms); 92 93 // Reports that |num_samples| samples were decoded from secondary packets. 94 void SecondaryDecodedSamples(int num_samples); 95 96 // Reports that the packet buffer was flushed. 97 void FlushedPacketBuffer(); 98 99 // Reports that the jitter buffer received a packet. 100 void ReceivedPacket(); 101 102 // Reports that a received packet was delayed by |delay_ms| milliseconds. 103 virtual void RelativePacketArrivalDelay(size_t delay_ms); 104 105 // Logs a delayed packet outage event of |num_samples| expanded at a sample 106 // rate of |fs_hz|. A delayed packet outage event is defined as an expand 107 // period caused not by an actual packet loss, but by a delayed packet. 108 virtual void LogDelayedPacketOutageEvent(int num_samples, int fs_hz); 109 110 // Returns the current network statistics in |stats|. The current sample rate 111 // is |fs_hz|, the total number of samples in packet buffer and sync buffer 112 // yet to play out is |num_samples_in_buffers|, and the number of samples per 113 // packet is |samples_per_packet|. The method does not populate 114 // |preferred_buffer_size_ms|, |jitter_peaks_found| or |clockdrift_ppm|; use 115 // the PopulateDelayManagerStats method for those. 116 void GetNetworkStatistics(int fs_hz, 117 size_t num_samples_in_buffers, 118 size_t samples_per_packet, 119 NetEqNetworkStatistics* stats); 120 121 // Returns a copy of this class's lifetime statistics. These statistics are 122 // never reset. 123 NetEqLifetimeStatistics GetLifetimeStatistics() const; 124 125 NetEqOperationsAndState GetOperationsAndState() const; 126 127 private: 128 static const int kMaxReportPeriod = 60; // Seconds before auto-reset. 129 static const size_t kLenWaitingTimes = 100; 130 131 class PeriodicUmaLogger { 132 public: 133 PeriodicUmaLogger(const std::string& uma_name, 134 int report_interval_ms, 135 int max_value); 136 virtual ~PeriodicUmaLogger(); 137 void AdvanceClock(int step_ms); 138 139 protected: 140 void LogToUma(int value) const; 141 virtual int Metric() const = 0; 142 virtual void Reset() = 0; 143 144 const std::string uma_name_; 145 const int report_interval_ms_; 146 const int max_value_; 147 int timer_ = 0; 148 }; 149 150 class PeriodicUmaCount final : public PeriodicUmaLogger { 151 public: 152 PeriodicUmaCount(const std::string& uma_name, 153 int report_interval_ms, 154 int max_value); 155 ~PeriodicUmaCount() override; 156 void RegisterSample(); 157 158 protected: 159 int Metric() const override; 160 void Reset() override; 161 162 private: 163 int counter_ = 0; 164 }; 165 166 class PeriodicUmaAverage final : public PeriodicUmaLogger { 167 public: 168 PeriodicUmaAverage(const std::string& uma_name, 169 int report_interval_ms, 170 int max_value); 171 ~PeriodicUmaAverage() override; 172 void RegisterSample(int value); 173 174 protected: 175 int Metric() const override; 176 void Reset() override; 177 178 private: 179 double sum_ = 0.0; 180 int counter_ = 0; 181 }; 182 183 // Corrects the concealed samples counter in lifetime_stats_. The value of 184 // num_samples_ is added directly to the stat if the correction is positive. 185 // If the correction is negative, it is cached and will be subtracted against 186 // future additions to the counter. This is meant to be called from 187 // Expanded{Voice,Noise}Samples{Correction}. 188 void ConcealedSamplesCorrection(int num_samples, bool is_voice); 189 190 // Calculates numerator / denominator, and returns the value in Q14. 191 static uint16_t CalculateQ14Ratio(size_t numerator, uint32_t denominator); 192 193 NetEqLifetimeStatistics lifetime_stats_; 194 NetEqOperationsAndState operations_and_state_; 195 size_t concealed_samples_correction_ = 0; 196 size_t silent_concealed_samples_correction_ = 0; 197 size_t preemptive_samples_; 198 size_t accelerate_samples_; 199 size_t added_zero_samples_; 200 size_t expanded_speech_samples_; 201 size_t expanded_noise_samples_; 202 size_t concealed_samples_at_event_end_ = 0; 203 size_t discarded_packets_; 204 size_t lost_timestamps_; 205 uint32_t timestamps_since_last_report_; 206 std::deque<int> waiting_times_; 207 uint32_t secondary_decoded_samples_; 208 size_t discarded_secondary_packets_; 209 PeriodicUmaCount delayed_packet_outage_counter_; 210 PeriodicUmaAverage excess_buffer_delay_; 211 PeriodicUmaCount buffer_full_counter_; 212 bool decoded_output_played_ = false; 213 214 RTC_DISALLOW_COPY_AND_ASSIGN(StatisticsCalculator); 215 }; 216 217 } // namespace webrtc 218 #endif // MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_ 219