Fix subrip subtitles a little.
authorCarl Hetherington <cth@carlh.net>
Thu, 12 Jun 2014 22:34:31 +0000 (23:34 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 12 Jun 2014 22:34:31 +0000 (23:34 +0100)
15 files changed:
src/lib/dcpomatic_time.cc
src/lib/dcpomatic_time.h
src/lib/ffmpeg_content.h
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/subrip.cc
src/lib/subrip_content.cc
src/lib/subrip_content.h
src/lib/subrip_decoder.cc
src/lib/subrip_decoder.h
src/lib/subrip_subtitle.h
src/lib/subtitle_content.h
src/lib/subtitle_decoder.cc
src/lib/subtitle_decoder.h
test/subrip_test.cc

index 98888646d0a841e26bcb077a426be8ac66e1e8e4..ae4dea44f5c0752f6b387365713f772336e8d867 100644 (file)
@@ -49,3 +49,9 @@ operator<< (ostream& s, DCPTime t)
        s << "[DCP " << t.get() << " " << t.seconds() << "s]";
        return s;
 }
+
+bool
+ContentTimePeriod::overlaps (ContentTimePeriod const & other) const
+{
+       return (from < other.to && to > other.from);
+}
index 2a871889a529be2ec7e7f6bcc7c0c15c2f2cf5c8..1421040733f8c7d709723bc2085828a667354554 100644 (file)
@@ -161,6 +161,8 @@ public:
        ContentTimePeriod operator+ (ContentTime const & o) const {
                return ContentTimePeriod (from + o, to + o);
        }
+
+       bool overlaps (ContentTimePeriod const & o) const;
 };
 
 class DCPTime : public Time
index 1a30fb60693db7683c18efc00b47a642848f1019..367c30103e77812927878d0f2f31062e995cc647 100644 (file)
@@ -73,9 +73,6 @@ public:
        void set_audio_mapping (AudioMapping);
        boost::filesystem::path audio_analysis_path () const;
 
-       /* SubtitleContent */
-       bool has_subtitle_during (ContentTimePeriod) const;
-
        void set_filters (std::vector<Filter const *> const &);
        
        std::vector<boost::shared_ptr<FFmpegSubtitleStream> > subtitle_streams () const {
@@ -111,6 +108,8 @@ public:
                return _first_video;
        }
 
+       bool has_subtitle_during (ContentTimePeriod) const;
+
 private:
        friend class ffmpeg_pts_offset_test;
        
index a2b71aec313f64be093cf10b1e0313c1fdccdbea..2041a4d17aa6433d10548473898b8a813a75bdb8 100644 (file)
@@ -575,3 +575,9 @@ FFmpegDecoder::decode_subtitle_packet ()
        
        avsubtitle_free (&sub);
 }
+
+bool
+FFmpegDecoder::has_subtitle_during (ContentTimePeriod p) const
+{
+       return _ffmpeg_content->has_subtitle_during (p);
+}
index 6006fc08d521b2595d418fbb24138e03e6485ebc..335364d2e18bdacfce192b3a0366ec546f408c3d 100644 (file)
@@ -72,6 +72,8 @@ private:
        int minimal_run (boost::function<bool (boost::optional<ContentTime>, boost::optional<ContentTime>, int)>);
        void seek_and_flush (ContentTime);
 
+       bool has_subtitle_during (ContentTimePeriod) const;
+       
        boost::shared_ptr<Log> _log;
        AVCodecContext* _subtitle_codec_context; ///< may be 0 if there is no subtitle
        AVCodec* _subtitle_codec;                ///< may be 0 if there is no subtitle
index 9d207d528d0f04f7060ebc18c5e8d2fbe4228a16..3217a4df0803a1bd4b192e18c6846ff33f4ffaa8 100644 (file)
@@ -90,8 +90,7 @@ SubRip::SubRip (shared_ptr<const SubRipContent> content)
                                throw SubRipError (line, _("a time/position line"), content->path (0));
                        }
 
-                       current->from = convert_time (p[0]);
-                       current->to = convert_time (p[2]);
+                       current->period = ContentTimePeriod (convert_time (p[0]), convert_time (p[2]));
 
                        if (p.size() > 3) {
                                current->x1 = convert_coordinate (p[3]);
@@ -233,5 +232,5 @@ SubRip::length () const
                return ContentTime ();
        }
 
-       return _subtitles.back().to;
+       return _subtitles.back().period.to;
 }
index d7825f518f977a4d525227572469d9f63f2482bb..892578adecc11595bf8059ee2530f87bf88dca14 100644 (file)
@@ -109,10 +109,3 @@ SubRipContent::identifier () const
 
        return s.str ();
 }
-
-bool
-SubRipContent::has_subtitle_during (ContentTimePeriod) const
-{
-       /* XXX */
-       return false;
-}
index 91de08350e0c97f3c9c455c41d793efdf7c64780..5688f81d5fe44639450e3d8d8a57d4acb9f4a9b3 100644 (file)
@@ -37,8 +37,6 @@ public:
        DCPTime full_length () const;
        std::string identifier () const;
 
-       bool has_subtitle_during (ContentTimePeriod) const;
-
 private:
        DCPTime _length;
 };
index e832c2d849d7d09a47de30a8027301d8e9cf380c..3d971fd4b4fe8516ec43d5b7111b9f095b6176be 100644 (file)
@@ -22,6 +22,7 @@
 #include "subrip_content.h"
 
 using std::list;
+using std::vector;
 using boost::shared_ptr;
 
 SubRipDecoder::SubRipDecoder (shared_ptr<const SubRipContent> content)
@@ -39,7 +40,7 @@ SubRipDecoder::seek (ContentTime time, bool accurate)
        
        _next = 0;
        list<SubRipSubtitlePiece>::const_iterator i = _subtitles[_next].pieces.begin();
-       while (i != _subtitles[_next].pieces.end() && _subtitles[_next].from < time) {
+       while (i != _subtitles[_next].pieces.end() && _subtitles[_next].period.from < time) {
                ++i;
        }
        
@@ -60,8 +61,8 @@ SubRipDecoder::pass ()
                                i->italic,
                                dcp::Color (255, 255, 255),
                                72,
-                               dcp::Time (rint (_subtitles[_next].from.seconds() * 250)),
-                               dcp::Time (rint (_subtitles[_next].to.seconds() * 250)),
+                               dcp::Time (rint (_subtitles[_next].period.from.seconds() * 250)),
+                               dcp::Time (rint (_subtitles[_next].period.to.seconds() * 250)),
                                0.9,
                                dcp::BOTTOM,
                                i->text,
@@ -77,3 +78,17 @@ SubRipDecoder::pass ()
        _next++;
        return false;
 }
+
+bool
+SubRipDecoder::has_subtitle_during (ContentTimePeriod p) const
+{
+       /* XXX: inefficient */
+
+       for (vector<SubRipSubtitle>::const_iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
+               if (p.overlaps (i->period)) {
+                       return true;
+               }
+       }
+
+       return false;
+}
index ca885a2efdd0d8d469330a3b0d2f3886fff9a7f0..d6c6e6bc2fa7fd37df7c4769c572fedaa7a7823c 100644 (file)
@@ -35,6 +35,8 @@ protected:
        bool pass ();
 
 private:
+       bool has_subtitle_during (ContentTimePeriod) const;
+       
        size_t _next;
 };
 
index dd46b6c6491584d4197e9b4ec4045f6aeda70798..646fc1f7aaec53c330733bd5fa36c44c81ab5780 100644 (file)
@@ -42,13 +42,7 @@ struct SubRipSubtitlePiece
 
 struct SubRipSubtitle
 {
-       SubRipSubtitle ()
-               : from (0)
-               , to (0)
-       {}
-       
-       ContentTime from;
-       ContentTime to;
+       ContentTimePeriod period;
        boost::optional<int> x1;
        boost::optional<int> x2;
        boost::optional<int> y1;
index cc91a2df82eec046faeb58030bcfa7a2ca7a76e3..7d4a385c97c61c52e537f57ef2bb801ed9cd2c7f 100644 (file)
@@ -39,8 +39,6 @@ public:
 
        void as_xml (xmlpp::Node *) const;
 
-       virtual bool has_subtitle_during (ContentTimePeriod) const = 0;
-       
        void set_subtitle_x_offset (double);
        void set_subtitle_y_offset (double);
        void set_subtitle_scale (double);
index 13cf481c8027f70e0b468235ef0736cf47278570..fc03442d539637b15f01d1f7debeabe465f11b57 100644 (file)
@@ -51,7 +51,8 @@ template <class T>
 list<shared_ptr<T> >
 SubtitleDecoder::get (list<shared_ptr<T> > const & subs, ContentTimePeriod period)
 {
-       if (!_subtitle_content->has_subtitle_during (period)) {
+       if (!has_subtitle_during (period)) {
+               cout << "no subtitle during this period.\n";
                return list<shared_ptr<T> > ();
        }
 
@@ -71,7 +72,7 @@ SubtitleDecoder::get (list<shared_ptr<T> > const & subs, ContentTimePeriod perio
        
        list<shared_ptr<T> > out;
        for (typename list<shared_ptr<T> >::const_iterator i = subs.begin(); i != subs.end(); ++i) {
-               if ((*i)->period().from <= period.to && (*i)->period().to >= period.from) {
+               if ((*i)->period().overlaps (period)) {
                        out.push_back (*i);
                }
        }
index 164c151e671089a78140339ed836604f05bb018b..c25edad493a578160af52ec261214cbcaf0653aa 100644 (file)
@@ -51,6 +51,8 @@ private:
        template <class T>
        std::list<boost::shared_ptr<T> > get (std::list<boost::shared_ptr<T> > const & subs, ContentTimePeriod period);
 
+       virtual bool has_subtitle_during (ContentTimePeriod) const = 0;
+       
        boost::shared_ptr<const SubtitleContent> _subtitle_content;
 };
 
index 19caca59232411d31b1384fd6e82220635e4fbae..adb548f0c2344b1375620460d3efdaa2e2a53df0 100644 (file)
@@ -135,45 +135,45 @@ BOOST_AUTO_TEST_CASE (subrip_parse_test)
        vector<SubRipSubtitle>::const_iterator i = s._subtitles.begin();
 
        BOOST_CHECK (i != s._subtitles.end ());
-       BOOST_CHECK_EQUAL (i->from, ContentTime::from_seconds ((1 * 60) + 49.200));
-       BOOST_CHECK_EQUAL (i->to, ContentTime::from_seconds ((1 * 60) + 52.351));
+       BOOST_CHECK_EQUAL (i->period.from, ContentTime::from_seconds ((1 * 60) + 49.200));
+       BOOST_CHECK_EQUAL (i->period.to, ContentTime::from_seconds ((1 * 60) + 52.351));
        BOOST_CHECK_EQUAL (i->pieces.size(), 1);
        BOOST_CHECK_EQUAL (i->pieces.front().text, "This is a subtitle, and it goes over two lines.");
 
        ++i;
        BOOST_CHECK (i != s._subtitles.end ());
-       BOOST_CHECK_EQUAL (i->from, ContentTime::from_seconds ((1 * 60) + 52.440));
-       BOOST_CHECK_EQUAL (i->to, ContentTime::from_seconds ((1 * 60) + 54.351));
+       BOOST_CHECK_EQUAL (i->period.from, ContentTime::from_seconds ((1 * 60) + 52.440));
+       BOOST_CHECK_EQUAL (i->period.to, ContentTime::from_seconds ((1 * 60) + 54.351));
        BOOST_CHECK_EQUAL (i->pieces.size(), 1);
        BOOST_CHECK_EQUAL (i->pieces.front().text, "We have emboldened this");
        BOOST_CHECK_EQUAL (i->pieces.front().bold, true);
 
        ++i;
        BOOST_CHECK (i != s._subtitles.end ());
-       BOOST_CHECK_EQUAL (i->from, ContentTime::from_seconds ((1 * 60) + 54.440));
-       BOOST_CHECK_EQUAL (i->to, ContentTime::from_seconds ((1 * 60) + 56.590));
+       BOOST_CHECK_EQUAL (i->period.from, ContentTime::from_seconds ((1 * 60) + 54.440));
+       BOOST_CHECK_EQUAL (i->period.to, ContentTime::from_seconds ((1 * 60) + 56.590));
        BOOST_CHECK_EQUAL (i->pieces.size(), 1);
        BOOST_CHECK_EQUAL (i->pieces.front().text, "And italicised this.");
        BOOST_CHECK_EQUAL (i->pieces.front().italic, true);
 
        ++i;
        BOOST_CHECK (i != s._subtitles.end ());
-       BOOST_CHECK_EQUAL (i->from, ContentTime::from_seconds ((1 * 60) + 56.680));
-       BOOST_CHECK_EQUAL (i->to, ContentTime::from_seconds ((1 * 60) + 58.955));
+       BOOST_CHECK_EQUAL (i->period.from, ContentTime::from_seconds ((1 * 60) + 56.680));
+       BOOST_CHECK_EQUAL (i->period.to, ContentTime::from_seconds ((1 * 60) + 58.955));
        BOOST_CHECK_EQUAL (i->pieces.size(), 1);
        BOOST_CHECK_EQUAL (i->pieces.front().text, "Shall I compare thee to a summers' day?");
 
        ++i;
        BOOST_CHECK (i != s._subtitles.end ());
-       BOOST_CHECK_EQUAL (i->from, ContentTime::from_seconds ((2 * 60) + 0.840));
-       BOOST_CHECK_EQUAL (i->to, ContentTime::from_seconds ((2 * 60) + 3.400));
+       BOOST_CHECK_EQUAL (i->period.from, ContentTime::from_seconds ((2 * 60) + 0.840));
+       BOOST_CHECK_EQUAL (i->period.to, ContentTime::from_seconds ((2 * 60) + 3.400));
        BOOST_CHECK_EQUAL (i->pieces.size(), 1);
        BOOST_CHECK_EQUAL (i->pieces.front().text, "Is this a dagger I see before me?");
 
        ++i;
        BOOST_CHECK (i != s._subtitles.end ());
-       BOOST_CHECK_EQUAL (i->from, ContentTime::from_seconds ((3 * 60) + 54.560));
-       BOOST_CHECK_EQUAL (i->to, ContentTime::from_seconds ((3 * 60) + 56.471));
+       BOOST_CHECK_EQUAL (i->period.from, ContentTime::from_seconds ((3 * 60) + 54.560));
+       BOOST_CHECK_EQUAL (i->period.to, ContentTime::from_seconds ((3 * 60) + 56.471));
        BOOST_CHECK_EQUAL (i->pieces.size(), 1);
        BOOST_CHECK_EQUAL (i->pieces.front().text, "Hello world.");