// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/codec/audio_decoder_opus.h"

#include <stdint.h>

#include "base/logging.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "remoting/proto/audio.pb.h"
#include "third_party/opus/src/include/opus.h"

namespace remoting {

namespace {

// Maximum size of an Opus frame in milliseconds.
const int kMaxFrameSizeMs = 120;

// Hosts will never generate more than 100 frames in a single packet.
const int kMaxFramesPerPacket = 100;

const AudioPacket::SamplingRate kSamplingRate =
    AudioPacket::SAMPLING_RATE_48000;

}  // namespace

AudioDecoderOpus::AudioDecoderOpus()
    : sampling_rate_(0), channels_(0), decoder_(nullptr) {}

AudioDecoderOpus::~AudioDecoderOpus() {
  DestroyDecoder();
}

void AudioDecoderOpus::InitDecoder() {
  DCHECK(!decoder_);
  int error;
  decoder_ = opus_decoder_create(kSamplingRate, channels_, &error);
  if (!decoder_) {
    LOG(ERROR) << "Failed to create OPUS decoder; Error code: " << error;
  }
}

void AudioDecoderOpus::DestroyDecoder() {
  if (decoder_) {
    opus_decoder_destroy(decoder_);
    decoder_ = nullptr;
  }
}

bool AudioDecoderOpus::ResetForPacket(AudioPacket* packet) {
  if (packet->channels() != channels_ ||
      packet->sampling_rate() != sampling_rate_) {
    DestroyDecoder();

    channels_ = packet->channels();
    sampling_rate_ = packet->sampling_rate();

    if (channels_ <= 0 || channels_ > 2 ||
        sampling_rate_ != kSamplingRate) {
      LOG(WARNING) << "Unsupported OPUS parameters: "
                   << channels_ << " channels with "
                   << sampling_rate_ << " samples per second.";
      return false;
    }
  }

  if (!decoder_) {
    InitDecoder();
  }

  return decoder_ != nullptr;
}

std::unique_ptr<AudioPacket> AudioDecoderOpus::Decode(
    std::unique_ptr<AudioPacket> packet) {
  if (packet->encoding() != AudioPacket::ENCODING_OPUS) {
    LOG(WARNING) << "Received an audio packet with encoding "
                 << packet->encoding() << " when an OPUS packet was expected.";
    return nullptr;
  }
  if (packet->data_size() > kMaxFramesPerPacket) {
    LOG(WARNING) << "Received an packet with too many frames.";
    return nullptr;
  }

  if (!ResetForPacket(packet.get())) {
    return nullptr;
  }

  // Create a new packet of decoded data.
  std::unique_ptr<AudioPacket> decoded_packet(new AudioPacket());
  decoded_packet->set_encoding(AudioPacket::ENCODING_RAW);
  decoded_packet->set_sampling_rate(kSamplingRate);
  decoded_packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
  decoded_packet->set_channels(packet->channels());

  int max_frame_samples = kMaxFrameSizeMs * kSamplingRate /
      base::Time::kMillisecondsPerSecond;
  int max_frame_bytes = max_frame_samples * channels_ *
      decoded_packet->bytes_per_sample();

  std::string* decoded_data = decoded_packet->add_data();
  decoded_data->resize(packet->data_size() * max_frame_bytes);
  int buffer_pos = 0;

  for (int i = 0; i < packet->data_size(); ++i) {
    int16_t* pcm_buffer =
        reinterpret_cast<int16_t*>(base::data(*decoded_data) + buffer_pos);
    CHECK_LE(buffer_pos + max_frame_bytes,
             static_cast<int>(decoded_data->size()));
    std::string* frame = packet->mutable_data(i);
    unsigned char* frame_data =
        reinterpret_cast<unsigned char*>(base::data(*frame));
    int result = opus_decode(decoder_, frame_data, frame->size(),
                             pcm_buffer, max_frame_samples, 0);
    if (result < 0) {
      LOG(ERROR) << "Failed decoding Opus frame. Error code: " << result;
      DestroyDecoder();
      return nullptr;
    }

    buffer_pos += result * packet->channels() *
        decoded_packet->bytes_per_sample();
  }

  if (!buffer_pos) {
    return nullptr;
  }

  decoded_data->resize(buffer_pos);

  return decoded_packet;
}

}  // namespace remoting
