blob: c136130b9c83391df8a0045165156fdbc3895065 [file] [log] [blame]
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +00001/*
2 * Copyright (c) 2013 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_engine/overuse_frame_detector.h"
12
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000013#include <assert.h>
pbos@webrtc.orga9575702013-08-30 17:16:32 +000014#include <math.h>
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000015
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +000016#include <algorithm>
17#include <list>
18
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000019#include "webrtc/modules/video_coding/utility/include/exp_filter.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000020#include "webrtc/system_wrappers/interface/clock.h"
21#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +000022#include "webrtc/system_wrappers/interface/logging.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000023
24namespace webrtc {
25
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000026// TODO(mflodman) Test different values for all of these to trigger correctly,
27// avoid fluctuations etc.
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000028namespace {
pbos@webrtc.orga9575702013-08-30 17:16:32 +000029const int64_t kProcessIntervalMs = 5000;
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000030
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000031// Weight factor to apply to the standard deviation.
32const float kWeightFactor = 0.997f;
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000033// Weight factor to apply to the average.
34const float kWeightFactorMean = 0.98f;
35
pbos@webrtc.orga9575702013-08-30 17:16:32 +000036// Delay between consecutive rampups. (Used for quick recovery.)
37const int kQuickRampUpDelayMs = 10 * 1000;
38// Delay between rampup attempts. Initially uses standard, scales up to max.
39const int kStandardRampUpDelayMs = 30 * 1000;
40const int kMaxRampUpDelayMs = 120 * 1000;
41// Expontential back-off factor, to prevent annoying up-down behaviour.
42const double kRampUpBackoffFactor = 2.0;
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000043
asapersson@webrtc.orgc7ff8f92013-11-26 11:12:33 +000044// The initial average encode time (set to a fairly small value).
45const float kInitialAvgEncodeTimeMs = 5.0f;
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +000046
47// The maximum exponent to use in VCMExpFilter.
48const float kSampleDiffMs = 33.0f;
49const float kMaxExp = 7.0f;
50
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000051} // namespace
52
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000053Statistics::Statistics() :
54 sum_(0.0),
55 count_(0),
56 filtered_samples_(new VCMExpFilter(kWeightFactorMean)),
57 filtered_variance_(new VCMExpFilter(kWeightFactor)) {
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000058 Reset();
59}
60
61void Statistics::SetOptions(const CpuOveruseOptions& options) {
62 options_ = options;
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000063}
64
65void Statistics::Reset() {
66 sum_ = 0.0;
67 count_ = 0;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000068 filtered_variance_->Reset(kWeightFactor);
69 filtered_variance_->Apply(1.0f, InitialVariance());
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000070}
71
72void Statistics::AddSample(float sample_ms) {
73 sum_ += sample_ms;
74 ++count_;
75
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000076 if (count_ < static_cast<uint32_t>(options_.min_frame_samples)) {
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000077 // Initialize filtered samples.
78 filtered_samples_->Reset(kWeightFactorMean);
79 filtered_samples_->Apply(1.0f, InitialMean());
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000080 return;
81 }
82
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +000083 float exp = sample_ms / kSampleDiffMs;
84 exp = std::min(exp, kMaxExp);
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000085 filtered_samples_->Apply(exp, sample_ms);
86 filtered_variance_->Apply(exp, (sample_ms - filtered_samples_->Value()) *
87 (sample_ms - filtered_samples_->Value()));
88}
89
90float Statistics::InitialMean() const {
91 if (count_ == 0)
92 return 0.0;
93 return sum_ / count_;
94}
95
96float Statistics::InitialVariance() const {
97 // Start in between the underuse and overuse threshold.
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000098 float average_stddev = (options_.low_capture_jitter_threshold_ms +
99 options_.high_capture_jitter_threshold_ms) / 2.0f;
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +0000100 return average_stddev * average_stddev;
101}
102
103float Statistics::Mean() const { return filtered_samples_->Value(); }
104
105float Statistics::StdDev() const {
106 return sqrt(std::max(filtered_variance_->Value(), 0.0f));
107}
108
109uint64_t Statistics::Count() const { return count_; }
110
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000111
112// Class for calculating the average encode time.
113class OveruseFrameDetector::EncodeTimeAvg {
114 public:
115 EncodeTimeAvg()
116 : kWeightFactor(0.5f),
117 filtered_encode_time_ms_(new VCMExpFilter(kWeightFactor)) {
118 filtered_encode_time_ms_->Apply(1.0f, kInitialAvgEncodeTimeMs);
119 }
120 ~EncodeTimeAvg() {}
121
122 void AddEncodeSample(float encode_time_ms, int64_t diff_last_sample_ms) {
123 float exp = diff_last_sample_ms / kSampleDiffMs;
124 exp = std::min(exp, kMaxExp);
125 filtered_encode_time_ms_->Apply(exp, encode_time_ms);
126 }
127
128 int filtered_encode_time_ms() const {
129 return static_cast<int>(filtered_encode_time_ms_->Value() + 0.5);
130 }
131
132 private:
133 const float kWeightFactor;
134 scoped_ptr<VCMExpFilter> filtered_encode_time_ms_;
135};
136
137// Class for calculating the encode usage.
138class OveruseFrameDetector::EncodeUsage {
139 public:
140 EncodeUsage()
141 : kWeightFactorFrameDiff(0.998f),
142 kWeightFactorEncodeTime(0.995f),
asapersson@webrtc.orge41dbee2014-05-13 13:45:13 +0000143 kInitialSampleDiffMs(40.0f),
144 kMaxSampleDiffMs(45.0f),
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000145 count_(0),
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000146 filtered_encode_time_ms_(new VCMExpFilter(kWeightFactorEncodeTime)),
147 filtered_frame_diff_ms_(new VCMExpFilter(kWeightFactorFrameDiff)) {
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000148 Reset();
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000149 }
150 ~EncodeUsage() {}
151
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000152 void SetOptions(const CpuOveruseOptions& options) {
153 options_ = options;
154 }
155
156 void Reset() {
157 count_ = 0;
158 filtered_frame_diff_ms_->Reset(kWeightFactorFrameDiff);
159 filtered_frame_diff_ms_->Apply(1.0f, kInitialSampleDiffMs);
160 filtered_encode_time_ms_->Reset(kWeightFactorEncodeTime);
161 filtered_encode_time_ms_->Apply(1.0f, InitialEncodeTimeMs());
162 }
163
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000164 void AddSample(float sample_ms) {
165 float exp = sample_ms / kSampleDiffMs;
166 exp = std::min(exp, kMaxExp);
167 filtered_frame_diff_ms_->Apply(exp, sample_ms);
168 }
169
170 void AddEncodeSample(float encode_time_ms, int64_t diff_last_sample_ms) {
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000171 ++count_;
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000172 float exp = diff_last_sample_ms / kSampleDiffMs;
173 exp = std::min(exp, kMaxExp);
174 filtered_encode_time_ms_->Apply(exp, encode_time_ms);
175 }
176
177 int UsageInPercent() const {
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000178 if (count_ < static_cast<uint32_t>(options_.min_frame_samples)) {
179 return static_cast<int>(InitialUsageInPercent() + 0.5f);
180 }
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000181 float frame_diff_ms = std::max(filtered_frame_diff_ms_->Value(), 1.0f);
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000182 frame_diff_ms = std::min(frame_diff_ms, kMaxSampleDiffMs);
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000183 float encode_usage_percent =
184 100.0f * filtered_encode_time_ms_->Value() / frame_diff_ms;
185 return static_cast<int>(encode_usage_percent + 0.5);
186 }
187
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000188 float InitialUsageInPercent() const {
189 // Start in between the underuse and overuse threshold.
190 return (options_.low_encode_usage_threshold_percent +
191 options_.high_encode_usage_threshold_percent) / 2.0f;
192 }
193
194 float InitialEncodeTimeMs() const {
195 return InitialUsageInPercent() * kInitialSampleDiffMs / 100;
196 }
197
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000198 private:
199 const float kWeightFactorFrameDiff;
200 const float kWeightFactorEncodeTime;
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000201 const float kInitialSampleDiffMs;
202 const float kMaxSampleDiffMs;
203 uint64_t count_;
204 CpuOveruseOptions options_;
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000205 scoped_ptr<VCMExpFilter> filtered_encode_time_ms_;
206 scoped_ptr<VCMExpFilter> filtered_frame_diff_ms_;
207};
208
209// Class for calculating the capture queue delay change.
210class OveruseFrameDetector::CaptureQueueDelay {
211 public:
212 CaptureQueueDelay()
213 : kWeightFactor(0.5f),
214 delay_ms_(0),
215 filtered_delay_ms_per_s_(new VCMExpFilter(kWeightFactor)) {
216 filtered_delay_ms_per_s_->Apply(1.0f, 0.0f);
217 }
218 ~CaptureQueueDelay() {}
219
220 void FrameCaptured(int64_t now) {
221 const size_t kMaxSize = 200;
222 if (frames_.size() > kMaxSize) {
223 frames_.pop_front();
224 }
225 frames_.push_back(now);
226 }
227
228 void FrameProcessingStarted(int64_t now) {
229 if (frames_.empty()) {
230 return;
231 }
232 delay_ms_ = now - frames_.front();
233 frames_.pop_front();
234 }
235
236 void CalculateDelayChange(int64_t diff_last_sample_ms) {
237 if (diff_last_sample_ms <= 0) {
238 return;
239 }
240 float exp = static_cast<float>(diff_last_sample_ms) / kProcessIntervalMs;
241 exp = std::min(exp, kMaxExp);
242 filtered_delay_ms_per_s_->Apply(exp,
243 delay_ms_ * 1000.0f / diff_last_sample_ms);
244 ClearFrames();
245 }
246
247 void ClearFrames() {
248 frames_.clear();
249 }
250
251 int delay_ms() const {
252 return delay_ms_;
253 }
254
255 int filtered_delay_ms_per_s() const {
256 return static_cast<int>(filtered_delay_ms_per_s_->Value() + 0.5);
257 }
258
259 private:
260 const float kWeightFactor;
261 std::list<int64_t> frames_;
262 int delay_ms_;
263 scoped_ptr<VCMExpFilter> filtered_delay_ms_per_s_;
264};
265
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000266OveruseFrameDetector::OveruseFrameDetector(Clock* clock)
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000267 : crit_(CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +0000268 observer_(NULL),
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000269 clock_(clock),
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000270 next_process_time_(clock_->TimeInMilliseconds()),
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000271 num_process_times_(0),
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000272 last_capture_time_(0),
273 last_overuse_time_(0),
274 checks_above_threshold_(0),
275 last_rampup_time_(0),
276 in_quick_rampup_(false),
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +0000277 current_rampup_delay_ms_(kStandardRampUpDelayMs),
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000278 num_pixels_(0),
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000279 last_encode_sample_ms_(0),
280 encode_time_(new EncodeTimeAvg()),
281 encode_usage_(new EncodeUsage()),
282 capture_queue_delay_(new CaptureQueueDelay()) {
283}
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000284
285OveruseFrameDetector::~OveruseFrameDetector() {
286}
287
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +0000288void OveruseFrameDetector::SetObserver(CpuOveruseObserver* observer) {
289 CriticalSectionScoped cs(crit_.get());
290 observer_ = observer;
291}
292
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000293void OveruseFrameDetector::SetOptions(const CpuOveruseOptions& options) {
294 assert(options.min_frame_samples > 0);
295 CriticalSectionScoped cs(crit_.get());
296 if (options_.Equals(options)) {
297 return;
298 }
299 options_ = options;
300 capture_deltas_.SetOptions(options);
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000301 encode_usage_->SetOptions(options);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000302 ResetAll(num_pixels_);
303}
304
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000305int OveruseFrameDetector::CaptureQueueDelayMsPerS() const {
306 CriticalSectionScoped cs(crit_.get());
307 return capture_queue_delay_->delay_ms();
308}
309
asapersson@webrtc.orgab6bf4f2014-05-27 07:43:15 +0000310void OveruseFrameDetector::GetCpuOveruseMetrics(
311 CpuOveruseMetrics* metrics) const {
312 CriticalSectionScoped cs(crit_.get());
313 metrics->capture_jitter_ms = static_cast<int>(capture_deltas_.StdDev() + 0.5);
314 metrics->avg_encode_time_ms = encode_time_->filtered_encode_time_ms();
315 metrics->encode_usage_percent = encode_usage_->UsageInPercent();
316 metrics->capture_queue_delay_ms_per_s =
317 capture_queue_delay_->filtered_delay_ms_per_s();
318}
319
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000320int32_t OveruseFrameDetector::TimeUntilNextProcess() {
321 CriticalSectionScoped cs(crit_.get());
322 return next_process_time_ - clock_->TimeInMilliseconds();
323}
324
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000325bool OveruseFrameDetector::FrameSizeChanged(int num_pixels) const {
326 if (num_pixels != num_pixels_) {
327 return true;
328 }
329 return false;
330}
331
332bool OveruseFrameDetector::FrameTimeoutDetected(int64_t now) const {
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000333 if (last_capture_time_ == 0) {
334 return false;
335 }
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000336 return (now - last_capture_time_) > options_.frame_timeout_interval_ms;
337}
338
339void OveruseFrameDetector::ResetAll(int num_pixels) {
340 num_pixels_ = num_pixels;
341 capture_deltas_.Reset();
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000342 encode_usage_->Reset();
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000343 capture_queue_delay_->ClearFrames();
344 last_capture_time_ = 0;
345 num_process_times_ = 0;
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000346}
347
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +0000348void OveruseFrameDetector::FrameCaptured(int width, int height) {
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000349 CriticalSectionScoped cs(crit_.get());
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +0000350
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000351 int64_t now = clock_->TimeInMilliseconds();
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000352 if (FrameSizeChanged(width * height) || FrameTimeoutDetected(now)) {
353 ResetAll(width * height);
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +0000354 }
355
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000356 if (last_capture_time_ != 0) {
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000357 capture_deltas_.AddSample(now - last_capture_time_);
358 encode_usage_->AddSample(now - last_capture_time_);
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000359 }
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000360 last_capture_time_ = now;
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000361
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000362 capture_queue_delay_->FrameCaptured(now);
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000363}
364
365void OveruseFrameDetector::FrameProcessingStarted() {
366 CriticalSectionScoped cs(crit_.get());
367 capture_queue_delay_->FrameProcessingStarted(clock_->TimeInMilliseconds());
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000368}
369
asapersson@webrtc.orgc7ff8f92013-11-26 11:12:33 +0000370void OveruseFrameDetector::FrameEncoded(int encode_time_ms) {
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000371 CriticalSectionScoped cs(crit_.get());
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000372 int64_t time = clock_->TimeInMilliseconds();
373 if (last_encode_sample_ms_ != 0) {
374 int64_t diff_ms = time - last_encode_sample_ms_;
375 encode_time_->AddEncodeSample(encode_time_ms, diff_ms);
376 encode_usage_->AddEncodeSample(encode_time_ms, diff_ms);
377 }
378 last_encode_sample_ms_ = time;
asapersson@webrtc.orgc7ff8f92013-11-26 11:12:33 +0000379}
380
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000381int32_t OveruseFrameDetector::Process() {
382 CriticalSectionScoped cs(crit_.get());
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000383
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +0000384 int64_t now = clock_->TimeInMilliseconds();
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000385
386 // Used to protect against Process() being called too often.
387 if (now < next_process_time_)
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000388 return 0;
389
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000390 int64_t diff_ms = now - next_process_time_ + kProcessIntervalMs;
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000391 next_process_time_ = now + kProcessIntervalMs;
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000392 ++num_process_times_;
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000393
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000394 capture_queue_delay_->CalculateDelayChange(diff_ms);
395
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000396 if (num_process_times_ <= options_.min_process_count) {
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000397 return 0;
398 }
399
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000400 if (IsOverusing()) {
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000401 // If the last thing we did was going up, and now have to back down, we need
402 // to check if this peak was short. If so we should back off to avoid going
403 // back and forth between this load, the system doesn't seem to handle it.
404 bool check_for_backoff = last_rampup_time_ > last_overuse_time_;
405 if (check_for_backoff) {
406 if (now - last_rampup_time_ < kStandardRampUpDelayMs) {
407 // Going up was not ok for very long, back off.
408 current_rampup_delay_ms_ *= kRampUpBackoffFactor;
409 if (current_rampup_delay_ms_ > kMaxRampUpDelayMs)
410 current_rampup_delay_ms_ = kMaxRampUpDelayMs;
411 } else {
412 // Not currently backing off, reset rampup delay.
413 current_rampup_delay_ms_ = kStandardRampUpDelayMs;
414 }
415 }
416
417 last_overuse_time_ = now;
418 in_quick_rampup_ = false;
419 checks_above_threshold_ = 0;
420
421 if (observer_ != NULL)
422 observer_->OveruseDetected();
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000423 } else if (IsUnderusing(now)) {
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000424 last_rampup_time_ = now;
425 in_quick_rampup_ = true;
426
427 if (observer_ != NULL)
428 observer_->NormalUsage();
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000429 }
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000430
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +0000431 int rampup_delay =
432 in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_;
433 LOG(LS_VERBOSE) << "Capture input stats: avg: " << capture_deltas_.Mean()
434 << " std_dev " << capture_deltas_.StdDev()
435 << " rampup delay " << rampup_delay
436 << " overuse >= " << options_.high_capture_jitter_threshold_ms
437 << " underuse < " << options_.low_capture_jitter_threshold_ms;
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +0000438 return 0;
439}
440
441bool OveruseFrameDetector::IsOverusing() {
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000442 bool overusing = false;
443 if (options_.enable_capture_jitter_method) {
444 overusing = capture_deltas_.StdDev() >=
445 options_.high_capture_jitter_threshold_ms;
446 } else if (options_.enable_encode_usage_method) {
447 overusing = encode_usage_->UsageInPercent() >=
448 options_.high_encode_usage_threshold_percent;
449 }
450
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000451 if (overusing) {
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000452 ++checks_above_threshold_;
453 } else {
454 checks_above_threshold_ = 0;
455 }
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000456 return checks_above_threshold_ >= options_.high_threshold_consecutive_count;
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000457}
458
459bool OveruseFrameDetector::IsUnderusing(int64_t time_now) {
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000460 int delay = in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_;
461 if (time_now < last_rampup_time_ + delay)
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000462 return false;
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000463
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000464 bool underusing = false;
465 if (options_.enable_capture_jitter_method) {
466 underusing = capture_deltas_.StdDev() <
467 options_.low_capture_jitter_threshold_ms;
468 } else if (options_.enable_encode_usage_method) {
469 underusing = encode_usage_->UsageInPercent() <
470 options_.low_encode_usage_threshold_percent;
471 }
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000472 return underusing;
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000473}
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000474} // namespace webrtc