blob: d4a2c627e484a581e824d2165d670ad221c112aa [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öller7dc26b72017-12-06 10:27:48 +010021#include "rtc_base/numerics/exp_filter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/sequenced_task_checker.h"
23#include "rtc_base/task_queue.h"
Sebastian Janssonecb68972019-01-18 10:30:54 +010024#include "rtc_base/task_utils/repeating_task.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "rtc_base/thread_annotations.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000026
27namespace webrtc {
28
Peter Boströme4499152016-02-05 11:13:28 +010029class VideoFrame;
Peter Boström300eeb62015-05-12 16:51:11 +020030
Peter Boström300eeb62015-05-12 16:51:11 +020031struct CpuOveruseOptions {
torbjorng448468d2016-02-10 08:11:57 -080032 CpuOveruseOptions();
Peter Boström300eeb62015-05-12 16:51:11 +020033
Peter Boström300eeb62015-05-12 16:51:11 +020034 int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010035 int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
Peter Boström300eeb62015-05-12 16:51:11 +020036 // General settings.
37 int frame_timeout_interval_ms; // The maximum allowed interval between two
38 // frames before resetting estimations.
Yves Gerey665174f2018-06-19 15:03:05 +020039 int min_frame_samples; // The minimum number of frames required.
Peter Boström300eeb62015-05-12 16:51:11 +020040 int min_process_count; // The number of initial process times required before
41 // triggering an overuse/underuse.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010042 int high_threshold_consecutive_count; // The number of consecutive checks
43 // above the high threshold before
44 // triggering an overuse.
Niels Möller83dbeac2017-12-14 16:39:44 +010045 // New estimator enabled if this is set non-zero.
46 int filter_time_ms; // Time constant for averaging
Peter Boström300eeb62015-05-12 16:51:11 +020047};
48
Åsa Persson746210f2015-09-08 10:52:42 +020049// Use to detect system overuse based on the send-side processing time of
perkjd52063f2016-09-07 06:32:18 -070050// incoming frames. All methods must be called on a single task queue but it can
51// be created and destroyed on an arbitrary thread.
52// OveruseFrameDetector::StartCheckForOveruse must be called to periodically
53// check for overuse.
54class OveruseFrameDetector {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000055 public:
Niels Möllerd1f7eb62018-03-28 16:40:58 +020056 explicit OveruseFrameDetector(CpuOveruseMetricsObserver* metrics_observer);
sprangfda496a2017-06-15 04:21:07 -070057 virtual ~OveruseFrameDetector();
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000058
perkjd52063f2016-09-07 06:32:18 -070059 // Start to periodically check for overuse.
Niels Möllerd1f7eb62018-03-28 16:40:58 +020060 void StartCheckForOveruse(const CpuOveruseOptions& options,
61 AdaptationObserverInterface* overuse_observer);
perkjd52063f2016-09-07 06:32:18 -070062
63 // StopCheckForOveruse must be called before destruction if
64 // StartCheckForOveruse has been called.
65 void StopCheckForOveruse();
66
Niels Möller7dc26b72017-12-06 10:27:48 +010067 // Defines the current maximum framerate targeted by the capturer. This is
68 // used to make sure the encode usage percent doesn't drop unduly if the
69 // capturer has quiet periods (for instance caused by screen capturers with
70 // variable capture rate depending on content updates), otherwise we might
71 // experience adaptation toggling.
72 virtual void OnTargetFramerateUpdated(int framerate_fps);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000073
Niels Möller7dc26b72017-12-06 10:27:48 +010074 // Called for each captured frame.
75 void FrameCaptured(const VideoFrame& frame, int64_t time_when_first_seen_us);
76
77 // Called for each sent frame.
Niels Möller83dbeac2017-12-14 16:39:44 +010078 void FrameSent(uint32_t timestamp,
79 int64_t time_sent_in_us,
80 int64_t capture_time_us,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020081 absl::optional<int> encode_duration_us);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +000082
Niels Möller904f8692017-12-07 11:22:39 +010083 // Interface for cpu load estimation. Intended for internal use only.
84 class ProcessingUsage {
85 public:
86 virtual void Reset() = 0;
87 virtual void SetMaxSampleDiffMs(float diff_ms) = 0;
Niels Möllere08cf3a2017-12-07 15:23:58 +010088 virtual void FrameCaptured(const VideoFrame& frame,
89 int64_t time_when_first_seen_us,
90 int64_t last_capture_time_us) = 0;
91 // Returns encode_time in us, if there's a new measurement.
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020092 virtual absl::optional<int> FrameSent(
Niels Möller83dbeac2017-12-14 16:39:44 +010093 // These two argument used by old estimator.
94 uint32_t timestamp,
95 int64_t time_sent_in_us,
96 // And these two by the new estimator.
97 int64_t capture_time_us,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +020098 absl::optional<int> encode_duration_us) = 0;
Niels Möllere08cf3a2017-12-07 15:23:58 +010099
Niels Möller904f8692017-12-07 11:22:39 +0100100 virtual int Value() = 0;
101 virtual ~ProcessingUsage() = default;
102 };
103
perkjd52063f2016-09-07 06:32:18 -0700104 protected:
Niels Möller73f29cb2018-01-31 16:09:31 +0100105 // Protected for test purposes.
106 void CheckForOveruse(AdaptationObserverInterface* overuse_observer);
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200107 void SetOptions(const CpuOveruseOptions& options);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000108
Niels Möller4db138e2018-04-19 09:04:13 +0200109 CpuOveruseOptions options_;
110
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000111 private:
perkjd52063f2016-09-07 06:32:18 -0700112 void EncodedFrameTimeMeasured(int encode_duration_ms);
Niels Möller213618e2018-07-24 09:29:58 +0200113 bool IsOverusing(int encode_usage_percent);
114 bool IsUnderusing(int encode_usage_percent, int64_t time_now);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000115
perkjd52063f2016-09-07 06:32:18 -0700116 bool FrameTimeoutDetected(int64_t now) const;
117 bool FrameSizeChanged(int num_pixels) const;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000118
Niels Möller7dc26b72017-12-06 10:27:48 +0100119 void ResetAll(int num_pixels);
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000120
Niels Möller904f8692017-12-07 11:22:39 +0100121 static std::unique_ptr<ProcessingUsage> CreateProcessingUsage(
Niels Möller6b642f72017-12-08 14:11:14 +0100122 const CpuOveruseOptions& options);
sprangc5d62e22017-04-02 23:53:04 -0700123
perkjd52063f2016-09-07 06:32:18 -0700124 rtc::SequencedTaskChecker task_checker_;
125 // Owned by the task queue from where StartCheckForOveruse is called.
Sebastian Janssonecb68972019-01-18 10:30:54 +0100126 RepeatingTaskHandle check_overuse_task_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000127
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000128 // Stats metrics.
129 CpuOveruseMetricsObserver* const metrics_observer_;
Niels Möller213618e2018-07-24 09:29:58 +0200130 absl::optional<int> encode_usage_percent_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000131
danilchapa37de392017-09-09 04:17:22 -0700132 int64_t num_process_times_ RTC_GUARDED_BY(task_checker_);
perkjd52063f2016-09-07 06:32:18 -0700133
danilchapa37de392017-09-09 04:17:22 -0700134 int64_t last_capture_time_us_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000135
asapersson74d85e12015-09-24 00:53:32 -0700136 // Number of pixels of last captured frame.
danilchapa37de392017-09-09 04:17:22 -0700137 int num_pixels_ RTC_GUARDED_BY(task_checker_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100138 int max_framerate_ RTC_GUARDED_BY(task_checker_);
danilchapa37de392017-09-09 04:17:22 -0700139 int64_t last_overuse_time_ms_ RTC_GUARDED_BY(task_checker_);
140 int checks_above_threshold_ RTC_GUARDED_BY(task_checker_);
141 int num_overuse_detections_ RTC_GUARDED_BY(task_checker_);
142 int64_t last_rampup_time_ms_ RTC_GUARDED_BY(task_checker_);
143 bool in_quick_rampup_ RTC_GUARDED_BY(task_checker_);
144 int current_rampup_delay_ms_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000145
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200146 std::unique_ptr<ProcessingUsage> usage_ RTC_PT_GUARDED_BY(task_checker_);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000147
henrikg3c089d72015-09-16 05:37:44 -0700148 RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000149};
150
151} // namespace webrtc
152
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200153#endif // VIDEO_OVERUSE_FRAME_DETECTOR_H_