| Index: webrtc/modules/video_coding/rtt_filter.cc
 | 
| diff --git a/webrtc/modules/video_coding/rtt_filter.cc b/webrtc/modules/video_coding/rtt_filter.cc
 | 
| index 30a6946f9740a2157a095080b442efa7c55fb9a4..742f70f1c10a9d21e180a30dc07645cde5bf6a77 100644
 | 
| --- a/webrtc/modules/video_coding/rtt_filter.cc
 | 
| +++ b/webrtc/modules/video_coding/rtt_filter.cc
 | 
| @@ -8,13 +8,14 @@
 | 
|   *  be found in the AUTHORS file in the root of the source tree.
 | 
|   */
 | 
|  
 | 
| -#include "webrtc/modules/video_coding/internal_defines.h"
 | 
|  #include "webrtc/modules/video_coding/rtt_filter.h"
 | 
|  
 | 
|  #include <math.h>
 | 
|  #include <stdlib.h>
 | 
|  #include <string.h>
 | 
|  
 | 
| +#include "webrtc/modules/video_coding/internal_defines.h"
 | 
| +
 | 
|  namespace webrtc {
 | 
|  
 | 
|  VCMRttFilter::VCMRttFilter()
 | 
| @@ -22,181 +23,143 @@ VCMRttFilter::VCMRttFilter()
 | 
|        _jumpStdDevs(2.5),
 | 
|        _driftStdDevs(3.5),
 | 
|        _detectThreshold(kMaxDriftJumpCount) {
 | 
| -    Reset();
 | 
| +  Reset();
 | 
|  }
 | 
|  
 | 
| -VCMRttFilter&
 | 
| -VCMRttFilter::operator=(const VCMRttFilter& rhs)
 | 
| -{
 | 
| -    if (this != &rhs)
 | 
| -    {
 | 
| -        _gotNonZeroUpdate = rhs._gotNonZeroUpdate;
 | 
| -        _avgRtt = rhs._avgRtt;
 | 
| -        _varRtt = rhs._varRtt;
 | 
| -        _maxRtt = rhs._maxRtt;
 | 
| -        _filtFactCount = rhs._filtFactCount;
 | 
| -        _jumpCount = rhs._jumpCount;
 | 
| -        _driftCount = rhs._driftCount;
 | 
| -        memcpy(_jumpBuf, rhs._jumpBuf, sizeof(_jumpBuf));
 | 
| -        memcpy(_driftBuf, rhs._driftBuf, sizeof(_driftBuf));
 | 
| -    }
 | 
| -    return *this;
 | 
| +VCMRttFilter& VCMRttFilter::operator=(const VCMRttFilter& rhs) {
 | 
| +  if (this != &rhs) {
 | 
| +    _gotNonZeroUpdate = rhs._gotNonZeroUpdate;
 | 
| +    _avgRtt = rhs._avgRtt;
 | 
| +    _varRtt = rhs._varRtt;
 | 
| +    _maxRtt = rhs._maxRtt;
 | 
| +    _filtFactCount = rhs._filtFactCount;
 | 
| +    _jumpCount = rhs._jumpCount;
 | 
| +    _driftCount = rhs._driftCount;
 | 
| +    memcpy(_jumpBuf, rhs._jumpBuf, sizeof(_jumpBuf));
 | 
| +    memcpy(_driftBuf, rhs._driftBuf, sizeof(_driftBuf));
 | 
| +  }
 | 
| +  return *this;
 | 
|  }
 | 
|  
 | 
| -void
 | 
| -VCMRttFilter::Reset()
 | 
| -{
 | 
| -    _gotNonZeroUpdate = false;
 | 
| -    _avgRtt = 0;
 | 
| -    _varRtt = 0;
 | 
| -    _maxRtt = 0;
 | 
| -    _filtFactCount = 1;
 | 
| -    _jumpCount = 0;
 | 
| -    _driftCount = 0;
 | 
| -    memset(_jumpBuf, 0, kMaxDriftJumpCount);
 | 
| -    memset(_driftBuf, 0, kMaxDriftJumpCount);
 | 
| +void VCMRttFilter::Reset() {
 | 
| +  _gotNonZeroUpdate = false;
 | 
| +  _avgRtt = 0;
 | 
| +  _varRtt = 0;
 | 
| +  _maxRtt = 0;
 | 
| +  _filtFactCount = 1;
 | 
| +  _jumpCount = 0;
 | 
| +  _driftCount = 0;
 | 
| +  memset(_jumpBuf, 0, kMaxDriftJumpCount);
 | 
| +  memset(_driftBuf, 0, kMaxDriftJumpCount);
 | 
|  }
 | 
|  
 | 
| -void
 | 
| -VCMRttFilter::Update(int64_t rttMs)
 | 
| -{
 | 
| -    if (!_gotNonZeroUpdate)
 | 
| -    {
 | 
| -        if (rttMs == 0)
 | 
| -        {
 | 
| -            return;
 | 
| -        }
 | 
| -        _gotNonZeroUpdate = true;
 | 
| +void VCMRttFilter::Update(int64_t rttMs) {
 | 
| +  if (!_gotNonZeroUpdate) {
 | 
| +    if (rttMs == 0) {
 | 
| +      return;
 | 
|      }
 | 
| +    _gotNonZeroUpdate = true;
 | 
| +  }
 | 
|  
 | 
| -    // Sanity check
 | 
| -    if (rttMs > 3000)
 | 
| -    {
 | 
| -        rttMs = 3000;
 | 
| -    }
 | 
| +  // Sanity check
 | 
| +  if (rttMs > 3000) {
 | 
| +    rttMs = 3000;
 | 
| +  }
 | 
|  
 | 
| -    double filtFactor = 0;
 | 
| -    if (_filtFactCount > 1)
 | 
| -    {
 | 
| -        filtFactor = static_cast<double>(_filtFactCount - 1) / _filtFactCount;
 | 
| -    }
 | 
| -    _filtFactCount++;
 | 
| -    if (_filtFactCount > _filtFactMax)
 | 
| -    {
 | 
| -        // This prevents filtFactor from going above
 | 
| -        // (_filtFactMax - 1) / _filtFactMax,
 | 
| -        // e.g., _filtFactMax = 50 => filtFactor = 49/50 = 0.98
 | 
| -        _filtFactCount = _filtFactMax;
 | 
| -    }
 | 
| -    double oldAvg = _avgRtt;
 | 
| -    double oldVar = _varRtt;
 | 
| -    _avgRtt = filtFactor * _avgRtt + (1 - filtFactor) * rttMs;
 | 
| -    _varRtt = filtFactor * _varRtt + (1 - filtFactor) *
 | 
| -                (rttMs - _avgRtt) * (rttMs - _avgRtt);
 | 
| -    _maxRtt = VCM_MAX(rttMs, _maxRtt);
 | 
| -    if (!JumpDetection(rttMs) || !DriftDetection(rttMs))
 | 
| -    {
 | 
| -        // In some cases we don't want to update the statistics
 | 
| -        _avgRtt = oldAvg;
 | 
| -        _varRtt = oldVar;
 | 
| -    }
 | 
| +  double filtFactor = 0;
 | 
| +  if (_filtFactCount > 1) {
 | 
| +    filtFactor = static_cast<double>(_filtFactCount - 1) / _filtFactCount;
 | 
| +  }
 | 
| +  _filtFactCount++;
 | 
| +  if (_filtFactCount > _filtFactMax) {
 | 
| +    // This prevents filtFactor from going above
 | 
| +    // (_filtFactMax - 1) / _filtFactMax,
 | 
| +    // e.g., _filtFactMax = 50 => filtFactor = 49/50 = 0.98
 | 
| +    _filtFactCount = _filtFactMax;
 | 
| +  }
 | 
| +  double oldAvg = _avgRtt;
 | 
| +  double oldVar = _varRtt;
 | 
| +  _avgRtt = filtFactor * _avgRtt + (1 - filtFactor) * rttMs;
 | 
| +  _varRtt = filtFactor * _varRtt +
 | 
| +            (1 - filtFactor) * (rttMs - _avgRtt) * (rttMs - _avgRtt);
 | 
| +  _maxRtt = VCM_MAX(rttMs, _maxRtt);
 | 
| +  if (!JumpDetection(rttMs) || !DriftDetection(rttMs)) {
 | 
| +    // In some cases we don't want to update the statistics
 | 
| +    _avgRtt = oldAvg;
 | 
| +    _varRtt = oldVar;
 | 
| +  }
 | 
|  }
 | 
|  
 | 
| -bool
 | 
| -VCMRttFilter::JumpDetection(int64_t rttMs)
 | 
| -{
 | 
| -    double diffFromAvg = _avgRtt - rttMs;
 | 
| -    if (fabs(diffFromAvg) > _jumpStdDevs * sqrt(_varRtt))
 | 
| -    {
 | 
| -        int diffSign = (diffFromAvg >= 0) ? 1 : -1;
 | 
| -        int jumpCountSign = (_jumpCount >= 0) ? 1 : -1;
 | 
| -        if (diffSign != jumpCountSign)
 | 
| -        {
 | 
| -            // Since the signs differ the samples currently
 | 
| -            // in the buffer is useless as they represent a
 | 
| -            // jump in a different direction.
 | 
| -            _jumpCount = 0;
 | 
| -        }
 | 
| -        if (abs(_jumpCount) < kMaxDriftJumpCount)
 | 
| -        {
 | 
| -            // Update the buffer used for the short time
 | 
| -            // statistics.
 | 
| -            // The sign of the diff is used for updating the counter since
 | 
| -            // we want to use the same buffer for keeping track of when
 | 
| -            // the RTT jumps down and up.
 | 
| -            _jumpBuf[abs(_jumpCount)] = rttMs;
 | 
| -            _jumpCount += diffSign;
 | 
| -        }
 | 
| -        if (abs(_jumpCount) >= _detectThreshold)
 | 
| -        {
 | 
| -            // Detected an RTT jump
 | 
| -            ShortRttFilter(_jumpBuf, abs(_jumpCount));
 | 
| -            _filtFactCount = _detectThreshold + 1;
 | 
| -            _jumpCount = 0;
 | 
| -        }
 | 
| -        else
 | 
| -        {
 | 
| -            return false;
 | 
| -        }
 | 
| +bool VCMRttFilter::JumpDetection(int64_t rttMs) {
 | 
| +  double diffFromAvg = _avgRtt - rttMs;
 | 
| +  if (fabs(diffFromAvg) > _jumpStdDevs * sqrt(_varRtt)) {
 | 
| +    int diffSign = (diffFromAvg >= 0) ? 1 : -1;
 | 
| +    int jumpCountSign = (_jumpCount >= 0) ? 1 : -1;
 | 
| +    if (diffSign != jumpCountSign) {
 | 
| +      // Since the signs differ the samples currently
 | 
| +      // in the buffer is useless as they represent a
 | 
| +      // jump in a different direction.
 | 
| +      _jumpCount = 0;
 | 
|      }
 | 
| -    else
 | 
| -    {
 | 
| -        _jumpCount = 0;
 | 
| -    }
 | 
| -    return true;
 | 
| -}
 | 
| -
 | 
| -bool
 | 
| -VCMRttFilter::DriftDetection(int64_t rttMs)
 | 
| -{
 | 
| -    if (_maxRtt - _avgRtt > _driftStdDevs * sqrt(_varRtt))
 | 
| -    {
 | 
| -        if (_driftCount < kMaxDriftJumpCount)
 | 
| -        {
 | 
| -            // Update the buffer used for the short time
 | 
| -            // statistics.
 | 
| -            _driftBuf[_driftCount] = rttMs;
 | 
| -            _driftCount++;
 | 
| -        }
 | 
| -        if (_driftCount >= _detectThreshold)
 | 
| -        {
 | 
| -            // Detected an RTT drift
 | 
| -            ShortRttFilter(_driftBuf, _driftCount);
 | 
| -            _filtFactCount = _detectThreshold + 1;
 | 
| -            _driftCount = 0;
 | 
| -        }
 | 
| +    if (abs(_jumpCount) < kMaxDriftJumpCount) {
 | 
| +      // Update the buffer used for the short time
 | 
| +      // statistics.
 | 
| +      // The sign of the diff is used for updating the counter since
 | 
| +      // we want to use the same buffer for keeping track of when
 | 
| +      // the RTT jumps down and up.
 | 
| +      _jumpBuf[abs(_jumpCount)] = rttMs;
 | 
| +      _jumpCount += diffSign;
 | 
|      }
 | 
| -    else
 | 
| -    {
 | 
| -        _driftCount = 0;
 | 
| +    if (abs(_jumpCount) >= _detectThreshold) {
 | 
| +      // Detected an RTT jump
 | 
| +      ShortRttFilter(_jumpBuf, abs(_jumpCount));
 | 
| +      _filtFactCount = _detectThreshold + 1;
 | 
| +      _jumpCount = 0;
 | 
| +    } else {
 | 
| +      return false;
 | 
|      }
 | 
| -    return true;
 | 
| +  } else {
 | 
| +    _jumpCount = 0;
 | 
| +  }
 | 
| +  return true;
 | 
|  }
 | 
|  
 | 
| -void
 | 
| -VCMRttFilter::ShortRttFilter(int64_t* buf, uint32_t length)
 | 
| -{
 | 
| -    if (length == 0)
 | 
| -    {
 | 
| -        return;
 | 
| +bool VCMRttFilter::DriftDetection(int64_t rttMs) {
 | 
| +  if (_maxRtt - _avgRtt > _driftStdDevs * sqrt(_varRtt)) {
 | 
| +    if (_driftCount < kMaxDriftJumpCount) {
 | 
| +      // Update the buffer used for the short time
 | 
| +      // statistics.
 | 
| +      _driftBuf[_driftCount] = rttMs;
 | 
| +      _driftCount++;
 | 
|      }
 | 
| -    _maxRtt = 0;
 | 
| -    _avgRtt = 0;
 | 
| -    for (uint32_t i=0; i < length; i++)
 | 
| -    {
 | 
| -        if (buf[i] > _maxRtt)
 | 
| -        {
 | 
| -            _maxRtt = buf[i];
 | 
| -        }
 | 
| -        _avgRtt += buf[i];
 | 
| +    if (_driftCount >= _detectThreshold) {
 | 
| +      // Detected an RTT drift
 | 
| +      ShortRttFilter(_driftBuf, _driftCount);
 | 
| +      _filtFactCount = _detectThreshold + 1;
 | 
| +      _driftCount = 0;
 | 
|      }
 | 
| -    _avgRtt = _avgRtt / static_cast<double>(length);
 | 
| +  } else {
 | 
| +    _driftCount = 0;
 | 
| +  }
 | 
| +  return true;
 | 
|  }
 | 
|  
 | 
| -int64_t
 | 
| -VCMRttFilter::RttMs() const
 | 
| -{
 | 
| -    return static_cast<int64_t>(_maxRtt + 0.5);
 | 
| +void VCMRttFilter::ShortRttFilter(int64_t* buf, uint32_t length) {
 | 
| +  if (length == 0) {
 | 
| +    return;
 | 
| +  }
 | 
| +  _maxRtt = 0;
 | 
| +  _avgRtt = 0;
 | 
| +  for (uint32_t i = 0; i < length; i++) {
 | 
| +    if (buf[i] > _maxRtt) {
 | 
| +      _maxRtt = buf[i];
 | 
| +    }
 | 
| +    _avgRtt += buf[i];
 | 
| +  }
 | 
| +  _avgRtt = _avgRtt / static_cast<double>(length);
 | 
|  }
 | 
|  
 | 
| +int64_t VCMRttFilter::RttMs() const {
 | 
| +  return static_cast<int64_t>(_maxRtt + 0.5);
 | 
|  }
 | 
| +}  // namespace webrtc
 | 
| 
 |