/*
 *  Copyright (c) 2013 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_DECISION_LOGIC_H_
#define MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_

#include "modules/audio_coding/neteq/defines.h"
#include "modules/audio_coding/neteq/include/neteq.h"
#include "modules/audio_coding/neteq/tick_timer.h"
#include "rtc_base/constructormagic.h"
#include "typedefs.h"  // NOLINT(build/include)

namespace webrtc {

// Forward declarations.
class BufferLevelFilter;
class DecoderDatabase;
class DelayManager;
class Expand;
class PacketBuffer;
class SyncBuffer;
struct Packet;

// This is the base class for the decision tree implementations. Derived classes
// must implement the method GetDecisionSpecialized().
class DecisionLogic {
 public:
  // Static factory function which creates different types of objects depending
  // on the |playout_mode|.
  static DecisionLogic* Create(int fs_hz,
                               size_t output_size_samples,
                               NetEqPlayoutMode playout_mode,
                               DecoderDatabase* decoder_database,
                               const PacketBuffer& packet_buffer,
                               DelayManager* delay_manager,
                               BufferLevelFilter* buffer_level_filter,
                               const TickTimer* tick_timer);

  // Constructor.
  DecisionLogic(int fs_hz,
                size_t output_size_samples,
                NetEqPlayoutMode playout_mode,
                DecoderDatabase* decoder_database,
                const PacketBuffer& packet_buffer,
                DelayManager* delay_manager,
                BufferLevelFilter* buffer_level_filter,
                const TickTimer* tick_timer);

  virtual ~DecisionLogic();

  // Resets object to a clean state.
  void Reset();

  // Resets parts of the state. Typically done when switching codecs.
  void SoftReset();

  // Sets the sample rate and the output block size.
  void SetSampleRate(int fs_hz, size_t output_size_samples);

  // Returns the operation that should be done next. |sync_buffer| and |expand|
  // are provided for reference. |decoder_frame_length| is the number of samples
  // obtained from the last decoded frame. If there is a packet available, it
  // should be supplied in |next_packet|; otherwise it should be NULL. The mode
  // resulting from the last call to NetEqImpl::GetAudio is supplied in
  // |prev_mode|. If there is a DTMF event to play, |play_dtmf| should be set to
  // true. The output variable |reset_decoder| will be set to true if a reset is
  // required; otherwise it is left unchanged (i.e., it can remain true if it
  // was true before the call).  This method end with calling
  // GetDecisionSpecialized to get the actual return value.
  Operations GetDecision(const SyncBuffer& sync_buffer,
                         const Expand& expand,
                         size_t decoder_frame_length,
                         const Packet* next_packet,
                         Modes prev_mode,
                         bool play_dtmf,
                         size_t generated_noise_samples,
                         bool* reset_decoder);

  // These methods test the |cng_state_| for different conditions.
  bool CngRfc3389On() const { return cng_state_ == kCngRfc3389On; }
  bool CngOff() const { return cng_state_ == kCngOff; }

  // Resets the |cng_state_| to kCngOff.
  void SetCngOff() { cng_state_ = kCngOff; }

  // Reports back to DecisionLogic whether the decision to do expand remains or
  // not. Note that this is necessary, since an expand decision can be changed
  // to kNormal in NetEqImpl::GetDecision if there is still enough data in the
  // sync buffer.
  virtual void ExpandDecision(Operations operation);

  // Adds |value| to |sample_memory_|.
  void AddSampleMemory(int32_t value) { sample_memory_ += value; }

  // Accessors and mutators.
  void set_sample_memory(int32_t value) { sample_memory_ = value; }
  size_t noise_fast_forward() const { return noise_fast_forward_; }
  size_t packet_length_samples() const { return packet_length_samples_; }
  void set_packet_length_samples(size_t value) {
    packet_length_samples_ = value;
  }
  void set_prev_time_scale(bool value) { prev_time_scale_ = value; }
  NetEqPlayoutMode playout_mode() const { return playout_mode_; }

 protected:
  // The value 5 sets maximum time-stretch rate to about 100 ms/s.
  static const int kMinTimescaleInterval = 5;

  enum CngState { kCngOff, kCngRfc3389On, kCngInternalOn };

  // Returns the operation that should be done next. |sync_buffer| and |expand|
  // are provided for reference. |decoder_frame_length| is the number of samples
  // obtained from the last decoded frame. If there is a packet available, it
  // should be supplied in |next_packet|; otherwise it should be NULL. The mode
  // resulting from the last call to NetEqImpl::GetAudio is supplied in
  // |prev_mode|. If there is a DTMF event to play, |play_dtmf| should be set to
  // true. The output variable |reset_decoder| will be set to true if a reset is
  // required; otherwise it is left unchanged (i.e., it can remain true if it
  // was true before the call).  Should be implemented by derived classes.
  virtual Operations GetDecisionSpecialized(const SyncBuffer& sync_buffer,
                                            const Expand& expand,
                                            size_t decoder_frame_length,
                                            const Packet* next_packet,
                                            Modes prev_mode,
                                            bool play_dtmf,
                                            bool* reset_decoder,
                                            size_t generated_noise_samples,
                                            size_t cur_size_samples) = 0;

  // Updates the |buffer_level_filter_| with the current buffer level
  // |buffer_size_packets|.
  void FilterBufferLevel(size_t buffer_size_packets, Modes prev_mode);

  DecoderDatabase* decoder_database_;
  const PacketBuffer& packet_buffer_;
  DelayManager* delay_manager_;
  BufferLevelFilter* buffer_level_filter_;
  const TickTimer* tick_timer_;
  int fs_mult_;
  size_t output_size_samples_;
  CngState cng_state_;  // Remember if comfort noise is interrupted by other
                        // event (e.g., DTMF).
  size_t noise_fast_forward_ = 0;
  size_t packet_length_samples_;
  int sample_memory_;
  bool prev_time_scale_;
  std::unique_ptr<TickTimer::Countdown> timescale_countdown_;
  int num_consecutive_expands_;
  const NetEqPlayoutMode playout_mode_;

 private:
  RTC_DISALLOW_COPY_AND_ASSIGN(DecisionLogic);
};

}  // namespace webrtc
#endif  // MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_
