blob: 61d1506a209c96b7829b02ee0c56488996015dda [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.orge6168f52013-06-26 11:23:01 +000013#include "webrtc/system_wrappers/interface/clock.h"
14#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000015#include "webrtc/video_engine/include/vie_base.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000016
17namespace webrtc {
18
19// TODO(mflodman) Test different thresholds.
20const int64_t kProcessIntervalMs = 2000;
21const int kOveruseHistoryMs = 5000;
22const float kMinEncodeRatio = 29 / 30.0f;
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000023const int kMinCallbackDeltaMs = 30000;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000024
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000025OveruseFrameDetector::OveruseFrameDetector(Clock* clock)
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000026 : crit_(CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000027 observer_(NULL),
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000028 clock_(clock),
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000029 last_process_time_(clock->TimeInMilliseconds()),
30 last_callback_time_(clock->TimeInMilliseconds()) {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000031}
32
33OveruseFrameDetector::~OveruseFrameDetector() {
34}
35
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000036void OveruseFrameDetector::SetObserver(CpuOveruseObserver* observer) {
37 CriticalSectionScoped cs(crit_.get());
38 observer_ = observer;
39}
40
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000041void OveruseFrameDetector::CapturedFrame() {
42 CriticalSectionScoped cs(crit_.get());
43 CleanOldSamples();
44 capture_times_.push_back(clock_->TimeInMilliseconds());
45}
46
47void OveruseFrameDetector::EncodedFrame() {
48 CriticalSectionScoped cs(crit_.get());
49 encode_times_.push_back(clock_->TimeInMilliseconds());
50}
51
52int32_t OveruseFrameDetector::TimeUntilNextProcess() {
53 return last_process_time_ + kProcessIntervalMs - clock_->TimeInMilliseconds();
54}
55
56int32_t OveruseFrameDetector::Process() {
57 CriticalSectionScoped cs(crit_.get());
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000058 int64_t now = clock_->TimeInMilliseconds();
59 if (now < last_process_time_ + kProcessIntervalMs)
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000060 return 0;
61
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000062 last_process_time_ = now;
63 if (!observer_ || encode_times_.size() == 0 || capture_times_.size() == 0)
64 return 0;
65
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000066 CleanOldSamples();
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000067 if (encode_times_.front() > now - kOveruseHistoryMs / 2) {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000068 return 0;
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000069 }
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000070 float encode_ratio = encode_times_.size() /
71 static_cast<float>(capture_times_.size());
72 if (encode_ratio < kMinEncodeRatio) {
73 observer_->OveruseDetected();
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000074 capture_times_.clear();
75 encode_times_.clear();
76 last_callback_time_ = now;
77 } else if (last_callback_time_ < now - kMinCallbackDeltaMs) {
78 // TODO(mflodman) This should only be triggered if we have a good reason to
79 // believe we can increase the resolution again.
80 observer_->NormalUsage();
81 last_callback_time_ = now;
82 capture_times_.clear();
83 encode_times_.clear();
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000084 }
85 return 0;
86}
87
88void OveruseFrameDetector::CleanOldSamples() {
89 int64_t time_now = clock_->TimeInMilliseconds();
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000090 while (!capture_times_.empty() &&
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000091 capture_times_.front() < time_now - kOveruseHistoryMs) {
92 capture_times_.pop_front();
93 }
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000094 while (!encode_times_.empty() &&
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000095 encode_times_.front() < time_now - kOveruseHistoryMs) {
96 encode_times_.pop_front();
97 }
98}
99} // namespace webrtc