Fix handling of timing in SMPTE subtitles.
authorCarl Hetherington <cth@carlh.net>
Sat, 10 Jan 2015 00:07:47 +0000 (00:07 +0000)
committerCarl Hetherington <cth@carlh.net>
Sat, 10 Jan 2015 00:07:47 +0000 (00:07 +0000)
14 files changed:
TO_PORT [new file with mode: 0644]
src/dcp_time.cc
src/dcp_time.h
src/font.cc
src/font.h
src/interop_subtitle_content.cc
src/smpte_subtitle_content.cc
src/subtitle.cc
src/subtitle.h
src/text.cc
src/text.h
test/dcp_time_test.cc
test/subtitle_test.cc
test/text_test.cc

diff --git a/TO_PORT b/TO_PORT
new file mode 100644 (file)
index 0000000..1f23b04
--- /dev/null
+++ b/TO_PORT
@@ -0,0 +1 @@
+SMPTE editable units stuff
\ No newline at end of file
index 4033e5dd5f3a4671b97e797c53e214876deec949..83a7f2bbf37f01699c37de357243a97a85c1589e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -33,31 +33,23 @@ using namespace std;
 using namespace boost;
 using namespace dcp;
 
-Time::Time (int frame, int frames_per_second)
+Time::Time (int frame, int frames_per_second, int tcr_)
        : h (0)
        , m (0)
        , s (0)
-       , t (0)
+       , e (0)
+       , tcr (tcr_)
 {
-       set (double (frame) / frames_per_second);
-}
-
-Time::Time (int64_t ticks)
-{
-       h = ticks / (60 * 60 * 250);
-       ticks -= int64_t (h) * 60 * 60 * 250;
-       m = ticks / (60 * 250);
-       ticks -= int64_t (m) * 60 * 250;
-       s = ticks / 250;
-       ticks -= int64_t (s) * 250;
-       t = ticks;
+       set (double (frame) / frames_per_second, tcr);
 }
 
 void
-Time::set (double ss)
+Time::set (double seconds, int tcr_)
 {
-       s = floor (ss);
-       t = int (round (1000 * (ss - s) / 4));
+       s = floor (seconds);
+       tcr = tcr_;
+       
+       e = int (round ((seconds - s) * tcr));
 
        if (s >= 60) {
                m = s / 60;
@@ -70,7 +62,8 @@ Time::set (double ss)
        }
 }
 
-Time::Time (string time)
+Time::Time (string time, int tcr_)
+       : tcr (tcr_)
 {
        vector<string> b;
        split (b, time, is_any_of (":"));
@@ -81,13 +74,13 @@ Time::Time (string time)
        h = raw_convert<int> (b[0]);
        m = raw_convert<int> (b[1]);
        s = raw_convert<int> (b[2]);
-       t = raw_convert<int> (b[3]);
+       e = raw_convert<int> (b[3]);
 }
 
 bool
 dcp::operator== (Time const & a, Time const & b)
 {
-       return (a.h == b.h && a.m == b.m && a.s == b.s && a.t == b.t);
+       return (a.h == b.h && a.m == b.m && a.s == b.s && (a.e * b.tcr) == (b.e * a.tcr));
 }
 
 bool
@@ -123,8 +116,8 @@ dcp::operator< (Time const & a, Time const & b)
                return a.s < b.s;
        }
 
-       if (a.t != b.t) {
-               return a.t < b.t;
+       if ((a.e * b.tcr) != (b.e * a.tcr)) {
+               return (a.e * b.tcr) < (b.e * a.tcr);
        }
 
        return true;
@@ -145,8 +138,8 @@ dcp::operator> (Time const & a, Time const & b)
                return a.s > b.s;
        }
 
-       if (a.t != b.t) {
-               return a.t > b.t;
+       if ((a.e * b.tcr) != (b.e * a.tcr)) {
+               return (a.e * b.tcr) > (b.e * a.tcr);
        }
 
        return true;
@@ -155,18 +148,27 @@ dcp::operator> (Time const & a, Time const & b)
 ostream &
 dcp::operator<< (ostream& s, Time const & t)
 {
-       s << t.h << ":" << t.m << ":" << t.s << "." << t.t;
+       s << t.h << ":" << t.m << ":" << t.s << "." << t.e;
        return s;
 }
 
 dcp::Time
-dcp::operator+ (Time a, Time const & b)
+dcp::operator+ (Time a, Time b)
 {
        Time r;
 
-       r.t = a.t + b.t;
-       if (r.t >= 250) {
-               r.t -= 250;
+       /* Make sure we have a common tcr */
+       if (a.tcr != b.tcr) {
+               a.e *= b.tcr;
+               b.e *= a.tcr;
+               r.tcr = a.tcr * b.tcr;
+       } else {
+               r.tcr = a.tcr;
+       }
+
+       r.e = a.e + b.e;
+       if (r.e >= r.tcr) {
+               r.e -= r.tcr;
                r.s++;
        }
 
@@ -188,13 +190,22 @@ dcp::operator+ (Time a, Time const & b)
 }
 
 dcp::Time
-dcp::operator- (Time a, Time const & b)
+dcp::operator- (Time a, Time b)
 {
        Time r;
 
-       r.t = a.t - b.t;
-       if (r.t < 0) {
-               r.t += 250;
+       /* Make sure we have a common tcr */
+       if (a.tcr != b.tcr) {
+               a.e *= b.tcr;
+               b.e *= a.tcr;
+               r.tcr = a.tcr * b.tcr;
+       } else {
+               r.tcr = a.tcr;
+       }
+       
+       r.e = a.e - b.e;
+       if (r.e < 0) {
+               r.e += r.tcr;
                r.s--;
        }
 
@@ -218,29 +229,22 @@ dcp::operator- (Time a, Time const & b)
 float
 dcp::operator/ (Time a, Time const & b)
 {
-       int64_t const at = a.h * 3600 * 250 + a.m * 60 * 250 + a.s * 250 + a.t;
-       int64_t const bt = b.h * 3600 * 250 + b.m * 60 * 250 + b.s * 250 + b.t;
+       int64_t const at = a.h * 3600 + a.m * 60 + a.s * float (a.e) / a.tcr;
+       int64_t const bt = b.h * 3600 + b.m * 60 + b.s * float (b.e) / b.tcr;
        return float (at) / bt;
 }
 
-/** @return A string of the form h:m:s:t */
+/** @return A string of the form h:m:s:e */
 string
 Time::to_string () const
 {
        stringstream str;
-       str << h << ":" << m << ":" << s << ":" << t;
+       str << h << ":" << m << ":" << s << ":" << e;
        return str.str ();
 }
 
-/** @return This time in ticks */
 int64_t
-Time::to_ticks () const
-{
-       return int64_t(t) + int64_t(s) * 250 + int64_t(m) * 60 * 250 + int64_t(h) * 60 * 60 * 250;
-}
-
-double
-Time::to_seconds () const
+Time::to_editable_units (int tcr_) const
 {
-       return double (to_ticks ()) / 250;
+       return (int64_t(e) * float (tcr_ / tcr)) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_;
 }
index 70bc55735111e297ae14f7f98479f7d5ab44be5b..23f860cf084fb678a6c79e8eb327cf419d2dd53d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -37,41 +37,41 @@ namespace dcp {
 class Time
 {
 public:
-       Time () : h (0), m (0), s (0), t (0) {}
+       Time () : h (0), m (0), s (0), e (0), tcr (1) {}
 
-       Time (int64_t ticks);
-
-       /** Construct a Time from a frame index (starting from 0)
-        *  and a frames per second count.
+       /** Construct a Time from a frame index (starting from 0),
+        *  a frames per second count and a timecode rate.
         */
-       Time (int frame, int frames_per_second);
+       Time (int frame, int frames_per_second, int tcr);
 
-       /** Construct a Time from hours, minutes, seconds and ticks.
+       /** Construct a Time from hours, minutes, seconds, editable units and a timecode rate.
         *  @param h_ Hours.
         *  @param m_ Minutes.
         *  @param s_ Seconds.
-        *  @param t_ Ticks (where 1 tick is 4 milliseconds).
+        *  @param e_ Editable units (where 1 editable unit is 1 / tcr_ seconds)
+        *  @param tcr_ Timecode rate; i.e. number of editable units per second.
         */
-       Time (int h_, int m_, int s_, int t_)
+       Time (int h_, int m_, int s_, int e_, int tcr_)
                : h (h_)
                , m (m_)
                , s (s_)
-               , t (t_)
+               , e (e_)
+               , tcr (tcr_)
        {}
 
-       Time (std::string time);
+       Time (std::string time, int tcr);
 
-       int h; ///< hours
-       int m; ///< minutes
-       int s; ///< seconds
-       int t; ///< `ticks', where 1 tick is 4 milliseconds
+       int h; ///<   hours
+       int m; ///<   minutes
+       int s; ///<   seconds
+       int e; ///<   editable units (where 1 editable unit is 1 / tcr_ seconds)
+       int tcr; ///< timecode rate: the number of editable units per second.
 
        std::string to_string () const;
-       int64_t to_ticks () const;
-       double to_seconds () const;
+       int64_t to_editable_units (int tcr_) const;
 
 private:
-       void set (double);
+       void set (double seconds, int tcr);
 };
 
 extern bool operator== (Time const & a, Time const & b);
@@ -81,8 +81,8 @@ extern bool operator< (Time const & a, Time const & b);
 extern bool operator> (Time const & a, Time const & b);
 extern bool operator>= (Time const & a, Time const & b);
 extern std::ostream & operator<< (std::ostream & s, Time const & t);
-extern Time operator+ (Time a, Time const & b);        
-extern Time operator- (Time a, Time const & b);
+extern Time operator+ (Time a, Time b);        
+extern Time operator- (Time a, Time b);
 extern float operator/ (Time a, Time const & b);
 
 }
index 99f49f90436b3223bdb0a8cc9b51514016c8cd48..8656e9090e0cf13c5eb1fe6e00242a7766667ede 100644 (file)
@@ -23,6 +23,7 @@
 #include "xml.h"
 #include "text.h"
 #include <libcxml/cxml.h>
+#include <boost/foreach.hpp>
 
 using std::string;
 using std::list;
@@ -30,7 +31,7 @@ using boost::shared_ptr;
 using boost::optional;
 using namespace dcp;
 
-Font::Font (boost::shared_ptr<const cxml::Node> node)
+Font::Font (cxml::ConstNodePtr node, int tcr)
 {
        text = node->content ();
        
@@ -49,9 +50,21 @@ Font::Font (boost::shared_ptr<const cxml::Node> node)
        if (c) {
                effect_colour = Colour (c.get ());
        }
-       subtitle_nodes = type_children<Subtitle> (node, "Subtitle");
-       font_nodes = type_children<Font> (node, "Font");
-       text_nodes = type_children<Text> (node, "Text");
+
+       list<cxml::NodePtr> s = node->node_children ("Subtitle");
+       BOOST_FOREACH (cxml::NodePtr& i, s) {
+               subtitle_nodes.push_back (shared_ptr<Subtitle> (new Subtitle (i, tcr)));
+       }
+
+       list<cxml::NodePtr> f = node->node_children ("Font");
+       BOOST_FOREACH (cxml::NodePtr& i, f) {
+               font_nodes.push_back (shared_ptr<Font> (new Font (i, tcr)));
+       }
+       
+       list<cxml::NodePtr> t = node->node_children ("Text");
+       BOOST_FOREACH (cxml::NodePtr& i, t) {
+               text_nodes.push_back (shared_ptr<Text> (new Text (i, tcr)));
+       }
 }
 
 Font::Font (std::list<boost::shared_ptr<Font> > const & font_nodes)
index d5ea5636ea75e162e7bde7feb262657b6b4762e7..a2589be4a934ac52de14ef229b49a73cc35b6382 100644 (file)
 
 #include "types.h"
 #include "subtitle.h"
+#include <libcxml/cxml.h>
 #include <boost/shared_ptr.hpp>
 #include <boost/optional.hpp>
 #include <list>
 
-namespace cxml {
-       class Node;
-}
-
 namespace dcp {
 
 /** @class Font
@@ -43,7 +40,7 @@ public:
                : size (0)
        {}
        
-       Font (boost::shared_ptr<const cxml::Node> node);
+       Font (cxml::ConstNodePtr node, int tcr);
        Font (std::list<boost::shared_ptr<Font> > const & font_nodes);
 
        std::string text;
index 218dbaea26887a3e44129c99341f73b749a42d33..1b6ee1a97a0fd8fda9adc7727e0d3666b1db9818 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #include "xml.h"
 #include "raw_convert.h"
 #include "font.h"
+#include <boost/foreach.hpp>
 
 using std::list;
 using std::string;
+using std::cout;
 using boost::shared_ptr;
 using boost::optional;
 using boost::dynamic_pointer_cast;
@@ -38,9 +40,13 @@ InteropSubtitleContent::InteropSubtitleContent (boost::filesystem::path file)
        _id = xml->string_child ("SubtitleID");
 
        _movie_title = xml->string_child ("MovieTitle");
-
        _load_font_nodes = type_children<dcp::InteropLoadFont> (xml, "LoadFont");
-       list<shared_ptr<dcp::Font> > font_nodes = type_children<dcp::Font> (xml, "Font");
+
+       list<cxml::NodePtr> f = xml->node_children ("Font");
+       list<shared_ptr<dcp::Font> > font_nodes;
+       BOOST_FOREACH (cxml::NodePtr& i, f) {
+               font_nodes.push_back (shared_ptr<Font> (new Font (i, 250)));
+       }
 
        parse_common (xml, font_nodes);
 }
@@ -148,8 +154,8 @@ InteropSubtitleContent::xml_as_string () const
                        subtitle_element->set_attribute ("SpotNumber", raw_convert<string> (spot_number++));
                        subtitle_element->set_attribute ("TimeIn", i->in().to_string());
                        subtitle_element->set_attribute ("TimeOut", i->out().to_string());
-                       subtitle_element->set_attribute ("FadeUpTime", raw_convert<string> (i->fade_up_time().to_ticks()));
-                       subtitle_element->set_attribute ("FadeDownTime", raw_convert<string> (i->fade_down_time().to_ticks()));
+                       subtitle_element->set_attribute ("FadeUpTime", raw_convert<string> (i->fade_up_time().to_editable_units(250)));
+                       subtitle_element->set_attribute ("FadeDownTime", raw_convert<string> (i->fade_down_time().to_editable_units(250)));
 
                        last_in = i->in ();
                        last_out = i->out ();
index e54b33c31b32b10f9200f9063e28ca8bb2336953..910219cb583bcda14669fd5a1c180027467b19d0 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #include "xml.h"
 #include "AS_DCP.h"
 #include "KM_util.h"
+#include <boost/foreach.hpp>
 
 using std::string;
 using std::list;
 using std::stringstream;
+using std::cout;
 using boost::shared_ptr;
 using namespace dcp;
 
@@ -62,8 +64,15 @@ SMPTESubtitleContent::SMPTESubtitleContent (boost::filesystem::path file, bool m
        
        _load_font_nodes = type_children<dcp::SMPTELoadFont> (xml, "LoadFont");
 
+       int tcr = xml->number_child<int> ("TimeCodeRate");
+
        shared_ptr<cxml::Node> subtitle_list = xml->optional_node_child ("SubtitleList");
-       list<shared_ptr<dcp::Font> > font_nodes = type_children<dcp::Font> (subtitle_list, "Font");
+
+       list<cxml::NodePtr> f = subtitle_list->node_children ("Font");
+       list<shared_ptr<dcp::Font> > font_nodes;
+       BOOST_FOREACH (cxml::NodePtr& i, f) {
+               font_nodes.push_back (shared_ptr<Font> (new Font (i, tcr)));
+       }
 
        parse_common (xml, font_nodes);
 }
index 12714961445eb8ac9077bb379ba9b991b9d40262..6c2ccd7ef8f96328196775b068e237c5181ef7cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #include <boost/lexical_cast.hpp>
 
 using std::string;
+using std::list;
+using boost::optional;
 using boost::shared_ptr;
 using boost::lexical_cast;
 using namespace dcp;
 
-Subtitle::Subtitle (boost::shared_ptr<const cxml::Node> node)
+Subtitle::Subtitle (boost::shared_ptr<const cxml::Node> node, int tcr)
 {
-       in = Time (node->string_attribute ("TimeIn"));
-       out = Time (node->string_attribute ("TimeOut"));
-       font_nodes = type_children<Font> (node, "Font");
-       text_nodes = type_children<Text> (node, "Text");
-       fade_up_time = fade_time (node, "FadeUpTime");
-       fade_down_time = fade_time (node, "FadeDownTime");
+       in = Time (node->string_attribute ("TimeIn"), tcr);
+       out = Time (node->string_attribute ("TimeOut"), tcr);
+
+       list<cxml::NodePtr> f = node->node_children ("Font");
+       for (list<cxml::NodePtr>::iterator i = f.begin(); i != f.end(); ++i) {
+               font_nodes.push_back (shared_ptr<Font> (new Font (*i, tcr)));
+       }
+
+       list<cxml::NodePtr> t = node->node_children ("Text");
+       for (list<cxml::NodePtr>::iterator i = t.begin(); i != t.end(); ++i) {
+               text_nodes.push_back (shared_ptr<Text> (new Text (*i, tcr)));
+       }
+       
+       fade_up_time = fade_time (node, "FadeUpTime", tcr);
+       fade_down_time = fade_time (node, "FadeDownTime", tcr);
 }
 
 Time
-Subtitle::fade_time (shared_ptr<const cxml::Node> node, string name)
+Subtitle::fade_time (shared_ptr<const cxml::Node> node, string name, int tcr)
 {
        string const u = node->optional_string_attribute (name).get_value_or ("");
        Time t;
        
        if (u.empty ()) {
-               t = Time (0, 0, 0, 20);
+               t = Time (0, 0, 0, 20, 250);
        } else if (u.find (":") != string::npos) {
-               t = Time (u);
+               t = Time (u, tcr);
        } else {
-               t = Time (0, 0, 0, lexical_cast<int> (u));
+               t = Time (0, 0, 0, lexical_cast<int> (u), tcr);
        }
 
-       if (t > Time (0, 0, 8, 0)) {
-               t = Time (0, 0, 8, 0);
+       if (t > Time (0, 0, 8, 0, 250)) {
+               t = Time (0, 0, 8, 0, 250);
        }
 
        return t;
index 073bfb0c04255bca33e44d33d8982dbcace32db5..0958a1d4d96b7a876d2e25f4afd3d99ada6b8f27 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "dcp_time.h"
 #include <boost/shared_ptr.hpp>
+#include <boost/optional.hpp>
 #include <list>
 
 namespace cxml {
@@ -37,7 +38,7 @@ class Subtitle
 {
 public:
        Subtitle () {}
-       Subtitle (boost::shared_ptr<const cxml::Node> node);
+       Subtitle (boost::shared_ptr<const cxml::Node> node, int tcr);
 
        Time in;
        Time out;
@@ -47,7 +48,7 @@ public:
        std::list<boost::shared_ptr<Text> > text_nodes;
 
 private:
-       Time fade_time (boost::shared_ptr<const cxml::Node>, std::string name);
+       Time fade_time (boost::shared_ptr<const cxml::Node>, std::string name, int tcr);
 };
 
 }
index 782d17112f88a737e3e580f3178857384d08757b..a846d9613921fff3c631aa0de9c5fb6326fbfddc 100644 (file)
 #include "xml.h"
 #include "font.h"
 #include <libcxml/cxml.h>
+#include <boost/foreach.hpp>
 
 using std::string;
+using std::list;
 using boost::shared_ptr;
 using boost::optional;
 using namespace dcp;
@@ -35,7 +37,7 @@ using namespace dcp;
  *  in this object's member variables.
  *  @param node Node to read.
  */
-Text::Text (boost::shared_ptr<const cxml::Node> node)
+Text::Text (boost::shared_ptr<const cxml::Node> node, int tcr)
        : v_align (CENTER)
 {
        text = node->content ();
@@ -54,5 +56,8 @@ Text::Text (boost::shared_ptr<const cxml::Node> node)
                v_align = string_to_valign (v.get ());
        }
 
-       font_nodes = type_children<Font> (node, "Font");
+       list<cxml::NodePtr> f = node->node_children ("Font");
+       BOOST_FOREACH (cxml::NodePtr& i, f) {
+               font_nodes.push_back (shared_ptr<Font> (new Font (i, tcr)));
+       }
 }
index 268d146ccb2789fecc8b0b5382efe760ff5b386f..fe314f764eafb6114b4d91b11e49a3fb5efe1720 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
 
 #include "types.h"
 #include <boost/shared_ptr.hpp>
+#include <boost/optional.hpp>
 #include <list>
 
 namespace cxml {
@@ -45,7 +46,7 @@ public:
                , v_align (TOP)
        {}
        
-       Text (boost::shared_ptr<const cxml::Node> node);
+       Text (boost::shared_ptr<const cxml::Node> node, int tcr);
 
        float v_position;
        VAlign v_align;
index 9f0072ab18f289f36b8fd40d30f6292fde18d24e..c987517ea9e40425d1ceb3dec6bf095fc95dfb06 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 /** Check that dcp::Time works */
 BOOST_AUTO_TEST_CASE (dcp_time)
 {
-       dcp::Time t (977143, 24);
+       /* tcr of 250 makes the editable event length the same as an Interop `tick' */
+       dcp::Time t (977143, 24, 250);
 
-       BOOST_CHECK_EQUAL (t.t, 73);
+       BOOST_CHECK_EQUAL (t.e, 73);
        BOOST_CHECK_EQUAL (t.s, 34);
        BOOST_CHECK_EQUAL (t.m, 18);
        BOOST_CHECK_EQUAL (t.h, 11);
        BOOST_CHECK_EQUAL (t.to_string(), "11:18:34:73");
-       BOOST_CHECK_EQUAL (t.to_ticks(), 10178573);
 
-       dcp::Time a (3, 2, 3, 4);
-       dcp::Time b (2, 3, 4, 5);
+       /* Use a tcr of 24 so that the editable event is a frame */
+       dcp::Time a (3, 2, 3, 4, 24);
+       dcp::Time b (2, 3, 4, 5, 24);
 
        dcp::Time r = a - b;
        BOOST_CHECK_EQUAL (r.h, 0);
        BOOST_CHECK_EQUAL (r.m, 58);
        BOOST_CHECK_EQUAL (r.s, 58);
-       BOOST_CHECK_EQUAL (r.t, 249);
-       BOOST_CHECK_EQUAL (r.to_string(), "0:58:58:249");
-       BOOST_CHECK_EQUAL (r.to_ticks(), 884749);
+       BOOST_CHECK_EQUAL (r.e, 23);
+       BOOST_CHECK_EQUAL (r.to_string(), "0:58:58:23");
 
-       a = dcp::Time (1, 58, 56, 240);
-       b = dcp::Time (1, 7, 12, 120);
+       /* Different tcr (25) */
+       a = dcp::Time (1, 58, 56, 2, 25);
+       b = dcp::Time (1, 7, 12, 1, 25);
        r = a + b;
        BOOST_CHECK_EQUAL (r.h, 3);
        BOOST_CHECK_EQUAL (r.m, 6);
-       BOOST_CHECK_EQUAL (r.s, 9);
-       BOOST_CHECK_EQUAL (r.t, 110);
-       BOOST_CHECK_EQUAL (r.to_string(), "3:6:9:110");
-       BOOST_CHECK_EQUAL (r.to_ticks(), 2792360);
+       BOOST_CHECK_EQUAL (r.s, 8);
+       BOOST_CHECK_EQUAL (r.e, 3);
+       BOOST_CHECK_EQUAL (r.to_string(), "3:6:8:3");
 
-       a = dcp::Time (24, 12, 6, 3);
-       b = dcp::Time (16, 8, 4, 2);
+       /* Another arbitrary tcr (30) */
+       a = dcp::Time (24, 12, 6, 3, 30);
+       b = dcp::Time (16, 8, 4, 2, 30);
        BOOST_CHECK_CLOSE (a / b, 1.5, 1e-5);
 
-       BOOST_CHECK_EQUAL (dcp::Time (4128391203LL).to_ticks(), 4128391203LL);
-       BOOST_CHECK_EQUAL (dcp::Time (60000).to_ticks(), 60000);
+       a = dcp::Time (3600 * 24, 24, 250);
+       BOOST_CHECK_EQUAL (a.h, 1);
+       BOOST_CHECK_EQUAL (a.m, 0);
+       BOOST_CHECK_EQUAL (a.s, 0);
+       BOOST_CHECK_EQUAL (a.e, 0);
+
+       a = dcp::Time (60 * 24, 24, 250);
+       BOOST_CHECK_EQUAL (a.h, 0);
+       BOOST_CHECK_EQUAL (a.m, 1);
+       BOOST_CHECK_EQUAL (a.s, 0);
+       BOOST_CHECK_EQUAL (a.e, 0);
 
        /* Check rounding; 3424 is 142.666666666... seconds or 0.166666666... ticks */
-       a = dcp::Time (3424, 24);
+       a = dcp::Time (3424, 24, 250);
        BOOST_CHECK_EQUAL (a.h, 0);
        BOOST_CHECK_EQUAL (a.m, 2);
        BOOST_CHECK_EQUAL (a.s, 22);
-       BOOST_CHECK_EQUAL (a.t, 167);
+       BOOST_CHECK_EQUAL (a.e, 167);
 
-       a = dcp::Time (3425, 24);
+       a = dcp::Time (3425, 24, 250);
        BOOST_CHECK_EQUAL (a.h, 0);
        BOOST_CHECK_EQUAL (a.m, 2);
        BOOST_CHECK_EQUAL (a.s, 22);
-       BOOST_CHECK_EQUAL (a.t, 177);
+       BOOST_CHECK_EQUAL (a.e, 177);
+
+       /* Check addition of times with different tcrs */
+       a = dcp::Time (0, 0, 0, 3, 24);
+       b = dcp::Time (0, 0, 0, 4, 48);
+       r = a + b;
+       BOOST_CHECK_EQUAL (r, dcp::Time (0, 0, 0, 240, 1152));
 }
index c7137beca4cd7e9f1c6386aedfcd2678ec54f4df..a3694717b42a12c5ed9949fdd5ba6b7b28311c70 100644 (file)
@@ -32,91 +32,91 @@ BOOST_AUTO_TEST_CASE (subtitles1)
 
        BOOST_CHECK_EQUAL (subs.language(), "French");
 
-       list<dcp::SubtitleString> s = subs.subtitles_during (dcp::Time (0, 0, 6, 1), dcp::Time (0, 0, 6, 2));
-       BOOST_CHECK_EQUAL (s.size(), 1);
+       list<dcp::SubtitleString> s = subs.subtitles_during (dcp::Time (0, 0, 6, 1, 250), dcp::Time (0, 0, 6, 2, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 1);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFontId"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   39,
-                                  dcp::Time (0, 0, 5, 198),
-                                  dcp::Time (0, 0, 7, 115),
+                                  dcp::Time (0, 0, 5, 198, 250),
+                                  dcp::Time (0, 0, 7, 115, 250),
                                   15,
                                   dcp::BOTTOM,
                                   "My jacket was Idi Amin's",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 1),
-                                  dcp::Time (0, 0, 0, 1)
+                                  dcp::Time (0, 0, 0, 1, 250),
+                                  dcp::Time (0, 0, 0, 1, 250)
                                   ));
                                                         
-       s = subs.subtitles_during (dcp::Time (0, 0, 7, 190), dcp::Time (0, 0, 7, 191));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       s = subs.subtitles_during (dcp::Time (0, 0, 7, 190, 250), dcp::Time (0, 0, 7, 191, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFontId"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   39,
-                                  dcp::Time (0, 0, 7, 177),
-                                  dcp::Time (0, 0, 11, 31),
+                                  dcp::Time (0, 0, 7, 177, 250),
+                                  dcp::Time (0, 0, 11, 31, 250),
                                   21,
                                   dcp::BOTTOM,
                                   "My corset was H.M. The Queen's",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 1),
-                                  dcp::Time (0, 0, 0, 1)
+                                  dcp::Time (0, 0, 0, 1, 250),
+                                  dcp::Time (0, 0, 0, 1, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFontId"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   39,
-                                  dcp::Time (0, 0, 7, 177),
-                                  dcp::Time (0, 0, 11, 31),
+                                  dcp::Time (0, 0, 7, 177, 250),
+                                  dcp::Time (0, 0, 11, 31, 250),
                                   15,
                                   dcp::BOTTOM,
                                   "My large wonderbra",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 1),
-                                  dcp::Time (0, 0, 0, 1)
+                                  dcp::Time (0, 0, 0, 1, 250),
+                                  dcp::Time (0, 0, 0, 1, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 0, 11, 95), dcp::Time (0, 0, 11, 96));
-       BOOST_CHECK_EQUAL (s.size(), 1);
+       s = subs.subtitles_during (dcp::Time (0, 0, 11, 95, 250), dcp::Time (0, 0, 11, 96, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 1);
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFontId"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   39,
-                                  dcp::Time (0, 0, 11, 94),
-                                  dcp::Time (0, 0, 13, 63),
+                                  dcp::Time (0, 0, 11, 94, 250),
+                                  dcp::Time (0, 0, 13, 63, 250),
                                   15,
                                   dcp::BOTTOM,
                                   "Once belonged to the Shah",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 1),
-                                  dcp::Time (0, 0, 0, 1)
+                                  dcp::Time (0, 0, 0, 1, 250),
+                                  dcp::Time (0, 0, 0, 1, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 0, 14, 42), dcp::Time (0, 0, 14, 43));
-       BOOST_CHECK_EQUAL (s.size(), 1);
+       s = subs.subtitles_during (dcp::Time (0, 0, 14, 42, 250), dcp::Time (0, 0, 14, 43, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 1);
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFontId"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   39,
-                                  dcp::Time (0, 0, 13, 104),
-                                  dcp::Time (0, 0, 15, 177),
+                                  dcp::Time (0, 0, 13, 104, 250),
+                                  dcp::Time (0, 0, 15, 177, 250),
                                   15,
                                   dcp::BOTTOM,
                                   "And these are Roy Hattersley's jeans",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 1),
-                                  dcp::Time (0, 0, 0, 1)
+                                  dcp::Time (0, 0, 0, 1, 250),
+                                  dcp::Time (0, 0, 0, 1, 250)
                                   ));
 }
 
@@ -125,303 +125,300 @@ BOOST_AUTO_TEST_CASE (subtitles2)
 {
        dcp::InteropSubtitleContent subs ("test/data/subs2.xml");
 
-       list<dcp::SubtitleString> s = subs.subtitles_during (dcp::Time (0, 0, 42, 100), dcp::Time (0, 0, 42, 101));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       list<dcp::SubtitleString> s = subs.subtitles_during (dcp::Time (0, 0, 42, 100, 250), dcp::Time (0, 0, 42, 101, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 0, 41, 62),
-                                  dcp::Time (0, 0, 43, 52),
+                                  dcp::Time (0, 0, 41, 62, 250),
+                                  dcp::Time (0, 0, 43, 52, 250),
                                   89,
                                   dcp::TOP,
                                   "At afternoon tea with John Peel",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 0, 41, 62),
-                                  dcp::Time (0, 0, 43, 52),
+                                  dcp::Time (0, 0, 41, 62, 250),
+                                  dcp::Time (0, 0, 43, 52, 250),
                                   95,
                                   dcp::TOP,
                                   "I enquired if his accent was real",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 0, 50, 50), dcp::Time (0, 0, 50, 51));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       s = subs.subtitles_during (dcp::Time (0, 0, 50, 50, 250), dcp::Time (0, 0, 50, 51, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 0, 50, 42),
-                                  dcp::Time (0, 0, 52, 21),
+                                  dcp::Time (0, 0, 50, 42, 250),
+                                  dcp::Time (0, 0, 52, 21, 250),
                                   89,
                                   dcp::TOP,
                                   "He said \"out of the house",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 0, 50, 42),
-                                  dcp::Time (0, 0, 52, 21),
+                                  dcp::Time (0, 0, 50, 42, 250),
+                                  dcp::Time (0, 0, 52, 21, 250),
                                   95,
                                   dcp::TOP,
                                   "I'm incredibly scouse",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 1, 2, 300), dcp::Time (0, 1, 2, 301));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       s = subs.subtitles_during (dcp::Time (0, 1, 2, 300, 250), dcp::Time (0, 1, 2, 301, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 2, 208),
-                                  dcp::Time (0, 1, 4, 10),
+                                  dcp::Time (0, 1, 2, 208, 250),
+                                  dcp::Time (0, 1, 4, 10, 250),
                                   89,
                                   dcp::TOP,
                                   "At home it depends how I feel.\"",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 2, 208),
-                                  dcp::Time (0, 1, 4, 10),
+                                  dcp::Time (0, 1, 2, 208, 250),
+                                  dcp::Time (0, 1, 4, 10, 250),
                                   95,
                                   dcp::TOP,
                                   "I spent a long weekend in Brighton",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 1, 15, 50), dcp::Time (0, 1, 15, 51));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       s = subs.subtitles_during (dcp::Time (0, 1, 15, 50, 250), dcp::Time (0, 1, 15, 51, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 15, 42),
-                                  dcp::Time (0, 1, 16, 42),
+                                  dcp::Time (0, 1, 15, 42, 250),
+                                  dcp::Time (0, 1, 16, 42, 250),
                                   89,
                                   dcp::TOP,
                                   "With the legendary Miss Enid Blyton",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 15, 42),
-                                  dcp::Time (0, 1, 16, 42),
+                                  dcp::Time (0, 1, 15, 42, 250),
+                                  dcp::Time (0, 1, 16, 42, 250),
                                   95,
                                   dcp::TOP,
                                   "She said \"you be Noddy",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 1, 27, 200), dcp::Time (0, 1, 27, 201));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       s = subs.subtitles_during (dcp::Time (0, 1, 27, 200, 250), dcp::Time (0, 1, 27, 201, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 27, 115),
-                                  dcp::Time (0, 1, 28, 208),
+                                  dcp::Time (0, 1, 27, 115, 250),
+                                  dcp::Time (0, 1, 28, 208, 250),
                                   89,
                                   dcp::TOP,
                                   "That curious creature the Sphinx",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 27, 115),
-                                  dcp::Time (0, 1, 28, 208),
+                                  dcp::Time (0, 1, 27, 115, 250),
+                                  dcp::Time (0, 1, 28, 208, 250),
                                   95,
                                   dcp::TOP,
                                   "Is smarter than anyone thinks",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 1, 42, 300), dcp::Time (0, 1, 42, 301));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       s = subs.subtitles_during (dcp::Time (0, 1, 42, 300, 250), dcp::Time (0, 1, 42, 301, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFont"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 42, 229),
-                                  dcp::Time (0, 1, 45, 62),
+                                  dcp::Time (0, 1, 42, 229, 250),
+                                  dcp::Time (0, 1, 45, 62, 250),
                                   89,
                                   dcp::TOP,
                                   "It sits there and smirks",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFont"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 42, 229),
-                                  dcp::Time (0, 1, 45, 62),
+                                  dcp::Time (0, 1, 42, 229, 250),
+                                  dcp::Time (0, 1, 45, 62, 250),
                                   95,
                                   dcp::TOP,
                                   "And you don't think it works",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 1, 45, 200), dcp::Time (0, 1, 45, 201));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       s = subs.subtitles_during (dcp::Time (0, 1, 45, 200, 250), dcp::Time (0, 1, 45, 201, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFont"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 45, 146),
-                                  dcp::Time (0, 1, 47, 94),
+                                  dcp::Time (0, 1, 45, 146, 250),
+                                  dcp::Time (0, 1, 47, 94, 250),
                                   89,
                                   dcp::TOP,
                                   "Then when you're not looking, it winks.",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFont"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 45, 146),
-                                  dcp::Time (0, 1, 47, 94),
+                                  dcp::Time (0, 1, 45, 146, 250),
+                                  dcp::Time (0, 1, 47, 94, 250),
                                   95,
                                   dcp::TOP,
                                   "When it snows you will find Sister Sledge",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 1, 47, 249), dcp::Time (0, 1, 47, 250));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       s = subs.subtitles_during (dcp::Time (0, 1, 47, 249, 250), dcp::Time (0, 1, 47, 250, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFont"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 47, 146),
-                                  dcp::Time (0, 1, 48, 167),
+                                  dcp::Time (0, 1, 47, 146, 250),
+                                  dcp::Time (0, 1, 48, 167, 250),
                                   89,
                                   dcp::TOP,
                                   "Out mooning, at night, on the ledge",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFont"),
                                   false,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 1, 47, 146),
-                                  dcp::Time (0, 1, 48, 167),
+                                  dcp::Time (0, 1, 47, 146, 250),
+                                  dcp::Time (0, 1, 48, 167, 250),
                                   95,
                                   dcp::TOP,
                                   "One storey down",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
 
-       s = subs.subtitles_during (dcp::Time (0, 2, 6, 210), dcp::Time (0, 2, 6, 211));
-       BOOST_CHECK_EQUAL (s.size(), 2);
+       s = subs.subtitles_during (dcp::Time (0, 2, 6, 210, 250), dcp::Time (0, 2, 6, 211, 250));
+       BOOST_REQUIRE_EQUAL (s.size(), 2);
        BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 2, 5, 208),
-                                  dcp::Time (0, 2, 7, 31),
+                                  dcp::Time (0, 2, 5, 208, 250),
+                                  dcp::Time (0, 2, 7, 31, 250),
                                   89,
                                   dcp::TOP,
                                   "HELLO",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
        BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString (
                                   string ("theFont"),
                                   true,
                                   dcp::Colour (255, 255, 255),
                                   42,
-                                  dcp::Time (0, 2, 5, 208),
-                                  dcp::Time (0, 2, 7, 31),
+                                  dcp::Time (0, 2, 5, 208, 250),
+                                  dcp::Time (0, 2, 7, 31, 250),
                                   95,
                                   dcp::TOP,
                                   "WORLD",
                                   dcp::BORDER,
                                   dcp::Colour (0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0),
-                                  dcp::Time (0, 0, 0, 0)
+                                  dcp::Time (0, 0, 0, 0, 250),
+                                  dcp::Time (0, 0, 0, 0, 250)
                                   ));
-
-       
-       
 }
index 55cb20c1fd1dfefde393c2c3c48098d2c25628bd..b8d76207c565e288771f4032681ea92d3487b0f5 100644 (file)
@@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE (text_test1)
        text->set_attribute("VAlign", "top");
        text->add_child_text("Hello world");
 
-       dcp::Text t (cxml::NodePtr (new cxml::Node (text)));
+       dcp::Text t (cxml::NodePtr (new cxml::Node (text)), 250);
        BOOST_CHECK_CLOSE (t.v_position, 4.2, 0.001);
        BOOST_CHECK_EQUAL (t.v_align, dcp::TOP);
        BOOST_CHECK_EQUAL (t.text, "Hello world");
@@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE (text_test2)
        text->set_attribute("Valign", "top");
        text->add_child_text("Hello world");
 
-       dcp::Text t (cxml::NodePtr (new cxml::Node (text)));
+       dcp::Text t (cxml::NodePtr (new cxml::Node (text)), 250);
        BOOST_CHECK_CLOSE (t.v_position, 4.2, 0.001);
        BOOST_CHECK_EQUAL (t.v_align, dcp::TOP);
        BOOST_CHECK_EQUAL (t.text, "Hello world");