From 588397fc600e888acf77375fe39c238ff2bf3649 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 25 Apr 2014 23:27:42 +0100 Subject: [PATCH] Collect player subtitle processing into a Subtitle class. --- src/lib/player.cc | 77 +++----------------------------- src/lib/player.h | 16 +------ src/lib/subtitle.cc | 106 ++++++++++++++++++++++++++++++++++++++++++++ src/lib/subtitle.h | 59 ++++++++++++++++++++++++ src/lib/wscript | 1 + 5 files changed, 174 insertions(+), 85 deletions(-) create mode 100644 src/lib/subtitle.cc create mode 100644 src/lib/subtitle.h diff --git a/src/lib/player.cc b/src/lib/player.cc index 7afe74831..d0653bc43 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -219,14 +219,14 @@ Player::process_video (weak_ptr weak_piece, shared_ptr image ) ); - if (_film->with_subtitles () && _out_subtitle.image && time >= _out_subtitle.from && time <= _out_subtitle.to) { + if (_film->with_subtitles () && _subtitle && _subtitle->out_image() && _subtitle->covers (time)) { Position const container_offset ( (_video_container_size.width - image_size.width) / 2, (_video_container_size.height - image_size.width) / 2 ); - pi->set_subtitle (_out_subtitle.image, _out_subtitle.position + container_offset); + pi->set_subtitle (_subtitle->out_image(), _subtitle->out_position() + container_offset); } @@ -466,7 +466,9 @@ Player::content_changed (weak_ptr w, int property, bool frequent) property == SubtitleContentProperty::SUBTITLE_SCALE ) { - update_subtitle (); + if (_subtitle) { + _subtitle->update (_film, _video_container_size); + } Changed (frequent); } else if ( @@ -574,74 +576,7 @@ Player::film_changed (Film::Property p) void Player::process_subtitle (weak_ptr weak_piece, shared_ptr image, dcpomatic::Rect rect, Time from, Time to) { - _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 = _in_subtitle.piece.lock (); - if (!piece) { - return; - } - - if (!_in_subtitle.image) { - _out_subtitle.image.reset (); - return; - } - - shared_ptr sc = dynamic_pointer_cast (piece->content); - assert (sc); - - dcpomatic::Rect in_rect = _in_subtitle.rect; - libdcp::Size scaled_size; - - in_rect.x += sc->subtitle_x_offset (); - in_rect.y += sc->subtitle_y_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 ( - scaled_size, - Scaler::from_id ("bicubic"), - _in_subtitle.image->pixel_format (), - true - ); - - /* XXX: hack */ - Time from = _in_subtitle.from; - Time to = _in_subtitle.to; - shared_ptr vc = dynamic_pointer_cast (piece->content); - if (vc) { - from = rint (from * vc->video_frame_rate() / _film->video_frame_rate()); - to = rint (to * vc->video_frame_rate() / _film->video_frame_rate()); - } - - _out_subtitle.from = from + piece->content->position (); - _out_subtitle.to = to + piece->content->position (); + _subtitle = 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 4368f48ba..5dad80ec7 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -30,6 +30,7 @@ #include "audio_merger.h" #include "audio_content.h" #include "piece.h" +#include "subtitle.h" class Job; class Film; @@ -142,20 +143,7 @@ private: boost::shared_ptr _black_frame; std::map, boost::shared_ptr > _resamplers; - struct { - boost::weak_ptr piece; - boost::shared_ptr image; - dcpomatic::Rect rect; - Time from; - Time to; - } _in_subtitle; - - struct { - boost::shared_ptr image; - Position position; - Time from; - Time to; - } _out_subtitle; + boost::optional _subtitle; #ifdef DCPOMATIC_DEBUG boost::shared_ptr _last_video; diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc new file mode 100644 index 000000000..f348833b0 --- /dev/null +++ b/src/lib/subtitle.cc @@ -0,0 +1,106 @@ +/* + Copyright (C) 2013-2014 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "subtitle.h" +#include "subtitle_content.h" +#include "piece.h" +#include "image.h" +#include "scaler.h" +#include "film.h" + +using boost::shared_ptr; +using boost::dynamic_pointer_cast; +using boost::weak_ptr; + +Subtitle::Subtitle (shared_ptr film, libdcp::Size video_container_size, weak_ptr weak_piece, shared_ptr image, dcpomatic::Rect rect, Time from, Time to) + : _piece (weak_piece) + , _in_image (image) + , _in_rect (rect) + , _in_from (from) + , _in_to (to) +{ + update (film, video_container_size); +} + +void +Subtitle::update (shared_ptr film, libdcp::Size video_container_size) +{ + shared_ptr piece = _piece.lock (); + if (!piece) { + return; + } + + if (!_in_image) { + _out_image.reset (); + return; + } + + shared_ptr sc = dynamic_pointer_cast (piece->content); + assert (sc); + + dcpomatic::Rect in_rect = _in_rect; + libdcp::Size scaled_size; + + in_rect.x += sc->subtitle_x_offset (); + in_rect.y += sc->subtitle_y_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_position.x = rint (video_container_size.width * (in_rect.x + (in_rect.width * (1 - sc->subtitle_scale ()) / 2))); + _out_position.y = rint (video_container_size.height * (in_rect.y + (in_rect.height * (1 - sc->subtitle_scale ()) / 2))); + + _out_image = _in_image->scale ( + scaled_size, + Scaler::from_id ("bicubic"), + _in_image->pixel_format (), + true + ); + + /* XXX: hack */ + Time from = _in_from; + Time to = _in_to; + shared_ptr vc = dynamic_pointer_cast (piece->content); + if (vc) { + from = rint (from * vc->video_frame_rate() / film->video_frame_rate()); + to = rint (to * vc->video_frame_rate() / film->video_frame_rate()); + } + + _out_from = from + piece->content->position (); + _out_to = to + piece->content->position (); +} + +bool +Subtitle::covers (Time t) const +{ + return _out_from <= t && t <= _out_to; +} diff --git a/src/lib/subtitle.h b/src/lib/subtitle.h new file mode 100644 index 000000000..7ba5912e0 --- /dev/null +++ b/src/lib/subtitle.h @@ -0,0 +1,59 @@ +/* + Copyright (C) 2013-2014 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include "rect.h" +#include "types.h" + +class Film; +class Piece; +class Image; + +class Subtitle +{ +public: + + Subtitle (boost::shared_ptr, libdcp::Size, boost::weak_ptr, boost::shared_ptr, dcpomatic::Rect, Time, Time); + + void update (boost::shared_ptr, libdcp::Size); + + bool covers (Time t) const; + + boost::shared_ptr out_image () const { + return _out_image; + } + + Position out_position () const { + return _out_position; + } + +private: + boost::weak_ptr _piece; + boost::shared_ptr _in_image; + dcpomatic::Rect _in_rect; + Time _in_from; + Time _in_to; + + boost::shared_ptr _out_image; + Position _out_position; + Time _out_from; + Time _out_to; +}; diff --git a/src/lib/wscript b/src/lib/wscript index dc90e17f3..d4231fd30 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -53,6 +53,7 @@ sources = """ sndfile_content.cc sndfile_decoder.cc sound_processor.cc + subtitle.cc subtitle_content.cc subtitle_decoder.cc timer.cc -- 2.30.2