Index: mojo/services/media/common/cpp/timeline_rate.h |
diff --git a/mojo/services/media/common/cpp/timeline_rate.h b/mojo/services/media/common/cpp/timeline_rate.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7aa021622b0b09e04e1381d497c7ab5239ca256b |
--- /dev/null |
+++ b/mojo/services/media/common/cpp/timeline_rate.h |
@@ -0,0 +1,128 @@ |
+// Copyright 2016 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. |
+ |
+#ifndef MOJO_SERVICES_MEDIA_COMMON_CPP_TIMELINE_RATE_H_ |
+#define MOJO_SERVICES_MEDIA_COMMON_CPP_TIMELINE_RATE_H_ |
+ |
+#include <stdint.h> |
+ |
+#include <limits> |
+ |
+#include "mojo/public/cpp/environment/logging.h" |
+ |
+namespace mojo { |
+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 { |
+ public: |
+ // Used to indicate overflow of scaling operations. |
+ static constexpr int64_t kOverflow = std::numeric_limits<int64_t>::max(); |
+ |
+ // 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(const TimelineRate& a, |
+ const 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) {} |
+ |
+ TimelineRate(uint32_t subject_delta, uint32_t reference_delta) |
+ : subject_delta_(subject_delta), reference_delta_(reference_delta) { |
+ MOJO_DCHECK(reference_delta != 0); |
+ Reduce(&subject_delta_, &reference_delta_); |
+ } |
+ |
+ // Returns the inverse of the rate. DCHECKs if the subject_delta of this |
+ // rate is zero. |
+ TimelineRate Inverse() const { |
+ MOJO_DCHECK(subject_delta_ != 0); |
+ return TimelineRate(reference_delta_, subject_delta_); |
+ } |
+ |
+ // Scales the value by this rate. Returns kOverflow on overflow. |
+ int64_t Scale(int64_t value) const { |
+ return Scale(value, subject_delta_, reference_delta_); |
+ } |
+ |
+ uint32_t subject_delta() const { return subject_delta_; } |
+ uint32_t reference_delta() const { return reference_delta_; } |
+ |
+ private: |
+ uint32_t subject_delta_; |
+ uint32_t reference_delta_; |
+}; |
+ |
+// Tests two rates for equality. |
+inline bool operator==(const TimelineRate& a, const TimelineRate& b) { |
+ return a.subject_delta() == b.subject_delta() && |
+ a.reference_delta() == b.reference_delta(); |
+} |
+ |
+// Tests two rates for inequality. |
+inline bool operator!=(const TimelineRate& a, const TimelineRate& b) { |
+ return !(a == b); |
+} |
+ |
+// Returns the product of the two rates. DCHECKs on loss of precision. |
+inline TimelineRate operator*(const TimelineRate& a, const 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*(const 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, const 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, const TimelineRate& b) { |
+ return b.Inverse().Scale(a); |
+} |
+ |
+} // namespace media |
+} // namespace mojo |
+ |
+#endif // MOJO_SERVICES_MEDIA_COMMON_CPP_TIMELINE_RATE_H_ |