Tidy up HMSF handling in a few places.
authorCarl Hetherington <cth@carlh.net>
Sat, 20 Mar 2021 09:19:46 +0000 (10:19 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 20 Mar 2021 09:19:46 +0000 (10:19 +0100)
src/lib/dcpomatic_time.h
src/lib/reel_writer.cc
src/lib/writer.cc
src/wx/content_view.cc
src/wx/timecode.h

index 62d8a28ccf1ddee397e85ed014e77beb929fae92..00a31a7a7057ab5ece9f7ba4b26984bf0735f91d 100644 (file)
@@ -39,6 +39,26 @@ struct dcpomatic_time_floor_test;
 
 namespace dcpomatic {
 
+
+class HMSF
+{
+public:
+       HMSF () {}
+
+       HMSF (int h_, int m_, int s_, int f_)
+               : h(h_)
+               , m(m_)
+               , s(s_)
+               , f(f_)
+       {}
+
+       int h = 0;
+       int m = 0;
+       int s = 0;
+       int f = 0;
+};
+
+
 /** A time in seconds, expressed as a number scaled up by Time::HZ.  We want two different
  *  versions of this class, dcpomatic::ContentTime and dcpomatic::DCPTime, and we want it to be impossible to
  *  convert implicitly between the two.  Hence there's this template hack.  I'm not
@@ -67,6 +87,16 @@ public:
        /* Explicit conversion from type O */
        Time (Time<O, S> d, FrameRateChange f);
 
+       /** @param hmsf Hours, minutes, seconds, frames.
+        *  @param fps Frame rate
+        */
+       Time (HMSF const& hmsf, float fps) {
+               *this = from_seconds (hmsf.h * 3600)
+                       + from_seconds (hmsf.m * 60)
+                       + from_seconds (hmsf.s)
+                       + from_frames (hmsf.f, fps);
+       }
+
        Type get () const {
                return _t;
        }
@@ -170,39 +200,34 @@ public:
 
        /** Split a time into hours, minutes, seconds and frames.
         *  @param r Frames per second.
-        *  @param h Returned hours.
-        *  @param m Returned minutes.
-        *  @param s Returned seconds.
-        *  @param f Returned frames.
+        *  @return Split time.
         */
        template <typename T>
-       void split (T r, int& h, int& m, int& s, int& f) const
+       HMSF split (T r) 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_round (r);
+               auto ff = frames_round (r);
+               HMSF hmsf;
 
-               h = ff / (3600 * r);
-               ff -= h * 3600 * r;
-               m = ff / (60 * r);
-               ff -= m * 60 * r;
-               s = ff / r;
-               ff -= s * r;
+               hmsf.h = ff / (3600 * r);
+               ff -= hmsf.h * 3600 * r;
+               hmsf.m = ff / (60 * r);
+               ff -= hmsf.m * 60 * r;
+               hmsf.s = ff / r;
+               ff -= hmsf.s * r;
 
-               f = static_cast<int> (ff);
+               hmsf.f = static_cast<int> (ff);
+               return hmsf;
        }
 
        template <typename T>
        std::string timecode (T r) const {
-               int h;
-               int m;
-               int s;
-               int f;
-               split (r, h, m, s, f);
+               auto hmsf = split (r);
 
                char buffer[128];
-               snprintf (buffer, sizeof (buffer), "%02d:%02d:%02d:%02d", h, m, s, f);
+               snprintf (buffer, sizeof(buffer), "%02d:%02d:%02d:%02d", hmsf.h, hmsf.m, hmsf.s, hmsf.f);
                return buffer;
        }
 
index 1847073737605b3611eb76f2ab4e16f93ac90c32..294c0b7b64c85ecc214e1f0e8974c738d2134c2d 100644 (file)
@@ -691,10 +691,9 @@ ReelWriter::create_reel_markers (shared_ptr<dcp::Reel> reel) const
        if (!reel_markers.empty ()) {
                auto ma = make_shared<dcp::ReelMarkersAsset>(dcp::Fraction(film()->video_frame_rate(), 1), reel->duration(), 0);
                for (auto const& i: reel_markers) {
-                       int h, m, s, f;
                        DCPTime relative = i.second - _period.from;
-                       relative.split (film()->video_frame_rate(), h, m, s, f);
-                       ma->set (i.first, dcp::Time(h, m, s, f, film()->video_frame_rate()));
+                       auto hmsf = relative.split (film()->video_frame_rate());
+                       ma->set (i.first, dcp::Time(hmsf.h, hmsf.m, hmsf.s, hmsf.f, film()->video_frame_rate()));
                }
                reel->add (ma);
        }
index 035fc2b1dbfa3328acd67f3f9ccc110e53c788a4..54e7473e88e61c92313a0af3d2ad7ddadc56f523 100644 (file)
@@ -733,15 +733,14 @@ Writer::write_cover_sheet (boost::filesystem::path output_dcp)
        }
        boost::algorithm::replace_all (text, "$AUDIO", description);
 
-       int h, m, s, fr;
-       film()->length().split(film()->video_frame_rate(), h, m, s, fr);
+       auto const hmsf = film()->length().split(film()->video_frame_rate());
        string length;
-       if (h == 0 && m == 0) {
-               length = String::compose("%1s", s);
-       } else if (h == 0 && m > 0) {
-               length = String::compose("%1m%2s", m, s);
-       } else if (h > 0 && m > 0) {
-               length = String::compose("%1h%2m%3s", h, m, s);
+       if (hmsf.h == 0 && hmsf.m == 0) {
+               length = String::compose("%1s", hmsf.s);
+       } else if (hmsf.h == 0 && hmsf.m > 0) {
+               length = String::compose("%1m%2s", hmsf.m, hmsf.s);
+       } else if (hmsf.h > 0 && hmsf.m > 0) {
+               length = String::compose("%1h%2m%3s", hmsf.h, hmsf.m, hmsf.s);
        }
 
        boost::algorithm::replace_all (text, "$LENGTH", length);
index 44e575d9393bcc06a349d88901c1cb5b20021a10..b3a66a7bee500393c43dd535d302dd8c87a13eeb 100644 (file)
@@ -133,13 +133,12 @@ ContentView::add (shared_ptr<Content> content)
        wxListItem it;
        it.SetId(N);
        it.SetColumn(0);
-       DCPTime length = content->approximate_length ();
-       int h, m, s, f;
-       length.split (24, h, m, s, f);
-       it.SetText(wxString::Format("%02d:%02d:%02d", h, m, s));
+       auto length = content->approximate_length ();
+       auto const hmsf = length.split (24);
+       it.SetText(wxString::Format("%02d:%02d:%02d", hmsf.h, hmsf.m, hmsf.s));
        InsertItem(it);
 
-       shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(content);
+       auto dcp = dynamic_pointer_cast<DCPContent>(content);
        if (dcp && dcp->content_kind()) {
                it.SetId(N);
                it.SetColumn(1);
index 3746b32cd621a3fa4710b27bad1a76cd7db20899..3fe35981db6a8048e5e44a6ebb61efbbdc4939d5 100644 (file)
@@ -67,56 +67,45 @@ public:
 
        void set (T t, float fps)
        {
-               int h;
-               int m;
-               int s;
-               int f;
-               t.split (fps, h, m, s, f);
+               auto const hmsf = t.split (fps);
 
-               checked_set (_hours, dcp::raw_convert<std::string>(h));
-               checked_set (_minutes, dcp::raw_convert<std::string>(m));
-               checked_set (_seconds, dcp::raw_convert<std::string>(s));
-               checked_set (_frames, dcp::raw_convert<std::string>(f));
+               checked_set (_hours, dcp::raw_convert<std::string>(hmsf.h));
+               checked_set (_minutes, dcp::raw_convert<std::string>(hmsf.m));
+               checked_set (_seconds, dcp::raw_convert<std::string>(hmsf.s));
+               checked_set (_frames, dcp::raw_convert<std::string>(hmsf.f));
 
                checked_set (_fixed, t.timecode (fps));
        }
 
        void set_hint (T t, float fps)
        {
-               int h;
-               int m;
-               int s;
-               int f;
-               t.split (fps, h, m, s, f);
-
-               _hours->SetHint (std_to_wx(dcp::raw_convert<std::string>(h)));
-               _minutes->SetHint (std_to_wx(dcp::raw_convert<std::string>(m)));
-               _seconds->SetHint (std_to_wx(dcp::raw_convert<std::string>(s)));
-               _frames->SetHint (std_to_wx(dcp::raw_convert<std::string>(f)));
+               auto hmsf = t.split (fps);
+
+               _hours->SetHint (std_to_wx(dcp::raw_convert<std::string>(hmsf.h)));
+               _minutes->SetHint (std_to_wx(dcp::raw_convert<std::string>(hmsf.m)));
+               _seconds->SetHint (std_to_wx(dcp::raw_convert<std::string>(hmsf.s)));
+               _frames->SetHint (std_to_wx(dcp::raw_convert<std::string>(hmsf.f)));
        }
 
        T get (float fps) const
        {
-               T t;
-
                auto value_or_hint = [](wxTextCtrl const * t) {
-                       if (!t->GetValue().IsEmpty()) {
-                               return wx_to_std (t->GetValue());
-                       } else {
-                               return wx_to_std (t->GetHint());
+                       auto s = wx_to_std (t->GetValue().IsEmpty() ? t->GetHint() : t->GetValue());
+                       if (s.empty()) {
+                               return 0;
                        }
+                       return dcp::raw_convert<int>(s);
                };
 
-               std::string const h = value_or_hint (_hours);
-               t += T::from_seconds (dcp::raw_convert<int>(h.empty() ? "0" : h) * 3600);
-               std::string const m = value_or_hint (_minutes);
-               t += T::from_seconds (dcp::raw_convert<int>(m.empty() ? "0" : m) * 60);
-               std::string const s = value_or_hint (_seconds);
-               t += T::from_seconds (dcp::raw_convert<int>(s.empty() ? "0" : s));
-               std::string const f = value_or_hint (_frames);
-               t += T::from_frames (dcp::raw_convert<int>(f.empty() ? "0" : f), fps);
-
-               return t;
+               return T (
+                       {
+                               value_or_hint(_hours),
+                               value_or_hint(_minutes),
+                               value_or_hint(_seconds),
+                               value_or_hint(_frames)
+                       },
+                       fps
+                       );
        }
 };