// Copyright 2014 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 "media/filters/audio_clock.h"

#include <stdint.h>
#include <stddef.h>

#include <algorithm>
#include <cmath>

#include "base/logging.h"

namespace media {

AudioClock::AudioClock(base::TimeDelta start_timestamp, int sample_rate)
    : start_timestamp_(start_timestamp),
      microseconds_per_frame_(
          static_cast<double>(base::Time::kMicrosecondsPerSecond) /
          sample_rate),
      total_buffered_frames_(0),
      front_timestamp_micros_(start_timestamp.InMicroseconds()),
      back_timestamp_micros_(start_timestamp.InMicroseconds()) {}

AudioClock::~AudioClock() {
}

void AudioClock::WroteAudio(int frames_written,
                            int frames_requested,
                            int delay_frames,
                            double playback_rate) {
  DCHECK_GE(frames_written, 0);
  DCHECK_LE(frames_written, frames_requested);
  DCHECK_GE(delay_frames, 0);
  DCHECK_GE(playback_rate, 0);

  // First write: initialize buffer with silence.
  if (start_timestamp_.InMicroseconds() == front_timestamp_micros_ &&
      buffered_.empty()) {
    PushBufferedAudioData(delay_frames, 0.0);
  }

  // Move frames from |buffered_| into the computed timestamp based on
  // |delay_frames|.
  //
  // The ordering of compute -> push -> pop eliminates unnecessary memory
  // reallocations in cases where |buffered_| gets emptied.
  int64_t frames_played =
      std::max(INT64_C(0), total_buffered_frames_ - delay_frames);
  PushBufferedAudioData(frames_written, playback_rate);
  PushBufferedAudioData(frames_requested - frames_written, 0.0);
  PopBufferedAudioData(frames_played);

  // Update our front and back timestamps.  The back timestamp is considered the
  // authoritative source of truth, so base the front timestamp on range of data
  // buffered.  Doing so avoids accumulation errors on the front timestamp.
  back_timestamp_micros_ +=
      frames_written * playback_rate * microseconds_per_frame_;

  // Don't let front timestamp move earlier in time, as could occur due to delay
  // frames pushed in the first write, above.
  front_timestamp_micros_ =
      std::max(front_timestamp_micros_,
               back_timestamp_micros_ - ComputeBufferedMediaDurationMicros());
  DCHECK_GE(front_timestamp_micros_, start_timestamp_.InMicroseconds());
  DCHECK_LE(front_timestamp_micros_, back_timestamp_micros_);
}

void AudioClock::CompensateForSuspendedWrites(base::TimeDelta elapsed,
                                              int delay_frames) {
  const int64_t frames_elapsed =
      elapsed.InMicroseconds() / microseconds_per_frame_ + 0.5;

  // No need to do anything if we're within the limits of our played out audio
  // or there are no delay frames, the next WroteAudio() call will expire
  // everything correctly.
  if (frames_elapsed < total_buffered_frames_ || !delay_frames)
    return;

  // Otherwise, flush everything and prime with the delay frames.
  WroteAudio(0, 0, 0, 0);
  DCHECK(buffered_.empty());
  PushBufferedAudioData(delay_frames, 0.0);
}

base::TimeDelta AudioClock::TimeUntilPlayback(base::TimeDelta timestamp) const {
  // Use front/back_timestamp() methods rather than internal members. The public
  // methods round to the nearest microsecond for conversion to TimeDelta and
  // the rounded value will likely be used by the caller.
  DCHECK_GE(timestamp, front_timestamp());
  DCHECK_LE(timestamp, back_timestamp());

  int64_t frames_until_timestamp = 0;
  double timestamp_us = timestamp.InMicroseconds();
  double media_time_us = front_timestamp().InMicroseconds();

  for (size_t i = 0; i < buffered_.size(); ++i) {
    // Leading silence is always accounted prior to anything else.
    if (buffered_[i].playback_rate == 0) {
      frames_until_timestamp += buffered_[i].frames;
      continue;
    }

    // Calculate upper bound on media time for current block of buffered frames.
    double delta_us = buffered_[i].frames * buffered_[i].playback_rate *
                      microseconds_per_frame_;
    double max_media_time_us = media_time_us + delta_us;

    // Determine amount of media time to convert to frames for current block. If
    // target timestamp falls within current block, scale the amount of frames
    // based on remaining amount of media time.
    if (timestamp_us <= max_media_time_us) {
      frames_until_timestamp +=
          buffered_[i].frames * (timestamp_us - media_time_us) / delta_us;
      break;
    }

    media_time_us = max_media_time_us;
    frames_until_timestamp += buffered_[i].frames;
  }

  return base::TimeDelta::FromMicroseconds(
      std::round(frames_until_timestamp * microseconds_per_frame_));
}

void AudioClock::ContiguousAudioDataBufferedForTesting(
    base::TimeDelta* total,
    base::TimeDelta* same_rate_total) const {
  double scaled_frames = 0;
  double scaled_frames_at_same_rate = 0;
  bool found_silence = false;
  for (size_t i = 0; i < buffered_.size(); ++i) {
    if (buffered_[i].playback_rate == 0) {
      found_silence = true;
      continue;
    }

    // Any buffered silence breaks our contiguous stretch of audio data.
    if (found_silence)
      break;

    scaled_frames += (buffered_[i].frames * buffered_[i].playback_rate);

    if (i == 0)
      scaled_frames_at_same_rate = scaled_frames;
  }

  *total = base::TimeDelta::FromMicroseconds(scaled_frames *
                                             microseconds_per_frame_);
  *same_rate_total = base::TimeDelta::FromMicroseconds(
      scaled_frames_at_same_rate * microseconds_per_frame_);
}

AudioClock::AudioData::AudioData(int64_t frames, double playback_rate)
    : frames(frames), playback_rate(playback_rate) {
}

void AudioClock::PushBufferedAudioData(int64_t frames, double playback_rate) {
  if (frames == 0)
    return;

  total_buffered_frames_ += frames;

  // Avoid creating extra elements where possible.
  if (!buffered_.empty() && buffered_.back().playback_rate == playback_rate) {
    buffered_.back().frames += frames;
    return;
  }

  buffered_.push_back(AudioData(frames, playback_rate));
}

void AudioClock::PopBufferedAudioData(int64_t frames) {
  DCHECK_LE(frames, total_buffered_frames_);

  total_buffered_frames_ -= frames;

  while (frames > 0) {
    int64_t frames_to_pop = std::min(buffered_.front().frames, frames);
    buffered_.front().frames -= frames_to_pop;
    if (buffered_.front().frames == 0)
      buffered_.pop_front();

    frames -= frames_to_pop;
  }
}

double AudioClock::ComputeBufferedMediaDurationMicros() const {
  double scaled_frames = 0;
  for (const auto& buffer : buffered_)
    scaled_frames += buffer.frames * buffer.playback_rate;
  return scaled_frames * microseconds_per_frame_;
}

}  // namespace media
