blob: 931b0b20f9aa53aeaafde00fcc8bee5bbdac3da4 [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"
palmkvist349092b2016-12-13 02:45:57 -080014
15namespace webrtc {
16
17QualityThreshold::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),
palmkvista40672a2017-01-13 05:58:34 -080030 count_high_(0),
31 num_high_states_(0),
32 num_certain_states_(0) {
palmkvist349092b2016-12-13 02:45:57 -080033 RTC_CHECK_GT(fraction, 0.5f);
34 RTC_CHECK_GT(max_measurements, 1);
35 RTC_CHECK_LT(low_threshold, high_threshold);
36}
37
Mirko Bonadei8fdcac32018-08-28 16:30:18 +020038QualityThreshold::~QualityThreshold() = default;
39
palmkvist349092b2016-12-13 02:45:57 -080040void 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) {
Oskar Sundbom8e07c132018-01-08 16:45:42 +010063 is_high_ = true;
palmkvist349092b2016-12-13 02:45:57 -080064 } else if (count_low_ >= sufficient_majority) {
Oskar Sundbom8e07c132018-01-08 16:45:42 +010065 is_high_ = false;
palmkvist349092b2016-12-13 02:45:57 -080066 }
67
68 if (until_full_ > 0)
69 --until_full_;
palmkvista40672a2017-01-13 05:58:34 -080070
71 if (is_high_) {
72 if (*is_high_)
73 ++num_high_states_;
74 ++num_certain_states_;
75 }
palmkvist349092b2016-12-13 02:45:57 -080076}
77
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020078absl::optional<bool> QualityThreshold::IsHigh() const {
palmkvist349092b2016-12-13 02:45:57 -080079 return is_high_;
80}
81
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020082absl::optional<double> QualityThreshold::CalculateVariance() const {
palmkvist349092b2016-12-13 02:45:57 -080083 if (until_full_ > 0) {
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020084 return absl::nullopt;
palmkvist349092b2016-12-13 02:45:57 -080085 }
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 }
Oskar Sundbom8e07c132018-01-08 16:45:42 +010092 return variance / (max_measurements_ - 1);
palmkvist349092b2016-12-13 02:45:57 -080093}
94
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020095absl::optional<double> QualityThreshold::FractionHigh(
palmkvista40672a2017-01-13 05:58:34 -080096 int min_required_samples) const {
97 RTC_DCHECK_GT(min_required_samples, 0);
98 if (num_certain_states_ < min_required_samples)
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020099 return absl::nullopt;
palmkvista40672a2017-01-13 05:58:34 -0800100
Oskar Sundbom8e07c132018-01-08 16:45:42 +0100101 return static_cast<double>(num_high_states_) / num_certain_states_;
palmkvista40672a2017-01-13 05:58:34 -0800102}
103
palmkvist349092b2016-12-13 02:45:57 -0800104} // namespace webrtc