diff options
Diffstat (limited to 'src/lib/dcpomatic_time.cc')
| -rw-r--r-- | src/lib/dcpomatic_time.cc | 294 |
1 files changed, 271 insertions, 23 deletions
diff --git a/src/lib/dcpomatic_time.cc b/src/lib/dcpomatic_time.cc index 60fc5342a..a969f4c19 100644 --- a/src/lib/dcpomatic_time.cc +++ b/src/lib/dcpomatic_time.cc @@ -20,10 +20,13 @@ #include "dcpomatic_time.h" +#include <dcp/raw_convert.h> +#include <boost/algorithm/string.hpp> #include <inttypes.h> using std::string; +using std::vector; using namespace dcpomatic; @@ -47,14 +50,6 @@ dcpomatic::operator<=(HMSF const& a, HMSF const& b) template <> -Time<ContentTimeDifferentiator, DCPTimeDifferentiator>::Time (DCPTime d, FrameRateChange f) - : _t (llrint(d.get() * f.speed_up)) -{ - -} - - -template <> Time<DCPTimeDifferentiator, ContentTimeDifferentiator>::Time (ContentTime d, FrameRateChange f) : _t (llrint(d.get() / f.speed_up)) { @@ -119,27 +114,280 @@ dcpomatic::to_string (ContentTime t) } +DCPTime::DCPTime(Type num) + : _num(num) + , _den(96000) +{ + +} + + +DCPTime::DCPTime(Type num, Type den) + : _num(num) + , _den(den) +{ + DCPOMATIC_ASSERT(_den); +} + + +DCPTime::DCPTime(ContentTime time, FrameRateChange frc) + : _num(llrint(time.get() / frc.speed_up)) + , _den(ContentTime::HZ) +{ + +} + + +DCPTime::DCPTime(string const& serializable_string) +{ + vector<string> parts; + boost::algorithm::split(parts, serializable_string, boost::is_any_of("_")); + if (parts.size() == 1) { + _num = dcp::raw_convert<int64_t>(parts[0]); + _den = 96000; + } else { + _num = dcp::raw_convert<int64_t>(parts[0]); + _den = dcp::raw_convert<int64_t>(parts[1]); + } +} + + +DCPTime::DCPTime(HMSF const& hmsf, float fps) +{ + *this = from_seconds(hmsf.h * 3600) + + from_seconds(hmsf.m * 60) + + from_seconds(hmsf.s) + + DCPTime(hmsf.f * 1000, fps * 1000); +} + + string -dcpomatic::to_string (DCPTime t) +DCPTime::to_serialisable_string() const { - char buffer[64]; -#ifdef DCPOMATIC_WINDOWS - __mingw_snprintf (buffer, sizeof(buffer), "[DCP %" PRId64 " %fs]", t.get(), t.seconds()); -#else - snprintf (buffer, sizeof(buffer), "[DCP %" PRId64 " %fs]", t.get(), t.seconds()); -#endif - return buffer; + return fmt::format("{}_{}", _num, _den); } string -dcpomatic::to_string (DCPTimePeriod p) +DCPTime::to_debug_string() const { - char buffer[64]; -#ifdef DCPOMATIC_WINDOWS - __mingw_snprintf (buffer, sizeof(buffer), "[DCP %" PRId64 " %fs -> %" PRId64 " %fs]", p.from.get(), p.from.seconds(), p.to.get(), p.to.seconds()); -#else - snprintf (buffer, sizeof(buffer), "[DCP %" PRId64 " %fs -> %" PRId64 " %fs]", p.from.get(), p.from.seconds(), p.to.get(), p.to.seconds()); -#endif + return fmt::format("[{}/{} {}]", _num, _den, seconds()); +} + + +double +DCPTime::seconds() const +{ + return static_cast<double>(_num) / _den; +} + +bool +DCPTime::operator<(DCPTime const& o) const +{ + DCPOMATIC_ASSERT(_den == o._den); + return _num < o._num; +} + + +bool +DCPTime::operator<=(DCPTime const& o) const +{ + DCPOMATIC_ASSERT(_den == o._den); + return _num <= o._num; +} + + +bool +DCPTime::operator==(DCPTime const& o) const +{ + DCPOMATIC_ASSERT(_den == o._den); + return _num == o._num; +} + + +bool +DCPTime::operator!=(DCPTime const& o) const +{ + DCPOMATIC_ASSERT(_den == o._den); + return _num != o._num; +} + + +bool +DCPTime::operator>=(DCPTime const& o) const +{ + DCPOMATIC_ASSERT(_den == o._den); + return _num >= o._num; +} + + +bool +DCPTime::operator>(DCPTime const& o) const +{ + DCPOMATIC_ASSERT(_den == o._den); + return _num > o._num; +} + + +int64_t +DCPTime::frames_floor(int r) const +{ + return (_num * r) / _den; +} + + +int64_t +DCPTime::frames_round(int r) const +{ + return ((_num * r) + (r / 2)) / _den; +} + + +int64_t +DCPTime::frames_ceil(int r) const +{ + return ((_num + 1) * r) / _den; +} + + +DCPTime +DCPTime::operator+(DCPTime const& o) const +{ + DCPOMATIC_ASSERT(_den == o._den); + return DCPTime(_num + o._num, _den); +} + + +DCPTime& +DCPTime::operator+=(DCPTime const& o) +{ + DCPOMATIC_ASSERT(_den == o._den); + _num += o._num; + return *this; +} + + +DCPTime +DCPTime::operator-(DCPTime const& o) const +{ + DCPOMATIC_ASSERT(_den == o._den); + return DCPTime(_num - o._num, _den); +} + + +DCPTime +DCPTime::operator-() const +{ + return DCPTime(-_num, _den); +} + + +DCPTime& +DCPTime::operator-=(DCPTime const& o) +{ + DCPOMATIC_ASSERT(_den == o._den); + _num -= o._num; + return *this; +} + + +DCPTime +DCPTime::operator*(int o) const +{ + return DCPTime(_num * o, _den); +} + + +DCPTime +DCPTime::operator/(int o) const +{ + return DCPTime(_num, _den * o); +} + + +DCPTime::operator bool() const +{ + return _num != 0; +} + + +DCPTime +DCPTime::max() const +{ + return DCPTime(INT64_MAX, _den); +} + + +DCPTime +DCPTime::from_seconds(double s) +{ + return DCPTime(s * 96000, 96000); +} + + +DCPTime +DCPTime::floor(int r) const +{ + return DCPTime(frames_floor(r), r); +} + + +DCPTime +DCPTime::round(int r) const +{ + return DCPTime(frames_round(r), r); +} + + +DCPTime +DCPTime::ceil(int r) const +{ + return DCPTime(frames_ceil(r), r); +} + + +DCPTime +DCPTime::abs() const +{ + return DCPTime(std::abs(_num), _den); +} + + +HMSF +DCPTime::splitX(int r) const +{ + /* Do this calculation with frames so that we can round + to a frame boundary at the start rather than the end. + */ + auto ff = frames_round(r); + HMSF hmsf; + + hmsf.h = ff / (3600 * r); + ff -= static_cast<int64_t>(hmsf.h) * 3600 * r; + hmsf.m = ff / (60 * r); + ff -= static_cast<int64_t>(hmsf.m) * 60 * r; + hmsf.s = ff / r; + ff -= static_cast<int64_t>(hmsf.s) * r; + + hmsf.f = static_cast<int>(ff); + return hmsf; +} + + +string +DCPTime::timecodeX(int r) const +{ + auto hmsf = splitX(r); + + char buffer[128]; + snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d:%02d", hmsf.h, hmsf.m, hmsf.s, hmsf.f); return buffer; } + + +ContentTime +DCPTime::content_time(FrameRateChange frc) const +{ + return ContentTime(frames_round(ContentTime::HZ) * frc.speed_up); +} + |
