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..584d79a8017140e003a0a8c37bd0b852f53a2667 100644 |
| --- a/webrtc/video/stats_counter.cc |
| +++ b/webrtc/video/stats_counter.cc |
| @@ -19,6 +19,47 @@ namespace webrtc { |
| namespace { |
| // Periodic time interval for processing samples. |
| const int64_t kProcessIntervalMs = 2000; |
| + |
| +int64_t Num(const std::map<uint32_t, StatsCounter::Samples>& samples) { |
| + int64_t num = 0; |
| + for (const auto& it : samples) |
| + num += it.second.num_; |
| + return num; |
| +} |
| + |
| +int64_t Sum(const std::map<uint32_t, StatsCounter::Samples>& samples) { |
| + int64_t sum = 0; |
| + for (const auto& it : samples) |
| + sum += it.second.sum_; |
| + return sum; |
| +} |
| + |
| +int Max(const std::map<uint32_t, StatsCounter::Samples>& samples) { |
| + int max = std::numeric_limits<int>::min(); |
| + for (const auto& it : samples) |
| + max = std::max(it.second.max_, max); |
| + return max; |
| +} |
| + |
| +void Reset(std::map<uint32_t, StatsCounter::Samples>* samples) { |
| + for (auto& it : *samples) |
| + it.second.Reset(); |
| +} |
| + |
| +int64_t Diff(const std::map<uint32_t, StatsCounter::Samples>& samples) { |
| + int64_t sum_diff = 0; |
| + int num = 0; |
| + for (const auto& it : samples) { |
| + if (it.second.num_ > 0) { |
| + int64_t diff = it.second.sum_ - it.second.last_sum_; |
| + if (diff >= 0) { |
| + sum_diff += diff; |
| + ++num; |
| + } |
| + } |
| + } |
| + return (num > 0) ? sum_diff : -1; |
| +} |
| } // namespace |
| // Class holding periodically computed metrics. |
| @@ -54,16 +95,32 @@ class AggregatedCounter { |
| AggregatedStats stats_; |
| }; |
| +// Gathered samples within a process interval. |
| +void StatsCounter::Samples::Add(int sample) { |
| + sum_ += sample; |
| + ++num_; |
| + max_ = std::max(sample, max_); |
| +} |
| + |
| +void StatsCounter::Samples::Set(int sample) { |
| + sum_ = sample; |
| + ++num_; |
| +} |
| + |
| +void StatsCounter::Samples::Reset() { |
| + if (num_ > 0) |
| + last_sum_ = sum_; |
| + sum_ = 0; |
| + num_ = 0; |
| + max_ = std::numeric_limits<int>::min(); |
| +} |
| + |
| // StatsCounter class. |
| StatsCounter::StatsCounter(Clock* clock, |
| bool include_empty_intervals, |
| StatsCounterObserver* observer) |
| - : max_(0), |
| - sum_(0), |
| - num_samples_(0), |
| - last_sum_(0), |
| + : include_empty_intervals_(include_empty_intervals), |
| clock_(clock), |
| - include_empty_intervals_(include_empty_intervals), |
| observer_(observer), |
| aggregated_counter_(new AggregatedCounter()), |
| last_process_time_ms_(-1) {} |
| @@ -98,20 +155,14 @@ bool StatsCounter::TimeToProcess() { |
| return true; |
| } |
| -void StatsCounter::Set(int sample) { |
| +void StatsCounter::Set(int sample, uint32_t ssrc) { |
| TryProcess(); |
| - ++num_samples_; |
| - sum_ = sample; |
| + samples_[ssrc].Set(sample); |
| } |
| void StatsCounter::Add(int sample) { |
| TryProcess(); |
| - ++num_samples_; |
| - sum_ += sample; |
| - |
| - if (num_samples_ == 1) |
| - max_ = sample; |
| - max_ = std::max(sample, max_); |
| + samples_[0].Add(sample); |
|
stefan-webrtc
2016/08/19 14:36:56
Is zero some default ssrc? I think it's also a val
åsapersson
2016/08/23 09:06:02
The ssrc can only be set for RateAccCounter (and n
stefan-webrtc
2016/09/08 07:13:34
Acknowledged.
|
| } |
| void StatsCounter::TryProcess() { |
| @@ -124,10 +175,8 @@ void StatsCounter::TryProcess() { |
| if (observer_) |
| observer_->OnMetricUpdated(metric); |
| } |
| - last_sum_ = sum_; |
| - sum_ = 0; |
| - max_ = 0; |
| - num_samples_ = 0; |
| + |
| + Reset(&samples_); |
| } |
| // StatsCounter sub-classes. |
| @@ -141,9 +190,11 @@ void AvgCounter::Add(int sample) { |
| } |
| bool AvgCounter::GetMetric(int* metric) const { |
| - if (num_samples_ == 0) |
| + int64_t num = Num(samples_); |
| + if (num == 0) |
| return false; |
| - *metric = (sum_ + num_samples_ / 2) / num_samples_; |
| + |
| + *metric = (Sum(samples_) + num / 2) / num; |
| return true; |
| } |
| @@ -157,9 +208,11 @@ void MaxCounter::Add(int sample) { |
| } |
| bool MaxCounter::GetMetric(int* metric) const { |
| - if (num_samples_ == 0) |
| + int64_t num = Num(samples_); |
| + if (num == 0) |
| return false; |
| - *metric = max_; |
| + |
| + *metric = Max(samples_); |
| return true; |
| } |
| @@ -173,9 +226,11 @@ void PercentCounter::Add(bool sample) { |
| } |
| bool PercentCounter::GetMetric(int* metric) const { |
| - if (num_samples_ == 0) |
| + int64_t num = Num(samples_); |
| + if (num == 0) |
| return false; |
| - *metric = (sum_ * 100 + num_samples_ / 2) / num_samples_; |
| + |
| + *metric = (Sum(samples_) * 100 + num / 2) / num; |
| return true; |
| } |
| @@ -189,9 +244,11 @@ void PermilleCounter::Add(bool sample) { |
| } |
| bool PermilleCounter::GetMetric(int* metric) const { |
| - if (num_samples_ == 0) |
| + int64_t num = Num(samples_); |
| + if (num == 0) |
| return false; |
| - *metric = (sum_ * 1000 + num_samples_ / 2) / num_samples_; |
| + |
| + *metric = (Sum(samples_) * 1000 + num / 2) / num; |
| return true; |
| } |
| @@ -205,9 +262,11 @@ void RateCounter::Add(int sample) { |
| } |
| bool RateCounter::GetMetric(int* metric) const { |
| - if (num_samples_ == 0) |
| + if (Num(samples_) == 0) |
| return false; |
| - *metric = (sum_ * 1000 + kProcessIntervalMs / 2) / kProcessIntervalMs; |
| + |
| + *metric = |
| + (Sum(samples_) * 1000 + kProcessIntervalMs / 2) / kProcessIntervalMs; |
| return true; |
| } |
| @@ -216,15 +275,19 @@ RateAccCounter::RateAccCounter(Clock* clock, |
| bool include_empty_intervals) |
| : StatsCounter(clock, include_empty_intervals, observer) {} |
| -void RateAccCounter::Set(int sample) { |
| - StatsCounter::Set(sample); |
| +void RateAccCounter::Set(int sample, uint32_t ssrc) { |
| + StatsCounter::Set(sample, ssrc); |
| } |
| bool RateAccCounter::GetMetric(int* metric) const { |
| - if (num_samples_ == 0 || last_sum_ > sum_) |
| + if (Num(samples_) == 0) |
| return false; |
| - *metric = |
| - ((sum_ - last_sum_) * 1000 + kProcessIntervalMs / 2) / kProcessIntervalMs; |
| + |
| + int64_t diff = Diff(samples_); |
| + if (diff < 0 || (!include_empty_intervals_ && diff == 0)) |
| + return false; |
| + |
| + *metric = (diff * 1000 + kProcessIntervalMs / 2) / kProcessIntervalMs; |
| return true; |
| } |