Chromium Code Reviews| Index: webrtc/video/stats_counter.cc |
| diff --git a/webrtc/video/stats_counter.cc b/webrtc/video/stats_counter.cc |
| index 42d23adcfc60f71015e690090c8d779e47959421..604904a86b221287e2956196057efdf14b711dd5 100644 |
| --- a/webrtc/video/stats_counter.cc |
| +++ b/webrtc/video/stats_counter.cc |
| @@ -12,6 +12,7 @@ |
| #include <algorithm> |
| +#include "webrtc/base/checks.h" |
| #include "webrtc/system_wrappers/include/clock.h" |
| namespace webrtc { |
| @@ -24,11 +25,12 @@ const int64_t kProcessIntervalMs = 2000; |
| // Class holding periodically computed metrics. |
| class AggregatedCounter { |
| public: |
| - AggregatedCounter() : sum_(0) {} |
| + AggregatedCounter() : last_sample_(0), sum_samples_(0) {} |
| ~AggregatedCounter() {} |
| void Add(int sample) { |
| - sum_ += sample; |
| + last_sample_ = sample; |
| + sum_samples_ += sample; |
| ++stats_.num_samples; |
| if (stats_.num_samples == 1) { |
| stats_.min = sample; |
| @@ -43,14 +45,20 @@ class AggregatedCounter { |
| return stats_; |
| } |
| + bool HasSamples() const { return stats_.num_samples > 0; } |
|
stefan-webrtc
2016/09/08 07:28:14
Maybe call this Empty() instead to align with inte
åsapersson
2016/09/08 13:15:02
Done.
|
| + |
| + int last_sample() const { return last_sample_; } |
| + |
| private: |
| void Compute() { |
| if (stats_.num_samples == 0) |
| return; |
| - stats_.average = (sum_ + stats_.num_samples / 2) / stats_.num_samples; |
| + stats_.average = |
| + (sum_samples_ + stats_.num_samples / 2) / stats_.num_samples; |
| } |
| - int64_t sum_; |
| + int last_sample_; |
| + int64_t sum_samples_; |
| AggregatedStats stats_; |
| }; |
| @@ -62,11 +70,12 @@ StatsCounter::StatsCounter(Clock* clock, |
| sum_(0), |
| num_samples_(0), |
| last_sum_(0), |
| + aggregated_counter_(new AggregatedCounter()), |
| clock_(clock), |
| include_empty_intervals_(include_empty_intervals), |
| observer_(observer), |
| - aggregated_counter_(new AggregatedCounter()), |
| - last_process_time_ms_(-1) {} |
| + last_process_time_ms_(-1), |
| + paused_(false) {} |
| StatsCounter::~StatsCounter() {} |
| @@ -74,7 +83,19 @@ AggregatedStats StatsCounter::GetStats() { |
| return aggregated_counter_->ComputeStats(); |
| } |
| -bool StatsCounter::TimeToProcess() { |
| +AggregatedStats StatsCounter::ProcessAndGetStats() { |
| + if (last_process_time_ms_ != -1) |
| + TryProcess(); // At least one sample is added. |
| + return aggregated_counter_->ComputeStats(); |
| +} |
| + |
| +void StatsCounter::ProcessAndPause() { |
| + if (last_process_time_ms_ != -1) |
| + TryProcess(); // At least one sample is added. |
| + paused_ = true; |
| +} |
| + |
| +bool StatsCounter::TimeToProcess(int* elapsed_intervals) { |
| int64_t now = clock_->TimeInMilliseconds(); |
| if (last_process_time_ms_ == -1) |
| last_process_time_ms_ = now; |
| @@ -87,14 +108,7 @@ bool StatsCounter::TimeToProcess() { |
| int64_t num_intervals = diff_ms / kProcessIntervalMs; |
| last_process_time_ms_ += num_intervals * kProcessIntervalMs; |
| - // Add zero for intervals without samples. |
| - if (include_empty_intervals_) { |
| - for (int64_t i = 0; i < num_intervals - 1; ++i) { |
| - aggregated_counter_->Add(0); |
| - if (observer_) |
| - observer_->OnMetricUpdated(0); |
| - } |
| - } |
| + *elapsed_intervals = num_intervals; |
| return true; |
| } |
| @@ -102,6 +116,7 @@ void StatsCounter::Set(int sample) { |
| TryProcess(); |
| ++num_samples_; |
| sum_ = sample; |
| + paused_ = false; |
| } |
| void StatsCounter::Add(int sample) { |
| @@ -112,29 +127,56 @@ void StatsCounter::Add(int sample) { |
| if (num_samples_ == 1) |
| max_ = sample; |
| max_ = std::max(sample, max_); |
| + paused_ = false; |
| +} |
| + |
| +// Reports periodically computed metric. |
| +void StatsCounter::ReportMetricToAggregatedCounter( |
| + int value, |
| + int num_values_to_add) const { |
| + for (int i = 0; i < num_values_to_add; ++i) { |
| + aggregated_counter_->Add(value); |
| + if (observer_) |
| + observer_->OnMetricUpdated(value); |
| + } |
| } |
| void StatsCounter::TryProcess() { |
| - if (!TimeToProcess()) |
| + int elapsed_intervals; |
| + if (!TimeToProcess(&elapsed_intervals)) |
| return; |
| + // Get and report periodically computed metric. |
| int metric; |
| - if (GetMetric(&metric)) { |
| - aggregated_counter_->Add(metric); |
| - if (observer_) |
| - observer_->OnMetricUpdated(metric); |
| + if (GetMetric(&metric)) |
| + ReportMetricToAggregatedCounter(metric, 1); |
| + |
| + // Report value for elapsed intervals without samples. |
| + if (IncludeEmptyIntervals()) { |
| + int empty_intervals = |
| + (num_samples_ == 0) ? elapsed_intervals : (elapsed_intervals - 1); |
|
stefan-webrtc
2016/09/08 07:28:14
I don't follow this, maybe add a comment on why we
åsapersson
2016/09/08 13:15:02
Done.
|
| + ReportMetricToAggregatedCounter(GetValueForEmptyInterval(), |
| + empty_intervals); |
| } |
| - last_sum_ = sum_; |
| + |
| + // Reset samples for elapsed interval. |
| + if (num_samples_ > 0) |
| + last_sum_ = sum_; |
| sum_ = 0; |
| max_ = 0; |
| num_samples_ = 0; |
| } |
| +bool StatsCounter::IncludeEmptyIntervals() const { |
| + return include_empty_intervals_ && !paused_ && |
| + aggregated_counter_->HasSamples(); |
| +} |
| + |
| // StatsCounter sub-classes. |
| -AvgCounter::AvgCounter(Clock* clock, StatsCounterObserver* observer) |
| - : StatsCounter(clock, |
| - false, // |include_empty_intervals| |
| - observer) {} |
| +AvgCounter::AvgCounter(Clock* clock, |
| + StatsCounterObserver* observer, |
| + bool include_empty_intervals) |
| + : StatsCounter(clock, include_empty_intervals, observer) {} |
| void AvgCounter::Add(int sample) { |
| StatsCounter::Add(sample); |
| @@ -147,6 +189,10 @@ bool AvgCounter::GetMetric(int* metric) const { |
| return true; |
| } |
| +int AvgCounter::GetValueForEmptyInterval() const { |
| + return aggregated_counter_->last_sample(); |
| +} |
| + |
| MaxCounter::MaxCounter(Clock* clock, StatsCounterObserver* observer) |
| : StatsCounter(clock, |
| false, // |include_empty_intervals| |
| @@ -163,6 +209,11 @@ bool MaxCounter::GetMetric(int* metric) const { |
| return true; |
| } |
| +int MaxCounter::GetValueForEmptyInterval() const { |
| + RTC_NOTREACHED(); |
| + return 0; |
| +} |
| + |
| PercentCounter::PercentCounter(Clock* clock, StatsCounterObserver* observer) |
| : StatsCounter(clock, |
| false, // |include_empty_intervals| |
| @@ -179,6 +230,11 @@ bool PercentCounter::GetMetric(int* metric) const { |
| return true; |
| } |
| +int PercentCounter::GetValueForEmptyInterval() const { |
| + RTC_NOTREACHED(); |
| + return 0; |
| +} |
| + |
| PermilleCounter::PermilleCounter(Clock* clock, StatsCounterObserver* observer) |
| : StatsCounter(clock, |
| false, // |include_empty_intervals| |
| @@ -195,6 +251,11 @@ bool PermilleCounter::GetMetric(int* metric) const { |
| return true; |
| } |
| +int PermilleCounter::GetValueForEmptyInterval() const { |
| + RTC_NOTREACHED(); |
| + return 0; |
| +} |
| + |
| RateCounter::RateCounter(Clock* clock, |
| StatsCounterObserver* observer, |
| bool include_empty_intervals) |
| @@ -211,6 +272,10 @@ bool RateCounter::GetMetric(int* metric) const { |
| return true; |
| } |
| +int RateCounter::GetValueForEmptyInterval() const { |
| + return 0; |
| +} |
| + |
| RateAccCounter::RateAccCounter(Clock* clock, |
| StatsCounterObserver* observer, |
| bool include_empty_intervals) |
| @@ -228,4 +293,8 @@ bool RateAccCounter::GetMetric(int* metric) const { |
| return true; |
| } |
| +int RateAccCounter::GetValueForEmptyInterval() const { |
| + return 0; |
| +} |
| + |
| } // namespace webrtc |