/*
 *  Copyright (c) 2012 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.
 */

#ifndef WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
#define WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_

#include <math.h>
#include <stdlib.h>

#include <memory>

#include "webrtc/base/exp_filter.h"
#include "webrtc/modules/video_coding/internal_defines.h"
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/typedefs.h"

namespace webrtc {
namespace media_optimization {

// Number of time periods used for (max) window filter for packet loss
// TODO(marpan): set reasonable window size for filtered packet loss,
// adjustment should be based on logged/real data of loss stats/correlation.
enum { kLossPrHistorySize = 10 };

// 1000 ms, total filter length is (kLossPrHistorySize * 1000) ms
enum { kLossPrShortFilterWinMs = 1000 };

// The type of filter used on the received packet loss reports.
enum FilterPacketLossMode {
  kNoFilter,   // No filtering on received loss.
  kAvgFilter,  // Recursive average filter.
  kMaxFilter   // Max-window filter, over the time interval of:
               // (kLossPrHistorySize * kLossPrShortFilterWinMs) ms.
};

// Thresholds for hybrid NACK/FEC
// common to media optimization and the jitter buffer.
const int64_t kLowRttNackMs = 20;

// If the RTT is higher than this an extra RTT wont be added to to the jitter
// buffer delay.
const int kMaxRttDelayThreshold = 500;

struct VCMProtectionParameters {
  VCMProtectionParameters()
      : rtt(0),
        lossPr(0.0f),
        bitRate(0.0f),
        packetsPerFrame(0.0f),
        packetsPerFrameKey(0.0f),
        frameRate(0.0f),
        keyFrameSize(0.0f),
        fecRateDelta(0),
        fecRateKey(0),
        codecWidth(0),
        codecHeight(0),
        numLayers(1) {}

  int64_t rtt;
  float lossPr;
  float bitRate;
  float packetsPerFrame;
  float packetsPerFrameKey;
  float frameRate;
  float keyFrameSize;
  uint8_t fecRateDelta;
  uint8_t fecRateKey;
  uint16_t codecWidth;
  uint16_t codecHeight;
  int numLayers;
};

/******************************/
/* VCMProtectionMethod class  */
/******************************/

enum VCMProtectionMethodEnum { kNack, kFec, kNackFec, kNone };

class VCMLossProbabilitySample {
 public:
  VCMLossProbabilitySample() : lossPr255(0), timeMs(-1) {}

  uint8_t lossPr255;
  int64_t timeMs;
};

class VCMProtectionMethod {
 public:
  VCMProtectionMethod();
  virtual ~VCMProtectionMethod();

  // Updates the efficiency of the method using the parameters provided
  //
  // Input:
  //         - parameters         : Parameters used to calculate efficiency
  //
  // Return value                 : True if this method is recommended in
  //                                the given conditions.
  virtual bool UpdateParameters(const VCMProtectionParameters* parameters) = 0;

  // Returns the protection type
  //
  // Return value                 : The protection type
  enum VCMProtectionMethodEnum Type() const { return _type; }

  // Returns the effective packet loss for ER, required by this protection
  // method
  //
  // Return value                 : Required effective packet loss
  virtual uint8_t RequiredPacketLossER() { return _effectivePacketLoss; }

  // Extracts the FEC protection factor for Key frame, required by this
  // protection method
  //
  // Return value                 : Required protectionFactor for Key frame
  virtual uint8_t RequiredProtectionFactorK() { return _protectionFactorK; }

  // Extracts the FEC protection factor for Delta frame, required by this
  // protection method
  //
  // Return value                 : Required protectionFactor for delta frame
  virtual uint8_t RequiredProtectionFactorD() { return _protectionFactorD; }

  // Extracts whether the FEC Unequal protection (UEP) is used for Key frame.
  //
  // Return value                 : Required Unequal protection on/off state.
  virtual bool RequiredUepProtectionK() { return _useUepProtectionK; }

  // Extracts whether the the FEC Unequal protection (UEP) is used for Delta
  // frame.
  //
  // Return value                 : Required Unequal protection on/off state.
  virtual bool RequiredUepProtectionD() { return _useUepProtectionD; }

  virtual int MaxFramesFec() const { return 1; }

 protected:
  uint8_t _effectivePacketLoss;
  uint8_t _protectionFactorK;
  uint8_t _protectionFactorD;
  // Estimation of residual loss after the FEC
  float _scaleProtKey;
  int32_t _maxPayloadSize;

  bool _useUepProtectionK;
  bool _useUepProtectionD;
  float _corrFecCost;
  enum VCMProtectionMethodEnum _type;
};

class VCMNackMethod : public VCMProtectionMethod {
 public:
  VCMNackMethod();
  virtual ~VCMNackMethod();
  virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
  // Get the effective packet loss
  bool EffectivePacketLoss(const VCMProtectionParameters* parameter);
};

class VCMFecMethod : public VCMProtectionMethod {
 public:
  VCMFecMethod();
  virtual ~VCMFecMethod();
  virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
  // Get the effective packet loss for ER
  bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
  // Get the FEC protection factors
  bool ProtectionFactor(const VCMProtectionParameters* parameters);
  // Get the boost for key frame protection
  uint8_t BoostCodeRateKey(uint8_t packetFrameDelta,
                           uint8_t packetFrameKey) const;
  // Convert the rates: defined relative to total# packets or source# packets
  uint8_t ConvertFECRate(uint8_t codeRate) const;
  // Get the average effective recovery from FEC: for random loss model
  float AvgRecoveryFEC(const VCMProtectionParameters* parameters) const;
  // Update FEC with protectionFactorD
  void UpdateProtectionFactorD(uint8_t protectionFactorD);
  // Update FEC with protectionFactorK
  void UpdateProtectionFactorK(uint8_t protectionFactorK);
  // Compute the bits per frame. Account for temporal layers when applicable.
  int BitsPerFrame(const VCMProtectionParameters* parameters);

 protected:
  enum { kUpperLimitFramesFec = 6 };
  // Thresholds values for the bytes/frame and round trip time, below which we
  // may turn off FEC, depending on |_numLayers| and |_maxFramesFec|.
  // Max bytes/frame for VGA, corresponds to ~140k at 25fps.
  enum { kMaxBytesPerFrameForFec = 700 };
  // Max bytes/frame for CIF and lower: corresponds to ~80k at 25fps.
  enum { kMaxBytesPerFrameForFecLow = 400 };
  // Max bytes/frame for frame size larger than VGA, ~200k at 25fps.
  enum { kMaxBytesPerFrameForFecHigh = 1000 };
};

class VCMNackFecMethod : public VCMFecMethod {
 public:
  VCMNackFecMethod(int64_t lowRttNackThresholdMs,
                   int64_t highRttNackThresholdMs);
  virtual ~VCMNackFecMethod();
  virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
  // Get the effective packet loss for ER
  bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
  // Get the protection factors
  bool ProtectionFactor(const VCMProtectionParameters* parameters);
  // Get the max number of frames the FEC is allowed to be based on.
  int MaxFramesFec() const;
  // Turn off the FEC based on low bitrate and other factors.
  bool BitRateTooLowForFec(const VCMProtectionParameters* parameters);

 private:
  int ComputeMaxFramesFec(const VCMProtectionParameters* parameters);

  int64_t _lowRttNackMs;
  int64_t _highRttNackMs;
  int _maxFramesFec;
};

class VCMLossProtectionLogic {
 public:
  explicit VCMLossProtectionLogic(int64_t nowMs);
  ~VCMLossProtectionLogic();

  // Set the protection method to be used
  //
  // Input:
  //        - newMethodType    : New requested protection method type. If one
  //                           is already set, it will be deleted and replaced
  void SetMethod(VCMProtectionMethodEnum newMethodType);

  // Update the round-trip time
  //
  // Input:
  //          - rtt           : Round-trip time in seconds.
  void UpdateRtt(int64_t rtt);

  // Update the filtered packet loss.
  //
  // Input:
  //          - packetLossEnc :  The reported packet loss filtered
  //                             (max window or average)
  void UpdateFilteredLossPr(uint8_t packetLossEnc);

  // Update the current target bit rate.
  //
  // Input:
  //          - bitRate          : The current target bit rate in kbits/s
  void UpdateBitRate(float bitRate);

  // Update the number of packets per frame estimate, for delta frames
  //
  // Input:
  //          - nPackets         : Number of packets in the latest sent frame.
  void UpdatePacketsPerFrame(float nPackets, int64_t nowMs);

  // Update the number of packets per frame estimate, for key frames
  //
  // Input:
  //          - nPackets         : umber of packets in the latest sent frame.
  void UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs);

  // Update the keyFrameSize estimate
  //
  // Input:
  //          - keyFrameSize     : The size of the latest sent key frame.
  void UpdateKeyFrameSize(float keyFrameSize);

  // Update the frame rate
  //
  // Input:
  //          - frameRate        : The current target frame rate.
  void UpdateFrameRate(float frameRate) { _frameRate = frameRate; }

  // Update the frame size
  //
  // Input:
  //          - width        : The codec frame width.
  //          - height       : The codec frame height.
  void UpdateFrameSize(size_t width, size_t height);

  // Update the number of active layers
  //
  // Input:
  //          - numLayers    : Number of layers used.
  void UpdateNumLayers(int numLayers);

  // The amount of packet loss to cover for with FEC.
  //
  // Input:
  //          - fecRateKey      : Packet loss to cover for with FEC when
  //                              sending key frames.
  //          - fecRateDelta    : Packet loss to cover for with FEC when
  //                              sending delta frames.
  void UpdateFECRates(uint8_t fecRateKey, uint8_t fecRateDelta) {
    _fecRateKey = fecRateKey;
    _fecRateDelta = fecRateDelta;
  }

  // Update the protection methods with the current VCMProtectionParameters
  // and set the requested protection settings.
  // Return value     : Returns true on update
  bool UpdateMethod();

  // Returns the method currently selected.
  //
  // Return value                 : The protection method currently selected.
  VCMProtectionMethod* SelectedMethod() const;

  // Return the protection type of the currently selected method
  VCMProtectionMethodEnum SelectedType() const;

  // Updates the filtered loss for the average and max window packet loss,
  // and returns the filtered loss probability in the interval [0, 255].
  // The returned filtered loss value depends on the parameter |filter_mode|.
  // The input parameter |lossPr255| is the received packet loss.

  // Return value                 : The filtered loss probability
  uint8_t FilteredLoss(int64_t nowMs,
                       FilterPacketLossMode filter_mode,
                       uint8_t lossPr255);

  void Reset(int64_t nowMs);

  void Release();

 private:
  // Sets the available loss protection methods.
  void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now);
  uint8_t MaxFilteredLossPr(int64_t nowMs) const;
  std::unique_ptr<VCMProtectionMethod> _selectedMethod;
  VCMProtectionParameters _currentParameters;
  int64_t _rtt;
  float _lossPr;
  float _bitRate;
  float _frameRate;
  float _keyFrameSize;
  uint8_t _fecRateKey;
  uint8_t _fecRateDelta;
  int64_t _lastPrUpdateT;
  int64_t _lastPacketPerFrameUpdateT;
  int64_t _lastPacketPerFrameUpdateTKey;
  rtc::ExpFilter _lossPr255;
  VCMLossProbabilitySample _lossPrHistory[kLossPrHistorySize];
  uint8_t _shortMaxLossPr255;
  rtc::ExpFilter _packetsPerFrame;
  rtc::ExpFilter _packetsPerFrameKey;
  size_t _codecWidth;
  size_t _codecHeight;
  int _numLayers;
};

}  // namespace media_optimization
}  // namespace webrtc

#endif  // WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
