// Copyright 2016 Google Inc. 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/starboard/player/filter/audio_renderer_impl_internal.h"

#include <algorithm>

#include "starboard/memory.h"
#include "starboard/shared/starboard/audio_sink/audio_sink_internal.h"
#include "starboard/shared/starboard/player/closure.h"

namespace starboard {
namespace shared {
namespace starboard {
namespace player {
namespace filter {

namespace {

const SbTime kEndOfStreamWrittenUpdateInterval = 5 * kSbTimeMillisecond;

}  // namespace

AudioRendererImpl::AudioRendererImpl(JobQueue* job_queue,
                                     scoped_ptr<AudioDecoder> decoder,
                                     const SbMediaAudioHeader& audio_header)
    : job_queue_(job_queue),
      channels_(audio_header.number_of_channels),
      bytes_per_frame_(
          (decoder->GetSampleType() == kSbMediaAudioSampleTypeInt16 ? 2 : 4) *
          channels_),
      playback_rate_(1.0),
      paused_(true),
      seeking_(false),
      seeking_to_pts_(0),
      frame_buffer_(kMaxCachedFrames * bytes_per_frame_),
      frames_in_buffer_(0),
      offset_in_frames_(0),
      frames_consumed_(0),
      frames_consumed_set_at_(SbTimeGetMonotonicNow()),
      end_of_stream_written_(false),
      end_of_stream_decoded_(false),
      decoder_(decoder.Pass()),
      audio_sink_(kSbAudioSinkInvalid),
      decoder_needs_full_reset_(false),
      buffers_in_decoder_(0) {
  SB_DCHECK(job_queue != NULL);
  SB_DCHECK(decoder_ != NULL);
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  frame_buffers_[0] = &frame_buffer_[0];

// TODO: The audio sink on Android is currently broken on certain devices,
// which causes all of playback to hang.  Log it for now, so we can tell
// when it happens, but this should be removed once the sink is fixed.
#if defined(NDEBUG)
  const bool kLogFramesConsumed = false;
#else
  const bool kLogFramesConsumed = true;
#endif
  if (kLogFramesConsumed) {
    log_frames_consumed_closure_ =
        Bind(&AudioRendererImpl::LogFramesConsumed, this);
    job_queue_->Schedule(log_frames_consumed_closure_, kSbTimeSecond);
  }
}

AudioRendererImpl::~AudioRendererImpl() {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  if (audio_sink_ != kSbAudioSinkInvalid) {
    SbAudioSinkDestroy(audio_sink_);
  }

  if (read_from_decoder_closure_.is_valid()) {
    job_queue_->Remove(read_from_decoder_closure_);
  }

  if (log_frames_consumed_closure_.is_valid()) {
    job_queue_->Remove(log_frames_consumed_closure_);
  }
}

void AudioRendererImpl::WriteSample(const InputBuffer& input_buffer) {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  if (end_of_stream_written_) {
    SB_LOG(ERROR) << "Appending audio sample at " << input_buffer.pts()
                  << " after EOS reached.";
    return;
  }

  decoder_->Decode(input_buffer);

  ScopedLock lock(mutex_);
  buffers_in_decoder_++;
  decoder_needs_full_reset_ = true;
  if (!read_from_decoder_closure_.is_valid()) {
    read_from_decoder_closure_ =
        Bind(&AudioRendererImpl::ReadFromDecoder, this);
    job_queue_->Schedule(read_from_decoder_closure_);
  }
}

void AudioRendererImpl::WriteEndOfStream() {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  SB_LOG_IF(WARNING, end_of_stream_written_)
      << "Try to write EOS after EOS is reached";
  if (end_of_stream_written_) {
    return;
  }

  decoder_->WriteEndOfStream();

  ScopedLock lock(mutex_);
  buffers_in_decoder_++;
  end_of_stream_written_ = true;
  decoder_needs_full_reset_ = true;
  // If we are seeking, we consider the seek is finished if end of stream is
  // reached as there won't be any audio data in future.
  if (seeking_) {
    seeking_ = false;
  }
}

void AudioRendererImpl::Play() {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  ScopedLock lock(mutex_);
  paused_ = false;
}

void AudioRendererImpl::Pause() {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  ScopedLock lock(mutex_);
  paused_ = true;
}

#if SB_API_VERSION >= 4
void AudioRendererImpl::SetPlaybackRate(double playback_rate) {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  playback_rate_ = playback_rate;

  if (audio_sink_) {
    audio_sink_->SetPlaybackRate(playback_rate);
  }
}
#endif  // SB_API_VERSION >= 4

void AudioRendererImpl::Seek(SbMediaTime seek_to_pts) {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());
  SB_DCHECK(seek_to_pts >= 0);

  SbAudioSinkDestroy(audio_sink_);
  // Now the sink is destroyed and the callbacks will no longer be called, so
  // the following modifications are safe without lock.
  audio_sink_ = kSbAudioSinkInvalid;

  seeking_to_pts_ = std::max<SbMediaTime>(seek_to_pts, 0);
  seeking_ = true;
  frames_in_buffer_ = 0;
  offset_in_frames_ = 0;
  frames_consumed_ = 0;
  frames_consumed_set_at_ = SbTimeGetMonotonicNow();
  end_of_stream_written_ = false;
  end_of_stream_decoded_ = false;
  pending_decoded_audio_ = NULL;
  buffers_in_decoder_ = 0;

  if (decoder_needs_full_reset_) {
    decoder_->Reset();
    decoder_needs_full_reset_ = false;
  }
}

bool AudioRendererImpl::IsEndOfStreamPlayed() const {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  ScopedLock lock(mutex_);
  return end_of_stream_decoded_ && frames_in_buffer_ == 0;
}

bool AudioRendererImpl::CanAcceptMoreData() const {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  ScopedLock lock(mutex_);
  if (end_of_stream_written_) {
    return false;
  }
  return buffers_in_decoder_ < kMaxbuffersInDecoder;
}

bool AudioRendererImpl::IsSeekingInProgress() const {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());
  return seeking_;
}

SbMediaTime AudioRendererImpl::GetCurrentTime() {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  if (seeking_) {
    return seeking_to_pts_;
  }
  return seeking_to_pts_ +
         frames_consumed_ * kSbMediaTimeSecond /
             decoder_->GetSamplesPerSecond();
}

void AudioRendererImpl::UpdateSourceStatus(int* frames_in_buffer,
                                           int* offset_in_frames,
                                           bool* is_playing,
                                           bool* is_eos_reached) {
  ScopedLock lock(mutex_);

  *is_eos_reached = end_of_stream_decoded_;

  if (!end_of_stream_decoded_ && !read_from_decoder_closure_.is_valid()) {
    read_from_decoder_closure_ =
        Bind(&AudioRendererImpl::ReadFromDecoder, this);
    if (paused_ || seeking_) {
      job_queue_->Schedule(read_from_decoder_closure_, 10 * kSbTimeMillisecond);
    } else {
      job_queue_->Schedule(read_from_decoder_closure_);
    }
  }

  if (paused_ || seeking_) {
    *is_playing = false;
    *frames_in_buffer = *offset_in_frames = 0;
    return;
  }

  *is_playing = true;
  *frames_in_buffer = frames_in_buffer_;
  *offset_in_frames = offset_in_frames_;
}

void AudioRendererImpl::ConsumeFrames(int frames_consumed) {
  ScopedLock lock(mutex_);

  SB_DCHECK(frames_consumed <= frames_in_buffer_);
  offset_in_frames_ += frames_consumed;
  offset_in_frames_ %= kMaxCachedFrames;
  frames_in_buffer_ -= frames_consumed;
  frames_consumed_ += frames_consumed;
  frames_consumed_set_at_ = SbTimeGetMonotonicNow();
}

void AudioRendererImpl::LogFramesConsumed() {
  SbTimeMonotonic time_since =
      SbTimeGetMonotonicNow() - frames_consumed_set_at_;
  if (time_since > kSbTimeSecond) {
    SB_DLOG(WARNING) << "|frames_consumed_| has not been updated for "
                     << (time_since / kSbTimeSecond) << "."
                     << ((time_since / (kSbTimeSecond / 10)) % 10)
                     << " seconds, and |pending_decoded_audio_| is "
                     << (!!pending_decoded_audio_ ? "" : "not ") << "ready.";
  }
  job_queue_->Schedule(log_frames_consumed_closure_, kSbTimeSecond);
}

// Try to read some audio data from the decoder.  Note that this operation is
// valid across seeking.  If a seek happens immediately after a ReadFromDecoder
// request is scheduled, the seek will reset the decoder.  So the
// ReadFromDecoder request will not read stale data.
void AudioRendererImpl::ReadFromDecoder() {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  ScopedLock lock(mutex_);
  SB_DCHECK(read_from_decoder_closure_.is_valid());
  read_from_decoder_closure_.reset();

  // Create the audio sink if it is the first incoming AU after seeking.
  if (audio_sink_ == kSbAudioSinkInvalid) {
    int sample_rate = decoder_->GetSamplesPerSecond();
    // TODO: Implement resampler.
    SB_DCHECK(sample_rate ==
              SbAudioSinkGetNearestSupportedSampleFrequency(sample_rate));
    // TODO: Handle sink creation failure.
    audio_sink_ = SbAudioSinkCreate(
        channels_, sample_rate, decoder_->GetSampleType(),
        kSbMediaAudioFrameStorageTypeInterleaved,
        reinterpret_cast<SbAudioSinkFrameBuffers>(frame_buffers_),
        kMaxCachedFrames, &AudioRendererImpl::UpdateSourceStatusFunc,
        &AudioRendererImpl::ConsumeFramesFunc, this);
#if SB_API_VERSION >= 4
    audio_sink_->SetPlaybackRate(playback_rate_);
#endif  // SB_API_VERSION >= 4
  }

  scoped_refptr<DecodedAudio> decoded_audio;
  if (pending_decoded_audio_) {
    decoded_audio = pending_decoded_audio_;
  } else {
    decoded_audio = decoder_->Read();
    if (decoded_audio) {
      SB_DCHECK(buffers_in_decoder_ > 0);
      buffers_in_decoder_--;
    }
  }
  pending_decoded_audio_ = NULL;
  if (!decoded_audio) {
    return;
  }

  if (decoded_audio->is_end_of_stream()) {
    SB_DCHECK(end_of_stream_written_);
    end_of_stream_decoded_ = true;
    return;
  }

  if (seeking_) {
    if (decoded_audio->pts() < seeking_to_pts_) {
      // Discard any audio data before the seeking target.
      return;
    }
  }

  if (!AppendDecodedAudio_Locked(decoded_audio)) {
    pending_decoded_audio_ = decoded_audio;
    return;
  }

  if (seeking_ && frame_buffer_.size() > kPrerollFrames * bytes_per_frame_) {
    seeking_ = false;
  }
}

// TODO: This function should be executed when lock is not acquired as it copies
// relatively large amount of data.
bool AudioRendererImpl::AppendDecodedAudio_Locked(
    const scoped_refptr<DecodedAudio>& decoded_audio) {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  const uint8_t* source_buffer = decoded_audio->buffer();
  int frames_to_append = decoded_audio->size() / bytes_per_frame_;

  if (frames_in_buffer_ + frames_to_append > kMaxCachedFrames) {
    return false;
  }

  int offset_to_append =
      (offset_in_frames_ + frames_in_buffer_) % kMaxCachedFrames;
  if (frames_to_append > kMaxCachedFrames - offset_to_append) {
    SbMemoryCopy(&frame_buffer_[offset_to_append * bytes_per_frame_],
                 source_buffer,
                 (kMaxCachedFrames - offset_to_append) * bytes_per_frame_);
    source_buffer += (kMaxCachedFrames - offset_to_append) * bytes_per_frame_;
    frames_to_append -= kMaxCachedFrames - offset_to_append;
    frames_in_buffer_ += kMaxCachedFrames - offset_to_append;
    offset_to_append = 0;
  }
  SbMemoryCopy(&frame_buffer_[offset_to_append * bytes_per_frame_],
               source_buffer, frames_to_append * bytes_per_frame_);
  frames_in_buffer_ += frames_to_append;

  return true;
}

// static
void AudioRendererImpl::UpdateSourceStatusFunc(int* frames_in_buffer,
                                               int* offset_in_frames,
                                               bool* is_playing,
                                               bool* is_eos_reached,
                                               void* context) {
  AudioRendererImpl* audio_renderer = static_cast<AudioRendererImpl*>(context);
  SB_DCHECK(audio_renderer);
  SB_DCHECK(frames_in_buffer);
  SB_DCHECK(offset_in_frames);
  SB_DCHECK(is_playing);
  SB_DCHECK(is_eos_reached);

  audio_renderer->UpdateSourceStatus(frames_in_buffer, offset_in_frames,
                                     is_playing, is_eos_reached);
}

// static
void AudioRendererImpl::ConsumeFramesFunc(int frames_consumed, void* context) {
  AudioRendererImpl* audio_renderer = static_cast<AudioRendererImpl*>(context);
  SB_DCHECK(audio_renderer);

  audio_renderer->ConsumeFrames(frames_consumed);
}

}  // namespace filter
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
