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

#ifndef LIB_MEDIA_CPP_TIMELINE_RATE_H_
#define LIB_MEDIA_CPP_TIMELINE_RATE_H_

#include <stdint.h>
#include <zircon/assert.h>

#include <limits>

namespace media {

// TODO(dalesat): Consider always allowing inexact results.

// Expresses the relative rate of a timeline as the ratio between two uint32_t
// values subject_delta / reference_delta. "subject" refers to the timeline
// whose rate is being represented, and "reference" refers to the timeline
// relative to which the rate is expressed.
class TimelineRate final {
 public:
  // Used to indicate overflow of scaling operations.
  static constexpr int64_t kOverflow = std::numeric_limits<int64_t>::max();

  // Zero as a TimelineRate.
  static const TimelineRate Zero;

  // Nanoseconds (subject) per second (reference) as a TimelineRate.
  static const TimelineRate NsPerSecond;

  // Reduces the ratio of *subject_delta and *reference_delta.
  static void Reduce(uint32_t* subject_delta, uint32_t* reference_delta);

  // Produces the product of the rates. If exact is true, DCHECKs on loss of
  // precision.
  static void Product(uint32_t a_subject_delta, uint32_t a_reference_delta,
                      uint32_t b_subject_delta, uint32_t b_reference_delta,
                      uint32_t* product_subject_delta, uint32_t* product_reference_delta,
                      bool exact = true);

  // Produces the product of the rates and the int64_t as an int64_t. Returns
  // kOverflow on overflow.
  static int64_t Scale(int64_t value, uint32_t subject_delta, uint32_t reference_delta);

  // Returns the product of the rates. If exact is true, DCHECKs on loss of
  // precision.
  static TimelineRate Product(TimelineRate a, TimelineRate b, bool exact = true) {
    uint32_t result_subject_delta;
    uint32_t result_reference_delta;
    Product(a.subject_delta(), a.reference_delta(), b.subject_delta(), b.reference_delta(),
            &result_subject_delta, &result_reference_delta, exact);
    return TimelineRate(result_subject_delta, result_reference_delta);
  }

  TimelineRate() : subject_delta_(0), reference_delta_(1) {}

  explicit TimelineRate(uint32_t subject_delta)
      : subject_delta_(subject_delta), reference_delta_(1) {}

  explicit TimelineRate(float rate_as_float)
      : subject_delta_(rate_as_float > 1.0f ? kFloatFactor
                                            : static_cast<uint32_t>(kFloatFactor * rate_as_float)),
        reference_delta_(rate_as_float > 1.0f ? static_cast<uint32_t>(kFloatFactor / rate_as_float)
                                              : kFloatFactor) {
    // The expressions above are intended to provide good precision for
    // 'reasonable' playback rate values (say in the range 0.0 to 4.0). The
    // expressions always produce a ratio of kFloatFactor and a number smaller
    // than kFloatFactor. kFloatFactor's value was chosen because floats have
    // a 23-bit mantissa, and operations with a larger factor would sacrifice
    // precision.
    ZX_DEBUG_ASSERT(rate_as_float >= 0.0f);
    Reduce(&subject_delta_, &reference_delta_);
  }

  TimelineRate(uint32_t subject_delta, uint32_t reference_delta)
      : subject_delta_(subject_delta), reference_delta_(reference_delta) {
    ZX_DEBUG_ASSERT(reference_delta != 0);
    Reduce(&subject_delta_, &reference_delta_);
  }

  // Determines whether this |TimelineRate| is invertible.
  bool invertible() const { return subject_delta_ != 0; }

  // Returns the inverse of the rate. DCHECKs if the subject_delta of this
  // rate is zero.
  TimelineRate Inverse() const {
    ZX_DEBUG_ASSERT(subject_delta_ != 0);

    // Note: TimelineRates should be always be in their reduced form.  Because
    // of this, we do not want to invoke the subject/reference constructor
    // (which will attempt to reduce the ratio).  Instead, use the default
    // constructor and just swap subject/reference.
    TimelineRate ret;
    ret.subject_delta_ = reference_delta_;
    ret.reference_delta_ = subject_delta_;
    return ret;
  }

  // Scales the value by this rate. Returns kOverflow on overflow.
  int64_t Scale(int64_t value) const { return Scale(value, subject_delta_, reference_delta_); }

  // Scales the value by the inverse of this rate.
  int64_t ScaleInverse(int64_t value) const {
    return Scale(value, reference_delta_, subject_delta_);
  }

  uint32_t subject_delta() const { return subject_delta_; }
  uint32_t reference_delta() const { return reference_delta_; }

 private:
  // A multiplier for float-to-TimelineRate conversions chosen because floats
  // have a 23-bit mantissa.
  static constexpr uint32_t kFloatFactor = 1ul << 23;

  uint32_t subject_delta_;
  uint32_t reference_delta_;
};

// Tests two rates for equality.
inline bool operator==(TimelineRate a, TimelineRate b) {
  return a.subject_delta() == b.subject_delta() && a.reference_delta() == b.reference_delta();
}

// Tests two rates for inequality.
inline bool operator!=(TimelineRate a, TimelineRate b) { return !(a == b); }

// Returns the ratio of the two rates. DCHECKs on loss of precision.
inline TimelineRate operator/(TimelineRate a, TimelineRate b) {
  return TimelineRate::Product(a, b.Inverse());
}

// Returns the product of the two rates. DCHECKs on loss of precision.
inline TimelineRate operator*(TimelineRate a, TimelineRate b) {
  return TimelineRate::Product(a, b);
}

// Returns the product of the rate and the int64_t. Returns kOverflow on
// overflow.
inline int64_t operator*(TimelineRate a, int64_t b) { return a.Scale(b); }

// Returns the product of the rate and the int64_t. Returns kOverflow on
// overflow.
inline int64_t operator*(int64_t a, TimelineRate b) { return b.Scale(a); }

// Returns the the int64_t divided by the rate. Returns kOverflow on
// overflow.
inline int64_t operator/(int64_t a, TimelineRate b) { return b.ScaleInverse(a); }

}  // namespace media

#endif  // LIB_MEDIA_CPP_TIMELINE_RATE_H_
