/*
 *  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 "modules/video_coding/main/source/media_opt_util.h"

#include <math.h>
#include <float.h>
#include <limits.h>

#include "modules/interface/module_common_types.h"
#include "modules/video_coding/codecs/vp8/main/interface/vp8_common_types.h"
#include "modules/video_coding/main/interface/video_coding_defines.h"
#include "modules/video_coding/main/source/er_tables_xor.h"
#include "modules/video_coding/main/source/fec_tables_xor.h"
#include "modules/video_coding/main/source/nack_fec_tables.h"

namespace webrtc {

VCMProtectionMethod::VCMProtectionMethod():
_effectivePacketLoss(0),
_protectionFactorK(0),
_protectionFactorD(0),
_residualPacketLossFec(0.0f),
_scaleProtKey(2.0f),
_maxPayloadSize(1460),
_qmRobustness(new VCMQmRobustness()),
_useUepProtectionK(false),
_useUepProtectionD(true),
_corrFecCost(1.0),
_type(kNone),
_efficiency(0)
{
    //
}

VCMProtectionMethod::~VCMProtectionMethod()
{
    delete _qmRobustness;
}
void
VCMProtectionMethod::UpdateContentMetrics(const
                                          VideoContentMetrics* contentMetrics)
{
    _qmRobustness->UpdateContent(contentMetrics);
}

VCMNackFecMethod::VCMNackFecMethod(int lowRttNackThresholdMs,
                                   int highRttNackThresholdMs)
    : VCMFecMethod(),
      _lowRttNackMs(lowRttNackThresholdMs),
      _highRttNackMs(highRttNackThresholdMs) {
  assert(lowRttNackThresholdMs >= -1 && highRttNackThresholdMs >= -1);
  assert(highRttNackThresholdMs == -1 ||
         lowRttNackThresholdMs <= highRttNackThresholdMs);
  assert(lowRttNackThresholdMs > -1 || highRttNackThresholdMs == -1);
  _type = kNackFec;
}

VCMNackFecMethod::~VCMNackFecMethod()
{
    //
}
bool
VCMNackFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters)
{
    // Hybrid Nack FEC has three operational modes:
    // 1. Low RTT (below kLowRttNackMs) - Nack only: Set FEC rate
    //    (_protectionFactorD) to zero. -1 means no FEC.
    // 2. High RTT (above _highRttNackMs) - FEC Only: Keep FEC factors.
    //    -1 means always allow NACK.
    // 3. Medium RTT values - Hybrid mode: We will only nack the
    //    residual following the decoding of the FEC (refer to JB logic). FEC
    //    delta protection factor will be adjusted based on the RTT.

    // Otherwise: we count on FEC; if the RTT is below a threshold, then we
    // nack the residual, based on a decision made in the JB.

    // Compute the protection factors
    VCMFecMethod::ProtectionFactor(parameters);
    if (_lowRttNackMs == -1 || parameters->rtt < _lowRttNackMs)
    {
        _protectionFactorD = 0;
        VCMFecMethod::UpdateProtectionFactorD(_protectionFactorD);
    }

    // When in Hybrid mode (RTT range), adjust FEC rates based on the
    // RTT (NACK effectiveness) - adjustment factor is in the range [0,1].
    else if (_highRttNackMs == -1 || parameters->rtt < _highRttNackMs)
    {
        // TODO(mikhal): Disabling adjustment temporarily.
        // WebRtc_UWord16 rttIndex = (WebRtc_UWord16) parameters->rtt;
        float adjustRtt = 1.0f;// (float)VCMNackFecTable[rttIndex] / 100.0f;

        // Adjust FEC with NACK on (for delta frame only)
        // table depends on RTT relative to rttMax (NACK Threshold)
        _protectionFactorD = static_cast<WebRtc_UWord8>
                            (adjustRtt *
                             static_cast<float>(_protectionFactorD));
        // update FEC rates after applying adjustment
        VCMFecMethod::UpdateProtectionFactorD(_protectionFactorD);
    }

    return true;
}

bool
VCMNackFecMethod::EffectivePacketLoss(const VCMProtectionParameters* parameters)
{
    // Set the effective packet loss for encoder (based on FEC code).
    // Compute the effective packet loss and residual packet loss due to FEC.
    VCMFecMethod::EffectivePacketLoss(parameters);
    return true;
}

bool
VCMNackFecMethod::UpdateParameters(const VCMProtectionParameters* parameters)
{
    ProtectionFactor(parameters);
    EffectivePacketLoss(parameters);

    // Efficiency computation is based on FEC and NACK

    // Add FEC cost: ignore I frames for now
    float fecRate = static_cast<float> (_protectionFactorD) / 255.0f;
    _efficiency = parameters->bitRate * fecRate * _corrFecCost;

    // Add NACK cost, when applicable
    if (_highRttNackMs == -1 || parameters->rtt < _highRttNackMs)
    {
        // nackCost  = (bitRate - nackCost) * (lossPr)
        _efficiency += parameters->bitRate * _residualPacketLossFec /
                       (1.0f + _residualPacketLossFec);
    }

    // Protection/fec rates obtained above are defined relative to total number
    // of packets (total rate: source + fec) FEC in RTP module assumes
    // protection factor is defined relative to source number of packets so we
    // should convert the factor to reduce mismatch between mediaOpt's rate and
    // the actual one
    _protectionFactorK = VCMFecMethod::ConvertFECRate(_protectionFactorK);
    _protectionFactorD = VCMFecMethod::ConvertFECRate(_protectionFactorD);

    return true;
}

VCMNackMethod::VCMNackMethod():
VCMProtectionMethod()
{
    _type = kNack;
}

VCMNackMethod::~VCMNackMethod()
{
    //
}

bool
VCMNackMethod::EffectivePacketLoss(const VCMProtectionParameters* parameter)
{
    // Effective Packet Loss, NA in current version.
    _effectivePacketLoss = 0;
    return true;
}

bool
VCMNackMethod::UpdateParameters(const VCMProtectionParameters* parameters)
{
    // Compute the effective packet loss
    EffectivePacketLoss(parameters);

    // nackCost  = (bitRate - nackCost) * (lossPr)
    _efficiency = parameters->bitRate * parameters->lossPr /
                  (1.0f + parameters->lossPr);
    return true;
}

VCMFecMethod::VCMFecMethod():
VCMProtectionMethod()
{
    _type = kFec;
}
VCMFecMethod::~VCMFecMethod()
{
    //
}

WebRtc_UWord8
VCMFecMethod::BoostCodeRateKey(WebRtc_UWord8 packetFrameDelta,
                               WebRtc_UWord8 packetFrameKey) const
{
    WebRtc_UWord8 boostRateKey = 2;
    // Default: ratio scales the FEC protection up for I frames
    WebRtc_UWord8 ratio = 1;

    if (packetFrameDelta > 0)
    {
        ratio = (WebRtc_Word8) (packetFrameKey / packetFrameDelta);
    }
    ratio = VCM_MAX(boostRateKey, ratio);

    return ratio;
}

WebRtc_UWord8
VCMFecMethod::ConvertFECRate(WebRtc_UWord8 codeRateRTP) const
{
    return static_cast<WebRtc_UWord8> (VCM_MIN(255,(0.5 + 255.0 * codeRateRTP /
                                      (float)(255 - codeRateRTP))));
}

// Update FEC with protectionFactorD
void
VCMFecMethod::UpdateProtectionFactorD(WebRtc_UWord8 protectionFactorD)
{
    _protectionFactorD = protectionFactorD;
}

// Update FEC with protectionFactorK
void
VCMFecMethod::UpdateProtectionFactorK(WebRtc_UWord8 protectionFactorK)
{
    _protectionFactorK = protectionFactorK;
}

// AvgRecoveryFEC: computes the residual packet loss (RPL) function.
// This is the average recovery from the FEC, assuming random packet loss model.
// Computed off-line for a range of FEC code parameters and loss rates.
float
VCMFecMethod::AvgRecoveryFEC(const VCMProtectionParameters* parameters) const
{
    // Total (avg) bits available per frame: total rate over actual/sent frame
    // rate units are kbits/frame
    const WebRtc_UWord16 bitRatePerFrame = static_cast<WebRtc_UWord16>
                        (parameters->bitRate / (parameters->frameRate));

    // Total (average) number of packets per frame (source and fec):
    const WebRtc_UWord8 avgTotPackets = 1 + static_cast<WebRtc_UWord8>
                        (static_cast<float> (bitRatePerFrame * 1000.0) /
                         static_cast<float> (8.0 * _maxPayloadSize) + 0.5);

    const float protectionFactor = static_cast<float>(_protectionFactorD) /
                                                      255.0;

    WebRtc_UWord8 fecPacketsPerFrame = static_cast<WebRtc_UWord8>
                                      (0.5 + protectionFactor * avgTotPackets);

    WebRtc_UWord8 sourcePacketsPerFrame = avgTotPackets - fecPacketsPerFrame;

    if ( (fecPacketsPerFrame == 0) || (sourcePacketsPerFrame == 0) )
    {
        // No protection, or rate too low: so average recovery from FEC == 0.
        return 0.0;
    }

    // Table defined up to kMaxNumPackets
    if (sourcePacketsPerFrame > kMaxNumPackets)
    {
        sourcePacketsPerFrame = kMaxNumPackets;
    }

    // Table defined up to kMaxNumPackets
    if (fecPacketsPerFrame > kMaxNumPackets)
    {
        fecPacketsPerFrame = kMaxNumPackets;
    }

    // Code index for tables: up to (kMaxNumPackets * kMaxNumPackets)
    WebRtc_UWord16 codeIndexTable[kMaxNumPackets * kMaxNumPackets];
    WebRtc_UWord16 k = 0;
    for (WebRtc_UWord8 i = 1; i <= kMaxNumPackets; i++)
    {
        for (WebRtc_UWord8 j = 1; j <= i; j++)
        {
            codeIndexTable[(j - 1) * kMaxNumPackets + i - 1] = k;
            k += 1;
        }
    }

    WebRtc_UWord8 lossRate = static_cast<WebRtc_UWord8> (255.0 *
                             parameters->lossPr + 0.5f);

    // Constrain lossRate to 50%: tables defined up to 50%
    if (lossRate >= kPacketLossMax)
    {
        lossRate = kPacketLossMax - 1;
    }

    const WebRtc_UWord16 codeIndex = (fecPacketsPerFrame - 1) * kMaxNumPackets +
                                     (sourcePacketsPerFrame - 1);

    const WebRtc_UWord16 indexTable = codeIndexTable[codeIndex] * kPacketLossMax +
                                      lossRate;

    // Check on table index
    assert(indexTable < kSizeAvgFECRecoveryXOR);
    float avgFecRecov = static_cast<float>(kAvgFECRecoveryXOR[indexTable]);

    return avgFecRecov;
}

bool
VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters)
{
    // FEC PROTECTION SETTINGS: varies with packet loss and bitrate

    // No protection if (filtered) packetLoss is 0
    WebRtc_UWord8 packetLoss = (WebRtc_UWord8) (255 * parameters->lossPr);
    if (packetLoss == 0)
    {
        _protectionFactorK = 0;
        _protectionFactorD = 0;
         return true;
    }

    // Parameters for FEC setting:
    // first partition size, thresholds, table pars, spatial resoln fac.

    // First partition protection: ~ 20%
    WebRtc_UWord8 firstPartitionProt = (WebRtc_UWord8) (255 * 0.20);

    // Minimum protection level needed to generate one FEC packet for one
    // source packet/frame (in RTP sender)
    WebRtc_UWord8 minProtLevelFec = 85;

    // Threshold on packetLoss and bitRrate/frameRate (=average #packets),
    // above which we allocate protection to cover at least first partition.
    WebRtc_UWord8 lossThr = 0;
    WebRtc_UWord8 packetNumThr = 1;

    // Parameters for range of rate index of table.
    const WebRtc_UWord8 ratePar1 = 5;
    const WebRtc_UWord8 ratePar2 = 49;

    // Spatial resolution size, relative to a reference size.
    float spatialSizeToRef = static_cast<float>
                           (parameters->codecWidth * parameters->codecHeight) /
                           (static_cast<float>(704 * 576));
    // resolnFac: This parameter will generally increase/decrease the FEC rate
    // (for fixed bitRate and packetLoss) based on system size.
    // Use a smaller exponent (< 1) to control/soften system size effect.
    const float resolnFac = 1.0 / powf(spatialSizeToRef, 0.3f);

    const int bitRatePerFrame = BitsPerFrame(parameters);


    // Average number of packets per frame (source and fec):
    const WebRtc_UWord8 avgTotPackets = 1 + (WebRtc_UWord8)
                                        ((float) bitRatePerFrame * 1000.0
                                       / (float) (8.0 * _maxPayloadSize) + 0.5);

    // FEC rate parameters: for P and I frame
    WebRtc_UWord8 codeRateDelta = 0;
    WebRtc_UWord8 codeRateKey = 0;

    // Get index for table: the FEC protection depends on an effective rate.
    // The range on the rate index corresponds to rates (bps)
    // from ~200k to ~8000k, for 30fps
    const WebRtc_UWord16 effRateFecTable = static_cast<WebRtc_UWord16>
                                           (resolnFac * bitRatePerFrame);
    WebRtc_UWord8 rateIndexTable =
        (WebRtc_UWord8) VCM_MAX(VCM_MIN((effRateFecTable - ratePar1) /
                                         ratePar1, ratePar2), 0);

    // Restrict packet loss range to 50:
    // current tables defined only up to 50%
    if (packetLoss >= kPacketLossMax)
    {
        packetLoss = kPacketLossMax - 1;
    }
    WebRtc_UWord16 indexTable = rateIndexTable * kPacketLossMax + packetLoss;

    // Check on table index
    assert(indexTable < kSizeCodeRateXORTable);

    // Protection factor for P frame
    codeRateDelta = kCodeRateXORTable[indexTable];

    if (packetLoss > lossThr && avgTotPackets > packetNumThr)
    {
        // Set a minimum based on first partition size.
        if (codeRateDelta < firstPartitionProt)
        {
            codeRateDelta = firstPartitionProt;
        }
    }

    // Check limit on amount of protection for P frame; 50% is max.
    if (codeRateDelta >= kPacketLossMax)
    {
        codeRateDelta = kPacketLossMax - 1;
    }

    float adjustFec = 1.0f;
    // Avoid additional adjustments when layers are active.
    // TODO(mikhal/marco): Update adjusmtent based on layer info.
    if (parameters->numLayers == 1)
    {
        adjustFec = _qmRobustness->AdjustFecFactor(codeRateDelta,
                                                   parameters->bitRate,
                                                   parameters->frameRate,
                                                   parameters->rtt,
                                                   packetLoss);
    }

    codeRateDelta = static_cast<WebRtc_UWord8>(codeRateDelta * adjustFec);

    // For Key frame:
    // Effectively at a higher rate, so we scale/boost the rate
    // The boost factor may depend on several factors: ratio of packet
    // number of I to P frames, how much protection placed on P frames, etc.
    const WebRtc_UWord8 packetFrameDelta = (WebRtc_UWord8)
                                           (0.5 + parameters->packetsPerFrame);
    const WebRtc_UWord8 packetFrameKey = (WebRtc_UWord8)
                                         (0.5 + parameters->packetsPerFrameKey);
    const WebRtc_UWord8 boostKey = BoostCodeRateKey(packetFrameDelta,
                                                    packetFrameKey);

    rateIndexTable = (WebRtc_UWord8) VCM_MAX(VCM_MIN(
                      1 + (boostKey * effRateFecTable - ratePar1) /
                      ratePar1,ratePar2),0);
    WebRtc_UWord16 indexTableKey = rateIndexTable * kPacketLossMax + packetLoss;

    indexTableKey = VCM_MIN(indexTableKey, kSizeCodeRateXORTable);

    // Check on table index
    assert(indexTableKey < kSizeCodeRateXORTable);

    // Protection factor for I frame
    codeRateKey = kCodeRateXORTable[indexTableKey];

    // Boosting for Key frame.
    int boostKeyProt = _scaleProtKey * codeRateDelta;
    if (boostKeyProt >= kPacketLossMax)
    {
        boostKeyProt = kPacketLossMax - 1;
    }

    // Make sure I frame protection is at least larger than P frame protection,
    // and at least as high as filtered packet loss.
    codeRateKey = static_cast<WebRtc_UWord8> (VCM_MAX(packetLoss,
            VCM_MAX(boostKeyProt, codeRateKey)));

    // Check limit on amount of protection for I frame: 50% is max.
    if (codeRateKey >= kPacketLossMax)
    {
        codeRateKey = kPacketLossMax - 1;
    }

    _protectionFactorK = codeRateKey;
    _protectionFactorD = codeRateDelta;

    // Generally there is a rate mis-match between the FEC cost estimated
    // in mediaOpt and the actual FEC cost sent out in RTP module.
    // This is more significant at low rates (small # of source packets), where
    // the granularity of the FEC decreases. In this case, non-zero protection
    // in mediaOpt may generate 0 FEC packets in RTP sender (since actual #FEC
    // is based on rounding off protectionFactor on actual source packet number).
    // The correction factor (_corrFecCost) attempts to corrects this, at least
    // for cases of low rates (small #packets) and low protection levels.

    float numPacketsFl = 1.0f + ((float) bitRatePerFrame * 1000.0
                                / (float) (8.0 * _maxPayloadSize) + 0.5);

    const float estNumFecGen = 0.5f + static_cast<float> (_protectionFactorD *
                                                         numPacketsFl / 255.0f);


    // We reduce cost factor (which will reduce overhead for FEC and
    // hybrid method) and not the protectionFactor.
    _corrFecCost = 1.0f;
    if (estNumFecGen < 1.1f && _protectionFactorD < minProtLevelFec)
    {
        _corrFecCost = 0.5f;
    }
    if (estNumFecGen < 0.9f && _protectionFactorD < minProtLevelFec)
    {
        _corrFecCost = 0.0f;
    }

     // TODO (marpan): Set the UEP protection on/off for Key and Delta frames
    _useUepProtectionK = _qmRobustness->SetUepProtection(codeRateKey,
                                                         parameters->bitRate,
                                                         packetLoss,
                                                         0);

    _useUepProtectionD = _qmRobustness->SetUepProtection(codeRateDelta,
                                                         parameters->bitRate,
                                                         packetLoss,
                                                         1);

    // DONE WITH FEC PROTECTION SETTINGS
    return true;
}

int VCMFecMethod::BitsPerFrame(const VCMProtectionParameters* parameters) {
  // When temporal layers are available FEC will only be applied on the base
  // layer.
  const float bitRateRatio =
    kVp8LayerRateAlloction[parameters->numLayers - 1][0];
  float frameRateRatio = powf(1 / 2, parameters->numLayers - 1);
  float bitRate = parameters->bitRate * bitRateRatio;
  float frameRate = parameters->frameRate * frameRateRatio;

  // TODO(mikhal): Update factor following testing.
  float adjustmentFactor = 1;

  // Average bits per frame (units of kbits)
  return static_cast<int>(adjustmentFactor * bitRate / frameRate);
}

bool
VCMFecMethod::EffectivePacketLoss(const VCMProtectionParameters* parameters)
{
    // Effective packet loss to encoder is based on RPL (residual packet loss)
    // this is a soft setting based on degree of FEC protection
    // RPL = received/input packet loss - average_FEC_recovery
    // note: received/input packet loss may be filtered based on FilteredLoss

    // The packet loss:
    WebRtc_UWord8 packetLoss = (WebRtc_UWord8) (255 * parameters->lossPr);

    float avgFecRecov = AvgRecoveryFEC(parameters);

    // Residual Packet Loss:
    _residualPacketLossFec = (float) (packetLoss - avgFecRecov) / 255.0f;

    // Effective Packet Loss, NA in current version.
    _effectivePacketLoss = 0;

    return true;
}

bool
VCMFecMethod::UpdateParameters(const VCMProtectionParameters* parameters)
{
    // Compute the protection factor
    ProtectionFactor(parameters);

    // Compute the effective packet loss
    EffectivePacketLoss(parameters);

    // Compute the bit cost
    // Ignore key frames for now.
    float fecRate = static_cast<float> (_protectionFactorD) / 255.0f;
    if (fecRate >= 0.0f)
    {
        // use this formula if the fecRate (protection factor) is defined
        // relative to number of source packets
        // this is the case for the previous tables:
        // _efficiency = parameters->bitRate * ( 1.0 - 1.0 / (1.0 + fecRate));

        // in the new tables, the fecRate is defined relative to total number of
        // packets (total rate), so overhead cost is:
        _efficiency = parameters->bitRate * fecRate * _corrFecCost;
    }
    else
    {
        _efficiency = 0.0f;
    }

    // Protection/fec rates obtained above is defined relative to total number
    // of packets (total rate: source+fec) FEC in RTP module assumes protection
    // factor is defined relative to source number of packets so we should
    // convert the factor to reduce mismatch between mediaOpt suggested rate and
    // the actual rate
    _protectionFactorK = ConvertFECRate(_protectionFactorK);
    _protectionFactorD = ConvertFECRate(_protectionFactorD);

    return true;
}
VCMLossProtectionLogic::VCMLossProtectionLogic(int64_t nowMs):
_selectedMethod(NULL),
_currentParameters(),
_rtt(0),
_lossPr(0.0f),
_bitRate(0.0f),
_frameRate(0.0f),
_keyFrameSize(0.0f),
_fecRateKey(0),
_fecRateDelta(0),
_lastPrUpdateT(0),
_lossPr255(0.9999f),
_lossPrHistory(),
_shortMaxLossPr255(0),
_packetsPerFrame(0.9999f),
_packetsPerFrameKey(0.9999f),
_residualPacketLossFec(0),
_boostRateKey(2),
_codecWidth(0),
_codecHeight(0),
_numLayers(1)
{
    Reset(nowMs);
}

VCMLossProtectionLogic::~VCMLossProtectionLogic()
{
    Release();
}

bool
VCMLossProtectionLogic::SetMethod(enum VCMProtectionMethodEnum newMethodType)
{
    if (_selectedMethod != NULL)
    {
        if (_selectedMethod->Type() == newMethodType)
        {
            // Nothing to update
            return false;
        }
        // New method - delete existing one
        delete _selectedMethod;
    }
    VCMProtectionMethod *newMethod = NULL;
    switch (newMethodType)
    {
        case kNack:
        {
            newMethod = new VCMNackMethod();
            break;
        }
        case kFec:
        {
            newMethod  = new VCMFecMethod();
            break;
        }
        case kNackFec:
        {
            // Default to always having NACK enabled for the hybrid mode.
            newMethod =  new VCMNackFecMethod(kLowRttNackMs, -1);
            break;
        }
        default:
        {
          return false;
          break;
        }

    }
    _selectedMethod = newMethod;
    return true;
}
bool
VCMLossProtectionLogic::RemoveMethod(enum VCMProtectionMethodEnum method)
{
    if (_selectedMethod == NULL)
    {
        return false;
    }
    else if (_selectedMethod->Type() == method)
    {
        delete _selectedMethod;
        _selectedMethod = NULL;
    }
    return true;
}

float
VCMLossProtectionLogic::RequiredBitRate() const
{
    float RequiredBitRate = 0.0f;
    if (_selectedMethod != NULL)
    {
        RequiredBitRate = _selectedMethod->RequiredBitRate();
    }
    return RequiredBitRate;
}

void
VCMLossProtectionLogic::UpdateRtt(WebRtc_UWord32 rtt)
{
    _rtt = rtt;
}

void
VCMLossProtectionLogic::UpdateResidualPacketLoss(float residualPacketLoss)
{
    _residualPacketLossFec = residualPacketLoss;
}

void
VCMLossProtectionLogic::UpdateMaxLossHistory(WebRtc_UWord8 lossPr255,
                                             WebRtc_Word64 now)
{
    if (_lossPrHistory[0].timeMs >= 0 &&
        now - _lossPrHistory[0].timeMs < kLossPrShortFilterWinMs)
    {
        if (lossPr255 > _shortMaxLossPr255)
        {
            _shortMaxLossPr255 = lossPr255;
        }
    }
    else
    {
        // Only add a new value to the history once a second
        if (_lossPrHistory[0].timeMs == -1)
        {
            // First, no shift
            _shortMaxLossPr255 = lossPr255;
        }
        else
        {
            // Shift
            for (WebRtc_Word32 i = (kLossPrHistorySize - 2); i >= 0; i--)
            {
                _lossPrHistory[i + 1].lossPr255 = _lossPrHistory[i].lossPr255;
                _lossPrHistory[i + 1].timeMs = _lossPrHistory[i].timeMs;
            }
        }
        if (_shortMaxLossPr255 == 0)
        {
            _shortMaxLossPr255 = lossPr255;
        }

        _lossPrHistory[0].lossPr255 = _shortMaxLossPr255;
        _lossPrHistory[0].timeMs = now;
        _shortMaxLossPr255 = 0;
    }
}

WebRtc_UWord8
VCMLossProtectionLogic::MaxFilteredLossPr(WebRtc_Word64 nowMs) const
{
    WebRtc_UWord8 maxFound = _shortMaxLossPr255;
    if (_lossPrHistory[0].timeMs == -1)
    {
        return maxFound;
    }
    for (WebRtc_Word32 i = 0; i < kLossPrHistorySize; i++)
    {
        if (_lossPrHistory[i].timeMs == -1)
        {
            break;
        }
        if (nowMs - _lossPrHistory[i].timeMs >
            kLossPrHistorySize * kLossPrShortFilterWinMs)
        {
            // This sample (and all samples after this) is too old
            break;
        }
        if (_lossPrHistory[i].lossPr255 > maxFound)
        {
            // This sample is the largest one this far into the history
            maxFound = _lossPrHistory[i].lossPr255;
        }
    }
    return maxFound;
}

WebRtc_UWord8 VCMLossProtectionLogic::FilteredLoss(
    int64_t nowMs,
    FilterPacketLossMode filter_mode,
    WebRtc_UWord8 lossPr255) {

  // Update the max window filter.
  UpdateMaxLossHistory(lossPr255, nowMs);

  // Update the recursive average filter.
  _lossPr255.Apply(static_cast<float> (nowMs - _lastPrUpdateT),
                   static_cast<float> (lossPr255));
  _lastPrUpdateT = nowMs;

  // Filtered loss: default is received loss (no filtering).
  WebRtc_UWord8 filtered_loss = lossPr255;

  switch (filter_mode) {
    case kNoFilter:
      break;
    case kAvgFilter:
      filtered_loss = static_cast<WebRtc_UWord8> (_lossPr255.Value() + 0.5);
      break;
    case kMaxFilter:
      filtered_loss = MaxFilteredLossPr(nowMs);
      break;
  }

  return filtered_loss;
}

void
VCMLossProtectionLogic::UpdateFilteredLossPr(WebRtc_UWord8 packetLossEnc)
{
    _lossPr = (float) packetLossEnc / (float) 255.0;
}

void
VCMLossProtectionLogic::UpdateBitRate(float bitRate)
{
    _bitRate = bitRate;
}

void
VCMLossProtectionLogic::UpdatePacketsPerFrame(float nPackets, int64_t nowMs)
{
    _packetsPerFrame.Apply(static_cast<float>(nowMs - _lastPacketPerFrameUpdateT),
                           nPackets);
    _lastPacketPerFrameUpdateT = nowMs;
}

void
VCMLossProtectionLogic::UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs)
{
    _packetsPerFrameKey.Apply(static_cast<float>(nowMs -
                              _lastPacketPerFrameUpdateTKey), nPackets);
    _lastPacketPerFrameUpdateTKey = nowMs;
}

void
VCMLossProtectionLogic::UpdateKeyFrameSize(float keyFrameSize)
{
    _keyFrameSize = keyFrameSize;
}

void
VCMLossProtectionLogic::UpdateFrameSize(WebRtc_UWord16 width,
                                        WebRtc_UWord16 height)
{
    _codecWidth = width;
    _codecHeight = height;
}

void VCMLossProtectionLogic::UpdateNumLayers(int numLayers) {
  _numLayers = (numLayers == 0) ? 1 : numLayers;
}

bool
VCMLossProtectionLogic::UpdateMethod()
{
    if (_selectedMethod == NULL)
    {
        return false;
    }
    _currentParameters.rtt = _rtt;
    _currentParameters.lossPr = _lossPr;
    _currentParameters.bitRate = _bitRate;
    _currentParameters.frameRate = _frameRate; // rename actual frame rate?
    _currentParameters.keyFrameSize = _keyFrameSize;
    _currentParameters.fecRateDelta = _fecRateDelta;
    _currentParameters.fecRateKey = _fecRateKey;
    _currentParameters.packetsPerFrame = _packetsPerFrame.Value();
    _currentParameters.packetsPerFrameKey = _packetsPerFrameKey.Value();
    _currentParameters.residualPacketLossFec = _residualPacketLossFec;
    _currentParameters.codecWidth = _codecWidth;
    _currentParameters.codecHeight = _codecHeight;
    _currentParameters.numLayers = _numLayers;
    return _selectedMethod->UpdateParameters(&_currentParameters);
}

VCMProtectionMethod*
VCMLossProtectionLogic::SelectedMethod() const
{
    return _selectedMethod;
}

VCMProtectionMethodEnum
VCMLossProtectionLogic::SelectedType() const
{
    return _selectedMethod->Type();
}

void
VCMLossProtectionLogic::Reset(int64_t nowMs)
{
    _lastPrUpdateT = nowMs;
    _lastPacketPerFrameUpdateT = nowMs;
    _lastPacketPerFrameUpdateTKey = nowMs;
    _lossPr255.Reset(0.9999f);
    _packetsPerFrame.Reset(0.9999f);
    _fecRateDelta = _fecRateKey = 0;
    for (WebRtc_Word32 i = 0; i < kLossPrHistorySize; i++)
    {
        _lossPrHistory[i].lossPr255 = 0;
        _lossPrHistory[i].timeMs = -1;
    }
    _shortMaxLossPr255 = 0;
    Release();
}

void
VCMLossProtectionLogic::Release()
{
    delete _selectedMethod;
    _selectedMethod = NULL;
}

}
