summaryrefslogtreecommitdiff
path: root/src/sub_time.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/sub_time.cc')
-rw-r--r--src/sub_time.cc160
1 files changed, 159 insertions, 1 deletions
diff --git a/src/sub_time.cc b/src/sub_time.cc
index 780dbc9..9c7b98b 100644
--- a/src/sub_time.cc
+++ b/src/sub_time.cc
@@ -86,6 +86,46 @@ Time::from_hmsm (int h, int m, int s, int ms)
return Time (h, m, s, ms, optional<int> (), optional<FrameRate> ());
}
+Time
+Time::from_frames (int64_t f, FrameRate r)
+{
+ double s = f / enum_to_value (r);
+ int const hours = floor (s / 3600);
+ s -= hours * 3600;
+ int const minutes = floor (s / 60);
+ s -= minutes * 60;
+ int const seconds = floor (s);
+ s -= seconds;
+ int const frames = rint (s * enum_to_value (r));
+
+ return Time::from_hmsf (hours, minutes, seconds, frames, r);
+}
+
+Time
+Time::from_milliseconds (int64_t m)
+{
+ int const hours = m / 3600000;
+ m -= hours * 3600000;
+ int const minutes = m / 60000;
+ m -= minutes * 60000;
+ int const seconds = m / 1000;
+ m -= seconds * 1000;
+
+ return Time (hours, minutes, seconds, m, optional<int> (), optional<FrameRate> ());
+}
+
+bool
+Time::operator<= (Time const & other) const
+{
+ return *this < other || *this == other;
+}
+
+bool
+Time::operator>= (Time const & other) const
+{
+ return *this > other || *this == other;
+}
+
bool
Time::operator< (Time const & other) const
{
@@ -159,7 +199,7 @@ Time::operator== (Time const & other) const
}
/* Otherwise we have to do it by comparing milliseconds */
- return abs (as_milliseconds() - other.as_milliseconds()) <= 1;
+ return as_milliseconds() == other.as_milliseconds();
}
bool
@@ -184,6 +224,124 @@ sub::operator<< (ostream& s, Time const & t)
return s;
}
+Time
+sub::operator+ (Time const & a, Time const & b)
+{
+ int seconds = 0;
+ int minutes = 0;
+ int hours = 0;
+
+ optional<int> frames;
+ optional<FrameRate> frame_rate;
+ optional<int> milliseconds;
+
+ if (a._frames && b._frames) {
+ if (!a._frame_rate || !b._frame_rate) {
+ throw UnknownFrameRateException ();
+ }
+ if (a._frame_rate.get() != b._frame_rate.get()) {
+ throw MismatchedFrameRateException ();
+ }
+
+ frame_rate = a._frame_rate.get ();
+ frames = a._frames.get() + b._frames.get();
+ if (frames.get() >= enum_to_value (frame_rate.get ())) {
+ frames = frames.get() - enum_to_value (frame_rate.get ());
+ ++seconds;
+ }
+ } else if (a._milliseconds && b._milliseconds) {
+ milliseconds = a._milliseconds.get() + b._milliseconds.get();
+ if (milliseconds >= 1000) {
+ milliseconds = milliseconds.get() - 1000;
+ ++seconds;
+ }
+ } else {
+ return Time::from_milliseconds (a.as_milliseconds() + b.as_milliseconds());
+ }
+
+ seconds += a.seconds + b.seconds;
+ if (seconds >= 60) {
+ seconds -= 60;
+ ++minutes;
+ }
+
+ minutes += a.minutes + b.minutes;
+ if (minutes >= 60) {
+ minutes -= 60;
+ ++hours;
+ }
+
+ hours += a.hours + b.hours;
+
+ if (frames) {
+ return sub::Time (hours, minutes, seconds, optional<int> (), frames.get(), frame_rate.get());
+ } else {
+ return sub::Time (hours, minutes, seconds, milliseconds.get(), optional<int> (), optional<FrameRate> ());
+ }
+}
+
+Time
+sub::operator- (Time const & a, Time const & b)
+{
+ int seconds = 0;
+ int minutes = 0;
+ int hours = 0;
+
+ optional<int> frames;
+ optional<FrameRate> frame_rate;
+ optional<int> milliseconds;
+
+ if (a._frames && b._frames) {
+ if (!a._frame_rate || !b._frame_rate) {
+ throw UnknownFrameRateException ();
+ }
+ if (a._frame_rate.get() != b._frame_rate.get()) {
+ throw MismatchedFrameRateException ();
+ }
+
+ frame_rate = a._frame_rate.get ();
+ frames = a._frames.get() - b._frames.get();
+ if (frames.get() < 0) {
+ frames = frames.get() + enum_to_value (frame_rate.get ());
+ --seconds;
+ }
+ } else if (a._milliseconds && b._milliseconds) {
+ milliseconds = a._milliseconds.get() - b._milliseconds.get();
+ if (milliseconds < 0) {
+ milliseconds = milliseconds.get() + 1000;
+ --seconds;
+ }
+ } else {
+ return Time::from_milliseconds (a.as_milliseconds() - b.as_milliseconds());
+ }
+
+ seconds += a.seconds - b.seconds;
+ if (seconds < 0) {
+ seconds += 60;
+ --minutes;
+ }
+
+ minutes += a.minutes - b.minutes;
+ if (minutes < 0) {
+ minutes += 60;
+ --hours;
+ }
+
+ hours += a.hours - b.hours;
+
+ if (frames) {
+ return sub::Time (hours, minutes, seconds, optional<int> (), frames.get(), frame_rate.get());
+ } else {
+ return sub::Time (hours, minutes, seconds, milliseconds.get(), optional<int> (), optional<FrameRate> ());
+ }
+}
+
+double
+sub::operator/ (Time const & a, Time const & b)
+{
+ return double (a.as_milliseconds()) / b.as_milliseconds();
+}
+
Time::Time (int h, int m, int s, optional<int> ms, optional<int> f, optional<FrameRate> r)
: hours (h)
, minutes (m)