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