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

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

Issue 1481003002: Revert of Make overuse estimator one dimensional. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years 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"
20 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" 19 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
21 #include "webrtc/system_wrappers/include/logging.h" 20 #include "webrtc/system_wrappers/include/logging.h"
22 21
23 namespace webrtc { 22 namespace webrtc {
24 23
25 enum { kMinFramePeriodHistoryLength = 60 }; 24 enum { kMinFramePeriodHistoryLength = 60 };
26 enum { kDeltaCounterMax = 1000 }; 25 enum { kDeltaCounterMax = 1000 };
27 26
28 OveruseEstimator::OveruseEstimator() 27 OveruseEstimator::OveruseEstimator(const OverUseDetectorOptions& options)
29 : num_of_deltas_(0), 28 : options_(options),
30 offset_(0), 29 num_of_deltas_(0),
31 prev_offset_(offset_), 30 slope_(options_.initial_slope),
32 e_(0.1), 31 offset_(options_.initial_offset),
33 process_noise_(1e-2), 32 prev_offset_(options_.initial_offset),
34 avg_noise_(0), 33 E_(),
35 var_noise_(50), 34 process_noise_(),
36 send_delta_history_() {} 35 avg_noise_(options_.initial_avg_noise),
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 }
37 42
38 OveruseEstimator::~OveruseEstimator() { 43 OveruseEstimator::~OveruseEstimator() {
39 send_delta_history_.clear(); 44 ts_delta_hist_.clear();
40 } 45 }
41 46
42 void OveruseEstimator::Update(double recv_delta_ms, 47 void OveruseEstimator::Update(int64_t t_delta,
43 double send_delta_ms, 48 double ts_delta,
49 int size_delta,
44 BandwidthUsage current_hypothesis) { 50 BandwidthUsage current_hypothesis) {
45 const double min_frame_period = UpdateMinFramePeriod(send_delta_ms); 51 const double min_frame_period = UpdateMinFramePeriod(ts_delta);
46 const double delta_ms = recv_delta_ms - send_delta_ms; 52 const double t_ts_delta = t_delta - ts_delta;
53 double fs_delta = size_delta;
47 54
48 ++num_of_deltas_; 55 ++num_of_deltas_;
49 if (num_of_deltas_ > kDeltaCounterMax) { 56 if (num_of_deltas_ > kDeltaCounterMax) {
50 num_of_deltas_ = kDeltaCounterMax; 57 num_of_deltas_ = kDeltaCounterMax;
51 } 58 }
52 59
53 // Update the Kalman filter. 60 // Update the Kalman filter.
54 e_ += process_noise_; 61 E_[0][0] += process_noise_[0];
62 E_[1][1] += process_noise_[1];
55 63
56 if ((current_hypothesis == kBwOverusing && offset_ < prev_offset_) || 64 if ((current_hypothesis == kBwOverusing && offset_ < prev_offset_) ||
57 (current_hypothesis == kBwUnderusing && offset_ > prev_offset_)) { 65 (current_hypothesis == kBwUnderusing && offset_ > prev_offset_)) {
58 e_ += 10 * process_noise_; 66 E_[1][1] += 10 * process_noise_[1];
59 } 67 }
60 68
61 const double residual = delta_ms - offset_; 69 const double h[2] = {fs_delta, 1.0};
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_;
62 74
63 const bool in_stable_state = (current_hypothesis == kBwNormal); 75 const bool in_stable_state = (current_hypothesis == kBwNormal);
64 const double max_residual = 3.0 * sqrt(var_noise_); 76 const double max_residual = 3.0 * sqrt(var_noise_);
65 // We try to filter out very late frames. For instance periodic key 77 // We try to filter out very late frames. For instance periodic key
66 // frames doesn't fit the Gaussian model well. 78 // frames doesn't fit the Gaussian model well.
67 if (fabs(residual) < max_residual) { 79 if (fabs(residual) < max_residual) {
68 UpdateNoiseEstimate(residual, min_frame_period, in_stable_state); 80 UpdateNoiseEstimate(residual, min_frame_period, in_stable_state);
69 } else { 81 } else {
70 UpdateNoiseEstimate(residual < 0 ? -max_residual : max_residual, 82 UpdateNoiseEstimate(residual < 0 ? -max_residual : max_residual,
71 min_frame_period, in_stable_state); 83 min_frame_period, in_stable_state);
72 } 84 }
73 const double k = e_ / (var_noise_ + e_); 85
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];
74 95
75 // Update state. 96 // Update state.
76 e_ = e_ * (1.0 - k); 97 E_[0][0] = e00 * IKh[0][0] + E_[1][0] * IKh[0][1];
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];
77 101
78 // The covariance matrix must be positive. 102 // The covariance matrix must be positive semi-definite.
79 RTC_DCHECK(e_ >= 0.0); 103 bool positive_semi_definite = E_[0][0] + E_[1][1] >= 0 &&
80 if (e_ < 0) 104 E_[0][0] * E_[1][1] - E_[0][1] * E_[1][0] >= 0 && E_[0][0] >= 0;
81 LOG(LS_ERROR) << "The over-use estimator's covariance is negative!"; 105 assert(positive_semi_definite);
106 if (!positive_semi_definite) {
107 LOG(LS_ERROR) << "The over-use estimator's covariance matrix is no longer "
108 "semi-definite.";
109 }
82 110
83 offset_ = offset_ + k * residual; 111 slope_ = slope_ + K[0] * residual;
112 prev_offset_ = offset_;
113 offset_ = offset_ + K[1] * residual;
84 } 114 }
85 115
86 double OveruseEstimator::UpdateMinFramePeriod(double send_delta_ms) { 116 double OveruseEstimator::UpdateMinFramePeriod(double ts_delta) {
87 double min_frame_period = send_delta_ms; 117 double min_frame_period = ts_delta;
88 if (send_delta_history_.size() >= kMinFramePeriodHistoryLength) { 118 if (ts_delta_hist_.size() >= kMinFramePeriodHistoryLength) {
89 send_delta_history_.pop_front(); 119 ts_delta_hist_.pop_front();
90 } 120 }
91 for (double delta_ms : send_delta_history_) { 121 std::list<double>::iterator it = ts_delta_hist_.begin();
92 min_frame_period = std::min(delta_ms, min_frame_period); 122 for (; it != ts_delta_hist_.end(); it++) {
123 min_frame_period = std::min(*it, min_frame_period);
93 } 124 }
94 send_delta_history_.push_back(send_delta_ms); 125 ts_delta_hist_.push_back(ts_delta);
95 return min_frame_period; 126 return min_frame_period;
96 } 127 }
97 128
98 void OveruseEstimator::UpdateNoiseEstimate(double residual, 129 void OveruseEstimator::UpdateNoiseEstimate(double residual,
99 double send_delta_ms, 130 double ts_delta,
100 bool stable_state) { 131 bool stable_state) {
101 if (!stable_state) { 132 if (!stable_state) {
102 return; 133 return;
103 } 134 }
104 // Faster filter during startup to faster adapt to the jitter level 135 // Faster filter during startup to faster adapt to the jitter level
105 // of the network. |alpha| is tuned for 30 frames per second, but is scaled 136 // of the network. |alpha| is tuned for 30 frames per second, but is scaled
106 // according to |send_delta_ms|. 137 // according to |ts_delta|.
107 double alpha = 0.01; 138 double alpha = 0.01;
108 if (num_of_deltas_ > 10*30) { 139 if (num_of_deltas_ > 10*30) {
109 alpha = 0.002; 140 alpha = 0.002;
110 } 141 }
111 // Only update the noise estimate if we're not over-using. |beta| is a 142 // Only update the noise estimate if we're not over-using. |beta| is a
112 // function of alpha and the time delta since the previous update. 143 // function of alpha and the time delta since the previous update.
113 const double beta = pow(1 - alpha, send_delta_ms * 30.0 / 1000.0); 144 const double beta = pow(1 - alpha, ts_delta * 30.0 / 1000.0);
114 avg_noise_ = beta * avg_noise_ 145 avg_noise_ = beta * avg_noise_
115 + (1 - beta) * residual; 146 + (1 - beta) * residual;
116 var_noise_ = beta * var_noise_ 147 var_noise_ = beta * var_noise_
117 + (1 - beta) * (avg_noise_ - residual) * (avg_noise_ - residual); 148 + (1 - beta) * (avg_noise_ - residual) * (avg_noise_ - residual);
118 if (var_noise_ < 1) { 149 if (var_noise_ < 1) {
119 var_noise_ = 1; 150 var_noise_ = 1;
120 } 151 }
121 } 152 }
122 } // namespace webrtc 153 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698