blob: ea0d76dd9015ec1255af744cfbd30b4f659d6bee [file] [log] [blame]
mflodman@webrtc.orge6168f52013-06-26 11:23:011/*
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 04:47:3111#ifndef VIDEO_OVERUSE_FRAME_DETECTOR_H_
12#define VIDEO_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"
Niels Möller213618e2018-07-24 07:29:5818#include "api/video/video_stream_encoder_observer.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3119#include "modules/video_coding/utility/quality_scaler.h"
20#include "rtc_base/constructormagic.h"
Niels Möller7dc26b72017-12-06 09:27:4821#include "rtc_base/numerics/exp_filter.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3122#include "rtc_base/sequenced_task_checker.h"
23#include "rtc_base/task_queue.h"
24#include "rtc_base/thread_annotations.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:0125
26namespace webrtc {
27
Peter Boströme4499152016-02-05 10:13:2828class VideoFrame;
Peter Boström300eeb62015-05-12 14:51:1129
Peter Boström300eeb62015-05-12 14:51:1130struct CpuOveruseOptions {
torbjorng448468d2016-02-10 16:11:5731 CpuOveruseOptions();
Peter Boström300eeb62015-05-12 14:51:1132
Peter Boström300eeb62015-05-12 14:51:1133 int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
kjellander@webrtc.org0fcaf992015-11-26 14:24:5234 int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
Peter Boström300eeb62015-05-12 14:51:1135 // General settings.
36 int frame_timeout_interval_ms; // The maximum allowed interval between two
37 // frames before resetting estimations.
Yves Gerey665174f2018-06-19 13:03:0538 int min_frame_samples; // The minimum number of frames required.
Peter Boström300eeb62015-05-12 14:51:1139 int min_process_count; // The number of initial process times required before
40 // triggering an overuse/underuse.
kjellander@webrtc.org0fcaf992015-11-26 14:24:5241 int high_threshold_consecutive_count; // The number of consecutive checks
42 // above the high threshold before
43 // triggering an overuse.
Niels Möller83dbeac2017-12-14 15:39:4444 // New estimator enabled if this is set non-zero.
45 int filter_time_ms; // Time constant for averaging
Peter Boström300eeb62015-05-12 14:51:1146};
47
Åsa Persson746210f2015-09-08 08:52:4248// Use to detect system overuse based on the send-side processing time of
perkjd52063f2016-09-07 13:32:1849// incoming frames. All methods must be called on a single task queue but it can
50// be created and destroyed on an arbitrary thread.
51// OveruseFrameDetector::StartCheckForOveruse must be called to periodically
52// check for overuse.
53class OveruseFrameDetector {
mflodman@webrtc.orge6168f52013-06-26 11:23:0154 public:
Niels Möllerd1f7eb62018-03-28 14:40:5855 explicit OveruseFrameDetector(CpuOveruseMetricsObserver* metrics_observer);
sprangfda496a2017-06-15 11:21:0756 virtual ~OveruseFrameDetector();
mflodman@webrtc.orge6168f52013-06-26 11:23:0157
perkjd52063f2016-09-07 13:32:1858 // Start to periodically check for overuse.
Niels Möllerd1f7eb62018-03-28 14:40:5859 void StartCheckForOveruse(const CpuOveruseOptions& options,
60 AdaptationObserverInterface* overuse_observer);
perkjd52063f2016-09-07 13:32:1861
62 // StopCheckForOveruse must be called before destruction if
63 // StartCheckForOveruse has been called.
64 void StopCheckForOveruse();
65
Niels Möller7dc26b72017-12-06 09:27:4866 // Defines the current maximum framerate targeted by the capturer. This is
67 // used to make sure the encode usage percent doesn't drop unduly if the
68 // capturer has quiet periods (for instance caused by screen capturers with
69 // variable capture rate depending on content updates), otherwise we might
70 // experience adaptation toggling.
71 virtual void OnTargetFramerateUpdated(int framerate_fps);
mflodman@webrtc.orge6168f52013-06-26 11:23:0172
Niels Möller7dc26b72017-12-06 09:27:4873 // Called for each captured frame.
74 void FrameCaptured(const VideoFrame& frame, int64_t time_when_first_seen_us);
75
76 // Called for each sent frame.
Niels Möller83dbeac2017-12-14 15:39:4477 void FrameSent(uint32_t timestamp,
78 int64_t time_sent_in_us,
79 int64_t capture_time_us,
Danil Chapovalovb9b146c2018-06-15 10:28:0780 absl::optional<int> encode_duration_us);
asapersson@webrtc.orgb24d3352013-11-20 13:51:4081
Niels Möller904f8692017-12-07 10:22:3982 // Interface for cpu load estimation. Intended for internal use only.
83 class ProcessingUsage {
84 public:
85 virtual void Reset() = 0;
86 virtual void SetMaxSampleDiffMs(float diff_ms) = 0;
Niels Möllere08cf3a2017-12-07 14:23:5887 virtual void FrameCaptured(const VideoFrame& frame,
88 int64_t time_when_first_seen_us,
89 int64_t last_capture_time_us) = 0;
90 // Returns encode_time in us, if there's a new measurement.
Danil Chapovalovb9b146c2018-06-15 10:28:0791 virtual absl::optional<int> FrameSent(
Niels Möller83dbeac2017-12-14 15:39:4492 // These two argument used by old estimator.
93 uint32_t timestamp,
94 int64_t time_sent_in_us,
95 // And these two by the new estimator.
96 int64_t capture_time_us,
Danil Chapovalovb9b146c2018-06-15 10:28:0797 absl::optional<int> encode_duration_us) = 0;
Niels Möllere08cf3a2017-12-07 14:23:5898
Niels Möller904f8692017-12-07 10:22:3999 virtual int Value() = 0;
100 virtual ~ProcessingUsage() = default;
101 };
102
perkjd52063f2016-09-07 13:32:18103 protected:
Niels Möller73f29cb2018-01-31 15:09:31104 // Protected for test purposes.
105 void CheckForOveruse(AdaptationObserverInterface* overuse_observer);
Niels Möllerd1f7eb62018-03-28 14:40:58106 void SetOptions(const CpuOveruseOptions& options);
mflodman@webrtc.orge6168f52013-06-26 11:23:01107
Niels Möller4db138e2018-04-19 07:04:13108 CpuOveruseOptions options_;
109
mflodman@webrtc.orge6168f52013-06-26 11:23:01110 private:
perkjd52063f2016-09-07 13:32:18111 class CheckOveruseTask;
asapersson@webrtc.org9aed0022014-10-16 06:57:12112
perkjd52063f2016-09-07 13:32:18113 void EncodedFrameTimeMeasured(int encode_duration_ms);
Niels Möller213618e2018-07-24 07:29:58114 bool IsOverusing(int encode_usage_percent);
115 bool IsUnderusing(int encode_usage_percent, int64_t time_now);
mflodman@webrtc.orge6168f52013-06-26 11:23:01116
perkjd52063f2016-09-07 13:32:18117 bool FrameTimeoutDetected(int64_t now) const;
118 bool FrameSizeChanged(int num_pixels) const;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01119
Niels Möller7dc26b72017-12-06 09:27:48120 void ResetAll(int num_pixels);
asapersson@webrtc.orgb60346e2014-02-17 19:02:15121
Niels Möller904f8692017-12-07 10:22:39122 static std::unique_ptr<ProcessingUsage> CreateProcessingUsage(
Niels Möller6b642f72017-12-08 13:11:14123 const CpuOveruseOptions& options);
sprangc5d62e22017-04-03 06:53:04124
perkjd52063f2016-09-07 13:32:18125 rtc::SequencedTaskChecker task_checker_;
126 // Owned by the task queue from where StartCheckForOveruse is called.
127 CheckOveruseTask* check_overuse_task_;
mflodman@webrtc.orge6168f52013-06-26 11:23:01128
pbos@webrtc.org3e6e2712015-02-26 12:19:31129 // Stats metrics.
130 CpuOveruseMetricsObserver* const metrics_observer_;
Niels Möller213618e2018-07-24 07:29:58131 absl::optional<int> encode_usage_percent_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01132
danilchapa37de392017-09-09 11:17:22133 int64_t num_process_times_ RTC_GUARDED_BY(task_checker_);
perkjd52063f2016-09-07 13:32:18134
danilchapa37de392017-09-09 11:17:22135 int64_t last_capture_time_us_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01136
asapersson74d85e12015-09-24 07:53:32137 // Number of pixels of last captured frame.
danilchapa37de392017-09-09 11:17:22138 int num_pixels_ RTC_GUARDED_BY(task_checker_);
Niels Möller7dc26b72017-12-06 09:27:48139 int max_framerate_ RTC_GUARDED_BY(task_checker_);
danilchapa37de392017-09-09 11:17:22140 int64_t last_overuse_time_ms_ RTC_GUARDED_BY(task_checker_);
141 int checks_above_threshold_ RTC_GUARDED_BY(task_checker_);
142 int num_overuse_detections_ RTC_GUARDED_BY(task_checker_);
143 int64_t last_rampup_time_ms_ RTC_GUARDED_BY(task_checker_);
144 bool in_quick_rampup_ RTC_GUARDED_BY(task_checker_);
145 int current_rampup_delay_ms_ RTC_GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01146
Niels Möllerd1f7eb62018-03-28 14:40:58147 std::unique_ptr<ProcessingUsage> usage_ RTC_PT_GUARDED_BY(task_checker_);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40148
henrikg3c089d72015-09-16 12:37:44149 RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
mflodman@webrtc.orge6168f52013-06-26 11:23:01150};
151
152} // namespace webrtc
153
Mirko Bonadei92ea95e2017-09-15 04:47:31154#endif // VIDEO_OVERUSE_FRAME_DETECTOR_H_