aboutsummaryrefslogtreecommitdiff
path: root/webrtc/video_engine/overuse_frame_detector.h
blob: df3c1a04ccbd9e96dd3e9b04f8dea48b3985c399 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_
#define WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_

#include "webrtc/base/constructormagic.h"
#include "webrtc/base/exp_filter.h"
#include "webrtc/modules/interface/module.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/video_engine/include/vie_base.h"

namespace webrtc {

class Clock;
class CpuOveruseObserver;
class CriticalSectionWrapper;

// TODO(pbos): Move this somewhere appropriate.
class Statistics {
 public:
  Statistics();

  void AddSample(float sample_ms);
  void Reset();
  void SetOptions(const CpuOveruseOptions& options);

  float Mean() const;
  float StdDev() const;
  uint64_t Count() const;

 private:
  float InitialMean() const;
  float InitialVariance() const;

  float sum_;
  uint64_t count_;
  CpuOveruseOptions options_;
  scoped_ptr<rtc::ExpFilter> filtered_samples_;
  scoped_ptr<rtc::ExpFilter> filtered_variance_;
};

// Use to detect system overuse based on jitter in incoming frames.
class OveruseFrameDetector : public Module {
 public:
  explicit OveruseFrameDetector(Clock* clock);
  ~OveruseFrameDetector();

  // Registers an observer receiving overuse and underuse callbacks. Set
  // 'observer' to NULL to disable callbacks.
  void SetObserver(CpuOveruseObserver* observer);

  // Sets options for overuse detection.
  void SetOptions(const CpuOveruseOptions& options);

  // Called for each captured frame.
  void FrameCaptured(int width, int height);

  // Called when the processing of a captured frame is started.
  void FrameProcessingStarted();

  // Called for each encoded frame.
  void FrameEncoded(int encode_time_ms);

  // Accessors.

  // Returns CpuOveruseMetrics where
  // capture_jitter_ms: The estimated jitter based on incoming captured frames.
  // avg_encode_time_ms: Running average of reported encode time
  //                     (FrameEncoded()). Only used for stats.
  // encode_usage_percent: The average encode time divided by the average time
  //                       difference between incoming captured frames.
  // capture_queue_delay_ms_per_s: The current time delay between an incoming
  //                               captured frame (FrameCaptured()) until the
  //                               frame is being processed
  //                               (FrameProcessingStarted()). (Note: if a new
  //                               frame is received before an old frame has
  //                               been processed, the old frame is skipped).
  //                               The delay is expressed in ms delay per sec.
  //                               Only used for stats.
  void GetCpuOveruseMetrics(CpuOveruseMetrics* metrics) const;

  int CaptureQueueDelayMsPerS() const;

  // Implements Module.
  virtual int32_t TimeUntilNextProcess() OVERRIDE;
  virtual int32_t Process() OVERRIDE;

 private:
  class EncodeTimeAvg;
  class EncodeTimeRsd;
  class EncodeUsage;
  class CaptureQueueDelay;

  bool IsOverusing();
  bool IsUnderusing(int64_t time_now);

  bool FrameTimeoutDetected(int64_t now) const;
  bool FrameSizeChanged(int num_pixels) const;

  void ResetAll(int num_pixels);

  // Protecting all members.
  scoped_ptr<CriticalSectionWrapper> crit_;

  // Observer getting overuse reports.
  CpuOveruseObserver* observer_;

  CpuOveruseOptions options_;

  Clock* clock_;
  int64_t next_process_time_;
  int64_t num_process_times_;

  Statistics capture_deltas_;
  int64_t last_capture_time_;

  int64_t last_overuse_time_;
  int checks_above_threshold_;
  int num_overuse_detections_;

  int64_t last_rampup_time_;
  bool in_quick_rampup_;
  int current_rampup_delay_ms_;

  // Number of pixels of last captured frame.
  int num_pixels_;

  int64_t last_encode_sample_ms_;
  scoped_ptr<EncodeTimeAvg> encode_time_;
  scoped_ptr<EncodeTimeRsd> encode_rsd_;
  scoped_ptr<EncodeUsage> encode_usage_;

  scoped_ptr<CaptureQueueDelay> capture_queue_delay_;

  DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
};

}  // namespace webrtc

#endif  // WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_