blob: 2b4dd61d21837fa80f8031d5ccc63c81cb4016cd [file] [log] [blame]
mflodman@webrtc.orge6168f52013-06-26 11:23:011/*
Henrik Boström62057622020-03-10 18:08:052 * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
mflodman@webrtc.orge6168f52013-06-26 11:23:013 *
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
Henrik Boström62057622020-03-10 18:08:0511#ifndef VIDEO_ADAPTATION_OVERUSE_FRAME_DETECTOR_H_
12#define VIDEO_ADAPTATION_OVERUSE_FRAME_DETECTOR_H_
mflodman@webrtc.orge6168f52013-06-26 11:23:0113
Peter Boströme4499152016-02-05 10:13:2814#include <list>
kwiberg27f982b2016-03-01 19:52:3315#include <memory>
Peter Boströme4499152016-02-05 10:13:2816
Danil Chapovalovb9b146c2018-06-15 10:28:0717#include "absl/types/optional.h"
Artem Titovd15a5752021-02-10 13:31:2418#include "api/sequence_checker.h"
Henrik Boström07b17df2020-01-15 10:42:1219#include "api/task_queue/task_queue_base.h"
Niels Möller213618e2018-07-24 07:29:5820#include "api/video/video_stream_encoder_observer.h"
Steve Anton10542f22019-01-11 17:11:0021#include "rtc_base/constructor_magic.h"
Niels Möllereea92882019-04-25 06:44:0422#include "rtc_base/experiments/field_trial_parser.h"
Niels Möller7dc26b72017-12-06 09:27:4823#include "rtc_base/numerics/exp_filter.h"
Mirko Bonadei20e4c802020-11-23 10:07:4224#include "rtc_base/system/no_unique_address.h"
Sebastian Janssonecb68972019-01-18 09:30:5425#include "rtc_base/task_utils/repeating_task.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3126#include "rtc_base/thread_annotations.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:0127
28namespace webrtc {
29
Peter Boströme4499152016-02-05 10:13:2830class VideoFrame;
Peter Boström300eeb62015-05-12 14:51:1131
Peter Boström300eeb62015-05-12 14:51:1132struct CpuOveruseOptions {
torbjorng448468d2016-02-10 16:11:5733 CpuOveruseOptions();
Peter Boström300eeb62015-05-12 14:51:1134
Peter Boström300eeb62015-05-12 14:51:1135 int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
kjellander@webrtc.org0fcaf992015-11-26 14:24:5236 int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
Peter Boström300eeb62015-05-12 14:51:1137 // General settings.
38 int frame_timeout_interval_ms; // The maximum allowed interval between two
39 // frames before resetting estimations.
Yves Gerey665174f2018-06-19 13:03:0540 int min_frame_samples; // The minimum number of frames required.
Peter Boström300eeb62015-05-12 14:51:1141 int min_process_count; // The number of initial process times required before
42 // triggering an overuse/underuse.
kjellander@webrtc.org0fcaf992015-11-26 14:24:5243 int high_threshold_consecutive_count; // The number of consecutive checks
44 // above the high threshold before
45 // triggering an overuse.
Niels Möller83dbeac2017-12-14 15:39:4446 // New estimator enabled if this is set non-zero.
47 int filter_time_ms; // Time constant for averaging
Peter Boström300eeb62015-05-12 14:51:1148};
49
Henrik Boström012aa372020-04-27 15:40:5550class OveruseFrameDetectorObserverInterface {
51 public:
52 // Called to signal that we can handle larger or more frequent frames.
53 virtual void AdaptUp() = 0;
54 // Called to signal that the source should reduce the resolution or framerate.
55 virtual void AdaptDown() = 0;
56
57 protected:
58 virtual ~OveruseFrameDetectorObserverInterface() {}
59};
60
Åsa Persson746210f2015-09-08 08:52:4261// Use to detect system overuse based on the send-side processing time of
perkjd52063f2016-09-07 13:32:1862// 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:0167 public:
Niels Möllerd1f7eb62018-03-28 14:40:5868 explicit OveruseFrameDetector(CpuOveruseMetricsObserver* metrics_observer);
sprangfda496a2017-06-15 11:21:0769 virtual ~OveruseFrameDetector();
mflodman@webrtc.orge6168f52013-06-26 11:23:0170
perkjd52063f2016-09-07 13:32:1871 // Start to periodically check for overuse.
Henrik Boström012aa372020-04-27 15:40:5572 void StartCheckForOveruse(
73 TaskQueueBase* task_queue_base,
74 const CpuOveruseOptions& options,
75 OveruseFrameDetectorObserverInterface* overuse_observer);
perkjd52063f2016-09-07 13:32:1876
77 // StopCheckForOveruse must be called before destruction if
78 // StartCheckForOveruse has been called.
79 void StopCheckForOveruse();
80
Niels Möller7dc26b72017-12-06 09:27:4881 // Defines the current maximum framerate targeted by the capturer. This is
82 // used to make sure the encode usage percent doesn't drop unduly if the
83 // capturer has quiet periods (for instance caused by screen capturers with
84 // variable capture rate depending on content updates), otherwise we might
85 // experience adaptation toggling.
86 virtual void OnTargetFramerateUpdated(int framerate_fps);
mflodman@webrtc.orge6168f52013-06-26 11:23:0187
Niels Möller7dc26b72017-12-06 09:27:4888 // Called for each captured frame.
89 void FrameCaptured(const VideoFrame& frame, int64_t time_when_first_seen_us);
90
91 // Called for each sent frame.
Niels Möller83dbeac2017-12-14 15:39:4492 void FrameSent(uint32_t timestamp,
93 int64_t time_sent_in_us,
94 int64_t capture_time_us,
Danil Chapovalovb9b146c2018-06-15 10:28:0795 absl::optional<int> encode_duration_us);
asapersson@webrtc.orgb24d3352013-11-20 13:51:4096
Niels Möller904f8692017-12-07 10:22:3997 // Interface for cpu load estimation. Intended for internal use only.
98 class ProcessingUsage {
99 public:
100 virtual void Reset() = 0;
101 virtual void SetMaxSampleDiffMs(float diff_ms) = 0;
Niels Möllere08cf3a2017-12-07 14:23:58102 virtual void FrameCaptured(const VideoFrame& frame,
103 int64_t time_when_first_seen_us,
104 int64_t last_capture_time_us) = 0;
105 // Returns encode_time in us, if there's a new measurement.
Danil Chapovalovb9b146c2018-06-15 10:28:07106 virtual absl::optional<int> FrameSent(
Niels Möller83dbeac2017-12-14 15:39:44107 // These two argument used by old estimator.
108 uint32_t timestamp,
109 int64_t time_sent_in_us,
110 // And these two by the new estimator.
111 int64_t capture_time_us,
Danil Chapovalovb9b146c2018-06-15 10:28:07112 absl::optional<int> encode_duration_us) = 0;
Niels Möllere08cf3a2017-12-07 14:23:58113
Niels Möller904f8692017-12-07 10:22:39114 virtual int Value() = 0;
115 virtual ~ProcessingUsage() = default;
116 };
117
perkjd52063f2016-09-07 13:32:18118 protected:
Niels Möller73f29cb2018-01-31 15:09:31119 // Protected for test purposes.
Henrik Boström012aa372020-04-27 15:40:55120 void CheckForOveruse(OveruseFrameDetectorObserverInterface* overuse_observer);
Niels Möllerd1f7eb62018-03-28 14:40:58121 void SetOptions(const CpuOveruseOptions& options);
mflodman@webrtc.orge6168f52013-06-26 11:23:01122
Niels Möller4db138e2018-04-19 07:04:13123 CpuOveruseOptions options_;
124
mflodman@webrtc.orge6168f52013-06-26 11:23:01125 private:
perkjd52063f2016-09-07 13:32:18126 void EncodedFrameTimeMeasured(int encode_duration_ms);
Niels Möller213618e2018-07-24 07:29:58127 bool IsOverusing(int encode_usage_percent);
128 bool IsUnderusing(int encode_usage_percent, int64_t time_now);
mflodman@webrtc.orge6168f52013-06-26 11:23:01129
perkjd52063f2016-09-07 13:32:18130 bool FrameTimeoutDetected(int64_t now) const;
131 bool FrameSizeChanged(int num_pixels) const;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01132
Niels Möller7dc26b72017-12-06 09:27:48133 void ResetAll(int num_pixels);
asapersson@webrtc.orgb60346e2014-02-17 19:02:15134
Niels Möller904f8692017-12-07 10:22:39135 static std::unique_ptr<ProcessingUsage> CreateProcessingUsage(
Niels Möller6b642f72017-12-08 13:11:14136 const CpuOveruseOptions& options);
sprangc5d62e22017-04-03 06:53:04137
Mirko Bonadei20e4c802020-11-23 10:07:42138 RTC_NO_UNIQUE_ADDRESS SequenceChecker task_checker_;
perkjd52063f2016-09-07 13:32:18139 // Owned by the task queue from where StartCheckForOveruse is called.
Sebastian Janssonecb68972019-01-18 09:30:54140 RepeatingTaskHandle check_overuse_task_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01141
pbos@webrtc.org3e6e2712015-02-26 12:19:31142 // Stats metrics.
143 CpuOveruseMetricsObserver* const metrics_observer_;
Niels Möller213618e2018-07-24 07:29:58144 absl::optional<int> encode_usage_percent_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01145
danilchapa37de392017-09-09 11:17:22146 int64_t num_process_times_ RTC_GUARDED_BY(task_checker_);
perkjd52063f2016-09-07 13:32:18147
danilchapa37de392017-09-09 11:17:22148 int64_t last_capture_time_us_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01149
asapersson74d85e12015-09-24 07:53:32150 // Number of pixels of last captured frame.
danilchapa37de392017-09-09 11:17:22151 int num_pixels_ RTC_GUARDED_BY(task_checker_);
Niels Möller7dc26b72017-12-06 09:27:48152 int max_framerate_ RTC_GUARDED_BY(task_checker_);
danilchapa37de392017-09-09 11:17:22153 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:01159
Niels Möllerd1f7eb62018-03-28 14:40:58160 std::unique_ptr<ProcessingUsage> usage_ RTC_PT_GUARDED_BY(task_checker_);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40161
Niels Möllereea92882019-04-25 06:44:04162 // If set by field trial, overrides CpuOveruseOptions::filter_time_ms.
163 FieldTrialOptional<TimeDelta> filter_time_constant_{"tau"};
164
henrikg3c089d72015-09-16 12:37:44165 RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
mflodman@webrtc.orge6168f52013-06-26 11:23:01166};
167
168} // namespace webrtc
169
Henrik Boström62057622020-03-10 18:08:05170#endif // VIDEO_ADAPTATION_OVERUSE_FRAME_DETECTOR_H_