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:
Ilya Nikolaevskiy
2018-11-05 12:55:18 +01:00
committed by Commit Bot
parent a1ead6f2ab
commit 26341990a1
10 changed files with 229 additions and 161 deletions

View File

@ -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

View File

@ -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_

View File

@ -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);
}

View File

@ -173,8 +173,8 @@ void QualityScaler::CheckQp() {
// If we have not observed at least this many frames we can't make a good
// scaling decision.
const size_t frames = config_.use_all_drop_reasons
? framedrop_percent_all_.size()
: framedrop_percent_media_opt_.size();
? framedrop_percent_all_.Size()
: framedrop_percent_media_opt_.Size();
if (frames < kMinFramesNeededToScale) {
observed_enough_frames_ = false;
return;
@ -183,8 +183,9 @@ void QualityScaler::CheckQp() {
// Check if we should scale down due to high frame drop.
const absl::optional<int> drop_rate =
config_.use_all_drop_reasons ? framedrop_percent_all_.GetAverage()
: framedrop_percent_media_opt_.GetAverage();
config_.use_all_drop_reasons
? framedrop_percent_all_.GetAverageRoundedDown()
: framedrop_percent_media_opt_.GetAverageRoundedDown();
if (drop_rate && *drop_rate >= kFramedropPercentThreshold) {
RTC_LOG(LS_INFO) << "Reporting high QP, framedrop percent " << *drop_rate;
ReportQpHigh();
@ -192,11 +193,12 @@ void QualityScaler::CheckQp() {
}
// Check if we should scale up or down based on QP.
const absl::optional<int> avg_qp_high = qp_smoother_high_
? qp_smoother_high_->GetAvg()
: average_qp_.GetAverage();
const absl::optional<int> avg_qp_high =
qp_smoother_high_ ? qp_smoother_high_->GetAvg()
: average_qp_.GetAverageRoundedDown();
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) {
RTC_LOG(LS_INFO) << "Checking average QP " << *avg_qp_high << " ("
<< *avg_qp_low << ").";

View File

@ -17,8 +17,8 @@
#include "absl/types/optional.h"
#include "api/video_codecs/video_encoder.h"
#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/numerics/moving_average.h"
#include "rtc_base/sequenced_task_checker.h"
namespace webrtc {
@ -79,9 +79,10 @@ class QualityScaler {
const VideoEncoder::QpThresholds thresholds_;
const int64_t sampling_period_ms_;
bool fast_rampup_ RTC_GUARDED_BY(&task_checker_);
MovingAverage average_qp_ RTC_GUARDED_BY(&task_checker_);
MovingAverage framedrop_percent_media_opt_ RTC_GUARDED_BY(&task_checker_);
MovingAverage framedrop_percent_all_ RTC_GUARDED_BY(&task_checker_);
rtc::MovingAverage average_qp_ RTC_GUARDED_BY(&task_checker_);
rtc::MovingAverage framedrop_percent_media_opt_
RTC_GUARDED_BY(&task_checker_);
rtc::MovingAverage framedrop_percent_all_ RTC_GUARDED_BY(&task_checker_);
// Used by QualityScalingExperiment.
const bool experiment_enabled_;