mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 22:00:47 +01:00
Move MovingAverage to rtc_base/numerics and update it.
This utility class is needed in rtcp_rtp. Instead of reimplementing it again, the existing class is moved to rtc_base, cleaned from unused features and extended as required for the new usage. Bug: webrtc:9914 Change-Id: I3b0d83d08d8fa5e1384b4721a93c6a90781948fd Reviewed-on: https://webrtc-review.googlesource.com/c/109081 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Åsa Persson <asapersson@webrtc.org> Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25498}
This commit is contained in:
parent
a1ead6f2ab
commit
26341990a1
10 changed files with 229 additions and 161 deletions
|
@ -240,8 +240,6 @@ rtc_source_set("video_coding_utility") {
|
||||||
"utility/framerate_controller.h",
|
"utility/framerate_controller.h",
|
||||||
"utility/ivf_file_writer.cc",
|
"utility/ivf_file_writer.cc",
|
||||||
"utility/ivf_file_writer.h",
|
"utility/ivf_file_writer.h",
|
||||||
"utility/moving_average.cc",
|
|
||||||
"utility/moving_average.h",
|
|
||||||
"utility/quality_scaler.cc",
|
"utility/quality_scaler.cc",
|
||||||
"utility/quality_scaler.h",
|
"utility/quality_scaler.h",
|
||||||
"utility/simulcast_rate_allocator.cc",
|
"utility/simulcast_rate_allocator.cc",
|
||||||
|
@ -858,7 +856,6 @@ if (rtc_include_tests) {
|
||||||
"utility/frame_dropper_unittest.cc",
|
"utility/frame_dropper_unittest.cc",
|
||||||
"utility/framerate_controller_unittest.cc",
|
"utility/framerate_controller_unittest.cc",
|
||||||
"utility/ivf_file_writer_unittest.cc",
|
"utility/ivf_file_writer_unittest.cc",
|
||||||
"utility/moving_average_unittest.cc",
|
|
||||||
"utility/quality_scaler_unittest.cc",
|
"utility/quality_scaler_unittest.cc",
|
||||||
"utility/simulcast_rate_allocator_unittest.cc",
|
"utility/simulcast_rate_allocator_unittest.cc",
|
||||||
"video_codec_initializer_unittest.cc",
|
"video_codec_initializer_unittest.cc",
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "modules/video_coding/utility/moving_average.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
MovingAverage::MovingAverage(size_t s) : sum_history_(s + 1, 0) {}
|
|
||||||
MovingAverage::~MovingAverage() = default;
|
|
||||||
|
|
||||||
void MovingAverage::AddSample(int sample) {
|
|
||||||
count_++;
|
|
||||||
sum_ += sample;
|
|
||||||
sum_history_[count_ % sum_history_.size()] = sum_;
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::optional<int> MovingAverage::GetAverage() const {
|
|
||||||
return GetAverage(size());
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::optional<int> MovingAverage::GetAverage(size_t num_samples) const {
|
|
||||||
if (num_samples > size() || num_samples == 0)
|
|
||||||
return absl::nullopt;
|
|
||||||
int sum = sum_ - sum_history_[(count_ - num_samples) % sum_history_.size()];
|
|
||||||
return sum / static_cast<int>(num_samples);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MovingAverage::Reset() {
|
|
||||||
count_ = 0;
|
|
||||||
sum_ = 0;
|
|
||||||
std::fill(sum_history_.begin(), sum_history_.end(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t MovingAverage::size() const {
|
|
||||||
return std::min(count_, sum_history_.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MODULES_VIDEO_CODING_UTILITY_MOVING_AVERAGE_H_
|
|
||||||
#define MODULES_VIDEO_CODING_UTILITY_MOVING_AVERAGE_H_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "absl/types/optional.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
class MovingAverage {
|
|
||||||
public:
|
|
||||||
explicit MovingAverage(size_t s);
|
|
||||||
~MovingAverage();
|
|
||||||
void AddSample(int sample);
|
|
||||||
absl::optional<int> GetAverage() const;
|
|
||||||
absl::optional<int> GetAverage(size_t num_samples) const;
|
|
||||||
void Reset();
|
|
||||||
size_t size() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t count_ = 0;
|
|
||||||
int sum_ = 0;
|
|
||||||
std::vector<int> sum_history_;
|
|
||||||
};
|
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // MODULES_VIDEO_CODING_UTILITY_MOVING_AVERAGE_H_
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "modules/video_coding/utility/moving_average.h"
|
|
||||||
|
|
||||||
#include "test/gtest.h"
|
|
||||||
|
|
||||||
TEST(MovingAverageTest, EmptyAverage) {
|
|
||||||
webrtc::MovingAverage moving_average(1);
|
|
||||||
EXPECT_EQ(0u, moving_average.size());
|
|
||||||
EXPECT_FALSE(moving_average.GetAverage(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test single value.
|
|
||||||
TEST(MovingAverageTest, OneElement) {
|
|
||||||
webrtc::MovingAverage moving_average(1);
|
|
||||||
moving_average.AddSample(3);
|
|
||||||
EXPECT_EQ(1u, moving_average.size());
|
|
||||||
EXPECT_EQ(3, *moving_average.GetAverage());
|
|
||||||
EXPECT_EQ(3, *moving_average.GetAverage(1));
|
|
||||||
EXPECT_FALSE(moving_average.GetAverage(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(MovingAverageTest, GetAverage) {
|
|
||||||
webrtc::MovingAverage moving_average(1024);
|
|
||||||
moving_average.AddSample(1);
|
|
||||||
moving_average.AddSample(1);
|
|
||||||
moving_average.AddSample(3);
|
|
||||||
moving_average.AddSample(3);
|
|
||||||
EXPECT_EQ(*moving_average.GetAverage(4), 2);
|
|
||||||
EXPECT_EQ(*moving_average.GetAverage(2), 3);
|
|
||||||
EXPECT_FALSE(moving_average.GetAverage(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(MovingAverageTest, Reset) {
|
|
||||||
webrtc::MovingAverage moving_average(5);
|
|
||||||
moving_average.AddSample(1);
|
|
||||||
EXPECT_EQ(1, *moving_average.GetAverage(1));
|
|
||||||
moving_average.Reset();
|
|
||||||
EXPECT_FALSE(moving_average.GetAverage(1));
|
|
||||||
EXPECT_FALSE(moving_average.GetAverage(6));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(MovingAverageTest, ManySamples) {
|
|
||||||
webrtc::MovingAverage moving_average(10);
|
|
||||||
for (int i = 1; i < 11; i++) {
|
|
||||||
moving_average.AddSample(i);
|
|
||||||
}
|
|
||||||
EXPECT_EQ(*moving_average.GetAverage(), 5);
|
|
||||||
moving_average.Reset();
|
|
||||||
for (int i = 1; i < 2001; i++) {
|
|
||||||
moving_average.AddSample(i);
|
|
||||||
}
|
|
||||||
EXPECT_EQ(*moving_average.GetAverage(), 1995);
|
|
||||||
}
|
|
|
@ -173,8 +173,8 @@ void QualityScaler::CheckQp() {
|
||||||
// If we have not observed at least this many frames we can't make a good
|
// If we have not observed at least this many frames we can't make a good
|
||||||
// scaling decision.
|
// scaling decision.
|
||||||
const size_t frames = config_.use_all_drop_reasons
|
const size_t frames = config_.use_all_drop_reasons
|
||||||
? framedrop_percent_all_.size()
|
? framedrop_percent_all_.Size()
|
||||||
: framedrop_percent_media_opt_.size();
|
: framedrop_percent_media_opt_.Size();
|
||||||
if (frames < kMinFramesNeededToScale) {
|
if (frames < kMinFramesNeededToScale) {
|
||||||
observed_enough_frames_ = false;
|
observed_enough_frames_ = false;
|
||||||
return;
|
return;
|
||||||
|
@ -183,8 +183,9 @@ void QualityScaler::CheckQp() {
|
||||||
|
|
||||||
// Check if we should scale down due to high frame drop.
|
// Check if we should scale down due to high frame drop.
|
||||||
const absl::optional<int> drop_rate =
|
const absl::optional<int> drop_rate =
|
||||||
config_.use_all_drop_reasons ? framedrop_percent_all_.GetAverage()
|
config_.use_all_drop_reasons
|
||||||
: framedrop_percent_media_opt_.GetAverage();
|
? framedrop_percent_all_.GetAverageRoundedDown()
|
||||||
|
: framedrop_percent_media_opt_.GetAverageRoundedDown();
|
||||||
if (drop_rate && *drop_rate >= kFramedropPercentThreshold) {
|
if (drop_rate && *drop_rate >= kFramedropPercentThreshold) {
|
||||||
RTC_LOG(LS_INFO) << "Reporting high QP, framedrop percent " << *drop_rate;
|
RTC_LOG(LS_INFO) << "Reporting high QP, framedrop percent " << *drop_rate;
|
||||||
ReportQpHigh();
|
ReportQpHigh();
|
||||||
|
@ -192,11 +193,12 @@ void QualityScaler::CheckQp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we should scale up or down based on QP.
|
// Check if we should scale up or down based on QP.
|
||||||
const absl::optional<int> avg_qp_high = qp_smoother_high_
|
const absl::optional<int> avg_qp_high =
|
||||||
? qp_smoother_high_->GetAvg()
|
qp_smoother_high_ ? qp_smoother_high_->GetAvg()
|
||||||
: average_qp_.GetAverage();
|
: average_qp_.GetAverageRoundedDown();
|
||||||
const absl::optional<int> avg_qp_low =
|
const absl::optional<int> avg_qp_low =
|
||||||
qp_smoother_low_ ? qp_smoother_low_->GetAvg() : average_qp_.GetAverage();
|
qp_smoother_low_ ? qp_smoother_low_->GetAvg()
|
||||||
|
: average_qp_.GetAverageRoundedDown();
|
||||||
if (avg_qp_high && avg_qp_low) {
|
if (avg_qp_high && avg_qp_low) {
|
||||||
RTC_LOG(LS_INFO) << "Checking average QP " << *avg_qp_high << " ("
|
RTC_LOG(LS_INFO) << "Checking average QP " << *avg_qp_high << " ("
|
||||||
<< *avg_qp_low << ").";
|
<< *avg_qp_low << ").";
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "common_types.h" // NOLINT(build/include)
|
#include "common_types.h" // NOLINT(build/include)
|
||||||
#include "modules/video_coding/utility/moving_average.h"
|
|
||||||
#include "rtc_base/experiments/quality_scaling_experiment.h"
|
#include "rtc_base/experiments/quality_scaling_experiment.h"
|
||||||
|
#include "rtc_base/numerics/moving_average.h"
|
||||||
#include "rtc_base/sequenced_task_checker.h"
|
#include "rtc_base/sequenced_task_checker.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
@ -79,9 +79,10 @@ class QualityScaler {
|
||||||
const VideoEncoder::QpThresholds thresholds_;
|
const VideoEncoder::QpThresholds thresholds_;
|
||||||
const int64_t sampling_period_ms_;
|
const int64_t sampling_period_ms_;
|
||||||
bool fast_rampup_ RTC_GUARDED_BY(&task_checker_);
|
bool fast_rampup_ RTC_GUARDED_BY(&task_checker_);
|
||||||
MovingAverage average_qp_ RTC_GUARDED_BY(&task_checker_);
|
rtc::MovingAverage average_qp_ RTC_GUARDED_BY(&task_checker_);
|
||||||
MovingAverage framedrop_percent_media_opt_ RTC_GUARDED_BY(&task_checker_);
|
rtc::MovingAverage framedrop_percent_media_opt_
|
||||||
MovingAverage framedrop_percent_all_ RTC_GUARDED_BY(&task_checker_);
|
RTC_GUARDED_BY(&task_checker_);
|
||||||
|
rtc::MovingAverage framedrop_percent_all_ RTC_GUARDED_BY(&task_checker_);
|
||||||
|
|
||||||
// Used by QualityScalingExperiment.
|
// Used by QualityScalingExperiment.
|
||||||
const bool experiment_enabled_;
|
const bool experiment_enabled_;
|
||||||
|
|
|
@ -68,7 +68,7 @@ rtc_source_set("compile_assert_c") {
|
||||||
}
|
}
|
||||||
|
|
||||||
# The subset of rtc_base approved for use outside of libjingle.
|
# The subset of rtc_base approved for use outside of libjingle.
|
||||||
# TODO(bugs.webrtc.org/9838): Create small and focues build targets and remove
|
# TODO(bugs.webrtc.org/9838): Create small and focused build targets and remove
|
||||||
# the old concept of rtc_base and rtc_base_approved.
|
# the old concept of rtc_base and rtc_base_approved.
|
||||||
rtc_source_set("rtc_base_approved") {
|
rtc_source_set("rtc_base_approved") {
|
||||||
visibility = [ "*" ]
|
visibility = [ "*" ]
|
||||||
|
@ -656,6 +656,8 @@ rtc_static_library("rtc_numerics") {
|
||||||
sources = [
|
sources = [
|
||||||
"numerics/exp_filter.cc",
|
"numerics/exp_filter.cc",
|
||||||
"numerics/exp_filter.h",
|
"numerics/exp_filter.h",
|
||||||
|
"numerics/moving_average.cc",
|
||||||
|
"numerics/moving_average.h",
|
||||||
"numerics/moving_median_filter.h",
|
"numerics/moving_median_filter.h",
|
||||||
"numerics/percentile_filter.h",
|
"numerics/percentile_filter.h",
|
||||||
"numerics/sequence_number_util.h",
|
"numerics/sequence_number_util.h",
|
||||||
|
@ -1211,6 +1213,7 @@ if (rtc_include_tests) {
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
"numerics/exp_filter_unittest.cc",
|
"numerics/exp_filter_unittest.cc",
|
||||||
|
"numerics/moving_average_unittest.cc",
|
||||||
"numerics/moving_median_filter_unittest.cc",
|
"numerics/moving_median_filter_unittest.cc",
|
||||||
"numerics/percentile_filter_unittest.cc",
|
"numerics/percentile_filter_unittest.cc",
|
||||||
"numerics/sequence_number_util_unittest.cc",
|
"numerics/sequence_number_util_unittest.cc",
|
||||||
|
|
60
rtc_base/numerics/moving_average.cc
Normal file
60
rtc_base/numerics/moving_average.cc
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rtc_base/numerics/moving_average.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "rtc_base/checks.h"
|
||||||
|
|
||||||
|
namespace rtc {
|
||||||
|
|
||||||
|
MovingAverage::MovingAverage(size_t window_size) : history_(window_size, 0) {
|
||||||
|
// Limit window size to avoid overflow.
|
||||||
|
RTC_DCHECK_LE(window_size, (int64_t{1} << 32) - 1);
|
||||||
|
}
|
||||||
|
MovingAverage::~MovingAverage() = default;
|
||||||
|
|
||||||
|
void MovingAverage::AddSample(int sample) {
|
||||||
|
count_++;
|
||||||
|
size_t index = count_ % history_.size();
|
||||||
|
if (count_ > history_.size())
|
||||||
|
sum_ -= history_[index];
|
||||||
|
sum_ += sample;
|
||||||
|
history_[index] = sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::optional<int> MovingAverage::GetAverageRoundedDown() const {
|
||||||
|
if (count_ == 0)
|
||||||
|
return absl::nullopt;
|
||||||
|
return sum_ / Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::optional<int> MovingAverage::GetAverageRoundedToClosest() const {
|
||||||
|
if (count_ == 0)
|
||||||
|
return absl::nullopt;
|
||||||
|
return (sum_ + Size() / 2) / Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::optional<double> MovingAverage::GetUnroundedAverage() const {
|
||||||
|
if (count_ == 0)
|
||||||
|
return absl::nullopt;
|
||||||
|
return sum_ / static_cast<double>(Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovingAverage::Reset() {
|
||||||
|
count_ = 0;
|
||||||
|
sum_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MovingAverage::Size() const {
|
||||||
|
return std::min(count_, history_.size());
|
||||||
|
}
|
||||||
|
} // namespace rtc
|
63
rtc_base/numerics/moving_average.h
Normal file
63
rtc_base/numerics/moving_average.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTC_BASE_NUMERICS_MOVING_AVERAGE_H_
|
||||||
|
#define RTC_BASE_NUMERICS_MOVING_AVERAGE_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/types/optional.h"
|
||||||
|
|
||||||
|
namespace rtc {
|
||||||
|
|
||||||
|
// Calculates average over fixed size window. If there are less than window
|
||||||
|
// size elements, calculates average of all inserted so far elements.
|
||||||
|
//
|
||||||
|
class MovingAverage {
|
||||||
|
public:
|
||||||
|
// Maximum supported window size is 2^32 - 1.
|
||||||
|
explicit MovingAverage(size_t window_size);
|
||||||
|
~MovingAverage();
|
||||||
|
// MovingAverage is neither copyable nor movable.
|
||||||
|
MovingAverage(const MovingAverage&) = delete;
|
||||||
|
MovingAverage& operator=(const MovingAverage&) = delete;
|
||||||
|
|
||||||
|
// Adds new sample. If the window is full, the oldest element is pushed out.
|
||||||
|
void AddSample(int sample);
|
||||||
|
|
||||||
|
// Returns rounded down average of last |window_size| elements or all
|
||||||
|
// elements if there are not enough of them. Returns nullopt if there were
|
||||||
|
// no elements added.
|
||||||
|
absl::optional<int> GetAverageRoundedDown() const;
|
||||||
|
|
||||||
|
// Same as above but rounded to the closest integer.
|
||||||
|
absl::optional<int> GetAverageRoundedToClosest() const;
|
||||||
|
|
||||||
|
// Returns unrounded average over the window.
|
||||||
|
absl::optional<double> GetUnroundedAverage() const;
|
||||||
|
|
||||||
|
// Resets to the initial state before any elements were added.
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
// Returns number of elements in the window.
|
||||||
|
size_t Size() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Total number of samples added to the class since last reset.
|
||||||
|
size_t count_ = 0;
|
||||||
|
// Sum of the samples in the moving window.
|
||||||
|
int64_t sum_ = 0;
|
||||||
|
// Circular buffer for all the samples in the moving window.
|
||||||
|
// Size is always |window_size|
|
||||||
|
std::vector<int> history_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace rtc
|
||||||
|
#endif // RTC_BASE_NUMERICS_MOVING_AVERAGE_H_
|
87
rtc_base/numerics/moving_average_unittest.cc
Normal file
87
rtc_base/numerics/moving_average_unittest.cc
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rtc_base/numerics/moving_average.h"
|
||||||
|
|
||||||
|
#include "test/gtest.h"
|
||||||
|
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
TEST(MovingAverageTest, EmptyAverage) {
|
||||||
|
rtc::MovingAverage moving_average(1);
|
||||||
|
EXPECT_EQ(0u, moving_average.Size());
|
||||||
|
EXPECT_EQ(absl::nullopt, moving_average.GetAverageRoundedDown());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test single value.
|
||||||
|
TEST(MovingAverageTest, OneElement) {
|
||||||
|
rtc::MovingAverage moving_average(1);
|
||||||
|
moving_average.AddSample(3);
|
||||||
|
EXPECT_EQ(1u, moving_average.Size());
|
||||||
|
EXPECT_EQ(3, *moving_average.GetAverageRoundedDown());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MovingAverageTest, GetAverage) {
|
||||||
|
rtc::MovingAverage moving_average(1024);
|
||||||
|
moving_average.AddSample(1);
|
||||||
|
moving_average.AddSample(1);
|
||||||
|
moving_average.AddSample(3);
|
||||||
|
moving_average.AddSample(3);
|
||||||
|
EXPECT_EQ(*moving_average.GetAverageRoundedDown(), 2);
|
||||||
|
EXPECT_EQ(*moving_average.GetAverageRoundedToClosest(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MovingAverageTest, GetAverageRoundedDownRounds) {
|
||||||
|
rtc::MovingAverage moving_average(1024);
|
||||||
|
moving_average.AddSample(1);
|
||||||
|
moving_average.AddSample(2);
|
||||||
|
moving_average.AddSample(2);
|
||||||
|
moving_average.AddSample(2);
|
||||||
|
EXPECT_EQ(*moving_average.GetAverageRoundedDown(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MovingAverageTest, GetAverageRoundedToClosestRounds) {
|
||||||
|
rtc::MovingAverage moving_average(1024);
|
||||||
|
moving_average.AddSample(1);
|
||||||
|
moving_average.AddSample(2);
|
||||||
|
moving_average.AddSample(2);
|
||||||
|
moving_average.AddSample(2);
|
||||||
|
EXPECT_EQ(*moving_average.GetAverageRoundedToClosest(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MovingAverageTest, Reset) {
|
||||||
|
rtc::MovingAverage moving_average(5);
|
||||||
|
moving_average.AddSample(1);
|
||||||
|
EXPECT_EQ(1, *moving_average.GetAverageRoundedDown());
|
||||||
|
EXPECT_EQ(1, *moving_average.GetAverageRoundedToClosest());
|
||||||
|
|
||||||
|
moving_average.Reset();
|
||||||
|
|
||||||
|
EXPECT_FALSE(moving_average.GetAverageRoundedDown());
|
||||||
|
moving_average.AddSample(10);
|
||||||
|
EXPECT_EQ(10, *moving_average.GetAverageRoundedDown());
|
||||||
|
EXPECT_EQ(10, *moving_average.GetAverageRoundedToClosest());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MovingAverageTest, ManySamples) {
|
||||||
|
rtc::MovingAverage moving_average(10);
|
||||||
|
for (int i = 1; i < 11; i++) {
|
||||||
|
moving_average.AddSample(i);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(*moving_average.GetAverageRoundedDown(), 5);
|
||||||
|
EXPECT_EQ(*moving_average.GetAverageRoundedToClosest(), 6);
|
||||||
|
for (int i = 1; i < 2001; i++) {
|
||||||
|
moving_average.AddSample(i);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(*moving_average.GetAverageRoundedDown(), 1995);
|
||||||
|
EXPECT_EQ(*moving_average.GetAverageRoundedToClosest(), 1996);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace test
|
Loading…
Reference in a new issue