#ifndef MEDIA_GPU_EXPONENTIAL_MOVING_AVERAGE_H_
#define MEDIA_GPU_EXPONENTIAL_MOVING_AVERAGE_H_
#include <algorithm>
#include <memory>
#include "base/time/time.h"
#include "media/gpu/media_gpu_export.h"
namespace media {
class MEDIA_GPU_EXPORT ExponentialMovingAverage {
public:
explicit ExponentialMovingAverage(base::TimeDelta max_window_size);
~ExponentialMovingAverage();
ExponentialMovingAverage(const ExponentialMovingAverage& other) = delete;
ExponentialMovingAverage& operator=(const ExponentialMovingAverage& other) =
delete;
base::TimeDelta curr_window_size() const { return curr_window_size_; }
base::TimeDelta max_window_size() const { return max_window_size_; }
float mean() const { return mean_; }
void update_max_window_size(base::TimeDelta max_window_size) {
max_window_size_ = max_window_size;
}
template <typename T>
void AddValue(T value, base::TimeDelta elapsed_time) {
float float_value = static_cast<float>(value);
curr_window_size_ = std::clamp(curr_window_size_ + elapsed_time,
base::Milliseconds(1), max_window_size_);
float alpha = static_cast<float>(std::min(
elapsed_time.InMillisecondsF() / curr_window_size_.InMillisecondsF(),
1.0));
mean_ += alpha * (float_value - mean_);
mean_square_ += alpha * (float_value * float_value - mean_square_);
}
float GetStdDeviation() const;
private:
float mean_ = 0.0f;
float mean_square_ = 0.0f;
base::TimeDelta curr_window_size_;
base::TimeDelta max_window_size_;
};
}
#endif