X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fdcpomatic_time.h;h=a0bbad06aeaeeed6530d214551fcbd82ab3a4d4d;hb=bde76c3341775bd02da59932d285e14eade64ae0;hp=05b4e1a5d7d1d2061fe26327068632e03c79c78b;hpb=1b1bc528ee5ca1fee1bd33f9fb6f79cd551e3b33;p=dcpomatic.git diff --git a/src/lib/dcpomatic_time.h b/src/lib/dcpomatic_time.h index 05b4e1a5d..a0bbad06a 100644 --- a/src/lib/dcpomatic_time.h +++ b/src/lib/dcpomatic_time.h @@ -21,6 +21,9 @@ #define DCPOMATIC_TIME_H #include +#include +#include +#include #include #include "frame_rate_change.h" @@ -36,13 +39,15 @@ public: : _t (0) {} - explicit Time (int64_t t) + typedef int64_t Type; + + explicit Time (Type t) : _t (t) {} virtual ~Time () {} - int64_t get () const { + Type get () const { return _t; } @@ -55,14 +60,46 @@ public: return rint (_t * r / HZ); } - operator bool () const { - return _t != 0; + template + void split (T r, int& h, int& m, int& s, int& f) const + { + /* Do this calculation with frames so that we can round + to a frame boundary at the start rather than the end. + */ + int64_t ff = frames (r); + + h = ff / (3600 * r); + ff -= h * 3600 * r; + m = ff / (60 * r); + ff -= m * 60 * r; + s = ff / r; + ff -= s * r; + + f = static_cast (ff); + } + + template + std::string timecode (T r) const { + int h; + int m; + int s; + int f; + split (r, h, m, s, f); + + std::ostringstream o; + o.width (2); + o.fill ('0'); + o << std::setw(2) << std::setfill('0') << h << ":" + << std::setw(2) << std::setfill('0') << m << ":" + << std::setw(2) << std::setfill('0') << s << ":" + << std::setw(2) << std::setfill('0') << f; + return o.str (); } protected: friend class dcptime_round_up_test; - int64_t _t; + Type _t; static const int HZ = 96000; }; @@ -72,8 +109,8 @@ class ContentTime : public Time { public: ContentTime () : Time () {} - explicit ContentTime (int64_t t) : Time (t) {} - ContentTime (int64_t n, int64_t d) : Time (n * HZ / d) {} + explicit ContentTime (Type t) : Time (t) {} + ContentTime (Type n, Type d) : Time (n * HZ / d) {} ContentTime (DCPTime d, FrameRateChange f); bool operator< (ContentTime const & o) const { @@ -109,6 +146,10 @@ public: return *this; } + ContentTime operator- () const { + return ContentTime (-_t); + } + ContentTime operator- (ContentTime const & o) const { return ContentTime (_t - o._t); } @@ -118,21 +159,58 @@ public: return *this; } + /** Round up to the nearest sampling interval + * at some sampling rate. + * @param r Sampling rate. + */ + ContentTime round_up (float r) { + Type const n = rint (HZ / r); + Type const a = _t + n - 1; + return ContentTime (a - (a % n)); + } + static ContentTime from_seconds (double s) { return ContentTime (s * HZ); } template static ContentTime from_frames (int64_t f, T r) { + assert (r > 0); return ContentTime (f * HZ / r); } + + static ContentTime max () { + return ContentTime (INT64_MAX); + } +}; + +std::ostream& operator<< (std::ostream& s, ContentTime t); + +class ContentTimePeriod +{ +public: + ContentTimePeriod () {} + ContentTimePeriod (ContentTime f, ContentTime t) + : from (f) + , to (t) + {} + + ContentTime from; + ContentTime to; + + ContentTimePeriod operator+ (ContentTime const & o) const { + return ContentTimePeriod (from + o, to + o); + } + + bool overlaps (ContentTimePeriod const & o) const; + bool contains (ContentTime const & o) const; }; class DCPTime : public Time { public: DCPTime () : Time () {} - explicit DCPTime (int64_t t) : Time (t) {} + explicit DCPTime (Type t) : Time (t) {} DCPTime (ContentTime t, FrameRateChange c) : Time (rint (t.get() / c.speed_up)) {} bool operator< (DCPTime const & o) const { @@ -168,6 +246,10 @@ public: return *this; } + DCPTime operator- () const { + return DCPTime (-_t); + } + DCPTime operator- (DCPTime const & o) const { return DCPTime (_t - o._t); } @@ -181,9 +263,9 @@ public: * at some sampling rate. * @param r Sampling rate. */ - DCPTime round_up (int r) { - int64_t const n = HZ / r; - int64_t const a = _t + n - 1; + DCPTime round_up (float r) { + Type const n = rint (HZ / r); + Type const a = _t + n - 1; return DCPTime (a - (a % n)); } @@ -197,6 +279,7 @@ public: template static DCPTime from_frames (int64_t f, T r) { + assert (r > 0); return DCPTime (f * HZ / r); } @@ -210,5 +293,6 @@ public: }; DCPTime min (DCPTime a, DCPTime b); +std::ostream& operator<< (std::ostream& s, DCPTime t); #endif