// Copyright 2022 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/libfdkaac/fdk_aac_audio_decoder.h"

#include "starboard/common/log.h"
#include "starboard/common/string.h"
#include "starboard/shared/libfdkaac/libfdkaac_library_loader.h"

namespace starboard {
namespace shared {
namespace libfdkaac {

FdkAacAudioDecoder::FdkAacAudioDecoder() {
  static_assert(sizeof(INT_PCM) == sizeof(int16_t),
                "sizeof(INT_PCM) has to be the same as sizeof(int16_t).");
  InitializeCodec();
}

FdkAacAudioDecoder::~FdkAacAudioDecoder() {
  TeardownCodec();
}

void FdkAacAudioDecoder::Initialize(const OutputCB& output_cb,
                                    const ErrorCB& error_cb) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(output_cb);
  SB_DCHECK(!output_cb_);
  SB_DCHECK(error_cb);
  SB_DCHECK(!error_cb_);

  output_cb_ = output_cb;
  error_cb_ = error_cb;
}

void FdkAacAudioDecoder::Decode(const InputBuffers& input_buffers,
                                const ConsumedCB& consumed_cb) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(input_buffers.size() == 1);
  SB_DCHECK(input_buffers[0]);
  SB_DCHECK(output_cb_);
  SB_DCHECK(decoder_ != NULL);

  if (input_buffers.empty() || !input_buffers[0]) {
    SB_LOG(ERROR) << "No input buffer to decode.";
    return;
  }
  if (stream_ended_) {
    SB_LOG(ERROR) << "Decode() is called after WriteEndOfStream() is called.";
    return;
  }
  const auto& input_buffer = input_buffers[0];
  if (!WriteToFdkDecoder(input_buffer)) {
    return;
  }

  decoding_input_buffers_.push(input_buffer);
  Schedule(consumed_cb);
  ReadFromFdkDecoder(kDecodeModeDoNotFlush);
}

scoped_refptr<FdkAacAudioDecoder::DecodedAudio> FdkAacAudioDecoder::Read(
    int* samples_per_second) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(output_cb_);
  SB_DCHECK(!decoded_audios_.empty());

  scoped_refptr<DecodedAudio> result;
  if (!decoded_audios_.empty()) {
    result = decoded_audios_.front();
    decoded_audios_.pop();
  }
  *samples_per_second = samples_per_second_;
  return result;
}

void FdkAacAudioDecoder::Reset() {
  SB_DCHECK(decoder_ != NULL);
  SB_DCHECK(BelongsToCurrentThread());

  TeardownCodec();
  InitializeCodec();

  stream_ended_ = false;
  decoded_audios_ = std::queue<scoped_refptr<DecodedAudio>>();  // clear
  partially_decoded_audio_ = nullptr;
  partially_decoded_audio_data_in_bytes_ = 0;
  decoding_input_buffers_ = decltype(decoding_input_buffers_)();  // clear
  // Clean up stream information and deduced results.
  has_stream_info_ = false;
  num_channels_ = 0;
  samples_per_second_ = 0;
  decoded_audio_size_in_bytes_ = 0;
  audio_data_to_discard_in_bytes_ = 0;
  CancelPendingJobs();
}

void FdkAacAudioDecoder::WriteEndOfStream() {
  SB_DCHECK(decoder_ != NULL);
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(output_cb_);

  while (!decoding_input_buffers_.empty()) {
    if (!ReadFromFdkDecoder(kDecodeModeFlush)) {
      return;
    }
  }
  stream_ended_ = true;
  // Put EOS into the queue.
  decoded_audios_.push(new DecodedAudio);
  Schedule(output_cb_);
}

void FdkAacAudioDecoder::InitializeCodec() {
  SB_DCHECK(decoder_ == NULL);
  decoder_ = aacDecoder_Open(TT_MP4_ADTS, 1);
  SB_DCHECK(decoder_ != NULL);

  // Set AAC_PCM_MAX_OUTPUT_CHANNELS to 0 to disable downmixing feature.
  // It makes the decoder output contain the same number of channels as the
  // encoded bitstream.
  AAC_DECODER_ERROR error =
      aacDecoder_SetParam(decoder_, AAC_PCM_MAX_OUTPUT_CHANNELS, 0);
  SB_DCHECK(error == AAC_DEC_OK);
}

void FdkAacAudioDecoder::TeardownCodec() {
  if (decoder_) {
    aacDecoder_Close(decoder_);
    decoder_ = nullptr;
  }
}

bool FdkAacAudioDecoder::WriteToFdkDecoder(
    const scoped_refptr<InputBuffer>& input_buffer) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(input_buffer);

  unsigned char* data = const_cast<unsigned char*>(input_buffer->data());
  const unsigned int data_size_in_bytes = input_buffer->size();
  unsigned int left_to_decode_in_bytes = input_buffer->size();
  AAC_DECODER_ERROR error = aacDecoder_Fill(
      decoder_, &data, &data_size_in_bytes, &left_to_decode_in_bytes);
  if (error != AAC_DEC_OK) {
    SB_LOG(ERROR) << "aacDecoder_Fill() failed with result : " << error;
    error_cb_(kSbPlayerErrorDecode,
              FormatString("aacDecoder_Fill() failed with result %d.", error));
    return false;
  }

  // Returned |left_to_decode_in_bytes| should always be 0 as DecodeFrame() will
  // be called immediately on the same thread.
  SB_DCHECK(left_to_decode_in_bytes == 0);
  return true;
}

bool FdkAacAudioDecoder::ReadFromFdkDecoder(DecodeMode mode) {
  SB_DCHECK(mode == kDecodeModeFlush || mode == kDecodeModeDoNotFlush);
  int flags = mode == kDecodeModeFlush ? AACDEC_FLUSH : 0;

  AAC_DECODER_ERROR error = aacDecoder_DecodeFrame(
      decoder_, reinterpret_cast<INT_PCM*>(output_buffer_),
      kMaxOutputBufferSizeInBytes / sizeof(INT_PCM), flags);
  if (error != AAC_DEC_OK) {
    error_cb_(
        kSbPlayerErrorDecode,
        FormatString("aacDecoder_DecodeFrame() failed with result %d.", error));
    return false;
  }

  TryToUpdateStreamInfo();
  SB_DCHECK(has_stream_info_);
  if (audio_data_to_discard_in_bytes_ >= decoded_audio_size_in_bytes_) {
    // Discard all decoded data in |output_buffer_|.
    audio_data_to_discard_in_bytes_ -= decoded_audio_size_in_bytes_;
    return true;
  }

  // Discard the initial |audio_data_to_discard_in_bytes_| in |output_buffer_|.
  int offset_in_bytes = audio_data_to_discard_in_bytes_;
  audio_data_to_discard_in_bytes_ = 0;
  TryToOutputDecodedAudio(output_buffer_ + offset_in_bytes,
                          decoded_audio_size_in_bytes_ - offset_in_bytes);
  return true;
}

void FdkAacAudioDecoder::TryToUpdateStreamInfo() {
  if (has_stream_info_) {
    return;
  }
  CStreamInfo* stream_info = aacDecoder_GetStreamInfo(decoder_);
  SB_DCHECK(stream_info);

  num_channels_ = stream_info->numChannels;
  samples_per_second_ = stream_info->sampleRate;
  decoded_audio_size_in_bytes_ =
      sizeof(int16_t) * stream_info->frameSize * num_channels_;
  audio_data_to_discard_in_bytes_ =
      sizeof(int16_t) * stream_info->outputDelay * num_channels_;
  has_stream_info_ = true;
}

void FdkAacAudioDecoder::TryToOutputDecodedAudio(const uint8_t* data,
                                                 int size_in_bytes) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(has_stream_info_);

  while (size_in_bytes > 0 && !decoding_input_buffers_.empty()) {
    if (!partially_decoded_audio_) {
      SB_DCHECK(partially_decoded_audio_data_in_bytes_ == 0);
      partially_decoded_audio_ = new DecodedAudio(
          num_channels_, kSbMediaAudioSampleTypeInt16Deprecated,
          kSbMediaAudioFrameStorageTypeInterleaved,
          decoding_input_buffers_.front()->timestamp(),
          decoded_audio_size_in_bytes_);
    }
    int freespace =
        static_cast<int>(partially_decoded_audio_->size_in_bytes()) -
        partially_decoded_audio_data_in_bytes_;
    if (size_in_bytes >= freespace) {
      memcpy(partially_decoded_audio_->data() +
                 partially_decoded_audio_data_in_bytes_,
             data, freespace);
      data += freespace;
      size_in_bytes -= freespace;
      SB_DCHECK(decoding_input_buffers_.front()->timestamp() ==
                partially_decoded_audio_->timestamp());

      const auto& sample_info =
          decoding_input_buffers_.front()->audio_sample_info();
      partially_decoded_audio_->AdjustForDiscardedDurations(
          samples_per_second_, sample_info.discarded_duration_from_front,
          sample_info.discarded_duration_from_back);
      decoding_input_buffers_.pop();
      decoded_audios_.push(partially_decoded_audio_);
      Schedule(output_cb_);
      partially_decoded_audio_ = nullptr;
      partially_decoded_audio_data_in_bytes_ = 0;
      continue;
    }
    memcpy(partially_decoded_audio_->data() +
               partially_decoded_audio_data_in_bytes_,
           data, size_in_bytes);
    partially_decoded_audio_data_in_bytes_ += size_in_bytes;
    return;
  }
}

}  // namespace libfdkaac
}  // namespace shared
}  // namespace starboard
