/* * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_ #define MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_ #include #include #include "absl/strings/string_view.h" #include "api/neteq/neteq.h" namespace webrtc { class DelayManager; // This class handles various network statistics in NetEq. class StatisticsCalculator { public: StatisticsCalculator(); virtual ~StatisticsCalculator(); StatisticsCalculator(const StatisticsCalculator&) = delete; StatisticsCalculator& operator=(const StatisticsCalculator&) = delete; // Resets most of the counters. void Reset(); // Resets the counters that are not handled by Reset(). void ResetMcu(); // Reports that `num_samples` samples were produced through expansion, and // that the expansion produced other than just noise samples. void ExpandedVoiceSamples(size_t num_samples, bool is_new_concealment_event); // Reports that `num_samples` samples were produced through expansion, and // that the expansion produced only noise samples. void ExpandedNoiseSamples(size_t num_samples, bool is_new_concealment_event); // Corrects the statistics for number of samples produced through non-noise // expansion by adding `num_samples` (negative or positive) to the current // value. The result is capped to zero to avoid negative values. void ExpandedVoiceSamplesCorrection(int num_samples); // Same as ExpandedVoiceSamplesCorrection but for noise samples. void ExpandedNoiseSamplesCorrection(int num_samples); void DecodedOutputPlayed(); // Mark end of expand event; triggers some stats to be reported. void EndExpandEvent(int fs_hz); // Reports that `num_samples` samples were produced through preemptive // expansion. void PreemptiveExpandedSamples(size_t num_samples); // Reports that `num_samples` samples were removed through accelerate. void AcceleratedSamples(size_t num_samples); // Reports that `num_samples` comfort noise samples were generated. void GeneratedNoiseSamples(size_t num_samples); // Reports that `num_packets` packets were discarded. virtual void PacketsDiscarded(size_t num_packets); // Reports that `num_packets` secondary (FEC) packets were discarded. virtual void SecondaryPacketsDiscarded(size_t num_packets); // Reports that `num_packets` secondary (FEC) packets were received. virtual void SecondaryPacketsReceived(size_t num_packets); // Increases the report interval counter with `num_samples` at a sample rate // of `fs_hz`. This is how the StatisticsCalculator gets notified that current // time is increasing. void IncreaseCounter(size_t num_samples, int fs_hz); // Update jitter buffer delay counter. void JitterBufferDelay(size_t num_samples, uint64_t waiting_time_ms, uint64_t target_delay_ms, uint64_t unlimited_target_delay_ms); // Stores new packet waiting time in waiting time statistics. void StoreWaitingTime(int waiting_time_ms); // Reports that `num_samples` samples were decoded from secondary packets. void SecondaryDecodedSamples(int num_samples); // Reports that the packet buffer was flushed. void FlushedPacketBuffer(); // Reports that the jitter buffer received a packet. void ReceivedPacket(); // Reports that a received packet was delayed by `delay_ms` milliseconds. virtual void RelativePacketArrivalDelay(size_t delay_ms); // Logs a delayed packet outage event of `num_samples` expanded at a sample // rate of `fs_hz`. A delayed packet outage event is defined as an expand // period caused not by an actual packet loss, but by a delayed packet. virtual void LogDelayedPacketOutageEvent(int num_samples, int fs_hz); // Returns the current network statistics in `stats`. The number of samples // per packet is `samples_per_packet`. The method does not populate // `preferred_buffer_size_ms`, `jitter_peaks_found` or `clockdrift_ppm`; use // the PopulateDelayManagerStats method for those. void GetNetworkStatistics(size_t samples_per_packet, NetEqNetworkStatistics* stats); // Returns a copy of this class's lifetime statistics. These statistics are // never reset. NetEqLifetimeStatistics GetLifetimeStatistics() const; NetEqOperationsAndState GetOperationsAndState() const; private: static const int kMaxReportPeriod = 60; // Seconds before auto-reset. static const size_t kLenWaitingTimes = 100; class PeriodicUmaLogger { public: PeriodicUmaLogger(absl::string_view uma_name, int report_interval_ms, int max_value); virtual ~PeriodicUmaLogger(); void AdvanceClock(int step_ms); protected: void LogToUma(int value) const; virtual int Metric() const = 0; virtual void Reset() = 0; const std::string uma_name_; const int report_interval_ms_; const int max_value_; int timer_ = 0; }; class PeriodicUmaCount final : public PeriodicUmaLogger { public: PeriodicUmaCount(absl::string_view uma_name, int report_interval_ms, int max_value); ~PeriodicUmaCount() override; void RegisterSample(); protected: int Metric() const override; void Reset() override; private: int counter_ = 0; }; class PeriodicUmaAverage final : public PeriodicUmaLogger { public: PeriodicUmaAverage(absl::string_view uma_name, int report_interval_ms, int max_value); ~PeriodicUmaAverage() override; void RegisterSample(int value); protected: int Metric() const override; void Reset() override; private: double sum_ = 0.0; int counter_ = 0; }; // Corrects the concealed samples counter in lifetime_stats_. The value of // num_samples_ is added directly to the stat if the correction is positive. // If the correction is negative, it is cached and will be subtracted against // future additions to the counter. This is meant to be called from // Expanded{Voice,Noise}Samples{Correction}. void ConcealedSamplesCorrection(int num_samples, bool is_voice); // Calculates numerator / denominator, and returns the value in Q14. static uint16_t CalculateQ14Ratio(size_t numerator, uint32_t denominator); NetEqLifetimeStatistics lifetime_stats_; NetEqOperationsAndState operations_and_state_; size_t concealed_samples_correction_ = 0; size_t silent_concealed_samples_correction_ = 0; size_t preemptive_samples_; size_t accelerate_samples_; size_t expanded_speech_samples_; size_t expanded_noise_samples_; size_t concealed_samples_at_event_end_ = 0; uint32_t timestamps_since_last_report_; std::deque waiting_times_; uint32_t secondary_decoded_samples_; size_t discarded_secondary_packets_; PeriodicUmaCount delayed_packet_outage_counter_; PeriodicUmaAverage excess_buffer_delay_; PeriodicUmaCount buffer_full_counter_; bool decoded_output_played_ = false; }; } // namespace webrtc #endif // MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_