Only put subtitles in a frame if they overlap more than half of that
authorCarl Hetherington <cth@carlh.net>
Sun, 14 Jan 2018 02:27:04 +0000 (02:27 +0000)
committerCarl Hetherington <cth@carlh.net>
Sun, 14 Jan 2018 02:27:04 +0000 (02:27 +0000)
frame; may help with #1166.

src/lib/active_subtitles.cc
src/lib/active_subtitles.h
src/lib/dcp_decoder.cc
src/lib/player.cc

index ff6724a..bc34a89 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2017 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2017-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -29,13 +29,14 @@ using std::pair;
 using std::make_pair;
 using boost::weak_ptr;
 using boost::shared_ptr;
+using boost::optional;
 
-/** Get the subtitles that should be burnt into a frame at a given time.
- *  @param time Frame time.
+/** Get the subtitles that should be burnt into a given period.
+ *  @param period Period of interest.
  *  @param always_burn_subtitles Always burn subtitles even if their content is not set to burn.
  */
 list<PlayerSubtitles>
-ActiveSubtitles::get_burnt (DCPTime time, bool always_burn_subtitles) const
+ActiveSubtitles::get_burnt (DCPTimePeriod period, bool always_burn_subtitles) const
 {
        list<PlayerSubtitles> ps;
 
@@ -52,7 +53,9 @@ ActiveSubtitles::get_burnt (DCPTime time, bool always_burn_subtitles) const
                }
 
                BOOST_FOREACH (Period j, i->second) {
-                       if (j.from <= time && (!j.to || j.to.get() > time)) {
+                       DCPTimePeriod test (j.from, j.to.get_value_or(DCPTime::max()));
+                       optional<DCPTimePeriod> overlap = period.overlap (test);
+                       if (overlap && overlap->duration() > DCPTime(period.duration().get() / 2)) {
                                ps.push_back (j.subs);
                        }
                }
index 97ca4c7..1496bc5 100644 (file)
@@ -36,7 +36,7 @@ class Piece;
 class ActiveSubtitles : public boost::noncopyable
 {
 public:
-       std::list<PlayerSubtitles> get_burnt (DCPTime time, bool always_burn_subtitles) const;
+       std::list<PlayerSubtitles> get_burnt (DCPTimePeriod period, bool always_burn_subtitles) const;
        void clear_before (DCPTime time);
        void clear ();
        void add_from (boost::weak_ptr<Piece> piece, PlayerSubtitles ps, DCPTime from);
index 23b8347..68aa214 100644 (file)
@@ -189,12 +189,14 @@ DCPDecoder::pass_subtitles (ContentTime next)
                        );
 
                BOOST_FOREACH (dcp::SubtitleString i, subs) {
+                       list<dcp::SubtitleString> s;
+                       s.push_back (i);
                        subtitle->emit_text (
                                ContentTimePeriod (
                                        ContentTime::from_frames (_offset - entry_point, vfr) + ContentTime::from_seconds (i.in().as_seconds ()),
                                        ContentTime::from_frames (_offset - entry_point, vfr) + ContentTime::from_seconds (i.out().as_seconds ())
                                        ),
-                               subs
+                               s
                                );
                }
        }
index 8e56991..eb8593e 100644 (file)
@@ -624,7 +624,7 @@ Player::subtitles_for_frame (DCPTime time) const
 {
        list<PositionImage> subtitles;
 
-       BOOST_FOREACH (PlayerSubtitles i, _active_subtitles.get_burnt (time, _always_burn_subtitles)) {
+       BOOST_FOREACH (PlayerSubtitles i, _active_subtitles.get_burnt (DCPTimePeriod(time, time + DCPTime::from_frames(1, _film->video_frame_rate())),  _always_burn_subtitles)) {
 
                /* Image subtitles */
                list<PositionImage> c = transform_image_subtitles (i.image);