diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-04-25 23:43:16 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-04-25 23:43:16 +0100 |
| commit | 9c1e0071803bf05f8c476d870e360c9e320ba696 (patch) | |
| tree | c94a825ad7a32495fa7e372ce79247e69c84c272 /src | |
| parent | 588397fc600e888acf77375fe39c238ff2bf3649 (diff) | |
Fix subtitle display when the next subtitle is decoded before the
previous one has finished; this requires that more than one subtitle be
kept by the player.
Reported-by: Matthias Damm
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/player.cc | 47 | ||||
| -rw-r--r-- | src/lib/player.h | 2 | ||||
| -rw-r--r-- | src/lib/subtitle.cc | 10 | ||||
| -rw-r--r-- | src/lib/subtitle.h | 15 |
4 files changed, 61 insertions, 13 deletions
diff --git a/src/lib/player.cc b/src/lib/player.cc index d0653bc43..1bb2e7cf4 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -219,17 +219,34 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image ) ); - if (_film->with_subtitles () && _subtitle && _subtitle->out_image() && _subtitle->covers (time)) { + if (_film->with_subtitles ()) { + for (list<Subtitle>::const_iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { + if (i->covers (time)) { + /* This may be true for more than one of _subtitles, but the last (latest-starting) + one is the one we want to use, so that's ok. + */ + Position<int> const container_offset ( + (_video_container_size.width - image_size.width) / 2, + (_video_container_size.height - image_size.width) / 2 + ); + + pi->set_subtitle (i->out_image(), i->out_position() + container_offset); + } + } + } - Position<int> const container_offset ( - (_video_container_size.width - image_size.width) / 2, - (_video_container_size.height - image_size.width) / 2 - ); + /* Clear out old subtitles */ + for (list<Subtitle>::iterator i = _subtitles.begin(); i != _subtitles.end(); ) { + list<Subtitle>::iterator j = i; + ++j; + + if (i->ends_before (time)) { + _subtitles.erase (i); + } - pi->set_subtitle (_subtitle->out_image(), _subtitle->out_position() + container_offset); + i = j; } - - + #ifdef DCPOMATIC_DEBUG _last_video = piece->content; #endif @@ -466,9 +483,10 @@ Player::content_changed (weak_ptr<Content> w, int property, bool frequent) property == SubtitleContentProperty::SUBTITLE_SCALE ) { - if (_subtitle) { - _subtitle->update (_film, _video_container_size); + for (list<Subtitle>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { + i->update (_film, _video_container_size); } + Changed (frequent); } else if ( @@ -576,7 +594,14 @@ Player::film_changed (Film::Property p) void Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<Image> image, dcpomatic::Rect<double> rect, Time from, Time to) { - _subtitle = Subtitle (_film, _video_container_size, weak_piece, image, rect, from, to); + if (!image) { + /* A null image means that we should stop any current subtitles at `from' */ + for (list<Subtitle>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { + i->set_stop (from); + } + } else { + _subtitles.push_back (Subtitle (_film, _video_container_size, weak_piece, image, rect, from, to)); + } } /** Re-emit the last frame that was emitted, using current settings for crop, ratio, scaler and subtitles. diff --git a/src/lib/player.h b/src/lib/player.h index 5dad80ec7..4d911a83b 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -143,7 +143,7 @@ private: boost::shared_ptr<PlayerImage> _black_frame; std::map<boost::shared_ptr<AudioContent>, boost::shared_ptr<Resampler> > _resamplers; - boost::optional<Subtitle> _subtitle; + std::list<Subtitle> _subtitles; #ifdef DCPOMATIC_DEBUG boost::shared_ptr<Content> _last_video; diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc index f348833b0..0d18861c4 100644 --- a/src/lib/subtitle.cc +++ b/src/lib/subtitle.cc @@ -97,6 +97,8 @@ Subtitle::update (shared_ptr<const Film> film, libdcp::Size video_container_size _out_from = from + piece->content->position (); _out_to = to + piece->content->position (); + + check_out_to (); } bool @@ -104,3 +106,11 @@ Subtitle::covers (Time t) const { return _out_from <= t && t <= _out_to; } + +void +Subtitle::check_out_to () +{ + if (_stop && _out_to > _stop.get ()) { + _out_to = _stop.get (); + } +} diff --git a/src/lib/subtitle.h b/src/lib/subtitle.h index 7ba5912e0..c74f5c1b9 100644 --- a/src/lib/subtitle.h +++ b/src/lib/subtitle.h @@ -19,6 +19,7 @@ #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> +#include <boost/optional.hpp> #include <libdcp/util.h> #include "rect.h" #include "types.h" @@ -34,8 +35,15 @@ public: Subtitle (boost::shared_ptr<const Film>, libdcp::Size, boost::weak_ptr<Piece>, boost::shared_ptr<Image>, dcpomatic::Rect<double>, Time, Time); void update (boost::shared_ptr<const Film>, libdcp::Size); + void set_stop (Time t) { + _stop = t; + check_out_to (); + } bool covers (Time t) const; + bool ends_before (Time t) const { + return _out_to < t; + } boost::shared_ptr<Image> out_image () const { return _out_image; @@ -45,7 +53,9 @@ public: return _out_position; } -private: +private: + void check_out_to (); + boost::weak_ptr<Piece> _piece; boost::shared_ptr<Image> _in_image; dcpomatic::Rect<double> _in_rect; @@ -56,4 +66,7 @@ private: Position<int> _out_position; Time _out_from; Time _out_to; + + /** Time at which this subtitle should stop (overriding _out_to) */ + boost::optional<Time> _stop; }; |
