Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(404)

Unified Diff: content/browser/media/capture/time_weighted_average.cc

Issue 1097633005: FeedbackSignalAccumulator utility class for averaging feedback signals (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/media/capture/time_weighted_average.cc
diff --git a/content/browser/media/capture/time_weighted_average.cc b/content/browser/media/capture/time_weighted_average.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f402ac006892d97fce77f1af4927fcfc9ced18be
--- /dev/null
+++ b/content/browser/media/capture/time_weighted_average.cc
@@ -0,0 +1,93 @@
+// 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/time_weighted_average.h"
+
+#include <cmath>
+
+namespace content {
+
+TimeWeightedAverage::TimeWeightedAverage(base::TimeDelta time_constant)
+ : time_constant_(time_constant) {
+ DCHECK(time_constant_ > base::TimeDelta());
+}
+
+void TimeWeightedAverage::Reset(double starting_value,
+ base::TimeTicks timestamp) {
+ DCHECK(!timestamp.is_null());
+ last_reset_time_ = timestamp;
+ average_ = starting_value;
+ most_recent_value_ = starting_value;
+ most_recent_count_ = 1;
+ most_recent_timestamp_ = timestamp;
+ second_most_recent_timestamp_ = timestamp;
+}
+
+bool TimeWeightedAverage::Update(double value, base::TimeTicks timestamp) {
+ DCHECK(!last_reset_time_.is_null());
+
+ // Edge case: Multiple updates at reset timestamp.
+ if (timestamp == last_reset_time_) {
+ MergeWithMostRecentDataPoint(value);
+ average_ = most_recent_value_;
+ return true;
+ }
+
+ if (timestamp <= second_most_recent_timestamp_)
+ return false; // Timestamp is too out-of-order, or before last reset.
+
+ // If |timestamp| is one step out-of-order, step the moving average back to
+ // its prior state, then forward with this update.
+ if (timestamp <= most_recent_timestamp_) {
+ StepBackward(most_recent_value_,
+ most_recent_timestamp_ - second_most_recent_timestamp_);
+
+ if (timestamp < most_recent_timestamp_) {
+ StepForward(value, timestamp - second_most_recent_timestamp_);
+ second_most_recent_timestamp_ = timestamp;
+ } else /* if (timestamp == most_recent_timestamp_) */ {
+ MergeWithMostRecentDataPoint(value);
+ }
+ } else {
+ second_most_recent_timestamp_ = most_recent_timestamp_;
+ most_recent_value_ = value;
+ most_recent_count_ = 1;
+ most_recent_timestamp_ = timestamp;
+ }
+
+ // Step the moving average forward using the latest update.
+ StepForward(most_recent_value_,
+ most_recent_timestamp_ - second_most_recent_timestamp_);
+
+ return true;
+}
+
+void TimeWeightedAverage::StepBackward(double last_value,
+ base::TimeDelta elapsed) {
+ const double elapsed_us = static_cast<double>(elapsed.InMicroseconds());
+ const double weight =
+ elapsed_us / (elapsed_us + time_constant_.InMicroseconds());
+ DCHECK_GE(weight, 0.0);
+ DCHECK_LT(weight, 1.0);
+ average_ -= weight * last_value;
+ average_ /= 1.0 - weight;
+ DCHECK(std::isfinite(average_));
+}
+
+void TimeWeightedAverage::StepForward(double next_value,
+ base::TimeDelta elapsed) {
+ const double elapsed_us = static_cast<double>(elapsed.InMicroseconds());
+ const double weight =
+ elapsed_us / (elapsed_us + time_constant_.InMicroseconds());
+ average_ = weight * next_value + (1.0 - weight) * average_;
+ DCHECK(std::isfinite(average_));
+}
+
+void TimeWeightedAverage::MergeWithMostRecentDataPoint(double value) {
+ most_recent_value_ = (most_recent_count_ * most_recent_value_ + value) /
+ (most_recent_count_ + 1);
+ ++most_recent_count_;
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698