Keep active subtitles around until the video they are on has been emitted.
authorCarl Hetherington <cth@carlh.net>
Fri, 5 May 2017 13:06:47 +0000 (14:06 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 5 May 2017 13:06:47 +0000 (14:06 +0100)
src/lib/player.cc
src/lib/player.h

index 3de26ec90fcae36e18f5c07cd62622d525aacaed..06a1b008dab2aad08ac8e01600114c55e2a4c2ba 100644 (file)
@@ -626,7 +626,7 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
 
        optional<PositionImage> subtitles;
 
-       for (ActiveSubtitles::const_iterator i = _active_subtitles.begin(); i != _active_subtitles.end(); ++i) {
+       for (ActiveSubtitlesMap::const_iterator i = _active_subtitles.begin(); i != _active_subtitles.end(); ++i) {
 
                shared_ptr<Piece> sub_piece = i->first.lock ();
                if (!sub_piece) {
@@ -637,17 +637,21 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
                        continue;
                }
 
-               pair<PlayerSubtitles, DCPTime> sub = i->second;
+               ActiveSubtitles sub = i->second;
+
+               if (sub.from > time || (sub.to && sub.to.get() <= time)) {
+                       continue;
+               }
 
                list<PositionImage> sub_images;
 
                /* Image subtitles */
-               list<PositionImage> c = transform_image_subtitles (sub.first.image);
+               list<PositionImage> c = transform_image_subtitles (sub.subs.image);
                copy (c.begin(), c.end(), back_inserter (sub_images));
 
                /* Text subtitles (rendered to an image) */
-               if (!sub.first.text.empty ()) {
-                       list<PositionImage> s = render_subtitles (sub.first.text, sub.first.fonts, _video_container_size, time);
+               if (!sub.subs.text.empty ()) {
+                       list<PositionImage> s = render_subtitles (sub.subs.text, sub.subs.fonts, _video_container_size, time);
                        copy (s.begin (), s.end (), back_inserter (sub_images));
                }
 
@@ -684,6 +688,15 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
        Video (_last_video, time);
 
        _last_video_time = time + one_video_frame ();
+
+       /* Clear any finished _active_subtitles */
+       ActiveSubtitlesMap updated;
+       for (ActiveSubtitlesMap::const_iterator i = _active_subtitles.begin(); i != _active_subtitles.end(); ++i) {
+               if (!i->second.to || i->second.to.get() >= time) {
+                       updated[i->first] = i->second;
+               }
+       }
+       _active_subtitles = updated;
 }
 
 void
@@ -836,7 +849,7 @@ Player::image_subtitle_start (weak_ptr<Piece> wp, ContentImageSubtitle subtitle)
        ps.image.push_back (subtitle.sub);
        DCPTime from (content_time_to_dcp (piece, subtitle.from()));
 
-       _active_subtitles[wp] = make_pair (ps, from);
+       _active_subtitles[wp] = ActiveSubtitles (ps, from);
 }
 
 void
@@ -875,7 +888,7 @@ Player::text_subtitle_start (weak_ptr<Piece> wp, ContentTextSubtitle subtitle)
                ps.add_fonts (piece->content->subtitle->fonts ());
        }
 
-       _active_subtitles[wp] = make_pair (ps, from);
+       _active_subtitles[wp] = ActiveSubtitles (ps, from);
 }
 
 void
@@ -890,11 +903,13 @@ Player::subtitle_stop (weak_ptr<Piece> wp, ContentTime to)
                return;
        }
 
+       DCPTime const dcp_to = content_time_to_dcp (piece, to);
+
        if (piece->content->subtitle->use() && !_always_burn_subtitles && !piece->content->subtitle->burn()) {
-               Subtitle (_active_subtitles[wp].first, DCPTimePeriod (_active_subtitles[wp].second, content_time_to_dcp (piece, to)));
+               Subtitle (_active_subtitles[wp].subs, DCPTimePeriod (_active_subtitles[wp].from, dcp_to));
        }
 
-       _active_subtitles.erase (wp);
+       _active_subtitles[wp].to = dcp_to;
 }
 
 void
index 719e4289595485ffa46153de92f7944194dcbdfe..18b47043a11f1be643c77b08038f4f686af112be 100644 (file)
@@ -152,7 +152,8 @@ private:
 
        AudioMerger _audio_merger;
 
-       class StreamState {
+       class StreamState
+       {
        public:
                StreamState () {}
 
@@ -169,8 +170,22 @@ private:
        std::list<DCPTimePeriod> _no_video;
        std::list<DCPTimePeriod> _no_audio;
 
-       typedef std::map<boost::weak_ptr<Piece>, std::pair<PlayerSubtitles, DCPTime> > ActiveSubtitles;
-       ActiveSubtitles _active_subtitles;
+       class ActiveSubtitles
+       {
+       public:
+               ActiveSubtitles () {}
+
+               ActiveSubtitles (PlayerSubtitles s, DCPTime f)
+                       : subs (s)
+                       , from (f)
+               {}
+
+               PlayerSubtitles subs;
+               DCPTime from;
+               boost::optional<DCPTime> to;
+       };
+       typedef std::map<boost::weak_ptr<Piece>, ActiveSubtitles> ActiveSubtitlesMap;
+       ActiveSubtitlesMap _active_subtitles;
 
        boost::shared_ptr<AudioProcessor> _audio_processor;
        typedef std::map<std::pair<boost::shared_ptr<const AudioContent>, AudioStreamPtr>, boost::shared_ptr<Resampler> > ResamplerMap;