blob: 2fb3104d538dccc756ca9464f61a12f434b8b9d3 [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
Peter Boström7623ce42015-12-09 12:13:30 +010011#ifndef WEBRTC_VIDEO_OVERUSE_FRAME_DETECTOR_H_
12#define WEBRTC_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
henrike@webrtc.org88fbb2d2014-05-21 21:18:46 +000017#include "webrtc/base/constructormagic.h"
tereliusbc5d9212017-01-13 09:14:33 -080018#include "webrtc/base/numerics/exp_filter.h"
Peter Boströme4499152016-02-05 11:13:28 +010019#include "webrtc/base/optional.h"
perkjd52063f2016-09-07 06:32:18 -070020#include "webrtc/base/sequenced_task_checker.h"
21#include "webrtc/base/task_queue.h"
asapersson@webrtc.orgcd621a82014-11-11 09:40:19 +000022#include "webrtc/base/thread_annotations.h"
kthelgason876222f2016-11-29 01:44:11 -080023#include "webrtc/modules/video_coding/utility/quality_scaler.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000024
25namespace webrtc {
26
Peter Boströme4499152016-02-05 11:13:28 +010027class EncodedFrameObserver;
28class VideoFrame;
Peter Boström300eeb62015-05-12 16:51:11 +020029
Peter Boström300eeb62015-05-12 16:51:11 +020030struct CpuOveruseOptions {
torbjorng448468d2016-02-10 08:11:57 -080031 CpuOveruseOptions();
Peter Boström300eeb62015-05-12 16:51:11 +020032
Peter Boström300eeb62015-05-12 16:51:11 +020033 int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010034 int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
Peter Boström300eeb62015-05-12 16:51:11 +020035 // General settings.
36 int frame_timeout_interval_ms; // The maximum allowed interval between two
37 // frames before resetting estimations.
38 int min_frame_samples; // The minimum number of frames required.
39 int min_process_count; // The number of initial process times required before
40 // triggering an overuse/underuse.
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010041 int high_threshold_consecutive_count; // The number of consecutive checks
42 // above the high threshold before
43 // triggering an overuse.
Peter Boström300eeb62015-05-12 16:51:11 +020044};
45
46struct CpuOveruseMetrics {
asapersson1aa420b2015-12-07 03:12:22 -080047 CpuOveruseMetrics() : encode_usage_percent(-1) {}
Peter Boström300eeb62015-05-12 16:51:11 +020048
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +010049 int encode_usage_percent; // Average encode time divided by the average time
50 // difference between incoming captured frames.
Peter Boström300eeb62015-05-12 16:51:11 +020051};
52
53class CpuOveruseMetricsObserver {
54 public:
55 virtual ~CpuOveruseMetricsObserver() {}
Peter Boströme4499152016-02-05 11:13:28 +010056 virtual void OnEncodedFrameTimeMeasured(int encode_duration_ms,
57 const CpuOveruseMetrics& metrics) = 0;
Peter Boström300eeb62015-05-12 16:51:11 +020058};
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000059
Åsa Persson746210f2015-09-08 10:52:42 +020060// Use to detect system overuse based on the send-side processing time of
perkjd52063f2016-09-07 06:32:18 -070061// incoming frames. All methods must be called on a single task queue but it can
62// be created and destroyed on an arbitrary thread.
63// OveruseFrameDetector::StartCheckForOveruse must be called to periodically
64// check for overuse.
65class OveruseFrameDetector {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000066 public:
nissee0e3bdf2017-01-18 02:16:20 -080067 OveruseFrameDetector(const CpuOveruseOptions& options,
sprangb1ca0732017-02-01 08:38:12 -080068 AdaptationObserverInterface* overuse_observer,
Peter Boströme4499152016-02-05 11:13:28 +010069 EncodedFrameObserver* encoder_timing_,
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +000070 CpuOveruseMetricsObserver* metrics_observer);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000071 ~OveruseFrameDetector();
72
perkjd52063f2016-09-07 06:32:18 -070073 // Start to periodically check for overuse.
74 void StartCheckForOveruse();
75
76 // StopCheckForOveruse must be called before destruction if
77 // StartCheckForOveruse has been called.
78 void StopCheckForOveruse();
79
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000080 // Called for each captured frame.
nissee0e3bdf2017-01-18 02:16:20 -080081 void FrameCaptured(const VideoFrame& frame, int64_t time_when_first_seen_us);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000082
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +000083 // Called for each sent frame.
nissee0e3bdf2017-01-18 02:16:20 -080084 void FrameSent(uint32_t timestamp, int64_t time_sent_in_us);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +000085
perkjd52063f2016-09-07 06:32:18 -070086 protected:
87 void CheckForOveruse(); // Protected for test purposes.
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000088
89 private:
sprangc5d62e22017-04-02 23:53:04 -070090 class OverdoseInjector;
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +000091 class SendProcessingUsage;
perkjd52063f2016-09-07 06:32:18 -070092 class CheckOveruseTask;
Peter Boströme4499152016-02-05 11:13:28 +010093 struct FrameTiming {
nissee0e3bdf2017-01-18 02:16:20 -080094 FrameTiming(int64_t capture_time_us, uint32_t timestamp, int64_t now)
95 : capture_time_us(capture_time_us),
Peter Boströme4499152016-02-05 11:13:28 +010096 timestamp(timestamp),
nissee0e3bdf2017-01-18 02:16:20 -080097 capture_us(now),
98 last_send_us(-1) {}
99 int64_t capture_time_us;
Peter Boströme4499152016-02-05 11:13:28 +0100100 uint32_t timestamp;
nissee0e3bdf2017-01-18 02:16:20 -0800101 int64_t capture_us;
102 int64_t last_send_us;
Peter Boströme4499152016-02-05 11:13:28 +0100103 };
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000104
perkjd52063f2016-09-07 06:32:18 -0700105 void EncodedFrameTimeMeasured(int encode_duration_ms);
asapersson74d85e12015-09-24 00:53:32 -0700106 bool IsOverusing(const CpuOveruseMetrics& metrics);
107 bool IsUnderusing(const CpuOveruseMetrics& metrics, int64_t time_now);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000108
perkjd52063f2016-09-07 06:32:18 -0700109 bool FrameTimeoutDetected(int64_t now) const;
110 bool FrameSizeChanged(int num_pixels) const;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000111
perkjd52063f2016-09-07 06:32:18 -0700112 void ResetAll(int num_pixels);
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000113
sprangc5d62e22017-04-02 23:53:04 -0700114 static std::unique_ptr<SendProcessingUsage> CreateSendProcessingUsage(
115 const CpuOveruseOptions& options);
116
perkjd52063f2016-09-07 06:32:18 -0700117 rtc::SequencedTaskChecker task_checker_;
118 // Owned by the task queue from where StartCheckForOveruse is called.
119 CheckOveruseTask* check_overuse_task_;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000120
Peter Boström4b91bd02015-06-26 06:58:16 +0200121 const CpuOveruseOptions options_;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000122
Peter Boström4b91bd02015-06-26 06:58:16 +0200123 // Observer getting overuse reports.
sprangb1ca0732017-02-01 08:38:12 -0800124 AdaptationObserverInterface* const observer_;
Peter Boströme4499152016-02-05 11:13:28 +0100125 EncodedFrameObserver* const encoder_timing_;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000126
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000127 // Stats metrics.
128 CpuOveruseMetricsObserver* const metrics_observer_;
perkjd52063f2016-09-07 06:32:18 -0700129 rtc::Optional<CpuOveruseMetrics> metrics_ GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000130
perkjd52063f2016-09-07 06:32:18 -0700131 int64_t num_process_times_ GUARDED_BY(task_checker_);
132
nissee0e3bdf2017-01-18 02:16:20 -0800133 int64_t last_capture_time_us_ GUARDED_BY(task_checker_);
134 int64_t last_processed_capture_time_us_ 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.
perkjd52063f2016-09-07 06:32:18 -0700137 int num_pixels_ GUARDED_BY(task_checker_);
138 int64_t last_overuse_time_ms_ GUARDED_BY(task_checker_);
139 int checks_above_threshold_ GUARDED_BY(task_checker_);
140 int num_overuse_detections_ GUARDED_BY(task_checker_);
141 int64_t last_rampup_time_ms_ GUARDED_BY(task_checker_);
142 bool in_quick_rampup_ GUARDED_BY(task_checker_);
143 int current_rampup_delay_ms_ GUARDED_BY(task_checker_);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000144
tommi@webrtc.org7a57f8f2015-02-08 18:27:46 +0000145 // TODO(asapersson): Can these be regular members (avoid separate heap
146 // allocs)?
perkjd52063f2016-09-07 06:32:18 -0700147 const std::unique_ptr<SendProcessingUsage> usage_ GUARDED_BY(task_checker_);
148 std::list<FrameTiming> frame_timing_ GUARDED_BY(task_checker_);
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000149
henrikg3c089d72015-09-16 05:37:44 -0700150 RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000151};
152
153} // namespace webrtc
154
Peter Boström7623ce42015-12-09 12:13:30 +0100155#endif // WEBRTC_VIDEO_OVERUSE_FRAME_DETECTOR_H_