From 4bfeba59854f5097c84b3c58f61b00ea36acae3f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 15 May 2017 15:54:52 +0100 Subject: Fix missing subtitle in some cases. 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 | 3 +++ src/lib/player.cc | 28 +++++++++++++++------------- src/lib/subtitle_decoder.cc | 6 ++++++ src/lib/subtitle_decoder.h | 2 ++ 4 files changed, 26 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index 1b281f718..1281897e0 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -55,4 +55,7 @@ Decoder::seek (ContentTime, bool) if (audio) { audio->seek (); } + if (subtitle) { + subtitle->seek (); + } } diff --git a/src/lib/player.cc b/src/lib/player.cc index d9f03b7a4..a711c80c0 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -545,18 +545,20 @@ Player::pass () /* Work out where to fill video from */ optional 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 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, DCPTime> > audio = _audio_merger.pull (pull_from); for (list, 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 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 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 (new PlayerVideo (*_last_video)), j); diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc index 43ee4c457..4e68e4a79 100644 --- a/src/lib/subtitle_decoder.cc +++ b/src/lib/subtitle_decoder.cc @@ -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 (); +} diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h index 92a6266de..9740b06e8 100644 --- a/src/lib/subtitle_decoder.h +++ b/src/lib/subtitle_decoder.h @@ -59,6 +59,8 @@ public: void emit_text (ContentTimePeriod period, sub::Subtitle const & subtitle); void emit_stop (ContentTime to); + void seek (); + boost::shared_ptr content () const { return _content; } -- cgit v1.2.3