Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: webrtc/modules/remote_bitrate_estimator/overuse_estimator.cc

Issue 1376423002: Make overuse estimator one dimensional. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Further cleanups. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h" 11 #include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <assert.h> 14 #include <assert.h>
15 #include <math.h> 15 #include <math.h>
16 #include <stdlib.h> 16 #include <stdlib.h>
17 #include <string.h> 17 #include <string.h>
18 18
19 #include "webrtc/base/checks.h"
19 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" 20 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
20 #include "webrtc/system_wrappers/interface/logging.h" 21 #include "webrtc/system_wrappers/interface/logging.h"
21 22
22 namespace webrtc { 23 namespace webrtc {
23 24
24 enum { kMinFramePeriodHistoryLength = 60 }; 25 enum { kMinFramePeriodHistoryLength = 60 };
25 enum { kDeltaCounterMax = 1000 }; 26 enum { kDeltaCounterMax = 1000 };
26 27
27 OveruseEstimator::OveruseEstimator(const OverUseDetectorOptions& options) 28 OveruseEstimator::OveruseEstimator()
28 : options_(options), 29 : num_of_deltas_(0),
29 num_of_deltas_(0), 30 offset_(0),
30 slope_(options_.initial_slope), 31 prev_offset_(offset_),
31 offset_(options_.initial_offset), 32 e_(0.1),
32 prev_offset_(options_.initial_offset), 33 process_noise_(0.01),
Gaetano Carlucci 2015/10/06 13:50:25 We can run some tests to verity this setting of th
stefan-webrtc 2015/11/24 16:08:03 We'll have to tune this, but for now I'll keep it
33 E_(), 34 avg_noise_(0),
34 process_noise_(), 35 var_noise_(50),
35 avg_noise_(options_.initial_avg_noise), 36 ts_delta_hist_() {}
36 var_noise_(options_.initial_var_noise),
37 ts_delta_hist_() {
38 memcpy(E_, options_.initial_e, sizeof(E_));
39 memcpy(process_noise_, options_.initial_process_noise,
40 sizeof(process_noise_));
41 }
42 37
43 OveruseEstimator::~OveruseEstimator() { 38 OveruseEstimator::~OveruseEstimator() {
44 ts_delta_hist_.clear(); 39 ts_delta_hist_.clear();
45 } 40 }
46 41
47 void OveruseEstimator::Update(int64_t t_delta, 42 void OveruseEstimator::Update(int64_t t_delta,
48 double ts_delta, 43 double ts_delta,
terelius 2015/10/12 12:04:41 s/t_delta/recv_t_delta or something similar? s/ts_
stefan-webrtc 2015/11/24 16:08:03 Done.
49 int size_delta,
50 BandwidthUsage current_hypothesis) { 44 BandwidthUsage current_hypothesis) {
51 const double min_frame_period = UpdateMinFramePeriod(ts_delta); 45 const double min_frame_period = UpdateMinFramePeriod(ts_delta);
52 const double t_ts_delta = t_delta - ts_delta; 46 const double t_ts_delta = t_delta - ts_delta;
53 double fs_delta = size_delta;
54 47
55 ++num_of_deltas_; 48 ++num_of_deltas_;
56 if (num_of_deltas_ > kDeltaCounterMax) { 49 if (num_of_deltas_ > kDeltaCounterMax) {
57 num_of_deltas_ = kDeltaCounterMax; 50 num_of_deltas_ = kDeltaCounterMax;
58 } 51 }
59 52
60 // Update the Kalman filter. 53 // Update the Kalman filter.
61 E_[0][0] += process_noise_[0]; 54 e_ += process_noise_;
62 E_[1][1] += process_noise_[1];
63 55
64 if ((current_hypothesis == kBwOverusing && offset_ < prev_offset_) || 56 if ((current_hypothesis == kBwOverusing && offset_ < prev_offset_) ||
65 (current_hypothesis == kBwUnderusing && offset_ > prev_offset_)) { 57 (current_hypothesis == kBwUnderusing && offset_ > prev_offset_)) {
66 E_[1][1] += 10 * process_noise_[1]; 58 e_ += 10 * process_noise_;
67 } 59 }
68 60
69 const double h[2] = {fs_delta, 1.0}; 61 const double residual = t_ts_delta - offset_;
70 const double Eh[2] = {E_[0][0]*h[0] + E_[0][1]*h[1],
71 E_[1][0]*h[0] + E_[1][1]*h[1]};
72
73 const double residual = t_ts_delta - slope_*h[0] - offset_;
74 62
75 const bool in_stable_state = (current_hypothesis == kBwNormal); 63 const bool in_stable_state = (current_hypothesis == kBwNormal);
76 const double max_residual = 3.0 * sqrt(var_noise_); 64 const double max_residual = 3.0 * sqrt(var_noise_);
77 // We try to filter out very late frames. For instance periodic key 65 // We try to filter out very late frames. For instance periodic key
78 // frames doesn't fit the Gaussian model well. 66 // frames doesn't fit the Gaussian model well.
79 if (fabs(residual) < max_residual) { 67 if (fabs(residual) < max_residual) {
80 UpdateNoiseEstimate(residual, min_frame_period, in_stable_state); 68 UpdateNoiseEstimate(residual, min_frame_period, in_stable_state);
81 } else { 69 } else {
82 UpdateNoiseEstimate(residual < 0 ? -max_residual : max_residual, 70 UpdateNoiseEstimate(residual < 0 ? -max_residual : max_residual,
83 min_frame_period, in_stable_state); 71 min_frame_period, in_stable_state);
84 } 72 }
85 73 const double k = e_ / (var_noise_ + e_);
86 const double denom = var_noise_ + h[0]*Eh[0] + h[1]*Eh[1];
87
88 const double K[2] = {Eh[0] / denom,
89 Eh[1] / denom};
90
91 const double IKh[2][2] = {{1.0 - K[0]*h[0], -K[0]*h[1]},
92 {-K[1]*h[0], 1.0 - K[1]*h[1]}};
93 const double e00 = E_[0][0];
94 const double e01 = E_[0][1];
95 74
96 // Update state. 75 // Update state.
97 E_[0][0] = e00 * IKh[0][0] + E_[1][0] * IKh[0][1]; 76 e_ = e_ * (1.0 - k);
98 E_[0][1] = e01 * IKh[0][0] + E_[1][1] * IKh[0][1];
99 E_[1][0] = e00 * IKh[1][0] + E_[1][0] * IKh[1][1];
100 E_[1][1] = e01 * IKh[1][0] + E_[1][1] * IKh[1][1];
101 77
102 // The covariance matrix must be positive semi-definite. 78 // The covariance matrix must be positive.
103 bool positive_semi_definite = E_[0][0] + E_[1][1] >= 0 && 79 RTC_DCHECK(e_ >= 0.0);
104 E_[0][0] * E_[1][1] - E_[0][1] * E_[1][0] >= 0 && E_[0][0] >= 0; 80 if (e_ < 0)
105 assert(positive_semi_definite); 81 LOG(LS_ERROR) << "The over-use estimator's covariance is negative!";
106 if (!positive_semi_definite) {
107 LOG(LS_ERROR) << "The over-use estimator's covariance matrix is no longer "
108 "semi-definite.";
109 }
110 82
111 slope_ = slope_ + K[0] * residual; 83 offset_ = offset_ + k * residual;
112 prev_offset_ = offset_;
113 offset_ = offset_ + K[1] * residual;
114 } 84 }
115 85
116 double OveruseEstimator::UpdateMinFramePeriod(double ts_delta) { 86 double OveruseEstimator::UpdateMinFramePeriod(double ts_delta) {
117 double min_frame_period = ts_delta; 87 double min_frame_period = ts_delta;
118 if (ts_delta_hist_.size() >= kMinFramePeriodHistoryLength) { 88 if (ts_delta_hist_.size() >= kMinFramePeriodHistoryLength) {
119 ts_delta_hist_.pop_front(); 89 ts_delta_hist_.pop_front();
120 } 90 }
121 std::list<double>::iterator it = ts_delta_hist_.begin(); 91 std::list<double>::iterator it = ts_delta_hist_.begin();
122 for (; it != ts_delta_hist_.end(); it++) { 92 for (; it != ts_delta_hist_.end(); it++) {
123 min_frame_period = std::min(*it, min_frame_period); 93 min_frame_period = std::min(*it, min_frame_period);
(...skipping 20 matching lines...) Expand all
144 const double beta = pow(1 - alpha, ts_delta * 30.0 / 1000.0); 114 const double beta = pow(1 - alpha, ts_delta * 30.0 / 1000.0);
145 avg_noise_ = beta * avg_noise_ 115 avg_noise_ = beta * avg_noise_
146 + (1 - beta) * residual; 116 + (1 - beta) * residual;
147 var_noise_ = beta * var_noise_ 117 var_noise_ = beta * var_noise_
148 + (1 - beta) * (avg_noise_ - residual) * (avg_noise_ - residual); 118 + (1 - beta) * (avg_noise_ - residual) * (avg_noise_ - residual);
149 if (var_noise_ < 1) { 119 if (var_noise_ < 1) {
150 var_noise_ = 1; 120 var_noise_ = 1;
151 } 121 }
152 } 122 }
153 } // namespace webrtc 123 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698