blob: b681ce40806d2a53fa6baced10bbfd47717f092c [file] [log] [blame]
palmkvist349092b2016-12-13 02:45:57 -08001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "video/quality_threshold.h"
palmkvist349092b2016-12-13 02:45:57 -080012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "rtc_base/checks.h"
14#include "rtc_base/logging.h"
palmkvist349092b2016-12-13 02:45:57 -080015
16namespace webrtc {
17
18QualityThreshold::QualityThreshold(int low_threshold,
19 int high_threshold,
20 float fraction,
21 int max_measurements)
22 : buffer_(new int[max_measurements]),
23 max_measurements_(max_measurements),
24 fraction_(fraction),
25 low_threshold_(low_threshold),
26 high_threshold_(high_threshold),
27 until_full_(max_measurements),
28 next_index_(0),
29 sum_(0),
30 count_low_(0),
palmkvista40672a2017-01-13 05:58:34 -080031 count_high_(0),
32 num_high_states_(0),
33 num_certain_states_(0) {
palmkvist349092b2016-12-13 02:45:57 -080034 RTC_CHECK_GT(fraction, 0.5f);
35 RTC_CHECK_GT(max_measurements, 1);
36 RTC_CHECK_LT(low_threshold, high_threshold);
37}
38
Mirko Bonadei8fdcac32018-08-28 16:30:18 +020039QualityThreshold::~QualityThreshold() = default;
40
palmkvist349092b2016-12-13 02:45:57 -080041void QualityThreshold::AddMeasurement(int measurement) {
42 int prev_val = until_full_ > 0 ? 0 : buffer_[next_index_];
43 buffer_[next_index_] = measurement;
44 next_index_ = (next_index_ + 1) % max_measurements_;
45
46 sum_ += measurement - prev_val;
47
48 if (until_full_ == 0) {
49 if (prev_val <= low_threshold_) {
50 --count_low_;
51 } else if (prev_val >= high_threshold_) {
52 --count_high_;
53 }
54 }
55
56 if (measurement <= low_threshold_) {
57 ++count_low_;
58 } else if (measurement >= high_threshold_) {
59 ++count_high_;
60 }
61
62 float sufficient_majority = fraction_ * max_measurements_;
63 if (count_high_ >= sufficient_majority) {
Oskar Sundbom8e07c132018-01-08 16:45:42 +010064 is_high_ = true;
palmkvist349092b2016-12-13 02:45:57 -080065 } else if (count_low_ >= sufficient_majority) {
Oskar Sundbom8e07c132018-01-08 16:45:42 +010066 is_high_ = false;
palmkvist349092b2016-12-13 02:45:57 -080067 }
68
69 if (until_full_ > 0)
70 --until_full_;
palmkvista40672a2017-01-13 05:58:34 -080071
72 if (is_high_) {
73 if (*is_high_)
74 ++num_high_states_;
75 ++num_certain_states_;
76 }
palmkvist349092b2016-12-13 02:45:57 -080077}
78
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020079absl::optional<bool> QualityThreshold::IsHigh() const {
palmkvist349092b2016-12-13 02:45:57 -080080 return is_high_;
81}
82
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020083absl::optional<double> QualityThreshold::CalculateVariance() const {
palmkvist349092b2016-12-13 02:45:57 -080084 if (until_full_ > 0) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020085 return absl::nullopt;
palmkvist349092b2016-12-13 02:45:57 -080086 }
87
88 double variance = 0;
89 double mean = static_cast<double>(sum_) / max_measurements_;
90 for (int i = 0; i < max_measurements_; ++i) {
91 variance += (buffer_[i] - mean) * (buffer_[i] - mean);
92 }
Oskar Sundbom8e07c132018-01-08 16:45:42 +010093 return variance / (max_measurements_ - 1);
palmkvist349092b2016-12-13 02:45:57 -080094}
95
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020096absl::optional<double> QualityThreshold::FractionHigh(
palmkvista40672a2017-01-13 05:58:34 -080097 int min_required_samples) const {
98 RTC_DCHECK_GT(min_required_samples, 0);
99 if (num_certain_states_ < min_required_samples)
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200100 return absl::nullopt;
palmkvista40672a2017-01-13 05:58:34 -0800101
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100102 return static_cast<double>(num_high_states_) / num_certain_states_;
palmkvista40672a2017-01-13 05:58:34 -0800103}
104
palmkvist349092b2016-12-13 02:45:57 -0800105} // namespace webrtc