blob: 20e097111b0dbd3f0ec7b593bb04c37b2e3d55b3 [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
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020017#include "absl/types/optional.h"
Niels Möller213618e2018-07-24 09:29:58 +020018#include "api/video/video_stream_encoder_observer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/video_coding/utility/quality_scaler.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "rtc_base/constructor_magic.h"
Niels Möllereea92882019-04-25 08:44:04 +020021#include "rtc_base/experiments/field_trial_parser.h"
Niels Möller7dc26b72017-12-06 10:27:48 +010022#include "rtc_base/numerics/exp_filter.h"
Sebastian Janssonb55015e2019-04-09 13:44:04 +020023#include "rtc_base/synchronization/sequence_checker.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/task_queue.h"
Sebastian Janssonecb68972019-01-18 10:30:54 +010025#include "rtc_base/task_utils/repeating_task.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "rtc_base/thread_annotations.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000027
28namespace webrtc {
29
Peter Boströme4499152016-02-05 11:13:28 +010030class VideoFrame;
Peter Boström300eeb62015-05-12 16:51:11 +020031
Peter Boström300eeb62015-05-12 16:51:11 +020032struct CpuOveruseOptions {
torbjorng448468d2016-02-10 08:11:57 -080033 CpuOveruseOptions();
Peter Boström300eeb62015-05-12 16:51:11 +020034
Peter Boström300eeb62015-05-12 16:51:11 +020035 int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010036 int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
Peter Boström300eeb62015-05-12 16:51:11 +020037 // General settings.
38 int frame_timeout_interval_ms; // The maximum allowed interval between two
39 // frames before resetting estimations.
Yves Gerey665174f2018-06-19 15:03:05 +020040 int min_frame_samples; // The minimum number of frames required.
Peter Boström300eeb62015-05-12 16:51:11 +020041 int min_process_count; // The number of initial process times required before
42 // triggering an overuse/underuse.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010043 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 16:39:44 +010046 // New estimator enabled if this is set non-zero.
47 int filter_time_ms; // Time constant for averaging
Peter Boström300eeb62015-05-12 16:51:11 +020048};
49
Åsa Persson746210f2015-09-08 10:52:42 +020050// Use to detect system overuse based on the send-side processing time of
perkjd52063f2016-09-07 06:32:18 -070051// incoming frames. All methods must be called on a single task queue but it can
52// be created and destroyed on an arbitrary thread.
53// OveruseFrameDetector::StartCheckForOveruse must be called to periodically
54// check for overuse.
55class OveruseFrameDetector {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000056 public:
Niels Möllerd1f7eb62018-03-28 16:40:58 +020057 explicit OveruseFrameDetector(CpuOveruseMetricsObserver* metrics_observer);
sprangfda496a2017-06-15 04:21:07 -070058 virtual ~OveruseFrameDetector();
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000059
perkjd52063f2016-09-07 06:32:18 -070060 // Start to periodically check for overuse.
Sebastian Janssoncda86dd2019-03-11 17:26:36 +010061 void StartCheckForOveruse(rtc::TaskQueue* task_queue,
62 const CpuOveruseOptions& options,
Niels Möllerd1f7eb62018-03-28 16:40:58 +020063 AdaptationObserverInterface* overuse_observer);
perkjd52063f2016-09-07 06:32:18 -070064
65 // StopCheckForOveruse must be called before destruction if
66 // StartCheckForOveruse has been called.
67 void StopCheckForOveruse();
68
Niels Möller7dc26b72017-12-06 10:27:48 +010069 // Defines the current maximum framerate targeted by the capturer. This is
70 // used to make sure the encode usage percent doesn't drop unduly if the
71 // capturer has quiet periods (for instance caused by screen capturers with
72 // variable capture rate depending on content updates), otherwise we might
73 // experience adaptation toggling.
74 virtual void OnTargetFramerateUpdated(int framerate_fps);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000075
Niels Möller7dc26b72017-12-06 10:27:48 +010076 // Called for each captured frame.
77 void FrameCaptured(const VideoFrame& frame, int64_t time_when_first_seen_us);
78
79 // Called for each sent frame.
Niels Möller83dbeac2017-12-14 16:39:44 +010080 void FrameSent(uint32_t timestamp,
81 int64_t time_sent_in_us,
82 int64_t capture_time_us,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020083 absl::optional<int> encode_duration_us);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +000084
Niels Möller904f8692017-12-07 11:22:39 +010085 // Interface for cpu load estimation. Intended for internal use only.
86 class ProcessingUsage {
87 public:
88 virtual void Reset() = 0;
89 virtual void SetMaxSampleDiffMs(float diff_ms) = 0;
Niels Möllere08cf3a2017-12-07 15:23:58 +010090 virtual void FrameCaptured(const VideoFrame& frame,
91 int64_t time_when_first_seen_us,
92 int64_t last_capture_time_us) = 0;
93 // Returns encode_time in us, if there's a new measurement.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020094 virtual absl::optional<int> FrameSent(
Niels Möller83dbeac2017-12-14 16:39:44 +010095 // These two argument used by old estimator.
96 uint32_t timestamp,
97 int64_t time_sent_in_us,
98 // And these two by the new estimator.
99 int64_t capture_time_us,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200100 absl::optional<int> encode_duration_us) = 0;
Niels Möllere08cf3a2017-12-07 15:23:58 +0100101
Niels Möller904f8692017-12-07 11:22:39 +0100102 virtual int Value() = 0;
103 virtual ~ProcessingUsage() = default;
104 };
105
perkjd52063f2016-09-07 06:32:18 -0700106 protected:
Niels Möller73f29cb2018-01-31 16:09:31 +0100107 // Protected for test purposes.
108 void CheckForOveruse(AdaptationObserverInterface* overuse_observer);
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200109 void SetOptions(const CpuOveruseOptions& options);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000110
Niels Möller4db138e2018-04-19 09:04:13 +0200111 CpuOveruseOptions options_;
112
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000113 private:
perkjd52063f2016-09-07 06:32:18 -0700114 void EncodedFrameTimeMeasured(int encode_duration_ms);
Niels Möller213618e2018-07-24 09:29:58 +0200115 bool IsOverusing(int encode_usage_percent);
116 bool IsUnderusing(int encode_usage_percent, int64_t time_now);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000117
perkjd52063f2016-09-07 06:32:18 -0700118 bool FrameTimeoutDetected(int64_t now) const;
119 bool FrameSizeChanged(int num_pixels) const;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000120
Niels Möller7dc26b72017-12-06 10:27:48 +0100121 void ResetAll(int num_pixels);
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000122
Niels Möller904f8692017-12-07 11:22:39 +0100123 static std::unique_ptr<ProcessingUsage> CreateProcessingUsage(
Niels Möller6b642f72017-12-08 14:11:14 +0100124 const CpuOveruseOptions& options);
sprangc5d62e22017-04-02 23:53:04 -0700125
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200126 SequenceChecker task_checker_;
perkjd52063f2016-09-07 06:32:18 -0700127 // Owned by the task queue from where StartCheckForOveruse is called.
Sebastian Janssonecb68972019-01-18 10:30:54 +0100128 RepeatingTaskHandle check_overuse_task_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000129
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000130 // Stats metrics.
131 CpuOveruseMetricsObserver* const metrics_observer_;
Niels Möller213618e2018-07-24 09:29:58 +0200132 absl::optional<int> encode_usage_percent_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000133
danilchapa37de392017-09-09 04:17:22 -0700134 int64_t num_process_times_ RTC_GUARDED_BY(task_checker_);
perkjd52063f2016-09-07 06:32:18 -0700135
danilchapa37de392017-09-09 04:17:22 -0700136 int64_t last_capture_time_us_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000137
asapersson74d85e12015-09-24 00:53:32 -0700138 // Number of pixels of last captured frame.
danilchapa37de392017-09-09 04:17:22 -0700139 int num_pixels_ RTC_GUARDED_BY(task_checker_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100140 int max_framerate_ RTC_GUARDED_BY(task_checker_);
danilchapa37de392017-09-09 04:17:22 -0700141 int64_t last_overuse_time_ms_ RTC_GUARDED_BY(task_checker_);
142 int checks_above_threshold_ RTC_GUARDED_BY(task_checker_);
143 int num_overuse_detections_ RTC_GUARDED_BY(task_checker_);
144 int64_t last_rampup_time_ms_ RTC_GUARDED_BY(task_checker_);
145 bool in_quick_rampup_ RTC_GUARDED_BY(task_checker_);
146 int current_rampup_delay_ms_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000147
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200148 std::unique_ptr<ProcessingUsage> usage_ RTC_PT_GUARDED_BY(task_checker_);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000149
Niels Möllereea92882019-04-25 08:44:04 +0200150 // If set by field trial, overrides CpuOveruseOptions::filter_time_ms.
151 FieldTrialOptional<TimeDelta> filter_time_constant_{"tau"};
152
henrikg3c089d72015-09-16 05:37:44 -0700153 RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000154};
155
156} // namespace webrtc
157
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200158#endif // VIDEO_OVERUSE_FRAME_DETECTOR_H_