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_FUNCTION_H_ |
| 6 #define MOJO_SERVICES_MEDIA_COMMON_CPP_TIMELINE_FUNCTION_H_ |
| 7 |
| 8 #include "mojo/public/cpp/environment/logging.h" |
| 9 #include "mojo/services/media/common/cpp/timeline_rate.h" |
| 10 |
| 11 namespace mojo { |
| 12 namespace media { |
| 13 |
| 14 // TODO(dalesat): Consider always allowing inexact results. |
| 15 |
| 16 // A linear function from int64_t to int64_t with non-negative slope that |
| 17 // translates reference timeline values into subject timeline values (the |
| 18 // 'subject' being the timeline that's represented by the function). The |
| 19 // representation is in point-slope form. The point is represented as two |
| 20 // int64_t time values (reference_time, subject_time), and the slope (rate) is |
| 21 // represented as a TimelineRate, the ratio of two uint32_t values |
| 22 // (subject_delta / reference_delta). |
| 23 class TimelineFunction { |
| 24 public: |
| 25 // Applies a timeline function. |
| 26 static int64_t Apply( |
| 27 int64_t reference_time, |
| 28 int64_t subject_time, |
| 29 const TimelineRate& rate, // subject_delta / reference_delta |
| 30 int64_t reference_input); |
| 31 |
| 32 // Applies the inverse of a timeline function. |
| 33 static int64_t ApplyInverse( |
| 34 int64_t reference_time, |
| 35 int64_t subject_time, |
| 36 const TimelineRate& rate, // subject_delta / reference_delta |
| 37 int64_t subject_input) { |
| 38 MOJO_DCHECK(rate.reference_delta() != 0u); |
| 39 return Apply(subject_time, reference_time, rate.Inverse(), subject_input); |
| 40 } |
| 41 |
| 42 // Composes two timeline functions B->C and A->B producing A->C. If exact is |
| 43 // true, DCHECKs on loss of precision. |
| 44 static TimelineFunction Compose(const TimelineFunction& bc, |
| 45 const TimelineFunction& ab, |
| 46 bool exact = true); |
| 47 |
| 48 TimelineFunction() : reference_time_(0), subject_time_(0) {} |
| 49 |
| 50 TimelineFunction(int64_t reference_time, |
| 51 int64_t subject_time, |
| 52 uint32_t reference_delta, |
| 53 uint32_t subject_delta) |
| 54 : reference_time_(reference_time), |
| 55 subject_time_(subject_time), |
| 56 rate_(subject_delta, reference_delta) {} |
| 57 |
| 58 TimelineFunction(int64_t reference_time, |
| 59 int64_t subject_time, |
| 60 const TimelineRate& rate) // subject_delta / reference_delta |
| 61 : reference_time_(reference_time), |
| 62 subject_time_(subject_time), |
| 63 rate_(rate) {} |
| 64 |
| 65 explicit TimelineFunction( |
| 66 const TimelineRate& rate) // subject_delta / reference_delta |
| 67 : reference_time_(0), |
| 68 subject_time_(0), |
| 69 rate_(rate) {} |
| 70 |
| 71 // Applies the function. Returns TimelineRate::kOverflow on overflow. |
| 72 int64_t Apply(int64_t reference_input) const { |
| 73 return Apply(reference_time_, subject_time_, rate_, reference_input); |
| 74 } |
| 75 |
| 76 // Applies the inverse of the function. Returns TimelineRate::kOverflow on |
| 77 // overflow. |
| 78 int64_t ApplyInverse(int64_t subject_input) const { |
| 79 MOJO_DCHECK(rate_.reference_delta() != 0u); |
| 80 return ApplyInverse(reference_time_, subject_time_, rate_, subject_input); |
| 81 } |
| 82 |
| 83 // Applies the function. Returns TimelineRate::kOverflow on overflow. |
| 84 int64_t operator()(int64_t reference_input) const { |
| 85 return Apply(reference_input); |
| 86 } |
| 87 |
| 88 // Returns a timeline function that is the inverse if this timeline function. |
| 89 TimelineFunction Inverse() const { |
| 90 MOJO_DCHECK(rate_.reference_delta() != 0u); |
| 91 return TimelineFunction(subject_time_, reference_time_, rate_.Inverse()); |
| 92 } |
| 93 |
| 94 int64_t reference_time() const { return reference_time_; } |
| 95 |
| 96 int64_t subject_time() const { return subject_time_; } |
| 97 |
| 98 const TimelineRate& rate() const { return rate_; } |
| 99 |
| 100 uint32_t reference_delta() const { return rate_.reference_delta(); } |
| 101 |
| 102 uint32_t subject_delta() const { return rate_.subject_delta(); } |
| 103 |
| 104 private: |
| 105 int64_t reference_time_; |
| 106 int64_t subject_time_; |
| 107 TimelineRate rate_; // subject_delta / reference_delta |
| 108 }; |
| 109 |
| 110 // Tests two timeline functions for equality. Equality requires equal basis |
| 111 // values. |
| 112 inline bool operator==(const TimelineFunction& a, const TimelineFunction& b) { |
| 113 return a.reference_time() == b.reference_time() && |
| 114 a.subject_time() == b.subject_time() && a.rate() == b.rate(); |
| 115 } |
| 116 |
| 117 // Tests two timeline functions for inequality. Equality requires equal basis |
| 118 // values. |
| 119 inline bool operator!=(const TimelineFunction& a, const TimelineFunction& b) { |
| 120 return !(a == b); |
| 121 } |
| 122 |
| 123 // Composes two timeline functions B->C and A->B producing A->C. DCHECKs on |
| 124 // loss of precision. |
| 125 inline TimelineFunction operator*(const TimelineFunction& bc, |
| 126 const TimelineFunction& ab) { |
| 127 return TimelineFunction::Compose(bc, ab); |
| 128 } |
| 129 |
| 130 } // namespace media |
| 131 } // namespace mojo |
| 132 |
| 133 #endif // MOJO_SERVICES_MEDIA_COMMON_CPP_TIMELINE_FUNCTION_H_ |
OLD | NEW |