blob: 8bffa05f4a9197fb0a5b0cf402586642fbfbf4f6 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_
12#define MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_
niklase@google.com470e71d2011-07-07 08:21:25 +000013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "modules/video_coding/rtt_filter.h"
Steve Anton10542f22019-01-11 09:11:00 -080015#include "rtc_base/rolling_accumulator.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000016
philipel9d3ab612015-12-21 04:12:39 -080017namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000018
sprang@webrtc.org70e2d112014-09-24 14:06:56 +000019class Clock;
20
philipel9d3ab612015-12-21 04:12:39 -080021class VCMJitterEstimator {
22 public:
Åsa Persson3fcc5be2019-04-04 09:40:27 +020023 explicit VCMJitterEstimator(Clock* clock);
philipel9d3ab612015-12-21 04:12:39 -080024 virtual ~VCMJitterEstimator();
25 VCMJitterEstimator& operator=(const VCMJitterEstimator& rhs);
niklase@google.com470e71d2011-07-07 08:21:25 +000026
Åsa Persson3fcc5be2019-04-04 09:40:27 +020027 // Resets the estimate to the initial state.
philipel9d3ab612015-12-21 04:12:39 -080028 void Reset();
29 void ResetNackCount();
niklase@google.com470e71d2011-07-07 08:21:25 +000030
philipel9d3ab612015-12-21 04:12:39 -080031 // Updates the jitter estimate with the new data.
32 //
33 // Input:
34 // - frameDelay : Delay-delta calculated by UTILDelayEstimate in
Åsa Persson3fcc5be2019-04-04 09:40:27 +020035 // milliseconds.
philipel9d3ab612015-12-21 04:12:39 -080036 // - frameSize : Frame size of the current frame.
37 // - incompleteFrame : Flags if the frame is used to update the
Åsa Persson3fcc5be2019-04-04 09:40:27 +020038 // estimate before it was complete.
39 // Default is false.
philipel9d3ab612015-12-21 04:12:39 -080040 void UpdateEstimate(int64_t frameDelayMS,
41 uint32_t frameSizeBytes,
42 bool incompleteFrame = false);
niklase@google.com470e71d2011-07-07 08:21:25 +000043
Åsa Persson3fcc5be2019-04-04 09:40:27 +020044 // Returns the current jitter estimate in milliseconds and adds an RTT
45 // dependent term in cases of retransmission.
philipel9d3ab612015-12-21 04:12:39 -080046 // Input:
47 // - rttMultiplier : RTT param multiplier (when applicable).
48 //
Åsa Persson3fcc5be2019-04-04 09:40:27 +020049 // Return value : Jitter estimate in milliseconds.
philipel4f6cd6a2016-08-03 10:59:32 +020050 virtual int GetJitterEstimate(double rttMultiplier);
niklase@google.com470e71d2011-07-07 08:21:25 +000051
philipel9d3ab612015-12-21 04:12:39 -080052 // Updates the nack counter.
53 void FrameNacked();
niklase@google.com470e71d2011-07-07 08:21:25 +000054
philipel9d3ab612015-12-21 04:12:39 -080055 // Updates the RTT filter.
56 //
57 // Input:
Åsa Persson3fcc5be2019-04-04 09:40:27 +020058 // - rttMs : RTT in ms.
philipel9d3ab612015-12-21 04:12:39 -080059 void UpdateRtt(int64_t rttMs);
niklase@google.com470e71d2011-07-07 08:21:25 +000060
philipel9d3ab612015-12-21 04:12:39 -080061 void UpdateMaxFrameSize(uint32_t frameSizeBytes);
niklase@google.com470e71d2011-07-07 08:21:25 +000062
Åsa Persson3fcc5be2019-04-04 09:40:27 +020063 // A constant describing the delay from the jitter buffer to the delay on the
64 // receiving side which is not accounted for by the jitter buffer nor the
65 // decoding delay estimate.
philipel9d3ab612015-12-21 04:12:39 -080066 static const uint32_t OPERATING_SYSTEM_JITTER = 10;
niklase@google.com470e71d2011-07-07 08:21:25 +000067
philipel9d3ab612015-12-21 04:12:39 -080068 protected:
Åsa Persson3fcc5be2019-04-04 09:40:27 +020069 // These are protected for better testing possibilities.
philipel9d3ab612015-12-21 04:12:39 -080070 double _theta[2]; // Estimated line parameters (slope, offset)
71 double _varNoise; // Variance of the time-deviation from the line
niklase@google.com470e71d2011-07-07 08:21:25 +000072
philipel9d3ab612015-12-21 04:12:39 -080073 private:
Åsa Persson3fcc5be2019-04-04 09:40:27 +020074 // Updates the Kalman filter for the line describing the frame size dependent
75 // jitter.
philipel9d3ab612015-12-21 04:12:39 -080076 //
77 // Input:
78 // - frameDelayMS : Delay-delta calculated by UTILDelayEstimate in
Åsa Persson3fcc5be2019-04-04 09:40:27 +020079 // milliseconds.
80 // - deltaFSBytes : Frame size delta, i.e. frame size at time T
81 // : minus frame size at time T-1.
philipel9d3ab612015-12-21 04:12:39 -080082 void KalmanEstimateChannel(int64_t frameDelayMS, int32_t deltaFSBytes);
niklase@google.com470e71d2011-07-07 08:21:25 +000083
Åsa Persson3fcc5be2019-04-04 09:40:27 +020084 // Updates the random jitter estimate, i.e. the variance of the time
85 // deviations from the line given by the Kalman filter.
philipel9d3ab612015-12-21 04:12:39 -080086 //
87 // Input:
Åsa Persson3fcc5be2019-04-04 09:40:27 +020088 // - d_dT : The deviation from the kalman estimate.
philipel9d3ab612015-12-21 04:12:39 -080089 // - incompleteFrame : True if the frame used to update the
Åsa Persson3fcc5be2019-04-04 09:40:27 +020090 // estimate with was incomplete.
philipel9d3ab612015-12-21 04:12:39 -080091 void EstimateRandomJitter(double d_dT, bool incompleteFrame);
niklase@google.com470e71d2011-07-07 08:21:25 +000092
philipel9d3ab612015-12-21 04:12:39 -080093 double NoiseThreshold() const;
niklase@google.com470e71d2011-07-07 08:21:25 +000094
philipel9d3ab612015-12-21 04:12:39 -080095 // Calculates the current jitter estimate.
96 //
Åsa Persson3fcc5be2019-04-04 09:40:27 +020097 // Return value : The current jitter estimate in milliseconds.
philipel9d3ab612015-12-21 04:12:39 -080098 double CalculateEstimate();
niklase@google.com470e71d2011-07-07 08:21:25 +000099
Åsa Persson3fcc5be2019-04-04 09:40:27 +0200100 // Post process the calculated estimate.
philipel9d3ab612015-12-21 04:12:39 -0800101 void PostProcessEstimate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000102
Åsa Persson3fcc5be2019-04-04 09:40:27 +0200103 // Calculates the difference in delay between a sample and the expected delay
104 // estimated by the Kalman filter.
philipel9d3ab612015-12-21 04:12:39 -0800105 //
106 // Input:
107 // - frameDelayMS : Delay-delta calculated by UTILDelayEstimate in
Åsa Persson3fcc5be2019-04-04 09:40:27 +0200108 // milliseconds.
philipel9d3ab612015-12-21 04:12:39 -0800109 // - deltaFS : Frame size delta, i.e. frame size at time
Åsa Persson3fcc5be2019-04-04 09:40:27 +0200110 // T minus frame size at time T-1.
philipel9d3ab612015-12-21 04:12:39 -0800111 //
Åsa Persson3fcc5be2019-04-04 09:40:27 +0200112 // Return value : The difference in milliseconds.
philipel9d3ab612015-12-21 04:12:39 -0800113 double DeviationFromExpectedDelay(int64_t frameDelayMS,
114 int32_t deltaFSBytes) const;
niklase@google.com470e71d2011-07-07 08:21:25 +0000115
philipel9d3ab612015-12-21 04:12:39 -0800116 double GetFrameRate() const;
sprang@webrtc.org70e2d112014-09-24 14:06:56 +0000117
Åsa Persson3fcc5be2019-04-04 09:40:27 +0200118 // Constants, filter parameters.
philipel9d3ab612015-12-21 04:12:39 -0800119 const double _phi;
120 const double _psi;
121 const uint32_t _alphaCountMax;
122 const double _thetaLow;
123 const uint32_t _nackLimit;
124 const int32_t _numStdDevDelayOutlier;
125 const int32_t _numStdDevFrameSizeOutlier;
126 const double _noiseStdDevs;
127 const double _noiseStdDevOffset;
niklase@google.com470e71d2011-07-07 08:21:25 +0000128
philipel9d3ab612015-12-21 04:12:39 -0800129 double _thetaCov[2][2]; // Estimate covariance
130 double _Qcov[2][2]; // Process noise covariance
131 double _avgFrameSize; // Average frame size
132 double _varFrameSize; // Frame size variance
133 double _maxFrameSize; // Largest frame size received (descending
134 // with a factor _psi)
135 uint32_t _fsSum;
136 uint32_t _fsCount;
niklase@google.com470e71d2011-07-07 08:21:25 +0000137
philipel9d3ab612015-12-21 04:12:39 -0800138 int64_t _lastUpdateT;
139 double _prevEstimate; // The previously returned jitter estimate
140 uint32_t _prevFrameSize; // Frame size of the previous frame
141 double _avgNoise; // Average of the random jitter
142 uint32_t _alphaCount;
143 double _filterJitterEstimate; // The filtered sum of jitter estimates
niklase@google.com470e71d2011-07-07 08:21:25 +0000144
philipel9d3ab612015-12-21 04:12:39 -0800145 uint32_t _startupCount;
niklase@google.com470e71d2011-07-07 08:21:25 +0000146
philipel9d3ab612015-12-21 04:12:39 -0800147 int64_t
148 _latestNackTimestamp; // Timestamp in ms when the latest nack was seen
149 uint32_t _nackCount; // Keeps track of the number of nacks received,
150 // but never goes above _nackLimit
151 VCMRttFilter _rttFilter;
niklase@google.com470e71d2011-07-07 08:21:25 +0000152
philipel9d3ab612015-12-21 04:12:39 -0800153 rtc::RollingAccumulator<uint64_t> fps_counter_;
Erik Språngb1e031a2018-11-01 11:20:49 +0100154 const double time_deviation_upper_bound_;
Sebastian Janssonaa01f272019-01-30 11:28:59 +0100155 Clock* clock_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000156};
157
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000158} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +0000159
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200160#endif // MODULES_VIDEO_CODING_JITTER_ESTIMATOR_H_