overuse_frame_detector.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright (c) 2020 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. #ifndef VIDEO_ADAPTATION_OVERUSE_FRAME_DETECTOR_H_
  11. #define VIDEO_ADAPTATION_OVERUSE_FRAME_DETECTOR_H_
  12. #include <list>
  13. #include <memory>
  14. #include "absl/types/optional.h"
  15. #include "api/task_queue/task_queue_base.h"
  16. #include "api/video/video_stream_encoder_observer.h"
  17. #include "rtc_base/constructor_magic.h"
  18. #include "rtc_base/experiments/field_trial_parser.h"
  19. #include "rtc_base/numerics/exp_filter.h"
  20. #include "rtc_base/synchronization/sequence_checker.h"
  21. #include "rtc_base/system/no_unique_address.h"
  22. #include "rtc_base/task_utils/repeating_task.h"
  23. #include "rtc_base/thread_annotations.h"
  24. namespace webrtc {
  25. class VideoFrame;
  26. struct CpuOveruseOptions {
  27. CpuOveruseOptions();
  28. int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
  29. int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
  30. // General settings.
  31. int frame_timeout_interval_ms; // The maximum allowed interval between two
  32. // frames before resetting estimations.
  33. int min_frame_samples; // The minimum number of frames required.
  34. int min_process_count; // The number of initial process times required before
  35. // triggering an overuse/underuse.
  36. int high_threshold_consecutive_count; // The number of consecutive checks
  37. // above the high threshold before
  38. // triggering an overuse.
  39. // New estimator enabled if this is set non-zero.
  40. int filter_time_ms; // Time constant for averaging
  41. };
  42. class OveruseFrameDetectorObserverInterface {
  43. public:
  44. // Called to signal that we can handle larger or more frequent frames.
  45. virtual void AdaptUp() = 0;
  46. // Called to signal that the source should reduce the resolution or framerate.
  47. virtual void AdaptDown() = 0;
  48. protected:
  49. virtual ~OveruseFrameDetectorObserverInterface() {}
  50. };
  51. // Use to detect system overuse based on the send-side processing time of
  52. // incoming frames. All methods must be called on a single task queue but it can
  53. // be created and destroyed on an arbitrary thread.
  54. // OveruseFrameDetector::StartCheckForOveruse must be called to periodically
  55. // check for overuse.
  56. class OveruseFrameDetector {
  57. public:
  58. explicit OveruseFrameDetector(CpuOveruseMetricsObserver* metrics_observer);
  59. virtual ~OveruseFrameDetector();
  60. // Start to periodically check for overuse.
  61. void StartCheckForOveruse(
  62. TaskQueueBase* task_queue_base,
  63. const CpuOveruseOptions& options,
  64. OveruseFrameDetectorObserverInterface* overuse_observer);
  65. // StopCheckForOveruse must be called before destruction if
  66. // StartCheckForOveruse has been called.
  67. void StopCheckForOveruse();
  68. // Defines the current maximum framerate targeted by the capturer. This is
  69. // used to make sure the encode usage percent doesn't drop unduly if the
  70. // capturer has quiet periods (for instance caused by screen capturers with
  71. // variable capture rate depending on content updates), otherwise we might
  72. // experience adaptation toggling.
  73. virtual void OnTargetFramerateUpdated(int framerate_fps);
  74. // Called for each captured frame.
  75. void FrameCaptured(const VideoFrame& frame, int64_t time_when_first_seen_us);
  76. // Called for each sent frame.
  77. void FrameSent(uint32_t timestamp,
  78. int64_t time_sent_in_us,
  79. int64_t capture_time_us,
  80. absl::optional<int> encode_duration_us);
  81. // Interface for cpu load estimation. Intended for internal use only.
  82. class ProcessingUsage {
  83. public:
  84. virtual void Reset() = 0;
  85. virtual void SetMaxSampleDiffMs(float diff_ms) = 0;
  86. virtual void FrameCaptured(const VideoFrame& frame,
  87. int64_t time_when_first_seen_us,
  88. int64_t last_capture_time_us) = 0;
  89. // Returns encode_time in us, if there's a new measurement.
  90. virtual absl::optional<int> FrameSent(
  91. // These two argument used by old estimator.
  92. uint32_t timestamp,
  93. int64_t time_sent_in_us,
  94. // And these two by the new estimator.
  95. int64_t capture_time_us,
  96. absl::optional<int> encode_duration_us) = 0;
  97. virtual int Value() = 0;
  98. virtual ~ProcessingUsage() = default;
  99. };
  100. protected:
  101. // Protected for test purposes.
  102. void CheckForOveruse(OveruseFrameDetectorObserverInterface* overuse_observer);
  103. void SetOptions(const CpuOveruseOptions& options);
  104. CpuOveruseOptions options_;
  105. private:
  106. void EncodedFrameTimeMeasured(int encode_duration_ms);
  107. bool IsOverusing(int encode_usage_percent);
  108. bool IsUnderusing(int encode_usage_percent, int64_t time_now);
  109. bool FrameTimeoutDetected(int64_t now) const;
  110. bool FrameSizeChanged(int num_pixels) const;
  111. void ResetAll(int num_pixels);
  112. static std::unique_ptr<ProcessingUsage> CreateProcessingUsage(
  113. const CpuOveruseOptions& options);
  114. RTC_NO_UNIQUE_ADDRESS SequenceChecker task_checker_;
  115. // Owned by the task queue from where StartCheckForOveruse is called.
  116. RepeatingTaskHandle check_overuse_task_ RTC_GUARDED_BY(task_checker_);
  117. // Stats metrics.
  118. CpuOveruseMetricsObserver* const metrics_observer_;
  119. absl::optional<int> encode_usage_percent_ RTC_GUARDED_BY(task_checker_);
  120. int64_t num_process_times_ RTC_GUARDED_BY(task_checker_);
  121. int64_t last_capture_time_us_ RTC_GUARDED_BY(task_checker_);
  122. // Number of pixels of last captured frame.
  123. int num_pixels_ RTC_GUARDED_BY(task_checker_);
  124. int max_framerate_ RTC_GUARDED_BY(task_checker_);
  125. int64_t last_overuse_time_ms_ RTC_GUARDED_BY(task_checker_);
  126. int checks_above_threshold_ RTC_GUARDED_BY(task_checker_);
  127. int num_overuse_detections_ RTC_GUARDED_BY(task_checker_);
  128. int64_t last_rampup_time_ms_ RTC_GUARDED_BY(task_checker_);
  129. bool in_quick_rampup_ RTC_GUARDED_BY(task_checker_);
  130. int current_rampup_delay_ms_ RTC_GUARDED_BY(task_checker_);
  131. std::unique_ptr<ProcessingUsage> usage_ RTC_PT_GUARDED_BY(task_checker_);
  132. // If set by field trial, overrides CpuOveruseOptions::filter_time_ms.
  133. FieldTrialOptional<TimeDelta> filter_time_constant_{"tau"};
  134. RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
  135. };
  136. } // namespace webrtc
  137. #endif // VIDEO_ADAPTATION_OVERUSE_FRAME_DETECTOR_H_