Fix missing subtitle in some cases.
authorCarl Hetherington <cth@carlh.net>
Mon, 15 May 2017 14:54:52 +0000 (15:54 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 15 May 2017 14:54:52 +0000 (15:54 +0100)
With this timeline:
-------> t
SUB1   SUB2    X

We might seek to X, then pass().  Before this change, SUB1 would have been emitted by
the call to the subtitle decoder, then we'd have emitted some black for X.  This would
lose SUB2.  Now we keep pass()ing and don't emit X until it's the earliest thing
(in the same way that the main decision of what to pass() works).

src/lib/decoder.cc
src/lib/player.cc
src/lib/subtitle_decoder.cc
src/lib/subtitle_decoder.h

index 1b281f718fe68e7dfc65d906171ebe1a3a2a4c6f..1281897e011a6e8199347967fcee46ed6adf0763 100644 (file)
@@ -55,4 +55,7 @@ Decoder::seek (ContentTime, bool)
        if (audio) {
                audio->seek ();
        }
+       if (subtitle) {
+               subtitle->seek ();
+       }
 }
index d9f03b7a416168813be30f10c82d1150b866fef2..a711c80c03521ad24aa2dd7fb21372b87911c85d 100644 (file)
@@ -545,18 +545,20 @@ Player::pass ()
 
        /* Work out where to fill video from */
        optional<DCPTime> video_fill_from;
-       if (_last_video_time && !_playlist->video_content_at(_last_video_time.get())) {
-               /* No seek; fill towards the next thing that might happen (or the end of the playlist) */
+       if (_last_video_time && !_playlist->video_content_at(*_last_video_time)) {
+               /* No seek; fill from the last video time */
                video_fill_from = _last_video_time;
-       } else if (_last_seek_time && !_playlist->video_content_at(_last_seek_time.get())) {
+       } else if (_last_seek_time && !_playlist->video_content_at(*_last_seek_time)) {
                /* Seek into an empty area; fill from the seek time */
                video_fill_from = _last_seek_time;
        }
 
        bool filled = false;
-
-       if (video_fill_from && ((fill_towards - video_fill_from.get())) > one_video_frame()) {
-               emit_video (black_player_video_frame(), video_fill_from.get());
+       /* Fill some black if we would emit before the earliest piece of content.  This is so we act like a phantom
+          Piece which emits black in spaces (we only emit if we are the earliest thing)
+       */
+       if (earliest && video_fill_from && *video_fill_from < earliest_content && ((fill_towards - *video_fill_from)) > one_video_frame()) {
+               emit_video (black_player_video_frame(), *video_fill_from);
                filled = true;
        } else if (_playlist->length() == DCPTime()) {
                /* Special case of an empty Film; just give one black frame */
@@ -565,16 +567,16 @@ Player::pass ()
        }
 
        optional<DCPTime> audio_fill_from;
-       if (_last_audio_time && !_playlist->audio_content_at(_last_audio_time.get())) {
+       if (_last_audio_time && !_playlist->audio_content_at(*_last_audio_time)) {
                /* No seek; fill from the last thing that happened */
                audio_fill_from = _last_audio_time;
-       } else if (_last_seek_time && !_playlist->audio_content_at(_last_seek_time.get())) {
+       } else if (_last_seek_time && !_playlist->audio_content_at(*_last_seek_time)) {
                /* Seek into an empty area; fill from the seek time */
                audio_fill_from = _last_seek_time;
        }
 
        if (audio_fill_from && audio_fill_from < fill_towards) {
-               DCPTimePeriod period (audio_fill_from.get(), fill_towards);
+               DCPTimePeriod period (*audio_fill_from, fill_towards);
                if (period.duration() > one_video_frame()) {
                        period.to = period.from + one_video_frame();
                }
@@ -597,7 +599,7 @@ Player::pass ()
 
        list<pair<shared_ptr<AudioBuffers>, DCPTime> > audio = _audio_merger.pull (pull_from);
        for (list<pair<shared_ptr<AudioBuffers>, DCPTime> >::iterator i = audio.begin(); i != audio.end(); ++i) {
-               if (_last_audio_time && i->second < _last_audio_time.get()) {
+               if (_last_audio_time && i->second < *_last_audio_time) {
                        /* There has been an accurate seek and we have received some audio before the seek time;
                           discard it.
                        */
@@ -609,7 +611,7 @@ Player::pass ()
                }
 
                if (_last_audio_time) {
-                       fill_audio (DCPTimePeriod (_last_audio_time.get(), i->second));
+                       fill_audio (DCPTimePeriod (*_last_audio_time, i->second));
                }
 
                emit_audio (i->first, i->second);
@@ -664,7 +666,7 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
        if (
                time < piece->content->position() ||
                time >= piece->content->end() ||
-               (_last_seek_time && _last_seek_accurate && time < _last_seek_time.get())) {
+               (_last_seek_time && _last_seek_accurate && time < *_last_seek_time)) {
                return;
        }
 
@@ -674,7 +676,7 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
 
        if (_last_video_time) {
                /* XXX: this may not work for 3D */
-               BOOST_FOREACH (DCPTimePeriod i, subtract(DCPTimePeriod (_last_video_time.get(), time), _no_video)) {
+               BOOST_FOREACH (DCPTimePeriod i, subtract(DCPTimePeriod (*_last_video_time, time), _no_video)) {
                        for (DCPTime j = i.from; j < i.to; j += one_video_frame()) {
                                if (_last_video) {
                                        emit_video (shared_ptr<PlayerVideo> (new PlayerVideo (*_last_video)), j);
index 43ee4c457c040c658f415180aef2db4536b58549..4e68e4a79ffb596962c518c9250c41f66b5c06fe 100644 (file)
@@ -210,3 +210,9 @@ SubtitleDecoder::emit_text (ContentTimePeriod period, sub::Subtitle const & s)
        emit_text_start (period.from, s);
        emit_stop (period.to);
 }
+
+void
+SubtitleDecoder::seek ()
+{
+       _position = ContentTime ();
+}
index 92a6266de4b96d19534a5a70e1eea7a15cc7117f..9740b06e8644f8ed93872eb62884ed6cfa63b1ae 100644 (file)
@@ -59,6 +59,8 @@ public:
        void emit_text (ContentTimePeriod period, sub::Subtitle const & subtitle);
        void emit_stop (ContentTime to);
 
+       void seek ();
+
        boost::shared_ptr<const SubtitleContent> content () const {
                return _content;
        }