OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef MOJO_SERVICES_MEDIA_COMMON_CPP_TIMELINE_RATE_H_ |
| 6 #define MOJO_SERVICES_MEDIA_COMMON_CPP_TIMELINE_RATE_H_ |
| 7 |
| 8 #include <stdint.h> |
| 9 |
| 10 #include <limits> |
| 11 |
| 12 #include "mojo/public/cpp/environment/logging.h" |
| 13 |
| 14 namespace mojo { |
| 15 namespace media { |
| 16 |
| 17 // TODO(dalesat): Consider always allowing inexact results. |
| 18 |
| 19 // Expresses the relative rate of a timeline as the ratio between two uint32_t |
| 20 // values subject_delta / reference_delta. "subject" refers to the timeline |
| 21 // whose rate is being represented, and "reference" refers to the timeline |
| 22 // relative to which the rate is expressed. |
| 23 class TimelineRate { |
| 24 public: |
| 25 // Used to indicate overflow of scaling operations. |
| 26 static constexpr int64_t kOverflow = std::numeric_limits<int64_t>::max(); |
| 27 |
| 28 // Reduces the ratio of *subject_delta and *reference_delta. |
| 29 static void Reduce(uint32_t* subject_delta, uint32_t* reference_delta); |
| 30 |
| 31 // Produces the product of the rates. If exact is true, DCHECKs on loss of |
| 32 // precision. |
| 33 static void Product(uint32_t a_subject_delta, |
| 34 uint32_t a_reference_delta, |
| 35 uint32_t b_subject_delta, |
| 36 uint32_t b_reference_delta, |
| 37 uint32_t* product_subject_delta, |
| 38 uint32_t* product_reference_delta, |
| 39 bool exact = true); |
| 40 |
| 41 // Produces the product of the rates and the int64_t as an int64_t. Returns |
| 42 // kOverflow on overflow. |
| 43 static int64_t Scale(int64_t value, |
| 44 uint32_t subject_delta, |
| 45 uint32_t reference_delta); |
| 46 |
| 47 // Returns the product of the rates. If exact is true, DCHECKs on loss of |
| 48 // precision. |
| 49 static TimelineRate Product(const TimelineRate& a, |
| 50 const TimelineRate& b, |
| 51 bool exact = true) { |
| 52 uint32_t result_subject_delta; |
| 53 uint32_t result_reference_delta; |
| 54 Product(a.subject_delta(), a.reference_delta(), b.subject_delta(), |
| 55 b.reference_delta(), &result_subject_delta, &result_reference_delta, |
| 56 exact); |
| 57 return TimelineRate(result_subject_delta, result_reference_delta); |
| 58 } |
| 59 |
| 60 TimelineRate() : subject_delta_(0), reference_delta_(1) {} |
| 61 |
| 62 explicit TimelineRate(uint32_t subject_delta) |
| 63 : subject_delta_(subject_delta), reference_delta_(1) {} |
| 64 |
| 65 TimelineRate(uint32_t subject_delta, uint32_t reference_delta) |
| 66 : subject_delta_(subject_delta), reference_delta_(reference_delta) { |
| 67 MOJO_DCHECK(reference_delta != 0); |
| 68 Reduce(&subject_delta_, &reference_delta_); |
| 69 } |
| 70 |
| 71 // Returns the inverse of the rate. DCHECKs if the subject_delta of this |
| 72 // rate is zero. |
| 73 TimelineRate Inverse() const { |
| 74 MOJO_DCHECK(subject_delta_ != 0); |
| 75 return TimelineRate(reference_delta_, subject_delta_); |
| 76 } |
| 77 |
| 78 // Scales the value by this rate. Returns kOverflow on overflow. |
| 79 int64_t Scale(int64_t value) const { |
| 80 return Scale(value, subject_delta_, reference_delta_); |
| 81 } |
| 82 |
| 83 uint32_t subject_delta() const { return subject_delta_; } |
| 84 uint32_t reference_delta() const { return reference_delta_; } |
| 85 |
| 86 private: |
| 87 uint32_t subject_delta_; |
| 88 uint32_t reference_delta_; |
| 89 }; |
| 90 |
| 91 // Tests two rates for equality. |
| 92 inline bool operator==(const TimelineRate& a, const TimelineRate& b) { |
| 93 return a.subject_delta() == b.subject_delta() && |
| 94 a.reference_delta() == b.reference_delta(); |
| 95 } |
| 96 |
| 97 // Tests two rates for inequality. |
| 98 inline bool operator!=(const TimelineRate& a, const TimelineRate& b) { |
| 99 return !(a == b); |
| 100 } |
| 101 |
| 102 // Returns the product of the two rates. DCHECKs on loss of precision. |
| 103 inline TimelineRate operator*(const TimelineRate& a, const TimelineRate& b) { |
| 104 return TimelineRate::Product(a, b); |
| 105 } |
| 106 |
| 107 // Returns the product of the rate and the int64_t. Returns kOverflow on |
| 108 // overflow. |
| 109 inline int64_t operator*(const TimelineRate& a, int64_t b) { |
| 110 return a.Scale(b); |
| 111 } |
| 112 |
| 113 // Returns the product of the rate and the int64_t. Returns kOverflow on |
| 114 // overflow. |
| 115 inline int64_t operator*(int64_t a, const TimelineRate& b) { |
| 116 return b.Scale(a); |
| 117 } |
| 118 |
| 119 // Returns the the int64_t divided by the rate. Returns kOverflow on |
| 120 // overflow. |
| 121 inline int64_t operator/(int64_t a, const TimelineRate& b) { |
| 122 return b.Inverse().Scale(a); |
| 123 } |
| 124 |
| 125 } // namespace media |
| 126 } // namespace mojo |
| 127 |
| 128 #endif // MOJO_SERVICES_MEDIA_COMMON_CPP_TIMELINE_RATE_H_ |
OLD | NEW |