diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-11 14:29:55 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-11 14:29:55 +0100 |
| commit | b655bd3359e9a014da68cd9f61e2a5b1d233247d (patch) | |
| tree | 42ab16fdc9621fd0314a71f051804cdacd1cb823 /src/lib | |
| parent | e64acff7da897cd03d88aa9e8e21682545a61cc2 (diff) | |
| parent | 2514ffcd1adcca4fc8e3db894afb5cdc6c857e94 (diff) | |
Merge branch '1.0' of /home/carl/git/dvdomatic into 1.0
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/combiner.cc | 74 | ||||
| -rw-r--r-- | src/lib/content.h | 1 | ||||
| -rw-r--r-- | src/lib/decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.cc | 4 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.h | 3 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 94 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/film.cc | 28 | ||||
| -rw-r--r-- | src/lib/film.h | 20 | ||||
| -rw-r--r-- | src/lib/image.cc | 4 | ||||
| -rw-r--r-- | src/lib/image.h | 5 | ||||
| -rw-r--r-- | src/lib/player.cc | 104 | ||||
| -rw-r--r-- | src/lib/player.h | 18 | ||||
| -rw-r--r-- | src/lib/position.h | 46 | ||||
| -rw-r--r-- | src/lib/rect.h | 79 | ||||
| -rw-r--r-- | src/lib/server.cc | 1 | ||||
| -rw-r--r-- | src/lib/subtitle.cc | 149 | ||||
| -rw-r--r-- | src/lib/subtitle.h | 81 | ||||
| -rw-r--r-- | src/lib/subtitle_content.cc | 72 | ||||
| -rw-r--r-- | src/lib/subtitle_content.h | 62 | ||||
| -rw-r--r-- | src/lib/subtitle_decoder.cc | 39 | ||||
| -rw-r--r-- | src/lib/subtitle_decoder.h | 37 | ||||
| -rw-r--r-- | src/lib/types.cc | 22 | ||||
| -rw-r--r-- | src/lib/types.h | 62 | ||||
| -rw-r--r-- | src/lib/util.cc | 4 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 21 | ||||
| -rw-r--r-- | src/lib/wscript | 3 |
27 files changed, 515 insertions, 524 deletions
diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc deleted file mode 100644 index f7d634832..000000000 --- a/src/lib/combiner.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> - - 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 "combiner.h" -#include "image.h" - -using boost::shared_ptr; - -Combiner::Combiner (shared_ptr<Log> log) - : TimedVideoProcessor (log) -{ - -} - -/** Process video for the left half of the frame. - * Subtitle parameter will be ignored. - * @param image Frame image. - */ -void -Combiner::process_video (shared_ptr<const Image> image, bool, shared_ptr<Subtitle>, double) -{ - _image.reset (new SimpleImage (image)); -} - -/** Process video for the right half of the frame. - * @param image Frame image. - * @param sub Subtitle (which will be put onto the whole frame) - */ -void -Combiner::process_video_b (shared_ptr<const Image> image, bool, shared_ptr<Subtitle> sub, double t) -{ - if (!_image) { - /* It's possible for filters in the A-side to mean that we get a B frame - before any A; just skip the B frame in that case. This at least prevents - a crash, but may not be right. - */ - return; - } - - /* Copy the right half of this image into our _image */ - /* XXX: this should probably be in the Image class */ - for (int i = 0; i < image->components(); ++i) { - int const line_size = image->line_size()[i]; - int const half_line_size = line_size / 2; - - uint8_t* p = _image->data()[i]; - uint8_t* q = image->data()[i]; - - for (int j = 0; j < image->lines (i); ++j) { - memcpy (p + half_line_size, q + half_line_size, half_line_size); - p += _image->stride()[i]; - q += image->stride()[i]; - } - } - - Video (_image, false, sub, t); - _image.reset (); -} diff --git a/src/lib/content.h b/src/lib/content.h index e33f517ab..5dcf27597 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -48,6 +48,7 @@ public: Content (boost::shared_ptr<const Film>, boost::filesystem::path); Content (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); Content (Content const &); + virtual ~Content () {} virtual void examine (boost::shared_ptr<Job>); virtual std::string summary () const = 0; diff --git a/src/lib/decoder.h b/src/lib/decoder.h index cfca6867f..dea4def3a 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -34,8 +34,6 @@ class Image; class Log; class DelayLine; -class TimedSubtitle; -class Subtitle; class FilterGraph; /** @class Decoder. diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 1135cc9a3..35f9f71f2 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -47,6 +47,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> f, boost::filesystem::path : Content (f, p) , VideoContent (f, p) , AudioContent (f, p) + , SubtitleContent (f, p) { } @@ -55,6 +56,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::N : Content (f, node) , VideoContent (f, node) , AudioContent (f, node) + , SubtitleContent (f, node) { list<shared_ptr<cxml::Node> > c = node->node_children ("SubtitleStream"); for (list<shared_ptr<cxml::Node> >::const_iterator i = c.begin(); i != c.end(); ++i) { @@ -84,6 +86,7 @@ FFmpegContent::FFmpegContent (FFmpegContent const & o) : Content (o) , VideoContent (o) , AudioContent (o) + , SubtitleContent (o) , _subtitle_streams (o._subtitle_streams) , _subtitle_stream (o._subtitle_stream) , _audio_streams (o._audio_streams) @@ -99,6 +102,7 @@ FFmpegContent::as_xml (xmlpp::Node* node) const Content::as_xml (node); VideoContent::as_xml (node); AudioContent::as_xml (node); + SubtitleContent::as_xml (node); boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index c5ccee77a..5b9f1f579 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -23,6 +23,7 @@ #include <boost/enable_shared_from_this.hpp> #include "video_content.h" #include "audio_content.h" +#include "subtitle_content.h" class Filter; @@ -79,7 +80,7 @@ public: static int const FILTERS; }; -class FFmpegContent : public VideoContent, public AudioContent +class FFmpegContent : public VideoContent, public AudioContent, public SubtitleContent { public: FFmpegContent (boost::shared_ptr<const Film>, boost::filesystem::path); diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d8ee278b3..fddb70294 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -41,7 +41,6 @@ extern "C" { #include "log.h" #include "ffmpeg_decoder.h" #include "filter_graph.h" -#include "subtitle.h" #include "audio_buffers.h" #include "i18n.h" @@ -61,6 +60,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegC : Decoder (f) , VideoDecoder (f) , AudioDecoder (f) + , SubtitleDecoder (f) , FFmpeg (c) , _subtitle_codec_context (0) , _subtitle_codec (0) @@ -142,27 +142,7 @@ FFmpegDecoder::pass () } else if (_ffmpeg_content->audio_stream() && _packet.stream_index == _ffmpeg_content->audio_stream()->id && _decode_audio) { decode_audio_packet (); } else if (_ffmpeg_content->subtitle_stream() && _packet.stream_index == _ffmpeg_content->subtitle_stream()->id) { -#if 0 - - int got_subtitle; - AVSubtitle sub; - if (avcodec_decode_subtitle2 (_subtitle_codec_context, &sub, &got_subtitle, &_packet) && got_subtitle) { - /* Sometimes we get an empty AVSubtitle, which is used by some codecs to - indicate that the previous subtitle should stop. - */ - if (sub.num_rects > 0) { - shared_ptr<TimedSubtitle> ts; - try { - subtitle (shared_ptr<TimedSubtitle> (new TimedSubtitle (sub))); - } catch (...) { - /* some problem with the subtitle; we probably didn't understand it */ - } - } else { - subtitle (shared_ptr<TimedSubtitle> ()); - } - avsubtitle_free (&sub); - } -#endif + decode_subtitle_packet (); } av_free_packet (&_packet); @@ -489,3 +469,73 @@ FFmpegDecoder::done () const return vd && ad; } +void +FFmpegDecoder::decode_subtitle_packet () +{ + int got_subtitle; + AVSubtitle sub; + if (avcodec_decode_subtitle2 (_subtitle_codec_context, &sub, &got_subtitle, &_packet) < 0 || !got_subtitle) { + return; + } + + /* Sometimes we get an empty AVSubtitle, which is used by some codecs to + indicate that the previous subtitle should stop. + */ + if (sub.num_rects <= 0) { + subtitle (shared_ptr<Image> (), dcpomatic::Rect<double> (), 0, 0); + return; + } else if (sub.num_rects > 1) { + throw DecodeError (_("multi-part subtitles not yet supported")); + } + + /* Subtitle PTS in seconds (within the source, not taking into account any of the + source that we may have chopped off for the DCP) + */ + double const packet_time = static_cast<double> (sub.pts) / AV_TIME_BASE; + + /* hence start time for this sub */ + Time const from = (packet_time + (double (sub.start_display_time) / 1e3)) * TIME_HZ; + Time const to = (packet_time + (double (sub.end_display_time) / 1e3)) * TIME_HZ; + + AVSubtitleRect const * rect = sub.rects[0]; + + if (rect->type != SUBTITLE_BITMAP) { + throw DecodeError (_("non-bitmap subtitles not yet supported")); + } + + shared_ptr<Image> image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (rect->w, rect->h), true)); + + /* Start of the first line in the subtitle */ + uint8_t* sub_p = rect->pict.data[0]; + /* sub_p looks up into a RGB palette which is here */ + uint32_t const * palette = (uint32_t *) rect->pict.data[1]; + /* Start of the output data */ + uint32_t* out_p = (uint32_t *) image->data()[0]; + + for (int y = 0; y < rect->h; ++y) { + uint8_t* sub_line_p = sub_p; + uint32_t* out_line_p = out_p; + for (int x = 0; x < rect->w; ++x) { + *out_line_p++ = palette[*sub_line_p++]; + } + sub_p += rect->pict.linesize[0]; + out_p += image->stride()[0] / sizeof (uint32_t); + } + + libdcp::Size const vs = _ffmpeg_content->video_size (); + + subtitle ( + image, + dcpomatic::Rect<double> ( + static_cast<double> (rect->x) / vs.width, + static_cast<double> (rect->y) / vs.height, + static_cast<double> (rect->w) / vs.width, + static_cast<double> (rect->h) / vs.height + ), + from, + to + ); + + + avsubtitle_free (&sub); +} diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index eebf75445..8819954db 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -35,6 +35,7 @@ extern "C" { #include "decoder.h" #include "video_decoder.h" #include "audio_decoder.h" +#include "subtitle_decoder.h" #include "ffmpeg.h" class Film; @@ -43,7 +44,7 @@ class ffmpeg_pts_offset_test; /** @class FFmpegDecoder * @brief A decoder using FFmpeg to decode content. */ -class FFmpegDecoder : public VideoDecoder, public AudioDecoder, public FFmpeg +class FFmpegDecoder : public VideoDecoder, public AudioDecoder, public SubtitleDecoder, public FFmpeg { public: FFmpegDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const FFmpegContent>, bool video, bool audio); @@ -69,6 +70,7 @@ private: bool decode_video_packet (); void decode_audio_packet (); + void decode_subtitle_packet (); void maybe_add_subtitle (); boost::shared_ptr<AudioBuffers> deinterleave_audio (uint8_t** data, int size); diff --git a/src/lib/film.cc b/src/lib/film.cc index 11fa87912..dad9d6808 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -94,8 +94,6 @@ Film::Film (string d) , _container (Config::instance()->default_container ()) , _scaler (Scaler::from_id ("bicubic")) , _with_subtitles (false) - , _subtitle_offset (0) - , _subtitle_scale (1) , _colour_lut (0) , _j2k_bandwidth (200000000) , _dci_metadata (Config::instance()->default_dci_metadata ()) @@ -142,8 +140,6 @@ Film::Film (Film const & o) , _container (o._container) , _scaler (o._scaler) , _with_subtitles (o._with_subtitles) - , _subtitle_offset (o._subtitle_offset) - , _subtitle_scale (o._subtitle_scale) , _colour_lut (o._colour_lut) , _j2k_bandwidth (o._j2k_bandwidth) , _dci_metadata (o._dci_metadata) @@ -348,8 +344,6 @@ Film::write_metadata () const root->add_child("Scaler")->add_child_text (_scaler->id ()); root->add_child("WithSubtitles")->add_child_text (_with_subtitles ? "1" : "0"); - root->add_child("SubtitleOffset")->add_child_text (lexical_cast<string> (_subtitle_offset)); - root->add_child("SubtitleScale")->add_child_text (lexical_cast<string> (_subtitle_scale)); root->add_child("ColourLUT")->add_child_text (lexical_cast<string> (_colour_lut)); root->add_child("J2KBandwidth")->add_child_text (lexical_cast<string> (_j2k_bandwidth)); _dci_metadata.as_xml (root->add_child ("DCIMetadata")); @@ -395,8 +389,6 @@ Film::read_metadata () _scaler = Scaler::from_id (f.string_child ("Scaler")); _with_subtitles = f.bool_child ("WithSubtitles"); - _subtitle_offset = f.number_child<float> ("SubtitleOffset"); - _subtitle_scale = f.number_child<float> ("SubtitleScale"); _colour_lut = f.number_child<int> ("ColourLUT"); _j2k_bandwidth = f.number_child<int> ("J2KBandwidth"); _dci_metadata = DCIMetadata (f.node_child ("DCIMetadata")); @@ -594,26 +586,6 @@ Film::set_with_subtitles (bool w) } void -Film::set_subtitle_offset (int o) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _subtitle_offset = o; - } - signal_changed (SUBTITLE_OFFSET); -} - -void -Film::set_subtitle_scale (float s) -{ - { - boost::mutex::scoped_lock lm (_state_mutex); - _subtitle_scale = s; - } - signal_changed (SUBTITLE_SCALE); -} - -void Film::set_colour_lut (int i) { { diff --git a/src/lib/film.h b/src/lib/film.h index 5bb9acf29..08fdc587b 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -135,8 +135,6 @@ public: CONTAINER, SCALER, WITH_SUBTITLES, - SUBTITLE_OFFSET, - SUBTITLE_SCALE, COLOUR_LUT, J2K_BANDWIDTH, DCI_METADATA, @@ -181,16 +179,6 @@ public: return _with_subtitles; } - int subtitle_offset () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _subtitle_offset; - } - - float subtitle_scale () const { - boost::mutex::scoped_lock lm (_state_mutex); - return _subtitle_scale; - } - int colour_lut () const { boost::mutex::scoped_lock lm (_state_mutex); return _colour_lut; @@ -229,8 +217,6 @@ public: void set_container (Ratio const *); void set_scaler (Scaler const *); void set_with_subtitles (bool); - void set_subtitle_offset (int); - void set_subtitle_scale (float); void set_colour_lut (int); void set_j2k_bandwidth (int); void set_dci_metadata (DCIMetadata); @@ -278,12 +264,6 @@ private: Scaler const * _scaler; /** True if subtitles should be shown for this film */ bool _with_subtitles; - /** y offset for placing subtitles, in source pixels; +ve is further down - the frame, -ve is further up. - */ - int _subtitle_offset; - /** scale factor to apply to subtitles */ - float _subtitle_scale; /** index of colour LUT to use when converting RGB to XYZ. * 0: sRGB * 1: Rec 709 diff --git a/src/lib/image.cc b/src/lib/image.cc index ac30f4ff0..c11bcbb8d 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -336,7 +336,7 @@ Image::make_black () } void -Image::alpha_blend (shared_ptr<const Image> other, Position position) +Image::alpha_blend (shared_ptr<const Image> other, Position<int> position) { /* Only implemented for RGBA onto RGB24 so far */ assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGBA); @@ -372,7 +372,7 @@ Image::alpha_blend (shared_ptr<const Image> other, Position position) } void -Image::copy (shared_ptr<const Image> other, Position position) +Image::copy (shared_ptr<const Image> other, Position<int> position) { /* Only implemented for RGB24 onto RGB24 so far */ assert (_pixel_format == PIX_FMT_RGB24 && other->pixel_format() == PIX_FMT_RGB24); diff --git a/src/lib/image.h b/src/lib/image.h index 5407ce66e..d40ba77b4 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -32,6 +32,7 @@ extern "C" { #include <libavfilter/avfilter.h> } #include "util.h" +#include "position.h" class Scaler; class SimpleImage; @@ -75,8 +76,8 @@ public: boost::shared_ptr<Image> scale_and_convert_to_rgb (libdcp::Size, Scaler const *, bool) const; boost::shared_ptr<Image> scale (libdcp::Size, Scaler const *, bool aligned) const; boost::shared_ptr<Image> post_process (std::string, bool aligned) const; - void alpha_blend (boost::shared_ptr<const Image> image, Position pos); - void copy (boost::shared_ptr<const Image> image, Position pos); + void alpha_blend (boost::shared_ptr<const Image> image, Position<int> pos); + void copy (boost::shared_ptr<const Image> image, Position<int> pos); boost::shared_ptr<Image> crop (Crop c, bool aligned) const; void make_black (); diff --git a/src/lib/player.cc b/src/lib/player.cc index 6b7dc2722..58ba57bdc 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -26,11 +26,13 @@ #include "imagemagick_content.h" #include "sndfile_decoder.h" #include "sndfile_content.h" +#include "subtitle_content.h" #include "playlist.h" #include "job.h" #include "image.h" #include "ratio.h" #include "resampler.h" +#include "scaler.h" using std::list; using std::cout; @@ -43,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 { @@ -215,48 +217,32 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image return; } - image = image->crop (content->crop(), true); + shared_ptr<Image> work_image = image->crop (content->crop(), true); libdcp::Size const image_size = content->ratio()->size (_video_container_size); - image = image->scale_and_convert_to_rgb (image_size, _film->scaler(), true); + work_image = work_image->scale_and_convert_to_rgb (image_size, _film->scaler(), true); -#if 0 - if (film->with_subtitles ()) { - shared_ptr<Subtitle> sub; - if (_timed_subtitle && _timed_subtitle->displayed_at (t)) { - sub = _timed_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(), film->subtitle_offset(), film->subtitle_scale() - ); - - shared_ptr<Image> im = sub->image()->scale (tx.size(), film->scaler(), true); - image->alpha_blend (im, tx.position()); - } + Time time = content->start() + (frame * frc.factor() * TIME_HZ / _film->dcp_video_frame_rate()); + + 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); } -#endif if (image_size != _video_container_size) { assert (image_size.width <= _video_container_size.width); 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 (image, Position ((_video_container_size.width - image_size.width) / 2, (_video_container_size.height - image_size.height) / 2)); - image = im; + 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; } - Time time = content->start() + (frame * frc.factor() * TIME_HZ / _film->dcp_video_frame_rate()); - - Video (image, same, time); + Video (work_image, same, time); time += TIME_HZ / _film->dcp_video_frame_rate(); if (frc.repeat) { - Video (image, true, time); + Video (work_image, true, time); time += TIME_HZ / _film->dcp_video_frame_rate(); } @@ -390,6 +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, _2, _3, _4)); piece->decoder = fd; } @@ -448,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 (); } } @@ -505,12 +496,59 @@ Player::film_changed (Film::Property p) last time we were run. */ - if ( - p == Film::SCALER || p == Film::WITH_SUBTITLES || - p == Film::SUBTITLE_SCALE || p == Film::SUBTITLE_OFFSET || - p == Film::CONTAINER - ) { - + if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER) { Changed (); } } + +void +Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<Image> image, dcpomatic::Rect<double> 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> piece = _in_subtitle.piece.lock (); + if (!piece) { + return; + } + + shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (piece->content); + assert (sc); + + 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 (); +} diff --git a/src/lib/player.h b/src/lib/player.h index 15fa4dbd6..5a4ee97be 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -27,6 +27,7 @@ #include "audio_buffers.h" #include "content.h" #include "film.h" +#include "rect.h" class Job; class Film; @@ -77,6 +78,7 @@ private: void process_video (boost::weak_ptr<Piece>, boost::shared_ptr<const Image>, bool, VideoContent::Frame); void process_audio (boost::weak_ptr<Piece>, boost::shared_ptr<const AudioBuffers>, AudioContent::Frame); + void process_subtitle (boost::weak_ptr<Piece>, boost::shared_ptr<Image>, dcpomatic::Rect<double>, Time, Time); void setup_pieces (); void playlist_changed (); void content_changed (boost::weak_ptr<Content>, int); @@ -86,6 +88,7 @@ private: void emit_silence (OutputAudioFrame); boost::shared_ptr<Resampler> resampler (boost::shared_ptr<AudioContent>); void film_changed (Film::Property); + void update_subtitle (); boost::shared_ptr<const Film> _film; boost::shared_ptr<const Playlist> _playlist; @@ -107,6 +110,21 @@ private: libdcp::Size _video_container_size; boost::shared_ptr<Image> _black_frame; std::map<boost::shared_ptr<AudioContent>, boost::shared_ptr<Resampler> > _resamplers; + + struct { + boost::weak_ptr<Piece> piece; + boost::shared_ptr<Image> image; + dcpomatic::Rect<double> rect; + Time from; + Time to; + } _in_subtitle; + + struct { + boost::shared_ptr<Image> image; + Position<int> position; + Time from; + Time to; + } _out_subtitle; }; #endif diff --git a/src/lib/position.h b/src/lib/position.h new file mode 100644 index 000000000..f904fe661 --- /dev/null +++ b/src/lib/position.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + 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. + +*/ + +#ifndef DVDOMATIC_POSITION_H +#define DVDOMATIC_POSITION_H + +/** @struct Position + * @brief A position. + */ +template <class T> +class Position +{ +public: + Position () + : x (0) + , y (0) + {} + + Position (T x_, T y_) + : x (x_) + , y (y_) + {} + + /** x coordinate */ + T x; + /** y coordinate */ + T y; +}; + +#endif diff --git a/src/lib/rect.h b/src/lib/rect.h new file mode 100644 index 000000000..df1869841 --- /dev/null +++ b/src/lib/rect.h @@ -0,0 +1,79 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + 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. + +*/ + +#ifndef DVDOMATIC_RECT_H +#define DVDOMATIC_RECT_H + +#include "position.h" + +/* Put this inside a namespace as Apple put a Rect in the global namespace */ + +namespace dcpomatic +{ + +/** @struct Rect + * @brief A rectangle. + */ +template <class T> +class Rect +{ +public: + + Rect () + : x (0) + , y (0) + , width (0) + , height (0) + {} + + Rect (T x_, T y_, T w_, T h_) + : x (x_) + , y (y_) + , width (w_) + , height (h_) + {} + + T x; + T y; + T width; + T height; + + Position<T> position () const { + return Position<T> (x, y); + } + + Rect<T> intersection (Rect<T> const & other) const { + T const tx = max (x, other.x); + T const ty = max (y, other.y); + + return Rect ( + tx, ty, + min (x + width, other.x + other.width) - tx, + min (y + height, other.y + other.height) - ty + ); + } + + bool contains (Position<T> p) const { + return (p.x >= x && p.x <= (x + width) && p.y >= y && p.y <= (y + height)); + } +}; + +} + +#endif diff --git a/src/lib/server.cc b/src/lib/server.cc index 5ca04c692..40d1c4c0c 100644 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@ -36,7 +36,6 @@ #include "image.h" #include "dcp_video_frame.h" #include "config.h" -#include "subtitle.h" #include "i18n.h" diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc deleted file mode 100644 index 7013f1d7d..000000000 --- a/src/lib/subtitle.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> - - 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. - -*/ - -/** @file src/subtitle.cc - * @brief Representations of subtitles. - */ - -#include "subtitle.h" -#include "image.h" -#include "exceptions.h" - -#include "i18n.h" - -using boost::shared_ptr; -using libdcp::Size; - -/** Construct a TimedSubtitle. This is a subtitle image, position, - * and a range of time over which it should be shown. - * @param sub AVSubtitle to read. - */ -TimedSubtitle::TimedSubtitle (AVSubtitle const & sub) -{ - assert (sub.num_rects > 0); - - /* Subtitle PTS in seconds (within the source, not taking into account any of the - source that we may have chopped off for the DCP) - */ - double const packet_time = static_cast<double> (sub.pts) / AV_TIME_BASE; - - /* hence start time for this sub */ - _from = (packet_time + (double (sub.start_display_time) / 1e3)) * TIME_HZ; - _to = (packet_time + (double (sub.end_display_time) / 1e3)) * TIME_HZ; - - if (sub.num_rects > 1) { - throw DecodeError (_("multi-part subtitles not yet supported")); - } - - AVSubtitleRect const * rect = sub.rects[0]; - - if (rect->type != SUBTITLE_BITMAP) { - throw DecodeError (_("non-bitmap subtitles not yet supported")); - } - - shared_ptr<Image> image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (rect->w, rect->h), true)); - - /* Start of the first line in the subtitle */ - uint8_t* sub_p = rect->pict.data[0]; - /* sub_p looks up into a RGB palette which is here */ - uint32_t const * palette = (uint32_t *) rect->pict.data[1]; - /* Start of the output data */ - uint32_t* out_p = (uint32_t *) image->data()[0]; - - for (int y = 0; y < rect->h; ++y) { - uint8_t* sub_line_p = sub_p; - uint32_t* out_line_p = out_p; - for (int x = 0; x < rect->w; ++x) { - *out_line_p++ = palette[*sub_line_p++]; - } - sub_p += rect->pict.linesize[0]; - out_p += image->stride()[0] / sizeof (uint32_t); - } - - _subtitle.reset (new Subtitle (Position (rect->x, rect->y), image)); -} - -/** @param t Time from the start of the source */ -bool -TimedSubtitle::displayed_at (Time t) const -{ - return t >= _from && t <= _to; -} - -/** Construct a subtitle, which is an image and a position. - * @param p Position within the (uncropped) source frame. - * @param i Image of the subtitle (should be RGBA). - */ -Subtitle::Subtitle (Position p, shared_ptr<Image> i) - : _position (p) - , _image (i) -{ - -} - -/** Given the area of a subtitle, work out the area it should - * take up when its video frame is scaled up, and it is optionally - * itself scaled and offset. - * @param target_x_scale the x scaling of the video frame that the subtitle is in. - * @param target_y_scale the y scaling of the video frame that the subtitle is in. - * @param sub_area The area of the subtitle within the original source. - * @param subtitle_offset y offset to apply to the subtitle position (+ve is down) - * in the coordinate space of the source. - * @param subtitle_scale scaling factor to apply to the subtitle image. - */ -dcpomatic::Rect -subtitle_transformed_area ( - float target_x_scale, float target_y_scale, - dcpomatic::Rect sub_area, int subtitle_offset, float subtitle_scale - ) -{ - dcpomatic::Rect tx; - - sub_area.y += subtitle_offset; - - /* We will scale the subtitle by the same amount as the video frame, and also by the additional - subtitle_scale - */ - tx.width = sub_area.width * target_x_scale * subtitle_scale; - tx.height = sub_area.height * target_y_scale * 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 target_x_scale and target_y_scale; this will be - * sub_area.x * target_x_scale and sub_area.y * target_y_scale. - * - * 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. - */ - - tx.x = rint (target_x_scale * (sub_area.x + (sub_area.width * (1 - subtitle_scale) / 2))); - tx.y = rint (target_y_scale * (sub_area.y + (sub_area.height * (1 - subtitle_scale) / 2))); - - return tx; -} - -/** @return area that this subtitle takes up, in the original uncropped source's coordinate space */ -dcpomatic::Rect -Subtitle::area () const -{ - return dcpomatic::Rect (_position.x, _position.y, _image->size().width, _image->size().height); -} diff --git a/src/lib/subtitle.h b/src/lib/subtitle.h deleted file mode 100644 index 1020397cc..000000000 --- a/src/lib/subtitle.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> - - 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. - -*/ - -/** @file src/subtitle.h - * @brief Representations of subtitles. - */ - -#include <list> -#include <boost/shared_ptr.hpp> -#include "types.h" - -struct AVSubtitle; -class Image; - -/** A subtitle, consisting of an image and a position */ -class Subtitle -{ -public: - Subtitle (Position p, boost::shared_ptr<Image> i); - - void set_position (Position p) { - _position = p; - } - - Position position () const { - return _position; - } - - boost::shared_ptr<Image> image () const { - return _image; - } - - dcpomatic::Rect area () const; - -private: - Position _position; - boost::shared_ptr<Image> _image; -}; - -dcpomatic::Rect -subtitle_transformed_area ( - float target_x_scale, float target_y_scale, - dcpomatic::Rect sub_area, int subtitle_offset, float subtitle_scale - ); - -/** A Subtitle class with details of the time over which it should be shown */ -class TimedSubtitle -{ -public: - TimedSubtitle (AVSubtitle const &); - - bool displayed_at (Time) const; - - boost::shared_ptr<Subtitle> subtitle () const { - return _subtitle; - } - -private: - /** the subtitle */ - boost::shared_ptr<Subtitle> _subtitle; - /** display from time from the start of the content */ - Time _from; - /** display to time from the start of the content */ - Time _to; -}; diff --git a/src/lib/subtitle_content.cc b/src/lib/subtitle_content.cc new file mode 100644 index 000000000..9fefbbfcd --- /dev/null +++ b/src/lib/subtitle_content.cc @@ -0,0 +1,72 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + 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 <libcxml/cxml.h> +#include "subtitle_content.h" + +using std::string; +using boost::shared_ptr; +using boost::lexical_cast; + +int const SubtitleContentProperty::SUBTITLE_OFFSET = 500; +int const SubtitleContentProperty::SUBTITLE_SCALE = 501; + +SubtitleContent::SubtitleContent (shared_ptr<const Film> f, boost::filesystem::path p) + : Content (f, p) + , _subtitle_offset (0) + , _subtitle_scale (1) +{ + +} + +SubtitleContent::SubtitleContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node) + : Content (f, node) + , _subtitle_offset (0) + , _subtitle_scale (1) +{ + _subtitle_offset = node->number_child<float> ("SubtitleOffset"); + _subtitle_scale = node->number_child<float> ("SubtitleScale"); +} + +void +SubtitleContent::as_xml (xmlpp::Node* root) const +{ + root->add_child("SubtitleOffset")->add_child_text (lexical_cast<string> (_subtitle_offset)); + root->add_child("SubtitleScale")->add_child_text (lexical_cast<string> (_subtitle_scale)); +} + +void +SubtitleContent::set_subtitle_offset (double o) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _subtitle_offset = o; + } + signal_changed (SubtitleContentProperty::SUBTITLE_OFFSET); +} + +void +SubtitleContent::set_subtitle_scale (double s) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _subtitle_scale = s; + } + signal_changed (SubtitleContentProperty::SUBTITLE_SCALE); +} diff --git a/src/lib/subtitle_content.h b/src/lib/subtitle_content.h new file mode 100644 index 000000000..1092b7b1c --- /dev/null +++ b/src/lib/subtitle_content.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + 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. + +*/ + +#ifndef DCPOMATIC_SUBTITLE_CONTENT_H +#define DCPOMATIC_SUBTITLE_CONTENT_H + +#include "content.h" + +class SubtitleContentProperty +{ +public: + static int const SUBTITLE_OFFSET; + static int const SUBTITLE_SCALE; +}; + +class SubtitleContent : public virtual Content +{ +public: + SubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path); + SubtitleContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); + + void as_xml (xmlpp::Node *) const; + + void set_subtitle_offset (double); + void set_subtitle_scale (double); + + double subtitle_offset () const { + boost::mutex::scoped_lock lm (_mutex); + return _subtitle_offset; + } + + double subtitle_scale () const { + boost::mutex::scoped_lock lm (_mutex); + return _subtitle_scale; + } + +private: + /** y offset for placing subtitles, as a proportion of the container height; + +ve is further down the frame, -ve is further up. + */ + double _subtitle_offset; + /** scale factor to apply to subtitles */ + double _subtitle_scale; +}; + +#endif diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc new file mode 100644 index 000000000..c06f3d718 --- /dev/null +++ b/src/lib/subtitle_decoder.cc @@ -0,0 +1,39 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + 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 <boost/shared_ptr.hpp> +#include "subtitle_decoder.h" + +using boost::shared_ptr; + +SubtitleDecoder::SubtitleDecoder (shared_ptr<const Film> f) + : Decoder (f) +{ + +} + + +/** Called by subclasses when a subtitle is ready. + * Image may be 0 to say that there is no current subtitle. + */ +void +SubtitleDecoder::subtitle (shared_ptr<Image> image, dcpomatic::Rect<double> rect, Time from, Time to) +{ + Subtitle (image, rect, from, to); +} diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h new file mode 100644 index 000000000..628f4d60d --- /dev/null +++ b/src/lib/subtitle_decoder.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + 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 <boost/signals2.hpp> +#include "decoder.h" +#include "rect.h" +#include "types.h" + +class Film; +class TimedSubtitle; + +class SubtitleDecoder : public virtual Decoder +{ +public: + SubtitleDecoder (boost::shared_ptr<const Film>); + + boost::signals2::signal<void (boost::shared_ptr<Image>, dcpomatic::Rect<double>, Time, Time)> Subtitle; + +protected: + void subtitle (boost::shared_ptr<Image>, dcpomatic::Rect<double>, Time, Time); +}; diff --git a/src/lib/types.cc b/src/lib/types.cc index 78cb4cd64..035c8363d 100644 --- a/src/lib/types.cc +++ b/src/lib/types.cc @@ -32,25 +32,3 @@ bool operator!= (Crop const & a, Crop const & b) return !(a == b); } - -/** @param other A Rect. - * @return The intersection of this with `other'. - */ -dcpomatic::Rect -dcpomatic::Rect::intersection (Rect const & other) const -{ - int const tx = max (x, other.x); - int const ty = max (y, other.y); - - return Rect ( - tx, ty, - min (x + width, other.x + other.width) - tx, - min (y + height, other.y + other.height) - ty - ); -} - -bool -dcpomatic::Rect::contains (Position p) const -{ - return (p.x >= x && p.x <= (x + width) && p.y >= y && p.y <= (y + height)); -} diff --git a/src/lib/types.h b/src/lib/types.h index 33f8239d8..67384103d 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -53,66 +53,4 @@ struct Crop extern bool operator== (Crop const & a, Crop const & b); extern bool operator!= (Crop const & a, Crop const & b); -/** @struct Position - * @brief A position. - */ -struct Position -{ - Position () - : x (0) - , y (0) - {} - - Position (int x_, int y_) - : x (x_) - , y (y_) - {} - - /** x coordinate */ - int x; - /** y coordinate */ - int y; -}; - -namespace dcpomatic { - -/** @struct Rect - * @brief A rectangle. - */ -struct Rect -{ - Rect () - : x (0) - , y (0) - , width (0) - , height (0) - {} - - Rect (int x_, int y_, int w_, int h_) - : x (x_) - , y (y_) - , width (w_) - , height (h_) - {} - - int x; - int y; - int width; - int height; - - Position position () const { - return Position (x, y); - } - - libdcp::Size size () const { - return libdcp::Size (width, height); - } - - Rect intersection (Rect const & other) const; - - bool contains (Position) const; -}; - -} - #endif diff --git a/src/lib/util.cc b/src/lib/util.cc index 2e4abe64d..53c457898 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -91,8 +91,8 @@ using boost::lexical_cast; using boost::optional; using libdcp::Size; -boost::thread::id ui_thread; -boost::filesystem::path backtrace_file; +static boost::thread::id ui_thread; +static boost::filesystem::path backtrace_file; /** Convert some number of seconds to a string representation * in hours, minutes and seconds. diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index f61e63d4d..457cfe47b 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -18,10 +18,7 @@ */ #include "video_decoder.h" -#include "subtitle.h" -#include "film.h" #include "image.h" -#include "ratio.h" #include "i18n.h" @@ -42,21 +39,3 @@ VideoDecoder::video (shared_ptr<const Image> image, bool same, VideoContent::Fra _video_position = frame + 1; } -#if 0 - -/** Called by subclasses when a subtitle is ready. - * s may be 0 to say that there is no current subtitle. - * @param s New current subtitle, or 0. - */ -void -VideoDecoder::subtitle (shared_ptr<TimedSubtitle> s) -{ - _timed_subtitle = s; - - if (_timed_subtitle) { - Position const p = _timed_subtitle->subtitle()->position (); - _timed_subtitle->subtitle()->set_position (Position (p.x - _video_content->crop().left, p.y - _video_content->crop().top)); - } -} -#endif - diff --git a/src/lib/wscript b/src/lib/wscript index 7660afb45..5c381b69c 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -44,7 +44,8 @@ sources = """ sndfile_content.cc sndfile_decoder.cc sound_processor.cc - subtitle.cc + subtitle_content.cc + subtitle_decoder.cc timer.cc transcode_job.cc transcoder.cc |
