Line data Source code
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 "webrtc/video/quality_threshold.h"
12 :
13 : #include "webrtc/base/checks.h"
14 : #include "webrtc/base/logging.h"
15 :
16 : namespace webrtc {
17 :
18 0 : QualityThreshold::QualityThreshold(int low_threshold,
19 : int high_threshold,
20 : float fraction,
21 0 : int max_measurements)
22 0 : : 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),
31 : count_high_(0),
32 : num_high_states_(0),
33 0 : num_certain_states_(0) {
34 0 : RTC_CHECK_GT(fraction, 0.5f);
35 0 : RTC_CHECK_GT(max_measurements, 1);
36 0 : RTC_CHECK_LT(low_threshold, high_threshold);
37 0 : }
38 :
39 0 : void QualityThreshold::AddMeasurement(int measurement) {
40 0 : int prev_val = until_full_ > 0 ? 0 : buffer_[next_index_];
41 0 : buffer_[next_index_] = measurement;
42 0 : next_index_ = (next_index_ + 1) % max_measurements_;
43 :
44 0 : sum_ += measurement - prev_val;
45 :
46 0 : if (until_full_ == 0) {
47 0 : if (prev_val <= low_threshold_) {
48 0 : --count_low_;
49 0 : } else if (prev_val >= high_threshold_) {
50 0 : --count_high_;
51 : }
52 : }
53 :
54 0 : if (measurement <= low_threshold_) {
55 0 : ++count_low_;
56 0 : } else if (measurement >= high_threshold_) {
57 0 : ++count_high_;
58 : }
59 :
60 0 : float sufficient_majority = fraction_ * max_measurements_;
61 0 : if (count_high_ >= sufficient_majority) {
62 0 : is_high_ = rtc::Optional<bool>(true);
63 0 : } else if (count_low_ >= sufficient_majority) {
64 0 : is_high_ = rtc::Optional<bool>(false);
65 : }
66 :
67 0 : if (until_full_ > 0)
68 0 : --until_full_;
69 :
70 0 : if (is_high_) {
71 0 : if (*is_high_)
72 0 : ++num_high_states_;
73 0 : ++num_certain_states_;
74 : }
75 0 : }
76 :
77 0 : rtc::Optional<bool> QualityThreshold::IsHigh() const {
78 0 : return is_high_;
79 : }
80 :
81 0 : rtc::Optional<double> QualityThreshold::CalculateVariance() const {
82 0 : if (until_full_ > 0) {
83 0 : return rtc::Optional<double>();
84 : }
85 :
86 0 : double variance = 0;
87 0 : double mean = static_cast<double>(sum_) / max_measurements_;
88 0 : for (int i = 0; i < max_measurements_; ++i) {
89 0 : variance += (buffer_[i] - mean) * (buffer_[i] - mean);
90 : }
91 0 : return rtc::Optional<double>(variance / (max_measurements_ - 1));
92 : }
93 :
94 0 : rtc::Optional<double> QualityThreshold::FractionHigh(
95 : int min_required_samples) const {
96 0 : RTC_DCHECK_GT(min_required_samples, 0);
97 0 : if (num_certain_states_ < min_required_samples)
98 0 : return rtc::Optional<double>();
99 :
100 0 : return rtc::Optional<double>(static_cast<double>(num_high_states_) /
101 0 : num_certain_states_);
102 : }
103 :
104 : } // namespace webrtc
|