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/main/source/rtt_filter.h"
16#include "webrtc/typedefs.h"
17
18namespace webrtc
19{
20
21class Clock;
22
23class VCMJitterEstimator
24{
25public:
26    VCMJitterEstimator(const Clock* clock,
27                       int32_t vcmId = 0,
28                       int32_t receiverId = 0);
29    virtual ~VCMJitterEstimator();
30    VCMJitterEstimator& operator=(const VCMJitterEstimator& rhs);
31
32    // Resets the estimate to the initial state
33    void Reset();
34    void ResetNackCount();
35
36    // Updates the jitter estimate with the new data.
37    //
38    // Input:
39    //          - frameDelay      : Delay-delta calculated by UTILDelayEstimate in milliseconds
40    //          - frameSize       : Frame size of the current frame.
41    //          - incompleteFrame : Flags if the frame is used to update the 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(uint32_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
71protected:
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
78private:
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 milliseconds
84    //          - deltaFSBytes    : Frame size delta, i.e.
85    //                            : frame size at time T minus frame size at time T-1
86    void KalmanEstimateChannel(int64_t frameDelayMS, int32_t deltaFSBytes);
87
88    // Updates the random jitter estimate, i.e. the variance
89    // of the time deviations from the line given by the Kalman filter.
90    //
91    // Input:
92    //          - d_dT              : The deviation from the kalman estimate
93    //          - incompleteFrame   : True if the frame used to update the estimate
94    //                                with was incomplete
95    void EstimateRandomJitter(double d_dT, bool incompleteFrame);
96
97    double NoiseThreshold() const;
98
99    // Calculates the current jitter estimate.
100    //
101    // Return value                 : The current jitter estimate in milliseconds
102    double CalculateEstimate();
103
104    // Post process the calculated estimate
105    void PostProcessEstimate();
106
107    // Calculates the difference in delay between a sample and the
108    // expected delay estimated by the Kalman filter.
109    //
110    // Input:
111    //          - frameDelayMS    : Delay-delta calculated by UTILDelayEstimate in milliseconds
112    //          - deltaFS         : Frame size delta, i.e. frame size at time
113    //                              T minus frame size at time T-1
114    //
115    // Return value                 : The difference in milliseconds
116    double DeviationFromExpectedDelay(int64_t frameDelayMS,
117                                      int32_t deltaFSBytes) const;
118
119    double GetFrameRate() const;
120
121    // Constants, filter parameters
122    int32_t         _vcmId;
123    int32_t         _receiverId;
124    const double          _phi;
125    const double          _psi;
126    const uint32_t  _alphaCountMax;
127    const double          _thetaLow;
128    const uint32_t  _nackLimit;
129    const int32_t   _numStdDevDelayOutlier;
130    const int32_t   _numStdDevFrameSizeOutlier;
131    const double          _noiseStdDevs;
132    const double          _noiseStdDevOffset;
133
134    double                _thetaCov[2][2]; // Estimate covariance
135    double                _Qcov[2][2];     // Process noise covariance
136    double                _avgFrameSize;   // Average frame size
137    double                _varFrameSize;   // Frame size variance
138    double                _maxFrameSize;   // Largest frame size received (descending
139                                           // with a factor _psi)
140    uint32_t        _fsSum;
141    uint32_t        _fsCount;
142
143    int64_t         _lastUpdateT;
144    double                _prevEstimate;         // The previously returned jitter estimate
145    uint32_t        _prevFrameSize;        // Frame size of the previous frame
146    double                _avgNoise;             // Average of the random jitter
147    uint32_t        _alphaCount;
148    double                _filterJitterEstimate; // The filtered sum of jitter estimates
149
150    uint32_t        _startupCount;
151
152    int64_t         _latestNackTimestamp;  // Timestamp in ms when the latest nack was seen
153    uint32_t        _nackCount;            // Keeps track of the number of nacks received,
154                                                 // but never goes above _nackLimit
155    VCMRttFilter          _rttFilter;
156
157    rtc::RollingAccumulator<uint64_t> fps_counter_;
158    enum ExperimentFlag { kInit, kEnabled, kDisabled };
159    ExperimentFlag low_rate_experiment_;
160    const Clock* clock_;
161};
162
163}  // namespace webrtc
164
165#endif // WEBRTC_MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_
166