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