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 RTC_BASE_RATE_STATISTICS_H_ 12 #define RTC_BASE_RATE_STATISTICS_H_ 13 14 #include <stddef.h> 15 #include <stdint.h> 16 17 #include <deque> 18 #include <memory> 19 20 #include "absl/types/optional.h" 21 #include "rtc_base/system/rtc_export.h" 22 23 namespace webrtc { 24 25 // Class to estimate rates based on counts in a sequence of 1-millisecond 26 // intervals. 27 28 // This class uses int64 for all its numbers because some rates can be very 29 // high; for instance, a 20 Mbit/sec video stream can wrap a 32-bit byte 30 // counter in 14 minutes. 31 32 // Note that timestamps used in Update(), Rate() and SetWindowSize() must never 33 // decrease for two consecutive calls. 34 // TODO(bugs.webrtc.org/11600): Migrate from int64_t to Timestamp. 35 36 class RTC_EXPORT RateStatistics { 37 public: 38 static constexpr float kBpsScale = 8000.0f; 39 40 // max_window_size_ms = Maximum window size in ms for the rate estimation. 41 // Initial window size is set to this, but may be changed 42 // to something lower by calling SetWindowSize(). 43 // scale = coefficient to convert counts/ms to desired unit 44 // ex: kBpsScale (8000) for bits/s if count represents bytes. 45 RateStatistics(int64_t max_window_size_ms, float scale); 46 47 RateStatistics(const RateStatistics& other); 48 49 RateStatistics(RateStatistics&& other); 50 51 ~RateStatistics(); 52 53 // Reset instance to original state. 54 void Reset(); 55 56 // Update rate with a new data point, moving averaging window as needed. 57 void Update(int64_t count, int64_t now_ms); 58 59 // Note that despite this being a const method, it still updates the internal 60 // state (moves averaging window), but it doesn't make any alterations that 61 // are observable from the other methods, as long as supplied timestamps are 62 // from a monotonic clock. Ie, it doesn't matter if this call moves the 63 // window, since any subsequent call to Update or Rate would still have moved 64 // the window as much or more. 65 absl::optional<int64_t> Rate(int64_t now_ms) const; 66 67 // Update the size of the averaging window. The maximum allowed value for 68 // window_size_ms is max_window_size_ms as supplied in the constructor. 69 bool SetWindowSize(int64_t window_size_ms, int64_t now_ms); 70 71 private: 72 void EraseOld(int64_t now_ms); 73 74 struct Bucket { 75 explicit Bucket(int64_t timestamp); 76 int64_t sum; // Sum of all samples in this bucket. 77 int num_samples; // Number of samples in this bucket. 78 const int64_t timestamp; // Timestamp this bucket corresponds to. 79 }; 80 // All buckets within the time window, ordered by time. 81 std::deque<Bucket> buckets_; 82 83 // Total count recorded in all buckets. 84 int64_t accumulated_count_; 85 86 // Timestamp of the first data point seen, or -1 of none seen. 87 int64_t first_timestamp_; 88 89 // True if accumulated_count_ has ever grown too large to be 90 // contained in its integer type. 91 bool overflow_ = false; 92 93 // The total number of samples in the buckets. 94 int num_samples_; 95 96 // To convert counts/ms to desired units 97 const float scale_; 98 99 // The window sizes, in ms, over which the rate is calculated. 100 const int64_t max_window_size_ms_; 101 int64_t current_window_size_ms_; 102 }; 103 } // namespace webrtc 104 105 #endif // RTC_BASE_RATE_STATISTICS_H_ 106