/*
 *  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.
 */

#include "webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h"

#include <algorithm>

#include <limits>
#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/safe_conversions.h"

namespace webrtc {

namespace {

const size_t kSampleRateHz = 16000;

AudioEncoderG722Config CreateConfig(const CodecInst& codec_inst) {
  AudioEncoderG722Config config;
  config.num_channels = rtc::dchecked_cast<int>(codec_inst.channels);
  config.frame_size_ms = codec_inst.pacsize / 16;
  return config;
}

}  // namespace

AudioEncoderG722Impl::AudioEncoderG722Impl(const AudioEncoderG722Config& config,
                                           int payload_type)
    : num_channels_(config.num_channels),
      payload_type_(payload_type),
      num_10ms_frames_per_packet_(
          static_cast<size_t>(config.frame_size_ms / 10)),
      num_10ms_frames_buffered_(0),
      first_timestamp_in_buffer_(0),
      encoders_(new EncoderState[num_channels_]),
      interleave_buffer_(2 * num_channels_) {
  RTC_CHECK(config.IsOk());
  const size_t samples_per_channel =
      kSampleRateHz / 100 * num_10ms_frames_per_packet_;
  for (size_t i = 0; i < num_channels_; ++i) {
    encoders_[i].speech_buffer.reset(new int16_t[samples_per_channel]);
    encoders_[i].encoded_buffer.SetSize(samples_per_channel / 2);
  }
  Reset();
}

AudioEncoderG722Impl::AudioEncoderG722Impl(const CodecInst& codec_inst)
    : AudioEncoderG722Impl(CreateConfig(codec_inst), codec_inst.pltype) {}

AudioEncoderG722Impl::~AudioEncoderG722Impl() = default;

int AudioEncoderG722Impl::SampleRateHz() const {
  return kSampleRateHz;
}

size_t AudioEncoderG722Impl::NumChannels() const {
  return num_channels_;
}

int AudioEncoderG722Impl::RtpTimestampRateHz() const {
  // The RTP timestamp rate for G.722 is 8000 Hz, even though it is a 16 kHz
  // codec.
  return kSampleRateHz / 2;
}

size_t AudioEncoderG722Impl::Num10MsFramesInNextPacket() const {
  return num_10ms_frames_per_packet_;
}

size_t AudioEncoderG722Impl::Max10MsFramesInAPacket() const {
  return num_10ms_frames_per_packet_;
}

int AudioEncoderG722Impl::GetTargetBitrate() const {
  // 4 bits/sample, 16000 samples/s/channel.
  return static_cast<int>(64000 * NumChannels());
}

void AudioEncoderG722Impl::Reset() {
  num_10ms_frames_buffered_ = 0;
  for (size_t i = 0; i < num_channels_; ++i)
    RTC_CHECK_EQ(0, WebRtcG722_EncoderInit(encoders_[i].encoder));
}

AudioEncoder::EncodedInfo AudioEncoderG722Impl::EncodeImpl(
    uint32_t rtp_timestamp,
    rtc::ArrayView<const int16_t> audio,
    rtc::Buffer* encoded) {
  if (num_10ms_frames_buffered_ == 0)
    first_timestamp_in_buffer_ = rtp_timestamp;

  // Deinterleave samples and save them in each channel's buffer.
  const size_t start = kSampleRateHz / 100 * num_10ms_frames_buffered_;
  for (size_t i = 0; i < kSampleRateHz / 100; ++i)
    for (size_t j = 0; j < num_channels_; ++j)
      encoders_[j].speech_buffer[start + i] = audio[i * num_channels_ + j];

  // If we don't yet have enough samples for a packet, we're done for now.
  if (++num_10ms_frames_buffered_ < num_10ms_frames_per_packet_) {
    return EncodedInfo();
  }

  // Encode each channel separately.
  RTC_CHECK_EQ(num_10ms_frames_buffered_, num_10ms_frames_per_packet_);
  num_10ms_frames_buffered_ = 0;
  const size_t samples_per_channel = SamplesPerChannel();
  for (size_t i = 0; i < num_channels_; ++i) {
    const size_t bytes_encoded = WebRtcG722_Encode(
        encoders_[i].encoder, encoders_[i].speech_buffer.get(),
        samples_per_channel, encoders_[i].encoded_buffer.data());
    RTC_CHECK_EQ(bytes_encoded, samples_per_channel / 2);
  }

  const size_t bytes_to_encode = samples_per_channel / 2 * num_channels_;
  EncodedInfo info;
  info.encoded_bytes = encoded->AppendData(
      bytes_to_encode, [&] (rtc::ArrayView<uint8_t> encoded) {
        // Interleave the encoded bytes of the different channels. Each separate
        // channel and the interleaved stream encodes two samples per byte, most
        // significant half first.
        for (size_t i = 0; i < samples_per_channel / 2; ++i) {
          for (size_t j = 0; j < num_channels_; ++j) {
            uint8_t two_samples = encoders_[j].encoded_buffer.data()[i];
            interleave_buffer_.data()[j] = two_samples >> 4;
            interleave_buffer_.data()[num_channels_ + j] = two_samples & 0xf;
          }
          for (size_t j = 0; j < num_channels_; ++j)
            encoded[i * num_channels_ + j] =
                interleave_buffer_.data()[2 * j] << 4 |
                interleave_buffer_.data()[2 * j + 1];
        }

        return bytes_to_encode;
      });
  info.encoded_timestamp = first_timestamp_in_buffer_;
  info.payload_type = payload_type_;
  info.encoder_type = CodecType::kG722;
  return info;
}

AudioEncoderG722Impl::EncoderState::EncoderState() {
  RTC_CHECK_EQ(0, WebRtcG722_CreateEncoder(&encoder));
}

AudioEncoderG722Impl::EncoderState::~EncoderState() {
  RTC_CHECK_EQ(0, WebRtcG722_FreeEncoder(encoder));
}

size_t AudioEncoderG722Impl::SamplesPerChannel() const {
  return kSampleRateHz / 100 * num_10ms_frames_per_packet_;
}

}  // namespace webrtc
