/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#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()
    : _filtFactMax(35),
      _jumpStdDevs(2.5),
      _driftStdDevs(3.5),
      _detectThreshold(kMaxDriftJumpCount) {
  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;
}

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;
  }

  // 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;
  }
}

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;
    }
  } 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;
    }
  } else {
    _driftCount = 0;
  }
  return true;
}

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
