2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/video_coding/main/source/internal_defines.h"
12 #include "webrtc/modules/video_coding/main/source/jitter_estimator.h"
13 #include "webrtc/modules/video_coding/main/source/rtt_filter.h"
22 VCMJitterEstimator::VCMJitterEstimator(int32_t vcmId, int32_t receiverId)
24 _receiverId(receiverId),
30 _numStdDevDelayOutlier(15),
31 _numStdDevFrameSizeOutlier(3),
32 _noiseStdDevs(2.33), // ~Less than 1% chance
33 // (look up in normal distribution table)...
34 _noiseStdDevOffset(30.0), // ...of getting 30 ms freezes
40 VCMJitterEstimator::operator=(const VCMJitterEstimator& rhs)
44 memcpy(_thetaCov, rhs._thetaCov, sizeof(_thetaCov));
45 memcpy(_Qcov, rhs._Qcov, sizeof(_Qcov));
48 _receiverId = rhs._receiverId;
49 _avgFrameSize = rhs._avgFrameSize;
50 _varFrameSize = rhs._varFrameSize;
51 _maxFrameSize = rhs._maxFrameSize;
53 _fsCount = rhs._fsCount;
54 _lastUpdateT = rhs._lastUpdateT;
55 _prevEstimate = rhs._prevEstimate;
56 _prevFrameSize = rhs._prevFrameSize;
57 _avgNoise = rhs._avgNoise;
58 _alphaCount = rhs._alphaCount;
59 _filterJitterEstimate = rhs._filterJitterEstimate;
60 _startupCount = rhs._startupCount;
61 _latestNackTimestamp = rhs._latestNackTimestamp;
62 _nackCount = rhs._nackCount;
63 _rttFilter = rhs._rttFilter;
68 // Resets the JitterEstimate
70 VCMJitterEstimator::Reset()
72 _theta[0] = 1/(512e3/8);
76 _thetaCov[0][0] = 1e-4;
77 _thetaCov[1][1] = 1e2;
78 _thetaCov[0][1] = _thetaCov[1][0] = 0;
79 _Qcov[0][0] = 2.5e-10;
81 _Qcov[0][1] = _Qcov[1][0] = 0;
90 _filterJitterEstimate = 0.0;
91 _latestNackTimestamp = 0;
100 VCMJitterEstimator::ResetNackCount()
105 // Updates the estimates with the new measurements
107 VCMJitterEstimator::UpdateEstimate(int64_t frameDelayMS, uint32_t frameSizeBytes,
108 bool incompleteFrame /* = false */)
110 if (frameSizeBytes == 0)
114 int deltaFS = frameSizeBytes - _prevFrameSize;
115 if (_fsCount < kFsAccuStartupSamples)
117 _fsSum += frameSizeBytes;
120 else if (_fsCount == kFsAccuStartupSamples)
122 // Give the frame size filter
123 _avgFrameSize = static_cast<double>(_fsSum) /
124 static_cast<double>(_fsCount);
127 if (!incompleteFrame || frameSizeBytes > _avgFrameSize)
129 double avgFrameSize = _phi * _avgFrameSize +
130 (1 - _phi) * frameSizeBytes;
131 if (frameSizeBytes < _avgFrameSize + 2 * sqrt(_varFrameSize))
133 // Only update the average frame size if this sample wasn't a
135 _avgFrameSize = avgFrameSize;
137 // Update the variance anyway since we want to capture cases where we only get
139 _varFrameSize = VCM_MAX(_phi * _varFrameSize + (1 - _phi) *
140 (frameSizeBytes - avgFrameSize) *
141 (frameSizeBytes - avgFrameSize), 1.0);
144 // Update max frameSize estimate
145 _maxFrameSize = VCM_MAX(_psi * _maxFrameSize, static_cast<double>(frameSizeBytes));
147 if (_prevFrameSize == 0)
149 _prevFrameSize = frameSizeBytes;
152 _prevFrameSize = frameSizeBytes;
154 // Only update the Kalman filter if the sample is not considered
155 // an extreme outlier. Even if it is an extreme outlier from a
156 // delay point of view, if the frame size also is large the
157 // deviation is probably due to an incorrect line slope.
158 double deviation = DeviationFromExpectedDelay(frameDelayMS, deltaFS);
160 if (fabs(deviation) < _numStdDevDelayOutlier * sqrt(_varNoise) ||
161 frameSizeBytes > _avgFrameSize + _numStdDevFrameSizeOutlier * sqrt(_varFrameSize))
163 // Update the variance of the deviation from the
164 // line given by the Kalman filter
165 EstimateRandomJitter(deviation, incompleteFrame);
166 // Prevent updating with frames which have been congested by a large
167 // frame, and therefore arrives almost at the same time as that frame.
168 // This can occur when we receive a large frame (key frame) which
169 // has been delayed. The next frame is of normal size (delta frame),
170 // and thus deltaFS will be << 0. This removes all frame samples
171 // which arrives after a key frame.
172 if ((!incompleteFrame || deviation >= 0.0) &&
173 static_cast<double>(deltaFS) > - 0.25 * _maxFrameSize)
175 // Update the Kalman filter with the new data
176 KalmanEstimateChannel(frameDelayMS, deltaFS);
181 int nStdDev = (deviation >= 0) ? _numStdDevDelayOutlier : -_numStdDevDelayOutlier;
182 EstimateRandomJitter(nStdDev * sqrt(_varNoise), incompleteFrame);
184 // Post process the total estimated jitter
185 if (_startupCount >= kStartupDelaySamples)
187 PostProcessEstimate();
195 // Updates the nack/packet ratio
197 VCMJitterEstimator::FrameNacked()
199 // Wait until _nackLimit retransmissions has been received,
200 // then always add ~1 RTT delay.
201 // TODO(holmer): Should we ever remove the additional delay if the
202 // the packet losses seem to have stopped? We could for instance scale
203 // the number of RTTs to add with the amount of retransmissions in a given
204 // time interval, or similar.
205 if (_nackCount < _nackLimit)
211 // Updates Kalman estimate of the channel
212 // The caller is expected to sanity check the inputs.
214 VCMJitterEstimator::KalmanEstimateChannel(int64_t frameDelayMS,
215 int32_t deltaFSBytes)
219 double kalmanGain[2];
227 _thetaCov[0][0] += _Qcov[0][0];
228 _thetaCov[0][1] += _Qcov[0][1];
229 _thetaCov[1][0] += _Qcov[1][0];
230 _thetaCov[1][1] += _Qcov[1][1];
233 // K = M*h'/(sigma2n + h*M*h') = M*h'/(1 + h*M*h')
236 // hMh_sigma = h*M*h' + R
237 Mh[0] = _thetaCov[0][0] * deltaFSBytes + _thetaCov[0][1];
238 Mh[1] = _thetaCov[1][0] * deltaFSBytes + _thetaCov[1][1];
239 // sigma weights measurements with a small deltaFS as noisy and
240 // measurements with large deltaFS as good
241 if (_maxFrameSize < 1.0)
245 double sigma = (300.0 * exp(-fabs(static_cast<double>(deltaFSBytes)) /
246 (1e0 * _maxFrameSize)) + 1) * sqrt(_varNoise);
251 hMh_sigma = deltaFSBytes * Mh[0] + Mh[1] + sigma;
252 if ((hMh_sigma < 1e-9 && hMh_sigma >= 0) || (hMh_sigma > -1e-9 && hMh_sigma <= 0))
257 kalmanGain[0] = Mh[0] / hMh_sigma;
258 kalmanGain[1] = Mh[1] / hMh_sigma;
261 // theta = theta + K*(dT - h*theta)
262 measureRes = frameDelayMS - (deltaFSBytes * _theta[0] + _theta[1]);
263 _theta[0] += kalmanGain[0] * measureRes;
264 _theta[1] += kalmanGain[1] * measureRes;
266 if (_theta[0] < _thetaLow)
268 _theta[0] = _thetaLow;
272 t00 = _thetaCov[0][0];
273 t01 = _thetaCov[0][1];
274 _thetaCov[0][0] = (1 - kalmanGain[0] * deltaFSBytes) * t00 -
275 kalmanGain[0] * _thetaCov[1][0];
276 _thetaCov[0][1] = (1 - kalmanGain[0] * deltaFSBytes) * t01 -
277 kalmanGain[0] * _thetaCov[1][1];
278 _thetaCov[1][0] = _thetaCov[1][0] * (1 - kalmanGain[1]) -
279 kalmanGain[1] * deltaFSBytes * t00;
280 _thetaCov[1][1] = _thetaCov[1][1] * (1 - kalmanGain[1]) -
281 kalmanGain[1] * deltaFSBytes * t01;
283 // Covariance matrix, must be positive semi-definite
284 assert(_thetaCov[0][0] + _thetaCov[1][1] >= 0 &&
285 _thetaCov[0][0] * _thetaCov[1][1] - _thetaCov[0][1] * _thetaCov[1][0] >= 0 &&
286 _thetaCov[0][0] >= 0);
289 // Calculate difference in delay between a sample and the
290 // expected delay estimated by the Kalman filter
292 VCMJitterEstimator::DeviationFromExpectedDelay(int64_t frameDelayMS,
293 int32_t deltaFSBytes) const
295 return frameDelayMS - (_theta[0] * deltaFSBytes + _theta[1]);
298 // Estimates the random jitter by calculating the variance of the
299 // sample distance from the line given by theta.
301 VCMJitterEstimator::EstimateRandomJitter(double d_dT, bool incompleteFrame)
304 if (_alphaCount == 0)
306 assert(_alphaCount > 0);
309 alpha = static_cast<double>(_alphaCount - 1) / static_cast<double>(_alphaCount);
311 if (_alphaCount > _alphaCountMax)
313 _alphaCount = _alphaCountMax;
315 double avgNoise = alpha * _avgNoise + (1 - alpha) * d_dT;
316 double varNoise = alpha * _varNoise +
317 (1 - alpha) * (d_dT - _avgNoise) * (d_dT - _avgNoise);
318 if (!incompleteFrame || varNoise > _varNoise)
320 _avgNoise = avgNoise;
321 _varNoise = varNoise;
325 // The variance should never be zero, since we might get
326 // stuck and consider all samples as outliers.
332 VCMJitterEstimator::NoiseThreshold() const
334 double noiseThreshold = _noiseStdDevs * sqrt(_varNoise) - _noiseStdDevOffset;
335 if (noiseThreshold < 1.0)
337 noiseThreshold = 1.0;
339 return noiseThreshold;
342 // Calculates the current jitter estimate from the filtered estimates
344 VCMJitterEstimator::CalculateEstimate()
346 double ret = _theta[0] * (_maxFrameSize - _avgFrameSize) + NoiseThreshold();
348 // A very low estimate (or negative) is neglected
350 if (_prevEstimate <= 0.01)
359 if (ret > 10000.0) // Sanity
368 VCMJitterEstimator::PostProcessEstimate()
370 _filterJitterEstimate = CalculateEstimate();
374 VCMJitterEstimator::UpdateRtt(uint32_t rttMs)
376 _rttFilter.Update(rttMs);
380 VCMJitterEstimator::UpdateMaxFrameSize(uint32_t frameSizeBytes)
382 if (_maxFrameSize < frameSizeBytes)
384 _maxFrameSize = frameSizeBytes;
388 // Returns the current filtered estimate if available,
389 // otherwise tries to calculate an estimate.
391 VCMJitterEstimator::GetJitterEstimate(double rttMultiplier)
393 double jitterMS = CalculateEstimate() + OPERATING_SYSTEM_JITTER;
394 if (_filterJitterEstimate > jitterMS)
396 jitterMS = _filterJitterEstimate;
398 if (_nackCount >= _nackLimit)
400 jitterMS += _rttFilter.RttMs() * rttMultiplier;
402 return static_cast<uint32_t>(jitterMS + 0.5);