/*
 *  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 MODULES_AUDIO_CODING_NETEQ_DELAY_MANAGER_H_
#define MODULES_AUDIO_CODING_NETEQ_DELAY_MANAGER_H_

#include <string.h>  // Provide access to size_t.

#include <memory>
#include <vector>

#include "absl/types/optional.h"
#include "modules/audio_coding/neteq/tick_timer.h"
#include "rtc_base/constructormagic.h"

namespace webrtc {

// Forward declaration.
class DelayPeakDetector;

class DelayManager {
 public:
  typedef std::vector<int> IATVector;

  // Create a DelayManager object. Notify the delay manager that the packet
  // buffer can hold no more than |max_packets_in_buffer| packets (i.e., this
  // is the number of packet slots in the buffer) and that the target delay
  // should be greater than or equal to |base_min_target_delay_ms|. Supply a
  // PeakDetector object to the DelayManager.
  DelayManager(size_t max_packets_in_buffer,
               int base_min_target_delay_ms,
               DelayPeakDetector* peak_detector,
               const TickTimer* tick_timer);

  virtual ~DelayManager();

  // Read the inter-arrival time histogram. Mainly for testing purposes.
  virtual const IATVector& iat_vector() const;

  // Updates the delay manager with a new incoming packet, with
  // |sequence_number| and |timestamp| from the RTP header. This updates the
  // inter-arrival time histogram and other statistics, as well as the
  // associated DelayPeakDetector. A new target buffer level is calculated.
  // Returns 0 on success, -1 on failure (invalid sample rate).
  virtual int Update(uint16_t sequence_number,
                     uint32_t timestamp,
                     int sample_rate_hz);

  // Calculates a new target buffer level. Called from the Update() method.
  // Sets target_level_ (in Q8) and returns the same value. Also calculates
  // and updates base_target_level_, which is the target buffer level before
  // taking delay peaks into account.
  virtual int CalculateTargetLevel(int iat_packets);

  // Notifies the DelayManager of how much audio data is carried in each packet.
  // The method updates the DelayPeakDetector too, and resets the inter-arrival
  // time counter. Returns 0 on success, -1 on failure.
  virtual int SetPacketAudioLength(int length_ms);

  // Resets the DelayManager and the associated DelayPeakDetector.
  virtual void Reset();

  // Calculates the average inter-arrival time deviation from the histogram.
  // The result is returned as parts-per-million deviation from the nominal
  // inter-arrival time. That is, if the average inter-arrival time is equal to
  // the nominal frame time, the return value is zero. A positive value
  // corresponds to packet spacing being too large, while a negative value means
  // that the packets arrive with less spacing than expected.
  virtual double EstimatedClockDriftPpm() const;

  // Returns true if peak-mode is active. That is, delay peaks were observed
  // recently. This method simply asks for the same information from the
  // DelayPeakDetector object.
  virtual bool PeakFound() const;

  // Reset the inter-arrival time counter to 0.
  virtual void ResetPacketIatCount();

  // Writes the lower and higher limits which the buffer level should stay
  // within to the corresponding pointers. The values are in (fractions of)
  // packets in Q8.
  virtual void BufferLimits(int* lower_limit, int* higher_limit) const;

  // Gets the target buffer level, in (fractions of) packets in Q8. This value
  // includes any extra delay set through the set_extra_delay_ms() method.
  virtual int TargetLevel() const;

  // Informs the delay manager whether or not the last decoded packet contained
  // speech.
  virtual void LastDecodedWasCngOrDtmf(bool it_was);

  // Notify the delay manager that empty packets have been received. These are
  // packets that are part of the sequence number series, so that an empty
  // packet will shift the sequence numbers for the following packets.
  virtual void RegisterEmptyPacket();

  // Apply compression or stretching to the IAT histogram, for a change in frame
  // size. This returns an updated histogram. This function is public for
  // testability.
  static IATVector ScaleHistogram(const IATVector& histogram,
                                  int old_packet_length,
                                  int new_packet_length);

  // Accessors and mutators.
  // Assuming |delay| is in valid range.
  virtual bool SetMinimumDelay(int delay_ms);
  virtual bool SetMaximumDelay(int delay_ms);
  virtual int base_target_level() const;
  virtual void set_streaming_mode(bool value);
  virtual int last_pack_cng_or_dtmf() const;
  virtual void set_last_pack_cng_or_dtmf(int value);

  // This accessor is only intended for testing purposes.
  const absl::optional<int>& forced_limit_probability_for_test() const {
    return forced_limit_probability_;
  }

 private:
  // Sets |iat_vector_| to the default start distribution and sets the
  // |base_target_level_| and |target_level_| to the corresponding values.
  void ResetHistogram();

  // Updates |iat_cumulative_sum_| and |max_iat_cumulative_sum_|. (These are
  // used by the streaming mode.) This method is called by Update().
  void UpdateCumulativeSums(int packet_len_ms, uint16_t sequence_number);

  // Updates the histogram |iat_vector_|. The probability for inter-arrival time
  // equal to |iat_packets| (in integer packets) is increased slightly, while
  // all other entries are decreased. This method is called by Update().
  void UpdateHistogram(size_t iat_packets);

  // Makes sure that |target_level_| is not too large, taking
  // |max_packets_in_buffer_| and |extra_delay_ms_| into account. This method is
  // called by Update().
  void LimitTargetLevel();

  bool first_packet_received_;
  const size_t max_packets_in_buffer_;  // Capacity of the packet buffer.
  IATVector iat_vector_;                // Histogram of inter-arrival times.
  int iat_factor_;  // Forgetting factor for updating the IAT histogram (Q15).
  const TickTimer* tick_timer_;
  const int base_min_target_delay_ms_;  // Lower bound for target_level_ and
                                        // minimum_delay_ms_.
  // Time elapsed since last packet.
  std::unique_ptr<TickTimer::Stopwatch> packet_iat_stopwatch_;
  int base_target_level_;  // Currently preferred buffer level before peak
                           // detection and streaming mode (Q0).
  // TODO(turajs) change the comment according to the implementation of
  // minimum-delay.
  int target_level_;   // Currently preferred buffer level in (fractions)
                       // of packets (Q8), before adding any extra delay.
  int packet_len_ms_;  // Length of audio in each incoming packet [ms].
  bool streaming_mode_;
  uint16_t last_seq_no_;         // Sequence number for last received packet.
  uint32_t last_timestamp_;      // Timestamp for the last received packet.
  int minimum_delay_ms_;         // Externally set minimum delay.
  int maximum_delay_ms_;         // Externally set maximum allowed delay.
  int iat_cumulative_sum_;       // Cumulative sum of delta inter-arrival times.
  int max_iat_cumulative_sum_;   // Max of |iat_cumulative_sum_|.
  // Time elapsed since maximum was observed.
  std::unique_ptr<TickTimer::Stopwatch> max_iat_stopwatch_;
  DelayPeakDetector& peak_detector_;
  int last_pack_cng_or_dtmf_;
  const bool frame_length_change_experiment_;
  const absl::optional<int> forced_limit_probability_;

  RTC_DISALLOW_COPY_AND_ASSIGN(DelayManager);
};

}  // namespace webrtc
#endif  // MODULES_AUDIO_CODING_NETEQ_DELAY_MANAGER_H_
