summaryrefslogtreecommitdiff
path: root/src/lib/player.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-07-10 20:29:00 +0100
committerCarl Hetherington <cth@carlh.net>2013-07-10 20:29:00 +0100
commit320a74efb8d9c8aacded2799459a92d5b7235d90 (patch)
tree1f547cb3cde20bd025dabddc6209390e22826b6a /src/lib/player.cc
parent623f3c66821d6a99bf0e683a8072b99a168f3a1c (diff)
Make subtitles work at least a bit.
Diffstat (limited to 'src/lib/player.cc')
-rw-r--r--src/lib/player.cc77
1 files changed, 51 insertions, 26 deletions
diff --git a/src/lib/player.cc b/src/lib/player.cc
index c615f0a89..58ba57bdc 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -32,7 +32,7 @@
#include "image.h"
#include "ratio.h"
#include "resampler.h"
-#include "subtitle.h"
+#include "scaler.h"
using std::list;
using std::cout;
@@ -45,7 +45,7 @@ using boost::shared_ptr;
using boost::weak_ptr;
using boost::dynamic_pointer_cast;
-#define DEBUG_PLAYER 1
+//#define DEBUG_PLAYER 1
class Piece
{
@@ -225,22 +225,8 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image
Time time = content->start() + (frame * frc.factor() * TIME_HZ / _film->dcp_video_frame_rate());
- if (_film->with_subtitles ()) {
- shared_ptr<Subtitle> sub;
- if (_subtitle && _subtitle->displayed_at (time - _subtitle_content_time)) {
- sub = _subtitle->subtitle ();
- }
-
- if (sub) {
- dcpomatic::Rect const tx = subtitle_transformed_area (
- float (image_size.width) / content->video_size().width,
- float (image_size.height) / content->video_size().height,
- sub->area(), _subtitle_offset, _subtitle_scale
- );
-
- shared_ptr<Image> im = sub->image()->scale (tx.size(), _film->scaler(), true);
- work_image->alpha_blend (im, tx.position());
- }
+ if (_film->with_subtitles () && _out_subtitle.image && time >= _out_subtitle.from && time <= _out_subtitle.to) {
+ work_image->alpha_blend (_out_subtitle.image, _out_subtitle.position);
}
if (image_size != _video_container_size) {
@@ -248,7 +234,7 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image
assert (image_size.height <= _video_container_size.height);
shared_ptr<Image> im (new SimpleImage (PIX_FMT_RGB24, _video_container_size, true));
im->make_black ();
- im->copy (work_image, Position ((_video_container_size.width - image_size.width) / 2, (_video_container_size.height - image_size.height) / 2));
+ im->copy (work_image, Position<int> ((_video_container_size.width - image_size.width) / 2, (_video_container_size.height - image_size.height) / 2));
work_image = im;
}
@@ -390,7 +376,7 @@ Player::setup_pieces ()
fd->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3));
fd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
- fd->Subtitle.connect (bind (&Player::process_subtitle, this, piece, _1));
+ fd->Subtitle.connect (bind (&Player::process_subtitle, this, piece, _1, _2, _3, _4));
piece->decoder = fd;
}
@@ -449,6 +435,10 @@ Player::content_changed (weak_ptr<Content> w, int p)
_have_valid_pieces = false;
Changed ();
+
+ } else if (p == SubtitleContentProperty::SUBTITLE_OFFSET || p == SubtitleContentProperty::SUBTITLE_SCALE) {
+ update_subtitle ();
+ Changed ();
}
}
@@ -512,9 +502,21 @@ Player::film_changed (Film::Property p)
}
void
-Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<TimedSubtitle> sub)
+Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<Image> image, dcpomatic::Rect<double> rect, Time from, Time to)
{
- shared_ptr<Piece> piece = weak_piece.lock ();
+ _in_subtitle.piece = weak_piece;
+ _in_subtitle.image = image;
+ _in_subtitle.rect = rect;
+ _in_subtitle.from = from;
+ _in_subtitle.to = to;
+
+ update_subtitle ();
+}
+
+void
+Player::update_subtitle ()
+{
+ shared_ptr<Piece> piece = _in_subtitle.piece.lock ();
if (!piece) {
return;
}
@@ -522,8 +524,31 @@ Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<TimedSubtitle>
shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (piece->content);
assert (sc);
- _subtitle = sub;
- _subtitle_content_time = piece->content->start ();
- _subtitle_offset = sc->subtitle_offset ();
- _subtitle_scale = sc->subtitle_scale ();
+ dcpomatic::Rect<double> in_rect = _in_subtitle.rect;
+ libdcp::Size scaled_size;
+
+ in_rect.y += sc->subtitle_offset ();
+
+ /* We will scale the subtitle up to fit _video_container_size, and also by the additional subtitle_scale */
+ scaled_size.width = in_rect.width * _video_container_size.width * sc->subtitle_scale ();
+ scaled_size.height = in_rect.height * _video_container_size.height * sc->subtitle_scale ();
+
+ /* Then we need a corrective translation, consisting of two parts:
+ *
+ * 1. that which is the result of the scaling of the subtitle by _video_container_size; this will be
+ * rect.x * _video_container_size.width and rect.y * _video_container_size.height.
+ *
+ * 2. that to shift the origin of the scale by subtitle_scale to the centre of the subtitle; this will be
+ * (width_before_subtitle_scale * (1 - subtitle_scale) / 2) and
+ * (height_before_subtitle_scale * (1 - subtitle_scale) / 2).
+ *
+ * Combining these two translations gives these expressions.
+ */
+
+ _out_subtitle.position.x = rint (_video_container_size.width * (in_rect.x + (in_rect.width * (1 - sc->subtitle_scale ()) / 2)));
+ _out_subtitle.position.y = rint (_video_container_size.height * (in_rect.y + (in_rect.height * (1 - sc->subtitle_scale ()) / 2)));
+
+ _out_subtitle.image = _in_subtitle.image->scale (libdcp::Size (scaled_size.width, scaled_size.height), Scaler::from_id ("bicubic"), true);
+ _out_subtitle.from = _in_subtitle.from + piece->content->start ();
+ _out_subtitle.to = _in_subtitle.to + piece->content->start ();
}