| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  *  Copyright (c) 2016 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 #include "webrtc/video/stats_counter.h" | 
|  | 12 | 
|  | 13 #include <algorithm> | 
|  | 14 | 
|  | 15 #include "webrtc/system_wrappers/include/clock.h" | 
|  | 16 | 
|  | 17 namespace webrtc { | 
|  | 18 | 
|  | 19 namespace { | 
|  | 20 // Periodic time interval for processing samples. | 
|  | 21 const int64_t kProcessIntervalMs = 2000; | 
|  | 22 }  // namespace | 
|  | 23 | 
|  | 24 // Class holding periodically computed metrics. | 
|  | 25 class AggregatedCounter { | 
|  | 26  public: | 
|  | 27   AggregatedCounter() : sum_(0) {} | 
|  | 28   ~AggregatedCounter() {} | 
|  | 29 | 
|  | 30   void Add(int sample) { | 
|  | 31     sum_ += sample; | 
|  | 32     ++stats_.num_samples; | 
|  | 33     if (stats_.num_samples == 1) { | 
|  | 34       stats_.min = sample; | 
|  | 35       stats_.max = sample; | 
|  | 36     } | 
|  | 37     stats_.min = std::min(sample, stats_.min); | 
|  | 38     stats_.max = std::max(sample, stats_.max); | 
|  | 39   } | 
|  | 40 | 
|  | 41   AggregatedStats ComputeStats() { | 
|  | 42     Compute(); | 
|  | 43     return stats_; | 
|  | 44   } | 
|  | 45 | 
|  | 46  private: | 
|  | 47   void Compute() { | 
|  | 48     if (stats_.num_samples == 0) | 
|  | 49       return; | 
|  | 50 | 
|  | 51     stats_.average = (sum_ + stats_.num_samples / 2) / stats_.num_samples; | 
|  | 52   } | 
|  | 53   int64_t sum_; | 
|  | 54   AggregatedStats stats_; | 
|  | 55 }; | 
|  | 56 | 
|  | 57 // StatsCounter class. | 
|  | 58 StatsCounter::StatsCounter(Clock* clock, | 
|  | 59                            bool include_empty_intervals, | 
|  | 60                            StatsCounterObserver* observer) | 
|  | 61     : max_(0), | 
|  | 62       sum_(0), | 
|  | 63       num_samples_(0), | 
|  | 64       last_sum_(0), | 
|  | 65       clock_(clock), | 
|  | 66       include_empty_intervals_(include_empty_intervals), | 
|  | 67       observer_(observer), | 
|  | 68       aggregated_counter_(new AggregatedCounter()), | 
|  | 69       last_process_time_ms_(-1) {} | 
|  | 70 | 
|  | 71 StatsCounter::~StatsCounter() {} | 
|  | 72 | 
|  | 73 AggregatedStats StatsCounter::GetStats() { | 
|  | 74   return aggregated_counter_->ComputeStats(); | 
|  | 75 } | 
|  | 76 | 
|  | 77 bool StatsCounter::TimeToProcess() { | 
|  | 78   int64_t now = clock_->TimeInMilliseconds(); | 
|  | 79   if (last_process_time_ms_ == -1) | 
|  | 80     last_process_time_ms_ = now; | 
|  | 81 | 
|  | 82   int64_t diff_ms = now - last_process_time_ms_; | 
|  | 83   if (diff_ms < kProcessIntervalMs) | 
|  | 84     return false; | 
|  | 85 | 
|  | 86   // Advance number of complete kProcessIntervalMs that have passed. | 
|  | 87   int64_t num_intervals = diff_ms / kProcessIntervalMs; | 
|  | 88   last_process_time_ms_ += num_intervals * kProcessIntervalMs; | 
|  | 89 | 
|  | 90   // Add zero for intervals without samples. | 
|  | 91   if (include_empty_intervals_) { | 
|  | 92     for (int64_t i = 0; i < num_intervals - 1; ++i) { | 
|  | 93       aggregated_counter_->Add(0); | 
|  | 94       if (observer_) | 
|  | 95         observer_->OnMetricUpdated(0); | 
|  | 96     } | 
|  | 97   } | 
|  | 98   return true; | 
|  | 99 } | 
|  | 100 | 
|  | 101 void StatsCounter::Set(int sample) { | 
|  | 102   TryProcess(); | 
|  | 103   ++num_samples_; | 
|  | 104   sum_ = sample; | 
|  | 105 } | 
|  | 106 | 
|  | 107 void StatsCounter::Add(int sample) { | 
|  | 108   TryProcess(); | 
|  | 109   ++num_samples_; | 
|  | 110   sum_ += sample; | 
|  | 111 | 
|  | 112   if (num_samples_ == 1) | 
|  | 113     max_ = sample; | 
|  | 114   max_ = std::max(sample, max_); | 
|  | 115 } | 
|  | 116 | 
|  | 117 void StatsCounter::TryProcess() { | 
|  | 118   if (!TimeToProcess()) | 
|  | 119     return; | 
|  | 120 | 
|  | 121   int metric; | 
|  | 122   if (GetMetric(&metric)) { | 
|  | 123     aggregated_counter_->Add(metric); | 
|  | 124     if (observer_) | 
|  | 125       observer_->OnMetricUpdated(metric); | 
|  | 126   } | 
|  | 127   last_sum_ = sum_; | 
|  | 128   sum_ = 0; | 
|  | 129   max_ = 0; | 
|  | 130   num_samples_ = 0; | 
|  | 131 } | 
|  | 132 | 
|  | 133 // StatsCounter sub-classes. | 
|  | 134 AvgCounter::AvgCounter(Clock* clock, StatsCounterObserver* observer) | 
|  | 135     : StatsCounter(clock, | 
|  | 136                    false,  // |include_empty_intervals| | 
|  | 137                    observer) {} | 
|  | 138 | 
|  | 139 void AvgCounter::Add(int sample) { | 
|  | 140   StatsCounter::Add(sample); | 
|  | 141 } | 
|  | 142 | 
|  | 143 bool AvgCounter::GetMetric(int* metric) const { | 
|  | 144   if (num_samples_ == 0) | 
|  | 145     return false; | 
|  | 146   *metric = (sum_ + num_samples_ / 2) / num_samples_; | 
|  | 147   return true; | 
|  | 148 } | 
|  | 149 | 
|  | 150 MaxCounter::MaxCounter(Clock* clock, StatsCounterObserver* observer) | 
|  | 151     : StatsCounter(clock, | 
|  | 152                    false,  // |include_empty_intervals| | 
|  | 153                    observer) {} | 
|  | 154 | 
|  | 155 void MaxCounter::Add(int sample) { | 
|  | 156   StatsCounter::Add(sample); | 
|  | 157 } | 
|  | 158 | 
|  | 159 bool MaxCounter::GetMetric(int* metric) const { | 
|  | 160   if (num_samples_ == 0) | 
|  | 161     return false; | 
|  | 162   *metric = max_; | 
|  | 163   return true; | 
|  | 164 } | 
|  | 165 | 
|  | 166 PercentCounter::PercentCounter(Clock* clock, StatsCounterObserver* observer) | 
|  | 167     : StatsCounter(clock, | 
|  | 168                    false,  // |include_empty_intervals| | 
|  | 169                    observer) {} | 
|  | 170 | 
|  | 171 void PercentCounter::Add(bool sample) { | 
|  | 172   StatsCounter::Add(sample ? 1 : 0); | 
|  | 173 } | 
|  | 174 | 
|  | 175 bool PercentCounter::GetMetric(int* metric) const { | 
|  | 176   if (num_samples_ == 0) | 
|  | 177     return false; | 
|  | 178   *metric = (sum_ * 100 + num_samples_ / 2) / num_samples_; | 
|  | 179   return true; | 
|  | 180 } | 
|  | 181 | 
|  | 182 PermilleCounter::PermilleCounter(Clock* clock, StatsCounterObserver* observer) | 
|  | 183     : StatsCounter(clock, | 
|  | 184                    false,  // |include_empty_intervals| | 
|  | 185                    observer) {} | 
|  | 186 | 
|  | 187 void PermilleCounter::Add(bool sample) { | 
|  | 188   StatsCounter::Add(sample ? 1 : 0); | 
|  | 189 } | 
|  | 190 | 
|  | 191 bool PermilleCounter::GetMetric(int* metric) const { | 
|  | 192   if (num_samples_ == 0) | 
|  | 193     return false; | 
|  | 194   *metric = (sum_ * 1000 + num_samples_ / 2) / num_samples_; | 
|  | 195   return true; | 
|  | 196 } | 
|  | 197 | 
|  | 198 RateCounter::RateCounter(Clock* clock, StatsCounterObserver* observer) | 
|  | 199     : StatsCounter(clock, | 
|  | 200                    true,  // |include_empty_intervals| | 
|  | 201                    observer) {} | 
|  | 202 | 
|  | 203 void RateCounter::Add(int sample) { | 
|  | 204   StatsCounter::Add(sample); | 
|  | 205 } | 
|  | 206 | 
|  | 207 bool RateCounter::GetMetric(int* metric) const { | 
|  | 208   if (num_samples_ == 0) | 
|  | 209     return false; | 
|  | 210   *metric = (sum_ * 1000 + kProcessIntervalMs / 2) / kProcessIntervalMs; | 
|  | 211   return true; | 
|  | 212 } | 
|  | 213 | 
|  | 214 RateAccCounter::RateAccCounter(Clock* clock, StatsCounterObserver* observer) | 
|  | 215     : StatsCounter(clock, | 
|  | 216                    true,  // |include_empty_intervals| | 
|  | 217                    observer) {} | 
|  | 218 | 
|  | 219 void RateAccCounter::Set(int sample) { | 
|  | 220   StatsCounter::Set(sample); | 
|  | 221 } | 
|  | 222 | 
|  | 223 bool RateAccCounter::GetMetric(int* metric) const { | 
|  | 224   if (num_samples_ == 0 || last_sum_ > sum_) | 
|  | 225     return false; | 
|  | 226   *metric = | 
|  | 227       ((sum_ - last_sum_) * 1000 + kProcessIntervalMs / 2) / kProcessIntervalMs; | 
|  | 228   return true; | 
|  | 229 } | 
|  | 230 | 
|  | 231 }  // namespace webrtc | 
| OLD | NEW | 
|---|