diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-10 20:29:00 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-10 20:29:00 +0100 |
| commit | 320a74efb8d9c8aacded2799459a92d5b7235d90 (patch) | |
| tree | 1f547cb3cde20bd025dabddc6209390e22826b6a /src/lib/player.cc | |
| parent | 623f3c66821d6a99bf0e683a8072b99a168f3a1c (diff) | |
Make subtitles work at least a bit.
Diffstat (limited to 'src/lib/player.cc')
| -rw-r--r-- | src/lib/player.cc | 77 |
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 (); } |
