/*
 *  Copyright (c) 2014 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_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_

#include "rtc_base/checks.h"

namespace webrtc {

template <typename T>
bool AudioEncoderIsacT<T>::Config::IsOk() const {
  if (max_bit_rate < 32000 && max_bit_rate != -1)
    return false;
  if (max_payload_size_bytes < 120 && max_payload_size_bytes != -1)
    return false;
  if (adaptive_mode && !bwinfo)
    return false;
  switch (sample_rate_hz) {
    case 16000:
      if (max_bit_rate > 53400)
        return false;
      if (max_payload_size_bytes > 400)
        return false;
      return (frame_size_ms == 30 || frame_size_ms == 60) &&
             (bit_rate == 0 || (bit_rate >= 10000 && bit_rate <= 32000));
    case 32000:
      if (max_bit_rate > 160000)
        return false;
      if (max_payload_size_bytes > 600)
        return false;
      return T::has_swb &&
             (frame_size_ms == 30 &&
              (bit_rate == 0 || (bit_rate >= 10000 && bit_rate <= 56000)));
    default:
      return false;
  }
}

template <typename T>
AudioEncoderIsacT<T>::AudioEncoderIsacT(const Config& config) {
  RecreateEncoderInstance(config);
}

template <typename T>
AudioEncoderIsacT<T>::~AudioEncoderIsacT() {
  RTC_CHECK_EQ(0, T::Free(isac_state_));
}

template <typename T>
int AudioEncoderIsacT<T>::SampleRateHz() const {
  return T::EncSampRate(isac_state_);
}

template <typename T>
size_t AudioEncoderIsacT<T>::NumChannels() const {
  return 1;
}

template <typename T>
size_t AudioEncoderIsacT<T>::Num10MsFramesInNextPacket() const {
  const int samples_in_next_packet = T::GetNewFrameLen(isac_state_);
  return static_cast<size_t>(rtc::CheckedDivExact(
      samples_in_next_packet, rtc::CheckedDivExact(SampleRateHz(), 100)));
}

template <typename T>
size_t AudioEncoderIsacT<T>::Max10MsFramesInAPacket() const {
  return 6;  // iSAC puts at most 60 ms in a packet.
}

template <typename T>
int AudioEncoderIsacT<T>::GetTargetBitrate() const {
  if (config_.adaptive_mode)
    return -1;
  return config_.bit_rate == 0 ? kDefaultBitRate : config_.bit_rate;
}

template <typename T>
AudioEncoder::EncodedInfo AudioEncoderIsacT<T>::EncodeImpl(
    uint32_t rtp_timestamp,
    rtc::ArrayView<const int16_t> audio,
    rtc::Buffer* encoded) {
  if (!packet_in_progress_) {
    // Starting a new packet; remember the timestamp for later.
    packet_in_progress_ = true;
    packet_timestamp_ = rtp_timestamp;
  }
  if (bwinfo_) {
    IsacBandwidthInfo bwinfo = bwinfo_->Get();
    T::SetBandwidthInfo(isac_state_, &bwinfo);
  }

  size_t encoded_bytes = encoded->AppendData(
      kSufficientEncodeBufferSizeBytes, [&](rtc::ArrayView<uint8_t> encoded) {
        int r = T::Encode(isac_state_, audio.data(), encoded.data());

        RTC_CHECK_GE(r, 0) << "Encode failed (error code "
                           << T::GetErrorCode(isac_state_) << ")";

        return static_cast<size_t>(r);
      });

  if (encoded_bytes == 0)
    return EncodedInfo();

  // Got enough input to produce a packet. Return the saved timestamp from
  // the first chunk of input that went into the packet.
  packet_in_progress_ = false;
  EncodedInfo info;
  info.encoded_bytes = encoded_bytes;
  info.encoded_timestamp = packet_timestamp_;
  info.payload_type = config_.payload_type;
  info.encoder_type = CodecType::kIsac;
  return info;
}

template <typename T>
void AudioEncoderIsacT<T>::Reset() {
  RecreateEncoderInstance(config_);
}

template <typename T>
void AudioEncoderIsacT<T>::RecreateEncoderInstance(const Config& config) {
  RTC_CHECK(config.IsOk());
  packet_in_progress_ = false;
  bwinfo_ = config.bwinfo;
  if (isac_state_)
    RTC_CHECK_EQ(0, T::Free(isac_state_));
  RTC_CHECK_EQ(0, T::Create(&isac_state_));
  RTC_CHECK_EQ(0, T::EncoderInit(isac_state_, config.adaptive_mode ? 0 : 1));
  RTC_CHECK_EQ(0, T::SetEncSampRate(isac_state_, config.sample_rate_hz));
  const int bit_rate = config.bit_rate == 0 ? kDefaultBitRate : config.bit_rate;
  if (config.adaptive_mode) {
    RTC_CHECK_EQ(0, T::ControlBwe(isac_state_, bit_rate, config.frame_size_ms,
                                  config.enforce_frame_size));
  } else {
    RTC_CHECK_EQ(0, T::Control(isac_state_, bit_rate, config.frame_size_ms));
  }
  if (config.max_payload_size_bytes != -1)
    RTC_CHECK_EQ(
        0, T::SetMaxPayloadSize(isac_state_, config.max_payload_size_bytes));
  if (config.max_bit_rate != -1)
    RTC_CHECK_EQ(0, T::SetMaxRate(isac_state_, config.max_bit_rate));

  // Set the decoder sample rate even though we just use the encoder. This
  // doesn't appear to be necessary to produce a valid encoding, but without it
  // we get an encoding that isn't bit-for-bit identical with what a combined
  // encoder+decoder object produces.
  RTC_CHECK_EQ(0, T::SetDecSampRate(isac_state_, config.sample_rate_hz));

  config_ = config;
}

}  // namespace webrtc

#endif  // MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_
