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