1 /*
2  *  Copyright (c) 2011 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 
11 #ifndef MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_
12 #define MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_
13 
14 #include "modules/video_coding/rtt_filter.h"
15 #include "rtc_base/rolling_accumulator.h"
16 
17 namespace webrtc {
18 
19 class Clock;
20 
21 class VCMJitterEstimator {
22  public:
23   explicit VCMJitterEstimator(Clock* clock);
24   virtual ~VCMJitterEstimator();
25   VCMJitterEstimator& operator=(const VCMJitterEstimator& rhs);
26 
27   // Resets the estimate to the initial state.
28   void Reset();
29 
30   // Updates the jitter estimate with the new data.
31   //
32   // Input:
33   //          - frameDelay      : Delay-delta calculated by UTILDelayEstimate in
34   //                              milliseconds.
35   //          - frameSize       : Frame size of the current frame.
36   //          - incompleteFrame : Flags if the frame is used to update the
37   //                              estimate before it was complete.
38   //                              Default is false.
39   void UpdateEstimate(int64_t frameDelayMS,
40                       uint32_t frameSizeBytes,
41                       bool incompleteFrame = false);
42 
43   // Returns the current jitter estimate in milliseconds and adds an RTT
44   // dependent term in cases of retransmission.
45   //  Input:
46   //          - rttMultiplier  : RTT param multiplier (when applicable).
47   //
48   // Return value              : Jitter estimate in milliseconds.
49   virtual int GetJitterEstimate(double rttMultiplier,
50                                 absl::optional<double> rttMultAddCapMs);
51 
52   // Updates the nack counter.
53   void FrameNacked();
54 
55   // Updates the RTT filter.
56   //
57   // Input:
58   //          - rttMs          : RTT in ms.
59   void UpdateRtt(int64_t rttMs);
60 
61   // A constant describing the delay from the jitter buffer to the delay on the
62   // receiving side which is not accounted for by the jitter buffer nor the
63   // decoding delay estimate.
64   static const uint32_t OPERATING_SYSTEM_JITTER = 10;
65 
66  protected:
67   // These are protected for better testing possibilities.
68   double _theta[2];  // Estimated line parameters (slope, offset)
69   double _varNoise;  // Variance of the time-deviation from the line
70 
71  private:
72   // Updates the Kalman filter for the line describing the frame size dependent
73   // jitter.
74   //
75   // Input:
76   //          - frameDelayMS    : Delay-delta calculated by UTILDelayEstimate in
77   //                              milliseconds.
78   //          - deltaFSBytes    : Frame size delta, i.e. frame size at time T
79   //                            : minus frame size at time T-1.
80   void KalmanEstimateChannel(int64_t frameDelayMS, int32_t deltaFSBytes);
81 
82   // Updates the random jitter estimate, i.e. the variance of the time
83   // deviations from the line given by the Kalman filter.
84   //
85   // Input:
86   //          - d_dT              : The deviation from the kalman estimate.
87   //          - incompleteFrame   : True if the frame used to update the
88   //                                estimate with was incomplete.
89   void EstimateRandomJitter(double d_dT, bool incompleteFrame);
90 
91   double NoiseThreshold() const;
92 
93   // Calculates the current jitter estimate.
94   //
95   // Return value                 : The current jitter estimate in milliseconds.
96   double CalculateEstimate();
97 
98   // Post process the calculated estimate.
99   void PostProcessEstimate();
100 
101   // Calculates the difference in delay between a sample and the expected delay
102   // estimated by the Kalman filter.
103   //
104   // Input:
105   //          - frameDelayMS    : Delay-delta calculated by UTILDelayEstimate in
106   //                              milliseconds.
107   //          - deltaFS         : Frame size delta, i.e. frame size at time
108   //                              T minus frame size at time T-1.
109   //
110   // Return value               : The difference in milliseconds.
111   double DeviationFromExpectedDelay(int64_t frameDelayMS,
112                                     int32_t deltaFSBytes) const;
113 
114   double GetFrameRate() const;
115 
116   // Constants, filter parameters.
117   const double _phi;
118   const double _psi;
119   const uint32_t _alphaCountMax;
120   const double _thetaLow;
121   const uint32_t _nackLimit;
122   const int32_t _numStdDevDelayOutlier;
123   const int32_t _numStdDevFrameSizeOutlier;
124   const double _noiseStdDevs;
125   const double _noiseStdDevOffset;
126 
127   double _thetaCov[2][2];  // Estimate covariance
128   double _Qcov[2][2];      // Process noise covariance
129   double _avgFrameSize;    // Average frame size
130   double _varFrameSize;    // Frame size variance
131   double _maxFrameSize;    // Largest frame size received (descending
132                            // with a factor _psi)
133   uint32_t _fsSum;
134   uint32_t _fsCount;
135 
136   int64_t _lastUpdateT;
137   double _prevEstimate;     // The previously returned jitter estimate
138   uint32_t _prevFrameSize;  // Frame size of the previous frame
139   double _avgNoise;         // Average of the random jitter
140   uint32_t _alphaCount;
141   double _filterJitterEstimate;  // The filtered sum of jitter estimates
142 
143   uint32_t _startupCount;
144 
145   int64_t
146       _latestNackTimestamp;  // Timestamp in ms when the latest nack was seen
147   uint32_t _nackCount;       // Keeps track of the number of nacks received,
148                              // but never goes above _nackLimit
149   VCMRttFilter _rttFilter;
150 
151   rtc::RollingAccumulator<uint64_t> fps_counter_;
152   const double time_deviation_upper_bound_;
153   const bool enable_reduced_delay_;
154   Clock* clock_;
155 };
156 
157 }  // namespace webrtc
158 
159 #endif  // MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_
160