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

#include <algorithm>

#include "starboard/memory.h"
#include "starboard/shared/starboard/media/media_util.h"

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

namespace {

// This class works only when the input format and output format are the same.
// It allows for a simplified AudioRenderer implementation by always using a
// resampler.
class IdentityAudioResampler : public AudioResampler {
 public:
  IdentityAudioResampler() : eos_reached_(false) {}
  scoped_refptr<DecodedAudio> Resample(
      const scoped_refptr<DecodedAudio>& audio_data) override {
    SB_DCHECK(!eos_reached_);

    return audio_data;
  }
  scoped_refptr<DecodedAudio> WriteEndOfStream() override {
    SB_DCHECK(!eos_reached_);
    eos_reached_ = true;
    return new DecodedAudio();
  }

 private:
  bool eos_reached_;
};

// AudioRenderer uses AudioTimeStretcher internally to adjust to playback rate.
// So we try to use kSbMediaAudioSampleTypeFloat32 and only use
// kSbMediaAudioSampleTypeInt16Deprecated when float32 is not supported.  To use
// kSbMediaAudioSampleTypeFloat32 will cause an extra conversion from float32 to
// int16 before the samples are sent to the audio sink.
SbMediaAudioSampleType GetSinkAudioSampleType(
    AudioRendererSink* audio_renderer_sink) {
  return audio_renderer_sink->IsAudioSampleTypeSupported(
             kSbMediaAudioSampleTypeFloat32)
             ? kSbMediaAudioSampleTypeFloat32
             : kSbMediaAudioSampleTypeInt16Deprecated;
}

}  // namespace

AudioRenderer::AudioRenderer(scoped_ptr<AudioDecoder> decoder,
                             scoped_ptr<AudioRendererSink> audio_renderer_sink,
                             const SbMediaAudioSampleInfo& audio_sample_info,
                             int max_cached_frames,
                             int min_frames_per_append)
    : max_cached_frames_(max_cached_frames),
      min_frames_per_append_(min_frames_per_append),
      channels_(audio_sample_info.number_of_channels),
      sink_sample_type_(GetSinkAudioSampleType(audio_renderer_sink.get())),
      bytes_per_frame_(media::GetBytesPerSample(sink_sample_type_) * channels_),
      frame_buffer_(max_cached_frames_ * bytes_per_frame_),
      frames_consumed_set_at_(SbTimeGetMonotonicNow()),
      decoder_(decoder.Pass()),
      process_audio_data_job_(
          std::bind(&AudioRenderer::ProcessAudioData, this)),
      audio_renderer_sink_(audio_renderer_sink.Pass()) {
  SB_DLOG(INFO) << "Creating AudioRenderer with " << channels_ << " channels, "
                << bytes_per_frame_ << " bytes per frame, "
                << max_cached_frames_ << " max cached frames, and "
                << min_frames_per_append_ << " min frames per append.";
  SB_DCHECK(decoder_ != NULL);
  SB_DCHECK(min_frames_per_append_ > 0);
  SB_DCHECK(max_cached_frames_ >= min_frames_per_append_ * 2);

  frame_buffers_[0] = &frame_buffer_[0];

#if SB_PLAYER_FILTER_ENABLE_STATE_CHECK
  Schedule(std::bind(&AudioRenderer::CheckAudioSinkStatus, this),
           kCheckAudioSinkStatusInterval);
#endif  // SB_PLAYER_FILTER_ENABLE_STATE_CHECK
}

AudioRenderer::~AudioRenderer() {
  SB_DLOG(INFO) << "Destroying AudioRenderer with " << channels_
                << " channels, " << bytes_per_frame_ << " bytes per frame, "
                << max_cached_frames_ << " max cached frames, and "
                << min_frames_per_append_ << " min frames per append.";
  SB_DCHECK(BelongsToCurrentThread());
}

void AudioRenderer::Initialize(const ErrorCB& error_cb,
                               const PrerolledCB& prerolled_cb,
                               const EndedCB& ended_cb) {
  SB_DCHECK(error_cb);
  SB_DCHECK(prerolled_cb);
  SB_DCHECK(ended_cb);
  SB_DCHECK(!error_cb_);
  SB_DCHECK(!prerolled_cb_);
  SB_DCHECK(!ended_cb_);

  error_cb_ = error_cb;
  prerolled_cb_ = prerolled_cb;
  ended_cb_ = ended_cb;

  decoder_->Initialize(std::bind(&AudioRenderer::OnDecoderOutput, this),
                       error_cb);
}

void AudioRenderer::WriteSample(
    const scoped_refptr<InputBuffer>& input_buffer) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(input_buffer);
  SB_DCHECK(can_accept_more_data_);

  if (eos_state_ >= kEOSWrittenToDecoder) {
    SB_LOG(ERROR) << "Appending audio sample at " << input_buffer->timestamp()
                  << " after EOS reached.";
    return;
  }

  can_accept_more_data_ = false;

  decoder_->Decode(input_buffer,
                   std::bind(&AudioRenderer::OnDecoderConsumed, this));
  first_input_written_ = true;
}

void AudioRenderer::WriteEndOfStream() {
  SB_DCHECK(BelongsToCurrentThread());
  // TODO: Check |can_accept_more_data_| and make WriteEndOfStream() depend on
  // CanAcceptMoreData() or callback.
  // SB_DCHECK(can_accept_more_data_);
  // can_accept_more_data_ = false;

  if (eos_state_ >= kEOSWrittenToDecoder) {
    SB_LOG(ERROR) << "Try to write EOS after EOS is reached";
    return;
  }

  decoder_->WriteEndOfStream();

  ScopedLock lock(mutex_);
  eos_state_ = kEOSWrittenToDecoder;
  first_input_written_ = true;
}

void AudioRenderer::SetVolume(double volume) {
  SB_DCHECK(BelongsToCurrentThread());
  audio_renderer_sink_->SetVolume(volume);
}

bool AudioRenderer::IsEndOfStreamWritten() const {
  SB_DCHECK(BelongsToCurrentThread());
  return eos_state_ >= kEOSWrittenToDecoder;
}

bool AudioRenderer::IsEndOfStreamPlayed() const {
  ScopedLock lock(mutex_);
  return IsEndOfStreamPlayed_Locked();
}

bool AudioRenderer::CanAcceptMoreData() const {
  SB_DCHECK(BelongsToCurrentThread());
  return eos_state_ == kEOSNotReceived && can_accept_more_data_ &&
         (!decoder_sample_rate_ || !time_stretcher_.IsQueueFull());
}

void AudioRenderer::Play() {
  SB_DCHECK(BelongsToCurrentThread());

  ScopedLock lock(mutex_);
  paused_ = false;
  consume_frames_called_ = false;
}

void AudioRenderer::Pause() {
  SB_DCHECK(BelongsToCurrentThread());

  ScopedLock lock(mutex_);
  paused_ = true;
}

void AudioRenderer::SetPlaybackRate(double playback_rate) {
  SB_DCHECK(BelongsToCurrentThread());

  ScopedLock lock(mutex_);

  if (playback_rate_ == 0.f && playback_rate > 0.f) {
    consume_frames_called_ = false;
  }

  playback_rate_ = playback_rate;

  audio_renderer_sink_->SetPlaybackRate(playback_rate_ > 0.0 ? 1.0 : 0.0);
  if (audio_renderer_sink_->HasStarted()) {
    // TODO: Remove SetPlaybackRate() support from audio sink as it only need to
    // support play/pause.
    if (playback_rate_ > 0.0) {
      if (process_audio_data_job_token_.is_valid()) {
        RemoveJobByToken(process_audio_data_job_token_);
        process_audio_data_job_token_.ResetToInvalid();
      }
      process_audio_data_job_token_ = Schedule(process_audio_data_job_);
    }
  }
}

void AudioRenderer::Seek(SbTime seek_to_time) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(seek_to_time >= 0);

  audio_renderer_sink_->Stop();

  {
    // Set the following states under a lock first to ensure that from now on
    // GetCurrentMediaTime() returns |seeking_to_time_|.
    ScopedLock scoped_lock(mutex_);
    eos_state_ = kEOSNotReceived;
    seeking_to_time_ = std::max<SbTime>(seek_to_time, 0);
    last_media_time_ = seek_to_time;
    ended_cb_called_ = false;
    seeking_ = true;
  }

  // Now the sink is stopped and the callbacks will no longer be called, so the
  // following modifications are safe without lock.
  if (resampler_) {
    resampler_.reset();
    time_stretcher_.FlushBuffers();
  }

  total_frames_sent_to_sink_ = 0;
  total_frames_consumed_by_sink_ = 0;
  frames_consumed_by_sink_since_last_get_current_time_ = 0;
  pending_decoder_outputs_ = 0;
  audio_frame_tracker_.Reset();
  frames_consumed_set_at_ = SbTimeGetMonotonicNow();
  can_accept_more_data_ = true;
  process_audio_data_job_token_.ResetToInvalid();

  is_eos_reached_on_sink_thread_ = false;
  is_playing_on_sink_thread_ = false;
  frames_in_buffer_on_sink_thread_ = 0;
  offset_in_frames_on_sink_thread_ = 0;
  frames_consumed_on_sink_thread_ = 0;
  silence_frames_written_after_eos_on_sink_thread_ = 0;
  silence_frames_consumed_on_sink_thread_ = 0;

  if (first_input_written_) {
    decoder_->Reset();
    decoder_sample_rate_ = nullopt;
    first_input_written_ = false;
  }

  CancelPendingJobs();

#if SB_PLAYER_FILTER_ENABLE_STATE_CHECK
  Schedule(std::bind(&AudioRenderer::CheckAudioSinkStatus, this),
           kCheckAudioSinkStatusInterval);
#endif  // SB_PLAYER_FILTER_ENABLE_STATE_CHECK
}

SbTime AudioRenderer::GetCurrentMediaTime(bool* is_playing,
                                          bool* is_eos_played,
                                          bool* is_underflow) {
  SB_DCHECK(is_playing);
  SB_DCHECK(is_eos_played);
  SB_DCHECK(is_underflow);

  SbTime media_time = 0;
  SbTimeMonotonic now = -1;
  SbTimeMonotonic elasped_since_last_set = 0;
  int64_t frames_played = 0;
  int samples_per_second = 1;

  {
    ScopedLock scoped_lock(mutex_);

    *is_playing = !paused_ && !seeking_;
    *is_eos_played = IsEndOfStreamPlayed_Locked();
    *is_underflow = underflow_;

    if (seeking_ || !decoder_sample_rate_) {
      return seeking_to_time_;
    }

    if (frames_consumed_by_sink_since_last_get_current_time_ > 0) {
      audio_frame_tracker_.RecordPlayedFrames(
          frames_consumed_by_sink_since_last_get_current_time_);
#if SB_LOG_MEDIA_TIME_STATS
      total_frames_consumed_ +=
          frames_consumed_by_sink_since_last_get_current_time_;
#endif  // SB_LOG_MEDIA_TIME_STATS
      frames_consumed_by_sink_since_last_get_current_time_ = 0;
    }

    // When the audio sink is transitioning from pause to play, it may come with
    // a long delay.  So ensure that ConsumeFrames() is called after Play()
    // before taking elapsed time into account.
    if (!paused_ && playback_rate_ > 0.f && consume_frames_called_) {
      now = SbTimeGetMonotonicNow();
      elasped_since_last_set = now - frames_consumed_set_at_;
    }
    samples_per_second = *decoder_sample_rate_;
    int64_t elapsed_frames =
        elasped_since_last_set * samples_per_second / kSbTimeSecond;
    frames_played =
        audio_frame_tracker_.GetFutureFramesPlayedAdjustedToPlaybackRate(
            elapsed_frames);
    media_time =
        seeking_to_time_ + frames_played * kSbTimeSecond / samples_per_second;
    if (media_time < last_media_time_) {
#if SB_LOG_MEDIA_TIME_STATS
      SB_LOG(WARNING) << "Audio time runs backwards from " << last_media_time_
                      << " to " << media_time;
#endif  // SB_LOG_MEDIA_TIME_STATS
      media_time = last_media_time_;
    }
    last_media_time_ = media_time;
  }

#if SB_LOG_MEDIA_TIME_STATS
  if (system_and_media_time_offset_ < 0 && frames_played > 0) {
    system_and_media_time_offset_ = now - media_time;
  }
  if (system_and_media_time_offset_ > 0) {
    SbTime offset = now - media_time;
    SbTime drift = offset - system_and_media_time_offset_;
    min_drift_ = std::min(drift, min_drift_);
    max_drift_ = std::max(drift, max_drift_);
    SB_LOG(ERROR) << "Media time stats: (" << now << "-"
                  << frames_consumed_set_at_ << "=" << elasped_since_last_set
                  << ") + " << total_frames_consumed_ << " => " << frames_played
                  << " => " << media_time << "  drift: " << drift << "/ ("
                  << min_drift_ << ", " << max_drift_
                  << ") "
                  // How long the audio frames left in sink can be played.
                  << (total_frames_sent_to_sink_ -
                      total_frames_consumed_by_sink_) *
                         kSbTimeSecond / samples_per_second;
  }
#endif  // SB_LOG_MEDIA_TIME_STATS

  return media_time;
}

void AudioRenderer::GetSourceStatus(int* frames_in_buffer,
                                    int* offset_in_frames,
                                    bool* is_playing,
                                    bool* is_eos_reached) {
#if SB_PLAYER_FILTER_ENABLE_STATE_CHECK
  sink_callbacks_since_last_check_.increment();
#endif  // SB_PLAYER_FILTER_ENABLE_STATE_CHECK

  {
    ScopedTryLock lock(mutex_);
    if (lock.is_locked()) {
      UpdateVariablesOnSinkThread_Locked(
          frames_consumed_set_at_on_sink_thread_);
    }
  }

  *is_eos_reached = is_eos_reached_on_sink_thread_;
  *is_playing = is_playing_on_sink_thread_;

  if (*is_playing) {
    *frames_in_buffer =
        frames_in_buffer_on_sink_thread_ - frames_consumed_on_sink_thread_;
    *offset_in_frames =
        (offset_in_frames_on_sink_thread_ + frames_consumed_on_sink_thread_) %
        max_cached_frames_;
  } else {
    *frames_in_buffer = *offset_in_frames = 0;
  }

  if (*is_eos_reached && *frames_in_buffer < max_cached_frames_) {
    // Fill silence frames on EOS to ensure keep the audio sink playing.
    auto start_offset =
        (*offset_in_frames + *frames_in_buffer) % max_cached_frames_;
    auto silence_frames_to_write = max_cached_frames_ - start_offset;
    SB_DCHECK(start_offset >= 0);
    SB_DCHECK(silence_frames_to_write >= 0);
    SB_DCHECK(start_offset + silence_frames_to_write <= max_cached_frames_);
    SbMemorySet(frame_buffer_.data() + start_offset * bytes_per_frame_, 0,
                silence_frames_to_write * bytes_per_frame_);
    silence_frames_written_after_eos_on_sink_thread_ += silence_frames_to_write;
    *frames_in_buffer += silence_frames_to_write;
  }
}

void AudioRenderer::ConsumeFrames(int frames_consumed
#if SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION || \
    SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
                                  ,
                                  SbTime frames_consumed_at
#endif  // SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION ||
        // SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
                                  ) {
#if SB_PLAYER_FILTER_ENABLE_STATE_CHECK
  sink_callbacks_since_last_check_.increment();
#endif  // SB_PLAYER_FILTER_ENABLE_STATE_CHECK

// Note that occasionally thread context switch may cause that the time
// recorded here is several milliseconds later than the time |frames_consumed|
// is recorded.  This causes the audio time to drift as much as the difference
// between the two times.
// This is usually not a huge issue as:
// 1. It happens rarely.
// 2. It doesn't accumulate.
// 3. It doesn't affect frame presenting even with a 60fps video.
// However, if this ever becomes a problem, we can smooth it out over multiple
// ConsumeFrames() calls.
#if SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION
  if (!kSbHasAsyncAudioFramesReporting) {
    frames_consumed_at = SbTimeGetMonotonicNow();
  }
#elif SB_API_VERSION < SB_FEATURE_RUNTIME_CONFIGS_VERSION && \
    !SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
  SbTime frames_consumed_at = SbTimeGetMonotonicNow();
#endif  // SB_API_VERSION < SB_FEATURE_RUNTIME_CONFIGS_VERSION &&
        // !SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)

  ScopedTryLock lock(mutex_);
  if (lock.is_locked()) {
    frames_consumed_on_sink_thread_ += frames_consumed;

    UpdateVariablesOnSinkThread_Locked(frames_consumed_at);
  } else {
    frames_consumed_on_sink_thread_ += frames_consumed;
    frames_consumed_set_at_on_sink_thread_ = frames_consumed_at;
  }
}

void AudioRenderer::UpdateVariablesOnSinkThread_Locked(
    SbTime system_time_on_consume_frames) {
  mutex_.DCheckAcquired();

  if (frames_consumed_on_sink_thread_ > 0) {
    SB_DCHECK(total_frames_consumed_by_sink_ + frames_consumed_on_sink_thread_ +
                  silence_frames_consumed_on_sink_thread_ <=
              total_frames_sent_to_sink_ +
                  silence_frames_written_after_eos_on_sink_thread_);
    auto non_silence_frames_consumed =
        std::min(total_frames_sent_to_sink_ - total_frames_consumed_by_sink_,
                 frames_consumed_on_sink_thread_);
    total_frames_consumed_by_sink_ += non_silence_frames_consumed;
    frames_consumed_by_sink_since_last_get_current_time_ +=
        non_silence_frames_consumed;
    if (non_silence_frames_consumed != 0) {
      frames_consumed_set_at_ = system_time_on_consume_frames;
    }
    consume_frames_called_ = true;
    silence_frames_consumed_on_sink_thread_ =
        frames_consumed_on_sink_thread_ - non_silence_frames_consumed;
    frames_consumed_on_sink_thread_ = 0;
  }

  is_eos_reached_on_sink_thread_ = eos_state_ >= kEOSSentToSink;
  frames_in_buffer_on_sink_thread_ = static_cast<int>(
      total_frames_sent_to_sink_ +
      silence_frames_written_after_eos_on_sink_thread_ -
      total_frames_consumed_by_sink_ - silence_frames_consumed_on_sink_thread_);
  underflow_ |=
      frames_in_buffer_on_sink_thread_ < kFramesInBufferBeginUnderflow;
  if (is_eos_reached_on_sink_thread_ ||
      frames_in_buffer_on_sink_thread_ >= buffered_frames_to_start_) {
    underflow_ = false;
  }
  is_playing_on_sink_thread_ = !paused_ && !seeking_ && !underflow_;
  offset_in_frames_on_sink_thread_ = (total_frames_consumed_by_sink_ +
                                      silence_frames_consumed_on_sink_thread_) %
                                     max_cached_frames_;

  if (IsEndOfStreamPlayed_Locked() && !ended_cb_called_) {
    ended_cb_called_ = true;
    Schedule(ended_cb_);
  }
}

void AudioRenderer::OnFirstOutput(
    const SbMediaAudioSampleType decoded_sample_type,
    const SbMediaAudioFrameStorageType decoded_storage_type,
    const int decoded_sample_rate) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(!decoder_sample_rate_);
  decoder_sample_rate_ = decoded_sample_rate;
  int destination_sample_rate =
      audio_renderer_sink_->GetNearestSupportedSampleFrequency(
          *decoder_sample_rate_);
  time_stretcher_.Initialize(kSbMediaAudioSampleTypeFloat32, channels_,
                             destination_sample_rate);

  buffered_frames_to_start_ = std::min(
      destination_sample_rate / 5, max_cached_frames_ - min_frames_per_append_);

  if (decoded_sample_rate != destination_sample_rate ||
      decoded_sample_type != sink_sample_type_ ||
      decoded_storage_type != kSbMediaAudioFrameStorageTypeInterleaved) {
    resampler_ = AudioResampler::Create(
        decoded_sample_type, decoded_storage_type, decoded_sample_rate,
        sink_sample_type_, kSbMediaAudioFrameStorageTypeInterleaved,
        destination_sample_rate, channels_);
    SB_DCHECK(resampler_);
  } else {
    resampler_.reset(new IdentityAudioResampler);
  }

  // TODO: Support planar only audio sink.
  audio_renderer_sink_->Start(
      channels_, destination_sample_rate, sink_sample_type_,
      kSbMediaAudioFrameStorageTypeInterleaved,
      reinterpret_cast<SbAudioSinkFrameBuffers>(frame_buffers_),
      max_cached_frames_, this);
  if (!audio_renderer_sink_->HasStarted()) {
#if SB_HAS(PLAYER_ERROR_MESSAGE)
    SB_LOG(ERROR) << "Failed to start audio sink.";
    error_cb_(kSbPlayerErrorDecode, "failed to start audio sink");
#else   // SB_HAS(PLAYER_ERROR_MESSAGE)
    error_cb_();
#endif  // SB_HAS(PLAYER_ERROR_MESSAGE)
  }
}

bool AudioRenderer::IsEndOfStreamPlayed_Locked() const {
  mutex_.DCheckAcquired();
  return eos_state_ >= kEOSSentToSink &&
         total_frames_sent_to_sink_ == total_frames_consumed_by_sink_;
}

void AudioRenderer::OnDecoderConsumed() {
  SB_DCHECK(BelongsToCurrentThread());

  // TODO: Unify EOS and non EOS request once WriteEndOfStream() depends on
  // CanAcceptMoreData().
  if (eos_state_ == kEOSNotReceived) {
    SB_DCHECK(!can_accept_more_data_);

    can_accept_more_data_ = true;
  }
}

void AudioRenderer::OnDecoderOutput() {
  SB_DCHECK(BelongsToCurrentThread());

  ++pending_decoder_outputs_;

  if (process_audio_data_job_token_.is_valid()) {
    RemoveJobByToken(process_audio_data_job_token_);
    process_audio_data_job_token_.ResetToInvalid();
  }

  ProcessAudioData();
}

void AudioRenderer::ProcessAudioData() {
  SB_DCHECK(BelongsToCurrentThread());

  process_audio_data_job_token_.ResetToInvalid();

  // Loop until no audio is appended, i.e. AppendAudioToFrameBuffer() returns
  // false.
  bool is_frame_buffer_full = false;
  if (audio_renderer_sink_->HasStarted()) {
    while (AppendAudioToFrameBuffer(&is_frame_buffer_full)) {
    }
  }

  while (pending_decoder_outputs_ > 0) {
    if (audio_renderer_sink_->HasStarted() && time_stretcher_.IsQueueFull()) {
      // There is no room to do any further processing, schedule the function
      // again for a later time.  The delay time is 1/4 of the buffer size.
      const SbTimeMonotonic delay =
          max_cached_frames_ * kSbTimeSecond / *decoder_sample_rate_ / 4;
      process_audio_data_job_token_ = Schedule(process_audio_data_job_, delay);
      return;
    }

    scoped_refptr<DecodedAudio> resampled_audio;
    int decoded_audio_sample_rate;
    scoped_refptr<DecodedAudio> decoded_audio =
        decoder_->Read(&decoded_audio_sample_rate);
    SB_DCHECK(decoded_audio);
    if (!audio_renderer_sink_->HasStarted()) {
      OnFirstOutput(decoded_audio->sample_type(), decoded_audio->storage_type(),
                    decoded_audio_sample_rate);
    }
    SB_DCHECK(resampler_);

    --pending_decoder_outputs_;
    if (!decoded_audio) {
      continue;
    }

    if (decoded_audio->is_end_of_stream()) {
      SB_DCHECK(eos_state_ == kEOSWrittenToDecoder) << eos_state_;
      {
        ScopedLock lock(mutex_);
        eos_state_ = kEOSDecoded;
        if (seeking_) {
          seeking_ = false;
          Schedule(prerolled_cb_);
        }
      }

      resampled_audio = resampler_->WriteEndOfStream();
    } else {
      // Discard any audio data before the seeking target.
      if (seeking_ && decoded_audio->timestamp() < seeking_to_time_) {
        continue;
      }

      resampled_audio = resampler_->Resample(decoded_audio);
    }

    if (resampled_audio && resampled_audio->size() > 0) {
      // |time_stretcher_| only support kSbMediaAudioSampleTypeFloat32 and
      // kSbMediaAudioFrameStorageTypeInterleaved.
      resampled_audio->SwitchFormatTo(kSbMediaAudioSampleTypeFloat32,
                                      kSbMediaAudioFrameStorageTypeInterleaved);
      time_stretcher_.EnqueueBuffer(resampled_audio);
    }

    // Loop until no audio is appended, i.e. AppendAudioToFrameBuffer() returns
    // false.
    while (AppendAudioToFrameBuffer(&is_frame_buffer_full)) {
    }
  }

  if (seeking_ || playback_rate_ == 0.0) {
    process_audio_data_job_token_ =
        Schedule(process_audio_data_job_, 5 * kSbTimeMillisecond);
    return;
  }

  if (is_frame_buffer_full) {
    // There are still audio data not appended so schedule a callback later.
    SbTimeMonotonic delay = 0;
    int64_t frames_in_buffer =
        total_frames_sent_to_sink_ - total_frames_consumed_by_sink_;
    if (max_cached_frames_ - frames_in_buffer < max_cached_frames_ / 4) {
      int frames_to_delay = static_cast<int>(
          max_cached_frames_ / 4 - (max_cached_frames_ - frames_in_buffer));
      delay = frames_to_delay * kSbTimeSecond / *decoder_sample_rate_;
    }
    process_audio_data_job_token_ = Schedule(process_audio_data_job_, delay);
  }
}

bool AudioRenderer::AppendAudioToFrameBuffer(bool* is_frame_buffer_full) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(is_frame_buffer_full);

  *is_frame_buffer_full = false;

  if (time_stretcher_.IsQueueFull()) {
    ScopedLock lock(mutex_);
    if (seeking_) {
      seeking_ = false;
      Schedule(prerolled_cb_);
    }
  }

  if (seeking_ || playback_rate_ == 0.0) {
    return false;
  }

  int frames_in_buffer = static_cast<int>(total_frames_sent_to_sink_ -
                                          total_frames_consumed_by_sink_);

  if (max_cached_frames_ - frames_in_buffer < min_frames_per_append_) {
    *is_frame_buffer_full = true;
    return false;
  }

  int offset_to_append = total_frames_sent_to_sink_ % max_cached_frames_;

  scoped_refptr<DecodedAudio> decoded_audio = time_stretcher_.Read(
      max_cached_frames_ - frames_in_buffer, playback_rate_);
  SB_DCHECK(decoded_audio);

  {
    ScopedLock lock(mutex_);
    if (decoded_audio->frames() == 0 && eos_state_ == kEOSDecoded) {
      eos_state_ = kEOSSentToSink;
    }
    audio_frame_tracker_.AddFrames(decoded_audio->frames(), playback_rate_);
  }

  // |time_stretcher_| only support kSbMediaAudioSampleTypeFloat32 and
  // kSbMediaAudioFrameStorageTypeInterleaved.
  decoded_audio->SwitchFormatTo(sink_sample_type_,
                                kSbMediaAudioFrameStorageTypeInterleaved);
  const uint8_t* source_buffer = decoded_audio->buffer();
  int frames_to_append = decoded_audio->frames();
  int frames_appended = 0;

  if (frames_to_append > max_cached_frames_ - offset_to_append) {
    SbMemoryCopy(&frame_buffer_[offset_to_append * bytes_per_frame_],
                 source_buffer,
                 (max_cached_frames_ - offset_to_append) * bytes_per_frame_);
    source_buffer += (max_cached_frames_ - offset_to_append) * bytes_per_frame_;
    frames_to_append -= max_cached_frames_ - offset_to_append;
    frames_appended += max_cached_frames_ - 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_appended += frames_to_append;

  total_frames_sent_to_sink_ += frames_appended;

  return frames_appended > 0;
}

#if SB_PLAYER_FILTER_ENABLE_STATE_CHECK
void AudioRenderer::CheckAudioSinkStatus() {
  SB_DCHECK(BelongsToCurrentThread());

  // Check if sink callbacks are called too frequently.
  if (sink_callbacks_since_last_check_.load() > kMaxSinkCallbacksBetweenCheck) {
    SB_LOG(WARNING) << "Sink callback has been called for "
                    << sink_callbacks_since_last_check_.load()
                    << " time since last check, which is too frequently.";
  }

  auto sink_callbacks_since_last_check =
      sink_callbacks_since_last_check_.exchange(0);

  if (paused_ || playback_rate_ == 0.0) {
    return;
  }

  // Check if sink has updated.
  SbTimeMonotonic elapsed = SbTimeGetMonotonicNow() - frames_consumed_set_at_;
  if (elapsed > kCheckAudioSinkStatusInterval) {
    ScopedLock lock(mutex_);
    SB_DLOG(WARNING) << "|frames_consumed_| has not been updated for "
                     << elapsed / kSbTimeSecond << " seconds, with "
                     << total_frames_sent_to_sink_ -
                            total_frames_consumed_by_sink_
                     << " frames in sink, " << (underflow_ ? "underflow, " : "")
                     << sink_callbacks_since_last_check
                     << " callbacks since last check.";
  }
  Schedule(std::bind(&AudioRenderer::CheckAudioSinkStatus, this),
           kCheckAudioSinkStatusInterval);
}
#endif  // SB_PLAYER_FILTER_ENABLE_STATE_CHECK

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