Add ContentTimePeriod class.
authorCarl Hetherington <cth@carlh.net>
Thu, 22 May 2014 13:57:56 +0000 (14:57 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 22 May 2014 13:57:56 +0000 (14:57 +0100)
src/lib/content_subtitle.cc
src/lib/content_subtitle.h
src/lib/dcpomatic_time.h
src/lib/ffmpeg_decoder.cc
src/lib/player.cc
src/lib/subtitle_decoder.cc
src/lib/subtitle_decoder.h
src/wx/subtitle_view.cc
test/subrip_test.cc

index 11873afee0a3791f00a28c10a5422c09ac4173ce..93e0677bb7c3c49031555af796a3425ae49ccd4c 100644 (file)
 
 #include "content_subtitle.h"
 
-ContentTime
-ContentTextSubtitle::from () const
+ContentTimePeriod
+ContentTextSubtitle::period () const
 {
        /* XXX: assuming we have some subs and they are all at the same time */
        assert (!subs.empty ());
-       return ContentTime::from_seconds (double (subs.front().in().to_ticks()) / 250);
-}
-
-ContentTime
-ContentTextSubtitle::to () const
-{
-       /* XXX: assuming we have some subs and they are all at the same time */
-       assert (!subs.empty ());
-       return ContentTime::from_seconds (double (subs.front().out().to_ticks()) / 250);
+       return ContentTimePeriod (
+               ContentTime::from_seconds (double (subs.front().in().to_ticks()) / 250),
+               ContentTime::from_seconds (double (subs.front().out().to_ticks()) / 250)
+               );
 }
index 8c266f4835da680495a3f07414d98b65935e54bc..6a28c37bf2c79b19eb3ffde4040f66559c6b277a 100644 (file)
@@ -30,34 +30,27 @@ class Image;
 class ContentSubtitle
 {
 public:
-       virtual ContentTime from () const = 0;
-       virtual ContentTime to () const = 0;
+       virtual ContentTimePeriod period () const = 0;
 };
 
 class ContentImageSubtitle : public ContentSubtitle
 {
 public:
-       ContentImageSubtitle (ContentTime f, ContentTime t, boost::shared_ptr<Image> im, dcpomatic::Rect<double> r)
+       ContentImageSubtitle (ContentTimePeriod p, boost::shared_ptr<Image> im, dcpomatic::Rect<double> r)
                : image (im)
                , rectangle (r)
-               , _from (f)
-               , _to (t)
+               , _period (p)
        {}
 
-       ContentTime from () const {
-               return _from;
+       ContentTimePeriod period () const {
+               return _period;
        }
 
-       ContentTime to () const {
-               return _to;
-       }
-       
        boost::shared_ptr<Image> image;
        dcpomatic::Rect<double> rectangle;
 
 private:
-       ContentTime _from;
-       ContentTime _to;
+       ContentTimePeriod _period;
 };
 
 class ContentTextSubtitle : public ContentSubtitle
@@ -67,8 +60,7 @@ public:
                : subs (s)
        {}
 
-       ContentTime from () const;
-       ContentTime to () const;
+       ContentTimePeriod period () const;
        
        std::list<dcp::SubtitleString> subs;
 };
index 109dc9b7fe1c34b9850409a2bb4787298a58d492..e56f58c4b10252295b76caf6d1ae022036d19a18 100644 (file)
@@ -146,6 +146,19 @@ public:
 
 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;
+};
+
 class DCPTime : public Time
 {
 public:
index 9548eaae9c1a9415d089957befda45233627fba1..eec70501a11b70ca52e83685cd2d6d1bcf209df5 100644 (file)
@@ -535,7 +535,7 @@ FFmpegDecoder::decode_subtitle_packet ()
           indicate that the previous subtitle should stop.
        */
        if (sub.num_rects <= 0) {
-               image_subtitle (ContentTime (), ContentTime (), shared_ptr<Image> (), dcpomatic::Rect<double> ());
+               image_subtitle (ContentTimePeriod (), shared_ptr<Image> (), dcpomatic::Rect<double> ());
                return;
        } else if (sub.num_rects > 1) {
                throw DecodeError (_("multi-part subtitles not yet supported"));
@@ -545,10 +545,11 @@ FFmpegDecoder::decode_subtitle_packet ()
           source that we may have chopped off for the DCP)
        */
        ContentTime packet_time = ContentTime::from_seconds (static_cast<double> (sub.pts) / AV_TIME_BASE) + _pts_offset;
-       
-       /* hence start time for this sub */
-       ContentTime const from = packet_time + ContentTime::from_seconds (sub.start_display_time / 1e3);
-       ContentTime const to = packet_time + ContentTime::from_seconds (sub.end_display_time / 1e3);
+
+       ContentTimePeriod period (
+               packet_time + ContentTime::from_seconds (sub.start_display_time / 1e3),
+               packet_time + ContentTime::from_seconds (sub.end_display_time / 1e3)
+               );
 
        AVSubtitleRect const * rect = sub.rects[0];
 
@@ -586,8 +587,7 @@ FFmpegDecoder::decode_subtitle_packet ()
        dcp::Size const vs = _ffmpeg_content->video_size ();
 
        image_subtitle (
-               from,
-               to,
+               period,
                image,
                dcpomatic::Rect<double> (
                        static_cast<double> (rect->x) / vs.width,
index 4865073d705484050330a604adc8e9de6b1ba4e1..b60dd846786056a2918b3a1338a8382183e81cea 100644 (file)
@@ -337,7 +337,7 @@ Player::content_to_player_video_frame (
                ContentTime const from = dcp_to_content_subtitle (*i, time);
                ContentTime const to = from + ContentTime::from_frames (1, content->video_frame_rate ());
                
-               list<shared_ptr<ContentImageSubtitle> > image_subtitles = subtitle_decoder->get_image_subtitles (from, to);
+               list<shared_ptr<ContentImageSubtitle> > image_subtitles = subtitle_decoder->get_image_subtitles (ContentTimePeriod (from, to));
                if (!image_subtitles.empty ()) {
                        list<PositionImage> im = process_content_image_subtitles (
                                subtitle_content,
@@ -348,7 +348,7 @@ Player::content_to_player_video_frame (
                }
                
                if (_burn_subtitles) {
-                       list<shared_ptr<ContentTextSubtitle> > text_subtitles = subtitle_decoder->get_text_subtitles (from, to);
+                       list<shared_ptr<ContentTextSubtitle> > text_subtitles = subtitle_decoder->get_text_subtitles (ContentTimePeriod (from, to));
                        if (!text_subtitles.empty ()) {
                                list<PositionImage> im = process_content_text_subtitles (text_subtitles);
                                copy (im.begin(), im.end(), back_inserter (sub_images));
index 0f5a1992c46bad7d9e43d58bf4048a601a0bc0a3..d114df97977c477748e7e844a0f65db27497d486 100644 (file)
@@ -34,9 +34,9 @@ SubtitleDecoder::SubtitleDecoder ()
  *  Image may be 0 to say that there is no current subtitle.
  */
 void
-SubtitleDecoder::image_subtitle (ContentTime from, ContentTime to, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
+SubtitleDecoder::image_subtitle (ContentTimePeriod period, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
 {
-       _decoded_image_subtitles.push_back (shared_ptr<ContentImageSubtitle> (new ContentImageSubtitle (from, to, image, rect)));
+       _decoded_image_subtitles.push_back (shared_ptr<ContentImageSubtitle> (new ContentImageSubtitle (period, image, rect)));
 }
 
 void
@@ -47,11 +47,11 @@ SubtitleDecoder::text_subtitle (list<dcp::SubtitleString> s)
 
 template <class T>
 list<shared_ptr<T> >
-SubtitleDecoder::get (list<shared_ptr<T> > const & subs, ContentTime from, ContentTime to)
+SubtitleDecoder::get (list<shared_ptr<T> > const & subs, ContentTimePeriod period)
 {
-       if (subs.empty() || from < subs.front()->from() || to > (subs.back()->to() + ContentTime::from_seconds (10))) {
+       if (subs.empty() || period.from < subs.front()->period().from || period.to > (subs.back()->period().to + ContentTime::from_seconds (10))) {
                /* Either we have no decoded data, or what we do have is a long way from what we want: seek */
-               seek (from, true);
+               seek (period.from, true);
        }
 
        /* Now enough pass() calls will either:
@@ -60,14 +60,14 @@ SubtitleDecoder::get (list<shared_ptr<T> > const & subs, ContentTime from, Conte
         *
         *  XXX: with subs being sparse, this may need more care...
         */
-       while (!pass() && (subs.empty() || (subs.front()->from() > from || to < subs.back()->to()))) {}
+       while (!pass() && (subs.empty() || (subs.front()->period().from > period.from || period.to < subs.back()->period().to))) {}
 
        /* Now look for what we wanted in the data we have collected */
        /* XXX: inefficient */
        
        list<shared_ptr<T> > out;
        for (typename list<shared_ptr<T> >::const_iterator i = subs.begin(); i != subs.end(); ++i) {
-               if ((*i)->from() <= to && (*i)->to() >= from) {
+               if ((*i)->period().from <= period.to && (*i)->period().to >= period.from) {
                        out.push_back (*i);
                }
        }
@@ -76,15 +76,15 @@ SubtitleDecoder::get (list<shared_ptr<T> > const & subs, ContentTime from, Conte
 }
 
 list<shared_ptr<ContentTextSubtitle> >
-SubtitleDecoder::get_text_subtitles (ContentTime from, ContentTime to)
+SubtitleDecoder::get_text_subtitles (ContentTimePeriod period)
 {
-       return get<ContentTextSubtitle> (_decoded_text_subtitles, from, to);
+       return get<ContentTextSubtitle> (_decoded_text_subtitles, period);
 }
 
 list<shared_ptr<ContentImageSubtitle> >
-SubtitleDecoder::get_image_subtitles (ContentTime from, ContentTime to)
+SubtitleDecoder::get_image_subtitles (ContentTimePeriod period)
 {
-       return get<ContentImageSubtitle> (_decoded_image_subtitles, from, to);
+       return get<ContentImageSubtitle> (_decoded_image_subtitles, period);
 }
 
 void
index a26348ee69a61b4842dd173446b2846c96fc0c70..fea4ab973fc615f8fb4824d647bb166285339e98 100644 (file)
@@ -35,13 +35,13 @@ class SubtitleDecoder : public virtual Decoder
 public:
        SubtitleDecoder ();
 
-       std::list<boost::shared_ptr<ContentImageSubtitle> > get_image_subtitles (ContentTime from, ContentTime to);
-       std::list<boost::shared_ptr<ContentTextSubtitle> > get_text_subtitles (ContentTime from, ContentTime to);
+       std::list<boost::shared_ptr<ContentImageSubtitle> > get_image_subtitles (ContentTimePeriod period);
+       std::list<boost::shared_ptr<ContentTextSubtitle> > get_text_subtitles (ContentTimePeriod period);
 
 protected:
        void seek (ContentTime, bool);
        
-       void image_subtitle (ContentTime from, ContentTime to, boost::shared_ptr<Image>, dcpomatic::Rect<double>);
+       void image_subtitle (ContentTimePeriod period, boost::shared_ptr<Image>, dcpomatic::Rect<double>);
        void text_subtitle (std::list<dcp::SubtitleString>);
 
        std::list<boost::shared_ptr<ContentImageSubtitle> > _decoded_image_subtitles;
@@ -49,7 +49,7 @@ protected:
 
 private:
        template <class T>
-       std::list<boost::shared_ptr<T> > get (std::list<boost::shared_ptr<T> > const & subs, ContentTime from, ContentTime to);
+       std::list<boost::shared_ptr<T> > get (std::list<boost::shared_ptr<T> > const & subs, ContentTimePeriod period);
 };
 
 #endif
index adbc4a62585eb7d8e2f842b36dd39c978e6cf688..d14f260c9c8ba4098e39527ab960514a38ac3df0 100644 (file)
@@ -63,7 +63,7 @@ SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<SubRipContent> content)
        }
 
        shared_ptr<SubRipDecoder> decoder (new SubRipDecoder (content));
-       list<shared_ptr<ContentTextSubtitle> > subs = decoder->get_text_subtitles (ContentTime(), ContentTime::max ());
+       list<shared_ptr<ContentTextSubtitle> > subs = decoder->get_text_subtitles (ContentTimePeriod (ContentTime(), ContentTime::max ()));
        int n = 0;
        for (list<shared_ptr<ContentTextSubtitle> >::const_iterator i = subs.begin(); i != subs.end(); ++i) {
                for (list<dcp::SubtitleString>::const_iterator j = (*i)->subs.begin(); j != (*i)->subs.end(); ++j) {
index de102369f28bf5c76ee573fbc22b61291fd88752..19caca59232411d31b1384fd6e82220635e4fbae 100644 (file)
@@ -190,7 +190,11 @@ BOOST_AUTO_TEST_CASE (subrip_render_test)
        BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471));
 
        shared_ptr<SubRipDecoder> decoder (new SubRipDecoder (content));
-       list<shared_ptr<ContentTextSubtitle> > cts = decoder->get_text_subtitles (ContentTime::from_seconds (109), ContentTime::from_seconds (110));
+       list<shared_ptr<ContentTextSubtitle> > cts = decoder->get_text_subtitles (
+               ContentTimePeriod (
+                       ContentTime::from_seconds (109), ContentTime::from_seconds (110)
+                       )
+               );
        BOOST_CHECK_EQUAL (cts.size(), 1);
 
        PositionImage image = render_subtitles (cts.front()->subs, dcp::Size (1998, 1080));