blob: 57758e2ed214a50bcefad61cf25f74470c5bd161 [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#ifndef WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_
12#define WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_
13
henrike@webrtc.org88fbb2d2014-05-21 21:18:46 +000014#include "webrtc/base/constructormagic.h"
tommi@webrtc.org18e75852015-01-29 12:34:40 +000015#include "webrtc/base/criticalsection.h"
minyue@webrtc.org74aaf292014-07-16 21:28:26 +000016#include "webrtc/base/exp_filter.h"
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +000017#include "webrtc/base/thread_annotations.h"
tommi@webrtc.org18e75852015-01-29 12:34:40 +000018#include "webrtc/base/thread_checker.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000019#include "webrtc/modules/interface/module.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000020#include "webrtc/system_wrappers/interface/scoped_ptr.h"
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000021#include "webrtc/video_engine/include/vie_base.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000022
23namespace webrtc {
24
25class Clock;
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000026class CpuOveruseObserver;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000027
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000028// TODO(pbos): Move this somewhere appropriate.
pbos@webrtc.orga9575702013-08-30 17:16:32 +000029class Statistics {
30 public:
31 Statistics();
32
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000033 void AddSample(float sample_ms);
pbos@webrtc.orga9575702013-08-30 17:16:32 +000034 void Reset();
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000035 void SetOptions(const CpuOveruseOptions& options);
pbos@webrtc.orga9575702013-08-30 17:16:32 +000036
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000037 float Mean() const;
38 float StdDev() const;
39 uint64_t Count() const;
pbos@webrtc.orga9575702013-08-30 17:16:32 +000040
41 private:
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +000042 float InitialMean() const;
43 float InitialVariance() const;
44
45 float sum_;
pbos@webrtc.orga9575702013-08-30 17:16:32 +000046 uint64_t count_;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000047 CpuOveruseOptions options_;
minyue@webrtc.org74aaf292014-07-16 21:28:26 +000048 scoped_ptr<rtc::ExpFilter> filtered_samples_;
49 scoped_ptr<rtc::ExpFilter> filtered_variance_;
pbos@webrtc.orga9575702013-08-30 17:16:32 +000050};
51
52// Use to detect system overuse based on jitter in incoming frames.
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000053class OveruseFrameDetector : public Module {
54 public:
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000055 explicit OveruseFrameDetector(Clock* clock);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000056 ~OveruseFrameDetector();
57
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000058 // Registers an observer receiving overuse and underuse callbacks. Set
59 // 'observer' to NULL to disable callbacks.
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000060 void SetObserver(CpuOveruseObserver* observer);
61
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000062 // Sets options for overuse detection.
63 void SetOptions(const CpuOveruseOptions& options);
64
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000065 // Called for each captured frame.
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +000066 void FrameCaptured(int width, int height, int64_t capture_time_ms);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000067
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +000068 // Called when the processing of a captured frame is started.
69 void FrameProcessingStarted();
70
71 // Called for each encoded frame.
asapersson@webrtc.orgc7ff8f92013-11-26 11:12:33 +000072 void FrameEncoded(int encode_time_ms);
73
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +000074 // Called for each sent frame.
75 void FrameSent(int64_t capture_time_ms);
76
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +000077 // Accessors.
asapersson@webrtc.orgc7ff8f92013-11-26 11:12:33 +000078
asapersson@webrtc.orgab6bf4f2014-05-27 07:43:15 +000079 // Returns CpuOveruseMetrics where
80 // capture_jitter_ms: The estimated jitter based on incoming captured frames.
81 // avg_encode_time_ms: Running average of reported encode time
82 // (FrameEncoded()). Only used for stats.
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +000083 // TODO(asapersson): Rename metric.
84 // encode_usage_percent: The average processing time of a frame on the
85 // send-side divided by the average time difference
86 // between incoming captured frames.
asapersson@webrtc.orgab6bf4f2014-05-27 07:43:15 +000087 // capture_queue_delay_ms_per_s: The current time delay between an incoming
88 // captured frame (FrameCaptured()) until the
89 // frame is being processed
90 // (FrameProcessingStarted()). (Note: if a new
91 // frame is received before an old frame has
92 // been processed, the old frame is skipped).
93 // The delay is expressed in ms delay per sec.
94 // Only used for stats.
95 void GetCpuOveruseMetrics(CpuOveruseMetrics* metrics) const;
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +000096
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +000097 // Only public for testing.
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +000098 int CaptureQueueDelayMsPerS() const;
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +000099 int LastProcessingTimeMs() const;
100 int FramesInQueue() const;
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000101
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000102 // Implements Module.
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000103 virtual int64_t TimeUntilNextProcess() OVERRIDE;
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000104 virtual int32_t Process() OVERRIDE;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000105
106 private:
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000107 class EncodeTimeAvg;
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000108 class SendProcessingUsage;
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000109 class CaptureQueueDelay;
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000110 class FrameQueue;
111
tommi@webrtc.org18e75852015-01-29 12:34:40 +0000112 // TODO(asapersson): This method is only used on one thread, so it shouldn't
113 // need a guard.
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000114 void AddProcessingTime(int elapsed_ms) EXCLUSIVE_LOCKS_REQUIRED(crit_);
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000115
tommi@webrtc.org18e75852015-01-29 12:34:40 +0000116 // TODO(asapersson): This method is always called on the processing thread.
117 // If locking is required, consider doing that locking inside the
118 // implementation and reduce scope as much as possible. We should also
119 // see if we can avoid calling out to other methods while holding the lock.
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000120 bool IsOverusing() EXCLUSIVE_LOCKS_REQUIRED(crit_);
121 bool IsUnderusing(int64_t time_now) EXCLUSIVE_LOCKS_REQUIRED(crit_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000122
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000123 bool FrameTimeoutDetected(int64_t now) const EXCLUSIVE_LOCKS_REQUIRED(crit_);
124 bool FrameSizeChanged(int num_pixels) const EXCLUSIVE_LOCKS_REQUIRED(crit_);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000125
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000126 void ResetAll(int num_pixels) EXCLUSIVE_LOCKS_REQUIRED(crit_);
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000127
tommi@webrtc.org18e75852015-01-29 12:34:40 +0000128 // Protecting all members except const and those that are only accessed on the
129 // processing thread.
130 // TODO(asapersson): See if we can reduce locking. As is, video frame
131 // processing contends with reading stats and the processing thread.
132 mutable rtc::CriticalSection crit_;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000133
134 // Observer getting overuse reports.
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000135 CpuOveruseObserver* observer_ GUARDED_BY(crit_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000136
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000137 CpuOveruseOptions options_ GUARDED_BY(crit_);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000138
tommi@webrtc.orga907e012015-01-28 17:33:12 +0000139 Clock* const clock_;
tommi@webrtc.org18e75852015-01-29 12:34:40 +0000140 int64_t next_process_time_; // Only accessed on the processing thread.
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000141 int64_t num_process_times_ GUARDED_BY(crit_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000142
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000143 Statistics capture_deltas_ GUARDED_BY(crit_);
144 int64_t last_capture_time_ GUARDED_BY(crit_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000145
tommi@webrtc.org18e75852015-01-29 12:34:40 +0000146 // These six members are only accessed on the processing thread.
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000147 int64_t last_overuse_time_;
148 int checks_above_threshold_;
asapersson@webrtc.orgd9803072014-06-16 14:27:19 +0000149 int num_overuse_detections_;
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000150
151 int64_t last_rampup_time_;
152 bool in_quick_rampup_;
153 int current_rampup_delay_ms_;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000154
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +0000155 // Number of pixels of last captured frame.
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000156 int num_pixels_ GUARDED_BY(crit_);
asapersson@webrtc.orge2af6222013-09-23 20:05:39 +0000157
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000158 int64_t last_encode_sample_ms_ GUARDED_BY(crit_);
tommi@webrtc.org18e75852015-01-29 12:34:40 +0000159 // TODO(asapersson): Can these be regular members (avoid separate heap
160 // allocs)?
161 const scoped_ptr<EncodeTimeAvg> encode_time_ GUARDED_BY(crit_);
162 const scoped_ptr<SendProcessingUsage> usage_ GUARDED_BY(crit_);
163 const scoped_ptr<FrameQueue> frame_queue_ GUARDED_BY(crit_);
164
165 // TODO(asapersson): This variable is only used on one thread, so it shouldn't
166 // need a guard.
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +0000167 int64_t last_sample_time_ms_ GUARDED_BY(crit_);
asapersson@webrtc.org9e5b0342013-12-04 13:47:44 +0000168
tommi@webrtc.org18e75852015-01-29 12:34:40 +0000169 const scoped_ptr<CaptureQueueDelay> capture_queue_delay_ GUARDED_BY(crit_);
170
171 rtc::ThreadChecker processing_thread_;
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000172
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000173 DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
174};
175
176} // namespace webrtc
177
178#endif // WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_