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

#include "webrtc/modules/audio_coding/neteq4/decision_logic.h"
#include "webrtc/system_wrappers/interface/constructor_magic.h"
#include "webrtc/typedefs.h"

namespace webrtc {

// Implementation of the DecisionLogic class for playout modes kPlayoutOn and
// kPlayoutStreaming.
class DecisionLogicNormal : public DecisionLogic {
 public:
  // Constructor.
  DecisionLogicNormal(int fs_hz,
                      int output_size_samples,
                      NetEqPlayoutMode playout_mode,
                      DecoderDatabase* decoder_database,
                      const PacketBuffer& packet_buffer,
                      DelayManager* delay_manager,
                      BufferLevelFilter* buffer_level_filter)
      : DecisionLogic(fs_hz, output_size_samples, playout_mode,
                      decoder_database, packet_buffer, delay_manager,
                      buffer_level_filter) {
  }

  // Destructor.
  virtual ~DecisionLogicNormal() {}

 protected:
  // 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, the
  // packet header should be supplied in |packet_header|; otherwise it should
  // be NULL. The mode resulting form 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).
  virtual Operations GetDecisionSpecialized(const SyncBuffer& sync_buffer,
                                            const Expand& expand,
                                            int decoder_frame_length,
                                            const RTPHeader* packet_header,
                                            Modes prev_mode, bool play_dtmf,
                                            bool* reset_decoder);

 private:
  static const int kAllowMergeWithoutExpandMs = 20;  // 20 ms.
  static const int kReinitAfterExpands = 100;
  static const int kMaxWaitForPacket = 10;

  // Returns the operation given that the next available packet is a comfort
  // noise payload (RFC 3389 only, not codec-internal).
  Operations CngOperation(Modes prev_mode, uint32_t target_timestamp,
                          uint32_t available_timestamp);

  // Returns the operation given that no packets are available (except maybe
  // a DTMF event, flagged by setting |play_dtmf| true).
  Operations NoPacket(bool play_dtmf);

  // Returns the operation to do given that the expected packet is available.
  Operations ExpectedPacketAvailable(Modes prev_mode, bool play_dtmf);

  // Returns the operation to do given that the expected packet is not
  // available, but a packet further into the future is at hand.
  Operations FuturePacketAvailable(const SyncBuffer& sync_buffer,
                                   const Expand& expand,
                                   int decoder_frame_length, Modes prev_mode,
                                   uint32_t target_timestamp,
                                   uint32_t available_timestamp,
                                   bool play_dtmf);

  // Checks if enough time has elapsed since the last successful timescale
  // operation was done (i.e., accelerate or preemptive expand).
  bool TimescaleAllowed() const { return timescale_hold_off_ == 0; }

  // Checks if the current (filtered) buffer level is under the target level.
  bool UnderTargetLevel() const;

  // Checks if |timestamp_leap| is so long into the future that a reset due
  // to exceeding kReinitAfterExpands will be done.
  bool ReinitAfterExpands(uint32_t timestamp_leap) const;

  // Checks if we still have not done enough expands to cover the distance from
  // the last decoded packet to the next available packet, the distance beeing
  // conveyed in |timestamp_leap|.
  bool PacketTooEarly(uint32_t timestamp_leap) const;

  // Checks if num_consecutive_expands_ >= kMaxWaitForPacket.
  bool MaxWaitForPacket() const;

  DISALLOW_COPY_AND_ASSIGN(DecisionLogicNormal);
};

}  // namespace webrtc
#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ4_DECISION_LOGIC_NORMAL_H_
