blob: 3525a976abfd286ee1b817cef9c28a2dfae4ce19 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef VIDEO_OVERUSE_FRAME_DETECTOR_H_
12#define VIDEO_OVERUSE_FRAME_DETECTOR_H_
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000013
Peter Boströme4499152016-02-05 11:13:28 +010014#include <list>
kwiberg27f982b2016-03-01 11:52:33 -080015#include <memory>
Peter Boströme4499152016-02-05 11:13:28 +010016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/optional.h"
18#include "modules/video_coding/utility/quality_scaler.h"
19#include "rtc_base/constructormagic.h"
Niels Möller7dc26b72017-12-06 10:27:48 +010020#include "rtc_base/numerics/exp_filter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/sequenced_task_checker.h"
22#include "rtc_base/task_queue.h"
23#include "rtc_base/thread_annotations.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000024
25namespace webrtc {
26
Peter Boströme4499152016-02-05 11:13:28 +010027class VideoFrame;
Peter Boström300eeb62015-05-12 16:51:11 +020028
Peter Boström300eeb62015-05-12 16:51:11 +020029struct CpuOveruseOptions {
torbjorng448468d2016-02-10 08:11:57 -080030 CpuOveruseOptions();
Peter Boström300eeb62015-05-12 16:51:11 +020031
Peter Boström300eeb62015-05-12 16:51:11 +020032 int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010033 int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
Peter Boström300eeb62015-05-12 16:51:11 +020034 // General settings.
35 int frame_timeout_interval_ms; // The maximum allowed interval between two
36 // frames before resetting estimations.
Niels Möller7dc26b72017-12-06 10:27:48 +010037 int min_frame_samples; // The minimum number of frames required.
Peter Boström300eeb62015-05-12 16:51:11 +020038 int min_process_count; // The number of initial process times required before
39 // triggering an overuse/underuse.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010040 int high_threshold_consecutive_count; // The number of consecutive checks
41 // above the high threshold before
42 // triggering an overuse.
Niels Möller83dbeac2017-12-14 16:39:44 +010043 // New estimator enabled if this is set non-zero.
44 int filter_time_ms; // Time constant for averaging
Peter Boström300eeb62015-05-12 16:51:11 +020045};
46
47struct CpuOveruseMetrics {
asapersson1aa420b2015-12-07 03:12:22 -080048 CpuOveruseMetrics() : encode_usage_percent(-1) {}
Peter Boström300eeb62015-05-12 16:51:11 +020049
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010050 int encode_usage_percent; // Average encode time divided by the average time
51 // difference between incoming captured frames.
Peter Boström300eeb62015-05-12 16:51:11 +020052};
53
54class CpuOveruseMetricsObserver {
55 public:
56 virtual ~CpuOveruseMetricsObserver() {}
Peter Boströme4499152016-02-05 11:13:28 +010057 virtual void OnEncodedFrameTimeMeasured(int encode_duration_ms,
58 const CpuOveruseMetrics& metrics) = 0;
Peter Boström300eeb62015-05-12 16:51:11 +020059};
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000060
Åsa Persson746210f2015-09-08 10:52:42 +020061// Use to detect system overuse based on the send-side processing time of
perkjd52063f2016-09-07 06:32:18 -070062// 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.
66class OveruseFrameDetector {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000067 public:
Niels Möllerd1f7eb62018-03-28 16:40:58 +020068 explicit OveruseFrameDetector(CpuOveruseMetricsObserver* metrics_observer);
sprangfda496a2017-06-15 04:21:07 -070069 virtual ~OveruseFrameDetector();
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000070
perkjd52063f2016-09-07 06:32:18 -070071 // Start to periodically check for overuse.
Niels Möllerd1f7eb62018-03-28 16:40:58 +020072 void StartCheckForOveruse(const CpuOveruseOptions& options,
73 AdaptationObserverInterface* overuse_observer);
perkjd52063f2016-09-07 06:32:18 -070074
75 // StopCheckForOveruse must be called before destruction if
76 // StartCheckForOveruse has been called.
77 void StopCheckForOveruse();
78
Niels Möller7dc26b72017-12-06 10:27:48 +010079 // Defines the current maximum framerate targeted by the capturer. This is
80 // used to make sure the encode usage percent doesn't drop unduly if the
81 // capturer has quiet periods (for instance caused by screen capturers with
82 // variable capture rate depending on content updates), otherwise we might
83 // experience adaptation toggling.
84 virtual void OnTargetFramerateUpdated(int framerate_fps);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000085
Niels Möller7dc26b72017-12-06 10:27:48 +010086 // Called for each captured frame.
87 void FrameCaptured(const VideoFrame& frame, int64_t time_when_first_seen_us);
88
89 // Called for each sent frame.
Niels Möller83dbeac2017-12-14 16:39:44 +010090 void FrameSent(uint32_t timestamp,
91 int64_t time_sent_in_us,
92 int64_t capture_time_us,
93 rtc::Optional<int> encode_duration_us);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +000094
Niels Möller904f8692017-12-07 11:22:39 +010095 // Interface for cpu load estimation. Intended for internal use only.
96 class ProcessingUsage {
97 public:
98 virtual void Reset() = 0;
99 virtual void SetMaxSampleDiffMs(float diff_ms) = 0;
Niels Möllere08cf3a2017-12-07 15:23:58 +0100100 virtual void FrameCaptured(const VideoFrame& frame,
101 int64_t time_when_first_seen_us,
102 int64_t last_capture_time_us) = 0;
103 // Returns encode_time in us, if there's a new measurement.
Niels Möller83dbeac2017-12-14 16:39:44 +0100104 virtual rtc::Optional<int> FrameSent(
105 // These two argument used by old estimator.
106 uint32_t timestamp,
107 int64_t time_sent_in_us,
108 // And these two by the new estimator.
109 int64_t capture_time_us,
110 rtc::Optional<int> encode_duration_us) = 0;
Niels Möllere08cf3a2017-12-07 15:23:58 +0100111
Niels Möller904f8692017-12-07 11:22:39 +0100112 virtual int Value() = 0;
113 virtual ~ProcessingUsage() = default;
114 };
115
perkjd52063f2016-09-07 06:32:18 -0700116 protected:
Niels Möller73f29cb2018-01-31 16:09:31 +0100117 // Protected for test purposes.
118 void CheckForOveruse(AdaptationObserverInterface* overuse_observer);
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200119 void SetOptions(const CpuOveruseOptions& options);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000120
Niels Möller4db138e2018-04-19 09:04:13 +0200121 CpuOveruseOptions options_;
122
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000123 private:
perkjd52063f2016-09-07 06:32:18 -0700124 class CheckOveruseTask;
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000125
perkjd52063f2016-09-07 06:32:18 -0700126 void EncodedFrameTimeMeasured(int encode_duration_ms);
asapersson74d85e12015-09-24 00:53:32 -0700127 bool IsOverusing(const CpuOveruseMetrics& metrics);
128 bool IsUnderusing(const CpuOveruseMetrics& metrics, int64_t time_now);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000129
perkjd52063f2016-09-07 06:32:18 -0700130 bool FrameTimeoutDetected(int64_t now) const;
131 bool FrameSizeChanged(int num_pixels) const;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000132
Niels Möller7dc26b72017-12-06 10:27:48 +0100133 void ResetAll(int num_pixels);
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000134
Niels Möller904f8692017-12-07 11:22:39 +0100135 static std::unique_ptr<ProcessingUsage> CreateProcessingUsage(
Niels Möller6b642f72017-12-08 14:11:14 +0100136 const CpuOveruseOptions& options);
sprangc5d62e22017-04-02 23:53:04 -0700137
perkjd52063f2016-09-07 06:32:18 -0700138 rtc::SequencedTaskChecker task_checker_;
139 // Owned by the task queue from where StartCheckForOveruse is called.
140 CheckOveruseTask* check_overuse_task_;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000141
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000142 // Stats metrics.
143 CpuOveruseMetricsObserver* const metrics_observer_;
danilchapa37de392017-09-09 04:17:22 -0700144 rtc::Optional<CpuOveruseMetrics> metrics_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000145
danilchapa37de392017-09-09 04:17:22 -0700146 int64_t num_process_times_ RTC_GUARDED_BY(task_checker_);
perkjd52063f2016-09-07 06:32:18 -0700147
danilchapa37de392017-09-09 04:17:22 -0700148 int64_t last_capture_time_us_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000149
asapersson74d85e12015-09-24 00:53:32 -0700150 // Number of pixels of last captured frame.
danilchapa37de392017-09-09 04:17:22 -0700151 int num_pixels_ RTC_GUARDED_BY(task_checker_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100152 int max_framerate_ RTC_GUARDED_BY(task_checker_);
danilchapa37de392017-09-09 04:17:22 -0700153 int64_t last_overuse_time_ms_ RTC_GUARDED_BY(task_checker_);
154 int checks_above_threshold_ RTC_GUARDED_BY(task_checker_);
155 int num_overuse_detections_ RTC_GUARDED_BY(task_checker_);
156 int64_t last_rampup_time_ms_ RTC_GUARDED_BY(task_checker_);
157 bool in_quick_rampup_ RTC_GUARDED_BY(task_checker_);
158 int current_rampup_delay_ms_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000159
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200160 std::unique_ptr<ProcessingUsage> usage_ RTC_PT_GUARDED_BY(task_checker_);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000161
henrikg3c089d72015-09-16 05:37:44 -0700162 RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000163};
164
165} // namespace webrtc
166
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200167#endif // VIDEO_OVERUSE_FRAME_DETECTOR_H_