Line data Source code
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_OVERUSE_FRAME_DETECTOR_H_
12 : #define WEBRTC_VIDEO_OVERUSE_FRAME_DETECTOR_H_
13 :
14 : #include <list>
15 : #include <memory>
16 :
17 : #include "webrtc/base/constructormagic.h"
18 : #include "webrtc/base/numerics/exp_filter.h"
19 : #include "webrtc/base/optional.h"
20 : #include "webrtc/base/sequenced_task_checker.h"
21 : #include "webrtc/base/task_queue.h"
22 : #include "webrtc/base/thread_annotations.h"
23 : #include "webrtc/modules/video_coding/utility/quality_scaler.h"
24 :
25 : namespace webrtc {
26 :
27 : class Clock;
28 : class EncodedFrameObserver;
29 : class VideoFrame;
30 :
31 : struct CpuOveruseOptions {
32 : CpuOveruseOptions();
33 :
34 : int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
35 : int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
36 : // General settings.
37 : int frame_timeout_interval_ms; // The maximum allowed interval between two
38 : // frames before resetting estimations.
39 : int min_frame_samples; // The minimum number of frames required.
40 : int min_process_count; // The number of initial process times required before
41 : // triggering an overuse/underuse.
42 : int high_threshold_consecutive_count; // The number of consecutive checks
43 : // above the high threshold before
44 : // triggering an overuse.
45 : };
46 :
47 : struct CpuOveruseMetrics {
48 0 : CpuOveruseMetrics() : encode_usage_percent(-1) {}
49 :
50 : int encode_usage_percent; // Average encode time divided by the average time
51 : // difference between incoming captured frames.
52 : };
53 :
54 0 : class CpuOveruseMetricsObserver {
55 : public:
56 0 : virtual ~CpuOveruseMetricsObserver() {}
57 : virtual void OnEncodedFrameTimeMeasured(int encode_duration_ms,
58 : const CpuOveruseMetrics& metrics) = 0;
59 : };
60 :
61 : // Use to detect system overuse based on the send-side processing time of
62 : // incoming frames. All methods must be called on a single task queue but it can
63 : // be created and destroyed on an arbitrary thread.
64 : // OveruseFrameDetector::StartCheckForOveruse must be called to periodically
65 : // check for overuse.
66 : class OveruseFrameDetector {
67 : public:
68 : OveruseFrameDetector(Clock* clock,
69 : const CpuOveruseOptions& options,
70 : ScalingObserverInterface* overuse_observer,
71 : EncodedFrameObserver* encoder_timing_,
72 : CpuOveruseMetricsObserver* metrics_observer);
73 : ~OveruseFrameDetector();
74 :
75 : // Start to periodically check for overuse.
76 : void StartCheckForOveruse();
77 :
78 : // StopCheckForOveruse must be called before destruction if
79 : // StartCheckForOveruse has been called.
80 : void StopCheckForOveruse();
81 :
82 : // Called for each captured frame.
83 : void FrameCaptured(const VideoFrame& frame, int64_t time_when_first_seen_ms);
84 :
85 : // Called for each sent frame.
86 : void FrameSent(uint32_t timestamp, int64_t time_sent_in_ms);
87 :
88 : protected:
89 : void CheckForOveruse(); // Protected for test purposes.
90 :
91 : private:
92 : class SendProcessingUsage;
93 : class CheckOveruseTask;
94 : struct FrameTiming {
95 0 : FrameTiming(int64_t capture_ntp_ms, uint32_t timestamp, int64_t now)
96 0 : : capture_ntp_ms(capture_ntp_ms),
97 : timestamp(timestamp),
98 : capture_ms(now),
99 0 : last_send_ms(-1) {}
100 : int64_t capture_ntp_ms;
101 : uint32_t timestamp;
102 : int64_t capture_ms;
103 : int64_t last_send_ms;
104 : };
105 :
106 : void EncodedFrameTimeMeasured(int encode_duration_ms);
107 : bool IsOverusing(const CpuOveruseMetrics& metrics);
108 : bool IsUnderusing(const CpuOveruseMetrics& metrics, int64_t time_now);
109 :
110 : bool FrameTimeoutDetected(int64_t now) const;
111 : bool FrameSizeChanged(int num_pixels) const;
112 :
113 : void ResetAll(int num_pixels);
114 :
115 : rtc::SequencedTaskChecker task_checker_;
116 : // Owned by the task queue from where StartCheckForOveruse is called.
117 : CheckOveruseTask* check_overuse_task_;
118 :
119 : const CpuOveruseOptions options_;
120 :
121 : // Observer getting overuse reports.
122 : ScalingObserverInterface* const observer_;
123 : EncodedFrameObserver* const encoder_timing_;
124 :
125 : // Stats metrics.
126 : CpuOveruseMetricsObserver* const metrics_observer_;
127 : rtc::Optional<CpuOveruseMetrics> metrics_ GUARDED_BY(task_checker_);
128 : Clock* const clock_;
129 :
130 : int64_t num_process_times_ GUARDED_BY(task_checker_);
131 :
132 : int64_t last_capture_time_ms_ GUARDED_BY(task_checker_);
133 : int64_t last_processed_capture_time_ms_ GUARDED_BY(task_checker_);
134 :
135 : // Number of pixels of last captured frame.
136 : int num_pixels_ GUARDED_BY(task_checker_);
137 : int64_t last_overuse_time_ms_ GUARDED_BY(task_checker_);
138 : int checks_above_threshold_ GUARDED_BY(task_checker_);
139 : int num_overuse_detections_ GUARDED_BY(task_checker_);
140 : int64_t last_rampup_time_ms_ GUARDED_BY(task_checker_);
141 : bool in_quick_rampup_ GUARDED_BY(task_checker_);
142 : int current_rampup_delay_ms_ GUARDED_BY(task_checker_);
143 :
144 : // TODO(asapersson): Can these be regular members (avoid separate heap
145 : // allocs)?
146 : const std::unique_ptr<SendProcessingUsage> usage_ GUARDED_BY(task_checker_);
147 : std::list<FrameTiming> frame_timing_ GUARDED_BY(task_checker_);
148 :
149 : RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
150 : };
151 :
152 : } // namespace webrtc
153 :
154 : #endif // WEBRTC_VIDEO_OVERUSE_FRAME_DETECTOR_H_
|