)
);
- 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
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 (
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.
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
+#include <boost/optional.hpp>
#include <libdcp/util.h>
#include "rect.h"
#include "types.h"
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;
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;
Position<int> _out_position;
Time _out_from;
Time _out_to;
+
+ /** Time at which this subtitle should stop (overriding _out_to) */
+ boost::optional<Time> _stop;
};