1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "video/quality_threshold.h"
12
13 #include "rtc_base/checks.h"
14
15 namespace webrtc {
16
QualityThreshold(int low_threshold,int high_threshold,float fraction,int max_measurements)17 QualityThreshold::QualityThreshold(int low_threshold,
18 int high_threshold,
19 float fraction,
20 int max_measurements)
21 : buffer_(new int[max_measurements]),
22 max_measurements_(max_measurements),
23 fraction_(fraction),
24 low_threshold_(low_threshold),
25 high_threshold_(high_threshold),
26 until_full_(max_measurements),
27 next_index_(0),
28 sum_(0),
29 count_low_(0),
30 count_high_(0),
31 num_high_states_(0),
32 num_certain_states_(0) {
33 RTC_CHECK_GT(fraction, 0.5f);
34 RTC_CHECK_GT(max_measurements, 1);
35 RTC_CHECK_LT(low_threshold, high_threshold);
36 }
37
38 QualityThreshold::~QualityThreshold() = default;
39
AddMeasurement(int measurement)40 void QualityThreshold::AddMeasurement(int measurement) {
41 int prev_val = until_full_ > 0 ? 0 : buffer_[next_index_];
42 buffer_[next_index_] = measurement;
43 next_index_ = (next_index_ + 1) % max_measurements_;
44
45 sum_ += measurement - prev_val;
46
47 if (until_full_ == 0) {
48 if (prev_val <= low_threshold_) {
49 --count_low_;
50 } else if (prev_val >= high_threshold_) {
51 --count_high_;
52 }
53 }
54
55 if (measurement <= low_threshold_) {
56 ++count_low_;
57 } else if (measurement >= high_threshold_) {
58 ++count_high_;
59 }
60
61 float sufficient_majority = fraction_ * max_measurements_;
62 if (count_high_ >= sufficient_majority) {
63 is_high_ = true;
64 } else if (count_low_ >= sufficient_majority) {
65 is_high_ = false;
66 }
67
68 if (until_full_ > 0)
69 --until_full_;
70
71 if (is_high_) {
72 if (*is_high_)
73 ++num_high_states_;
74 ++num_certain_states_;
75 }
76 }
77
IsHigh() const78 absl::optional<bool> QualityThreshold::IsHigh() const {
79 return is_high_;
80 }
81
CalculateVariance() const82 absl::optional<double> QualityThreshold::CalculateVariance() const {
83 if (until_full_ > 0) {
84 return absl::nullopt;
85 }
86
87 double variance = 0;
88 double mean = static_cast<double>(sum_) / max_measurements_;
89 for (int i = 0; i < max_measurements_; ++i) {
90 variance += (buffer_[i] - mean) * (buffer_[i] - mean);
91 }
92 return variance / (max_measurements_ - 1);
93 }
94
FractionHigh(int min_required_samples) const95 absl::optional<double> QualityThreshold::FractionHigh(
96 int min_required_samples) const {
97 RTC_DCHECK_GT(min_required_samples, 0);
98 if (num_certain_states_ < min_required_samples)
99 return absl::nullopt;
100
101 return static_cast<double>(num_high_states_) / num_certain_states_;
102 }
103
104 } // namespace webrtc
105