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

#include <vector>

#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/common_types.h"
#include "webrtc/engine_configurations.h"
#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
#include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h"
#include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h"

namespace webrtc {

class CriticalSectionWrapper;
class AudioCodingImpl;

namespace acm2 {

class ACMDTMFDetection;
class ACMGenericCodec;

class AudioCodingModuleImpl : public AudioCodingModule {
 public:
  friend webrtc::AudioCodingImpl;

  explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config);
  ~AudioCodingModuleImpl();

  /////////////////////////////////////////
  //   Sender
  //

  // Initialize send codec.
  virtual int InitializeSender() OVERRIDE;

  // Reset send codec.
  virtual int ResetEncoder() OVERRIDE;

  // Can be called multiple times for Codec, CNG, RED.
  virtual int RegisterSendCodec(const CodecInst& send_codec) OVERRIDE;

  // Get current send codec.
  virtual int SendCodec(CodecInst* current_codec) const OVERRIDE;

  // Get current send frequency.
  virtual int SendFrequency() const OVERRIDE;

  // Get encode bit-rate.
  // Adaptive rate codecs return their current encode target rate, while other
  // codecs return there long-term average or their fixed rate.
  virtual int SendBitrate() const OVERRIDE;

  // Set available bandwidth, inform the encoder about the
  // estimated bandwidth received from the remote party.
  virtual int SetReceivedEstimatedBandwidth(int bw) OVERRIDE;

  // Register a transport callback which will be
  // called to deliver the encoded buffers.
  virtual int RegisterTransportCallback(
      AudioPacketizationCallback* transport) OVERRIDE;

  // Add 10 ms of raw (PCM) audio data to the encoder.
  virtual int Add10MsData(const AudioFrame& audio_frame) OVERRIDE;

  /////////////////////////////////////////
  // (RED) Redundant Coding
  //

  // Configure RED status i.e. on/off.
  virtual int SetREDStatus(bool enable_red) OVERRIDE;

  // Get RED status.
  virtual bool REDStatus() const OVERRIDE;

  /////////////////////////////////////////
  // (FEC) Forward Error Correction (codec internal)
  //

  // Configure FEC status i.e. on/off.
  virtual int SetCodecFEC(bool enabled_codec_fec) OVERRIDE;

  // Get FEC status.
  virtual bool CodecFEC() const OVERRIDE;

  // Set target packet loss rate
  virtual int SetPacketLossRate(int loss_rate) OVERRIDE;

  /////////////////////////////////////////
  //   (VAD) Voice Activity Detection
  //   and
  //   (CNG) Comfort Noise Generation
  //

  virtual int SetVAD(bool enable_dtx = true,
                     bool enable_vad = false,
                     ACMVADMode mode = VADNormal) OVERRIDE;

  virtual int VAD(bool* dtx_enabled,
                  bool* vad_enabled,
                  ACMVADMode* mode) const OVERRIDE;

  virtual int RegisterVADCallback(ACMVADCallback* vad_callback) OVERRIDE;

  /////////////////////////////////////////
  //   Receiver
  //

  // Initialize receiver, resets codec database etc.
  virtual int InitializeReceiver() OVERRIDE;

  // Reset the decoder state.
  virtual int ResetDecoder() OVERRIDE;

  // Get current receive frequency.
  virtual int ReceiveFrequency() const OVERRIDE;

  // Get current playout frequency.
  virtual int PlayoutFrequency() const OVERRIDE;

  // Register possible receive codecs, can be called multiple times,
  // for codecs, CNG, DTMF, RED.
  virtual int RegisterReceiveCodec(const CodecInst& receive_codec) OVERRIDE;

  // Get current received codec.
  virtual int ReceiveCodec(CodecInst* current_codec) const OVERRIDE;

  // Incoming packet from network parsed and ready for decode.
  virtual int IncomingPacket(const uint8_t* incoming_payload,
                             const size_t payload_length,
                             const WebRtcRTPHeader& rtp_info) OVERRIDE;

  // Incoming payloads, without rtp-info, the rtp-info will be created in ACM.
  // One usage for this API is when pre-encoded files are pushed in ACM.
  virtual int IncomingPayload(const uint8_t* incoming_payload,
                              const size_t payload_length,
                              uint8_t payload_type,
                              uint32_t timestamp) OVERRIDE;

  // Minimum playout delay.
  virtual int SetMinimumPlayoutDelay(int time_ms) OVERRIDE;

  // Maximum playout delay.
  virtual int SetMaximumPlayoutDelay(int time_ms) OVERRIDE;

  // Smallest latency NetEq will maintain.
  virtual int LeastRequiredDelayMs() const OVERRIDE;

  // Impose an initial delay on playout. ACM plays silence until |delay_ms|
  // audio is accumulated in NetEq buffer, then starts decoding payloads.
  virtual int SetInitialPlayoutDelay(int delay_ms) OVERRIDE;

  // TODO(turajs): DTMF playout is always activated in NetEq these APIs should
  // be removed, as well as all VoE related APIs and methods.
  //
  // Configure Dtmf playout status i.e on/off playout the incoming outband Dtmf
  // tone.
  virtual int SetDtmfPlayoutStatus(bool enable) OVERRIDE { return 0; }

  // Get Dtmf playout status.
  virtual bool DtmfPlayoutStatus() const OVERRIDE { return true; }

  // Estimate the Bandwidth based on the incoming stream, needed
  // for one way audio where the RTCP send the BW estimate.
  // This is also done in the RTP module .
  virtual int DecoderEstimatedBandwidth() const OVERRIDE;

  // Set playout mode voice, fax.
  virtual int SetPlayoutMode(AudioPlayoutMode mode) OVERRIDE;

  // Get playout mode voice, fax.
  virtual AudioPlayoutMode PlayoutMode() const OVERRIDE;

  // Get playout timestamp.
  virtual int PlayoutTimestamp(uint32_t* timestamp) OVERRIDE;

  // Get 10 milliseconds of raw audio data to play out, and
  // automatic resample to the requested frequency if > 0.
  virtual int PlayoutData10Ms(int desired_freq_hz,
                              AudioFrame* audio_frame) OVERRIDE;

  /////////////////////////////////////////
  //   Statistics
  //

  virtual int GetNetworkStatistics(NetworkStatistics* statistics) OVERRIDE;

  // GET RED payload for iSAC. The method id called when 'this' ACM is
  // the default ACM.
  // TODO(henrik.lundin) Not used. Remove?
  int REDPayloadISAC(int isac_rate,
                     int isac_bw_estimate,
                     uint8_t* payload,
                     int16_t* length_bytes);

  virtual int ReplaceInternalDTXWithWebRtc(bool use_webrtc_dtx) OVERRIDE;

  virtual int IsInternalDTXReplacedWithWebRtc(bool* uses_webrtc_dtx) OVERRIDE;

  virtual int SetISACMaxRate(int max_bit_per_sec) OVERRIDE;

  virtual int SetISACMaxPayloadSize(int max_size_bytes) OVERRIDE;

  virtual int ConfigISACBandwidthEstimator(
      int frame_size_ms,
      int rate_bit_per_sec,
      bool enforce_frame_size = false) OVERRIDE;

  int SetOpusApplication(OpusApplicationMode application) override;

  // If current send codec is Opus, informs it about the maximum playback rate
  // the receiver will render.
  virtual int SetOpusMaxPlaybackRate(int frequency_hz) OVERRIDE;

  virtual int UnregisterReceiveCodec(uint8_t payload_type) OVERRIDE;

  virtual int EnableNack(size_t max_nack_list_size) OVERRIDE;

  virtual void DisableNack() OVERRIDE;

  virtual std::vector<uint16_t> GetNackList(
      int64_t round_trip_time_ms) const OVERRIDE;

  virtual void GetDecodingCallStatistics(
      AudioDecodingCallStats* stats) const OVERRIDE;

 private:
  int Add10MsDataInternal(const AudioFrame& audio_frame);
  int Encode();

  ACMGenericCodec* CreateCodec(const CodecInst& codec);

  int InitializeReceiverSafe() EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);

  bool HaveValidEncoder(const char* caller_name) const
      EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);

  // Set VAD/DTX status. This function does not acquire a lock, and it is
  // created to be called only from inside a critical section.
  int SetVADSafe(bool enable_dtx, bool enable_vad, ACMVADMode mode)
      EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);

  // Preprocessing of input audio, including resampling and down-mixing if
  // required, before pushing audio into encoder's buffer.
  //
  // in_frame: input audio-frame
  // ptr_out: pointer to output audio_frame. If no preprocessing is required
  //          |ptr_out| will be pointing to |in_frame|, otherwise pointing to
  //          |preprocess_frame_|.
  //
  // Return value:
  //   -1: if encountering an error.
  //    0: otherwise.
  int PreprocessToAddData(const AudioFrame& in_frame,
                          const AudioFrame** ptr_out)
      EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);

  // Change required states after starting to receive the codec corresponding
  // to |index|.
  int UpdateUponReceivingCodec(int index);

  // Get a pointer to AudioDecoder of the given codec. For some codecs, e.g.
  // iSAC, encoding and decoding have to be performed on a shared
  // codec-instance. By calling this method, we get the codec-instance that ACM
  // owns, then pass that to NetEq. This way, we perform both encoding and
  // decoding on the same codec-instance. Furthermore, ACM would have control
  // over decoder functionality if required. If |codec| does not share an
  // instance between encoder and decoder, the |*decoder| is set NULL.
  // The field ACMCodecDB::CodecSettings.owns_decoder indicates that if a
  // codec owns the decoder-instance. For such codecs |*decoder| should be a
  // valid pointer, otherwise it will be NULL.
  int GetAudioDecoder(const CodecInst& codec, int codec_id,
                      int mirror_id, AudioDecoder** decoder)
      EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);

  void SetCngPayloadType(int sample_rate_hz, int payload_type)
      EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);

  void EnableCopyRedForAllCodecs(bool enable)
      EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);

  CriticalSectionWrapper* acm_crit_sect_;
  int id_;  // TODO(henrik.lundin) Make const.
  uint32_t expected_codec_ts_ GUARDED_BY(acm_crit_sect_);
  uint32_t expected_in_ts_ GUARDED_BY(acm_crit_sect_);
  CodecInst send_codec_inst_ GUARDED_BY(acm_crit_sect_);

  uint8_t cng_nb_pltype_ GUARDED_BY(acm_crit_sect_);
  uint8_t cng_wb_pltype_ GUARDED_BY(acm_crit_sect_);
  uint8_t cng_swb_pltype_ GUARDED_BY(acm_crit_sect_);
  uint8_t cng_fb_pltype_ GUARDED_BY(acm_crit_sect_);

  uint8_t red_pltype_ GUARDED_BY(acm_crit_sect_);
  bool vad_enabled_ GUARDED_BY(acm_crit_sect_);
  bool dtx_enabled_ GUARDED_BY(acm_crit_sect_);
  ACMVADMode vad_mode_ GUARDED_BY(acm_crit_sect_);
  ACMGenericCodec* codecs_[ACMCodecDB::kMaxNumCodecs]
      GUARDED_BY(acm_crit_sect_);
  int mirror_codec_idx_[ACMCodecDB::kMaxNumCodecs] GUARDED_BY(acm_crit_sect_);
  bool stereo_send_ GUARDED_BY(acm_crit_sect_);
  int current_send_codec_idx_ GUARDED_BY(acm_crit_sect_);
  bool send_codec_registered_ GUARDED_BY(acm_crit_sect_);
  ACMResampler resampler_ GUARDED_BY(acm_crit_sect_);
  AcmReceiver receiver_;  // AcmReceiver has it's own internal lock.

  // RED.
  bool red_enabled_ GUARDED_BY(acm_crit_sect_);

  // Codec internal FEC
  bool codec_fec_enabled_ GUARDED_BY(acm_crit_sect_);

  // This is to keep track of CN instances where we can send DTMFs.
  uint8_t previous_pltype_ GUARDED_BY(acm_crit_sect_);

  // Used when payloads are pushed into ACM without any RTP info
  // One example is when pre-encoded bit-stream is pushed from
  // a file.
  // IMPORTANT: this variable is only used in IncomingPayload(), therefore,
  // no lock acquired when interacting with this variable. If it is going to
  // be used in other methods, locks need to be taken.
  WebRtcRTPHeader* aux_rtp_header_;

  bool receiver_initialized_ GUARDED_BY(acm_crit_sect_);

  AudioFrame preprocess_frame_ GUARDED_BY(acm_crit_sect_);
  bool first_10ms_data_ GUARDED_BY(acm_crit_sect_);

  CriticalSectionWrapper* callback_crit_sect_;
  AudioPacketizationCallback* packetization_callback_
      GUARDED_BY(callback_crit_sect_);
  ACMVADCallback* vad_callback_ GUARDED_BY(callback_crit_sect_);
};

}  // namespace acm2

class AudioCodingImpl : public AudioCoding {
 public:
  AudioCodingImpl(const Config& config) {
    AudioCodingModule::Config config_old = config.ToOldConfig();
    acm_old_.reset(new acm2::AudioCodingModuleImpl(config_old));
    acm_old_->RegisterTransportCallback(config.transport);
    acm_old_->RegisterVADCallback(config.vad_callback);
    acm_old_->SetDtmfPlayoutStatus(config.play_dtmf);
    if (config.initial_playout_delay_ms > 0) {
      acm_old_->SetInitialPlayoutDelay(config.initial_playout_delay_ms);
    }
    playout_frequency_hz_ = config.playout_frequency_hz;
  }

  virtual ~AudioCodingImpl() OVERRIDE {};

  virtual bool RegisterSendCodec(AudioEncoder* send_codec) OVERRIDE;

  virtual bool RegisterSendCodec(int encoder_type,
                                 uint8_t payload_type,
                                 int frame_size_samples = 0) OVERRIDE;

  virtual const AudioEncoder* GetSenderInfo() const OVERRIDE;

  virtual const CodecInst* GetSenderCodecInst() OVERRIDE;

  virtual int Add10MsAudio(const AudioFrame& audio_frame) OVERRIDE;

  virtual const ReceiverInfo* GetReceiverInfo() const OVERRIDE;

  virtual bool RegisterReceiveCodec(AudioDecoder* receive_codec) OVERRIDE;

  virtual bool RegisterReceiveCodec(int decoder_type,
                                    uint8_t payload_type) OVERRIDE;

  virtual bool InsertPacket(const uint8_t* incoming_payload,
                            size_t payload_len_bytes,
                            const WebRtcRTPHeader& rtp_info) OVERRIDE;

  virtual bool InsertPayload(const uint8_t* incoming_payload,
                             size_t payload_len_byte,
                             uint8_t payload_type,
                             uint32_t timestamp) OVERRIDE;

  virtual bool SetMinimumPlayoutDelay(int time_ms) OVERRIDE;

  virtual bool SetMaximumPlayoutDelay(int time_ms) OVERRIDE;

  virtual int LeastRequiredDelayMs() const OVERRIDE;

  virtual bool PlayoutTimestamp(uint32_t* timestamp) OVERRIDE;

  virtual bool Get10MsAudio(AudioFrame* audio_frame) OVERRIDE;

  virtual bool GetNetworkStatistics(
      NetworkStatistics* network_statistics) OVERRIDE;

  virtual bool EnableNack(size_t max_nack_list_size) OVERRIDE;

  virtual void DisableNack() OVERRIDE;

  virtual bool SetVad(bool enable_dtx,
                      bool enable_vad,
                      ACMVADMode vad_mode) OVERRIDE;

  virtual std::vector<uint16_t> GetNackList(
      int round_trip_time_ms) const OVERRIDE;

  virtual void GetDecodingCallStatistics(
      AudioDecodingCallStats* call_stats) const OVERRIDE;

 private:
  // Temporary method to be used during redesign phase.
  // Maps |codec_type| (a value from the anonymous enum in acm2::ACMCodecDB) to
  // |codec_name|, |sample_rate_hz|, and |channels|.
  // TODO(henrik.lundin) Remove this when no longer needed.
  static bool MapCodecTypeToParameters(int codec_type,
                                       std::string* codec_name,
                                       int* sample_rate_hz,
                                       int* channels);

  int playout_frequency_hz_;
  // TODO(henrik.lundin): All members below this line are temporary and should
  // be removed after refactoring is completed.
  rtc::scoped_ptr<acm2::AudioCodingModuleImpl> acm_old_;
  CodecInst current_send_codec_;
};

}  // namespace webrtc

#endif  // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_
