summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-04-25 23:43:16 +0100
committerCarl Hetherington <cth@carlh.net>2014-04-25 23:43:16 +0100
commit9c1e0071803bf05f8c476d870e360c9e320ba696 (patch)
treec94a825ad7a32495fa7e372ce79247e69c84c272 /src
parent588397fc600e888acf77375fe39c238ff2bf3649 (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.cc47
-rw-r--r--src/lib/player.h2
-rw-r--r--src/lib/subtitle.cc10
-rw-r--r--src/lib/subtitle.h15
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;
};