1 /* 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 14 #include "webrtc/base/constructormagic.h" 15 #include "webrtc/base/criticalsection.h" 16 #include "webrtc/base/scoped_ptr.h" 17 #include "webrtc/base/exp_filter.h" 18 #include "webrtc/base/thread_annotations.h" 19 #include "webrtc/base/thread_checker.h" 20 #include "webrtc/modules/interface/module.h" 21 #include "webrtc/video_engine/include/vie_base.h" 22 23 namespace webrtc { 24 25 class Clock; 26 class CpuOveruseObserver; 27 28 // TODO(pbos): Move this somewhere appropriate. 29 class Statistics { 30 public: 31 Statistics(); 32 33 void AddSample(float sample_ms); 34 void Reset(); 35 void SetOptions(const CpuOveruseOptions& options); 36 37 float Mean() const; 38 float StdDev() const; 39 uint64_t Count() const; 40 41 private: 42 float InitialMean() const; 43 float InitialVariance() const; 44 45 float sum_; 46 uint64_t count_; 47 CpuOveruseOptions options_; 48 rtc::scoped_ptr<rtc::ExpFilter> filtered_samples_; 49 rtc::scoped_ptr<rtc::ExpFilter> filtered_variance_; 50 }; 51 52 // Use to detect system overuse based on jitter in incoming frames. 53 class OveruseFrameDetector : public Module { 54 public: 55 OveruseFrameDetector(Clock* clock, 56 CpuOveruseMetricsObserver* metrics_observer); 57 ~OveruseFrameDetector(); 58 59 // Registers an observer receiving overuse and underuse callbacks. Set 60 // 'observer' to NULL to disable callbacks. 61 void SetObserver(CpuOveruseObserver* observer); 62 63 // Sets options for overuse detection. 64 void SetOptions(const CpuOveruseOptions& options); 65 66 // Called for each captured frame. 67 void FrameCaptured(int width, int height, int64_t capture_time_ms); 68 69 // Called when the processing of a captured frame is started. 70 void FrameProcessingStarted(); 71 72 // Called for each encoded frame. 73 void FrameEncoded(int encode_time_ms); 74 75 // Called for each sent frame. 76 void FrameSent(int64_t capture_time_ms); 77 78 // Only public for testing. 79 int CaptureQueueDelayMsPerS() const; 80 int LastProcessingTimeMs() const; 81 int FramesInQueue() const; 82 83 // Implements Module. 84 int64_t TimeUntilNextProcess() override; 85 int32_t Process() override; 86 87 private: 88 class EncodeTimeAvg; 89 class SendProcessingUsage; 90 class CaptureQueueDelay; 91 class FrameQueue; 92 93 void UpdateCpuOveruseMetrics() EXCLUSIVE_LOCKS_REQUIRED(crit_); 94 95 // TODO(asapersson): This method is only used on one thread, so it shouldn't 96 // need a guard. 97 void AddProcessingTime(int elapsed_ms) EXCLUSIVE_LOCKS_REQUIRED(crit_); 98 99 // TODO(asapersson): This method is always called on the processing thread. 100 // If locking is required, consider doing that locking inside the 101 // implementation and reduce scope as much as possible. We should also 102 // see if we can avoid calling out to other methods while holding the lock. 103 bool IsOverusing() EXCLUSIVE_LOCKS_REQUIRED(crit_); 104 bool IsUnderusing(int64_t time_now) EXCLUSIVE_LOCKS_REQUIRED(crit_); 105 106 bool FrameTimeoutDetected(int64_t now) const EXCLUSIVE_LOCKS_REQUIRED(crit_); 107 bool FrameSizeChanged(int num_pixels) const EXCLUSIVE_LOCKS_REQUIRED(crit_); 108 109 void ResetAll(int num_pixels) EXCLUSIVE_LOCKS_REQUIRED(crit_); 110 111 // Protecting all members except const and those that are only accessed on the 112 // processing thread. 113 // TODO(asapersson): See if we can reduce locking. As is, video frame 114 // processing contends with reading stats and the processing thread. 115 mutable rtc::CriticalSection crit_; 116 117 // Observer getting overuse reports. 118 CpuOveruseObserver* observer_ GUARDED_BY(crit_); 119 120 CpuOveruseOptions options_ GUARDED_BY(crit_); 121 122 // Stats metrics. 123 CpuOveruseMetricsObserver* const metrics_observer_; 124 CpuOveruseMetrics metrics_ GUARDED_BY(crit_); 125 126 Clock* const clock_; 127 int64_t next_process_time_; // Only accessed on the processing thread. 128 int64_t num_process_times_ GUARDED_BY(crit_); 129 130 Statistics capture_deltas_ GUARDED_BY(crit_); 131 int64_t last_capture_time_ GUARDED_BY(crit_); 132 133 // These six members are only accessed on the processing thread. 134 int64_t last_overuse_time_; 135 int checks_above_threshold_; 136 int num_overuse_detections_; 137 138 int64_t last_rampup_time_; 139 bool in_quick_rampup_; 140 int current_rampup_delay_ms_; 141 142 // Number of pixels of last captured frame. 143 int num_pixels_ GUARDED_BY(crit_); 144 145 int64_t last_encode_sample_ms_; // Only accessed by one thread. 146 147 // TODO(asapersson): Can these be regular members (avoid separate heap 148 // allocs)? 149 const rtc::scoped_ptr<EncodeTimeAvg> encode_time_ GUARDED_BY(crit_); 150 const rtc::scoped_ptr<SendProcessingUsage> usage_ GUARDED_BY(crit_); 151 const rtc::scoped_ptr<FrameQueue> frame_queue_ GUARDED_BY(crit_); 152 153 int64_t last_sample_time_ms_; // Only accessed by one thread. 154 155 const rtc::scoped_ptr<CaptureQueueDelay> capture_queue_delay_ 156 GUARDED_BY(crit_); 157 158 rtc::ThreadChecker processing_thread_; 159 160 DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector); 161 }; 162 163 } // namespace webrtc 164 165 #endif // WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_ 166