/*
 *  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/main/source/internal_defines.h"
#include "webrtc/modules/video_coding/main/source/rtt_filter.h"

#include <math.h>
#include <stdlib.h>
#include <string.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(uint32_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(uint32_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(uint32_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(uint32_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);
}

uint32_t
VCMRttFilter::RttMs() const
{
    return static_cast<uint32_t>(_maxRtt + 0.5);
}

}
