| Index: content/browser/media/capture/feedback_signal_accumulator.cc
|
| diff --git a/content/browser/media/capture/feedback_signal_accumulator.cc b/content/browser/media/capture/feedback_signal_accumulator.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..43d6d833c71dcdc37038cba96f11f377aa3f8c33
|
| --- /dev/null
|
| +++ b/content/browser/media/capture/feedback_signal_accumulator.cc
|
| @@ -0,0 +1,56 @@
|
| +// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/browser/media/capture/feedback_signal_accumulator.h"
|
| +
|
| +#include <algorithm>
|
| +#include <cmath>
|
| +
|
| +namespace content {
|
| +
|
| +FeedbackSignalAccumulator::FeedbackSignalAccumulator(base::TimeDelta half_life)
|
| + : half_life_(half_life) {
|
| + DCHECK(half_life_ > base::TimeDelta());
|
| +}
|
| +
|
| +void FeedbackSignalAccumulator::Reset(double starting_value,
|
| + base::TimeTicks timestamp) {
|
| + DCHECK(!timestamp.is_null());
|
| + average_ = update_value_ = prior_average_ = starting_value;
|
| + reset_time_ = update_time_ = prior_update_time_ = timestamp;
|
| +}
|
| +
|
| +bool FeedbackSignalAccumulator::Update(double value,
|
| + base::TimeTicks timestamp) {
|
| + DCHECK(!reset_time_.is_null());
|
| +
|
| + if (timestamp < update_time_) {
|
| + return false; // Not in chronological order.
|
| + } else if (timestamp == update_time_) {
|
| + if (timestamp == reset_time_) {
|
| + // Edge case: Multiple updates at reset timestamp.
|
| + average_ = update_value_ = prior_average_ =
|
| + std::max(value, update_value_);
|
| + return true;
|
| + }
|
| + if (value <= update_value_)
|
| + return true;
|
| + update_value_ = value;
|
| + } else {
|
| + prior_average_ = average_;
|
| + prior_update_time_ = update_time_;
|
| + update_value_ = value;
|
| + update_time_ = timestamp;
|
| + }
|
| +
|
| + const double elapsed_us =
|
| + static_cast<double>((update_time_ - prior_update_time_).InMicroseconds());
|
| + const double weight = elapsed_us / (elapsed_us + half_life_.InMicroseconds());
|
| + average_ = weight * update_value_ + (1.0 - weight) * prior_average_;
|
| + DCHECK(std::isfinite(average_));
|
| +
|
| + return true;
|
| +}
|
| +
|
| +} // namespace content
|
|
|