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 | |
| parent | 623f3c66821d6a99bf0e683a8072b99a168f3a1c (diff) | |
Make subtitles work at least a bit.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 64 | ||||
| -rw-r--r-- | src/lib/image.cc | 4 | ||||
| -rw-r--r-- | src/lib/image.h | 5 | ||||
| -rw-r--r-- | src/lib/player.cc | 77 | ||||
| -rw-r--r-- | src/lib/player.h | 23 | ||||
| -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 | 82 | ||||
| -rw-r--r-- | src/lib/subtitle_content.cc | 4 | ||||
| -rw-r--r-- | src/lib/subtitle_content.h | 16 | ||||
| -rw-r--r-- | src/lib/subtitle_decoder.cc | 8 | ||||
| -rw-r--r-- | src/lib/subtitle_decoder.h | 6 | ||||
| -rw-r--r-- | src/lib/types.cc | 22 | ||||
| -rw-r--r-- | src/lib/types.h | 62 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 3 | ||||
| -rw-r--r-- | src/lib/wscript | 1 |
19 files changed, 269 insertions, 385 deletions
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_decoder.cc b/src/lib/ffmpeg_decoder.cc index 3714c1542..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" @@ -478,20 +477,65 @@ FFmpegDecoder::decode_subtitle_packet () 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) { - shared_ptr<TimedSubtitle> ts; - try { - subtitle (shared_ptr<TimedSubtitle> (new TimedSubtitle (sub))); - } catch (...) { - /* some problem with the subtitle; we probably didn't understand it */ + 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++]; } - } else { - subtitle (shared_ptr<TimedSubtitle> ()); + 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/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 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 (); } diff --git a/src/lib/player.h b/src/lib/player.h index 32ef25d47..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; @@ -35,7 +36,6 @@ class AudioContent; class Piece; class Image; class Resampler; -class TimedSubtitle; /** @class Player * @brief A class which can `play' a Playlist; emitting its audio and video. @@ -78,7 +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<TimedSubtitle>); + 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); @@ -88,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; @@ -110,10 +111,20 @@ private: boost::shared_ptr<Image> _black_frame; std::map<boost::shared_ptr<AudioContent>, boost::shared_ptr<Resampler> > _resamplers; - boost::shared_ptr<TimedSubtitle> _subtitle; - Time _subtitle_content_time; - int _subtitle_offset; - float _subtitle_scale; + 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 47735c453..000000000 --- a/src/lib/subtitle.h +++ /dev/null @@ -1,82 +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 */ -/** XXX: merge with Subtitle? */ -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 index c8de9887e..9fefbbfcd 100644 --- a/src/lib/subtitle_content.cc +++ b/src/lib/subtitle_content.cc @@ -52,7 +52,7 @@ SubtitleContent::as_xml (xmlpp::Node* root) const } void -SubtitleContent::set_subtitle_offset (int o) +SubtitleContent::set_subtitle_offset (double o) { { boost::mutex::scoped_lock lm (_mutex); @@ -62,7 +62,7 @@ SubtitleContent::set_subtitle_offset (int o) } void -SubtitleContent::set_subtitle_scale (float s) +SubtitleContent::set_subtitle_scale (double s) { { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/subtitle_content.h b/src/lib/subtitle_content.h index 5eb4e500d..1092b7b1c 100644 --- a/src/lib/subtitle_content.h +++ b/src/lib/subtitle_content.h @@ -37,26 +37,26 @@ public: void as_xml (xmlpp::Node *) const; - void set_subtitle_offset (int); - void set_subtitle_scale (float); + void set_subtitle_offset (double); + void set_subtitle_scale (double); - int subtitle_offset () const { + double subtitle_offset () const { boost::mutex::scoped_lock lm (_mutex); return _subtitle_offset; } - float subtitle_scale () const { + double subtitle_scale () const { boost::mutex::scoped_lock lm (_mutex); return _subtitle_scale; } private: - /** y offset for placing subtitles, in source pixels; +ve is further down - the frame, -ve is further up. + /** y offset for placing subtitles, as a proportion of the container height; + +ve is further down the frame, -ve is further up. */ - int _subtitle_offset; + double _subtitle_offset; /** scale factor to apply to subtitles */ - float _subtitle_scale; + double _subtitle_scale; }; #endif diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc index 0ffe5e501..c06f3d718 100644 --- a/src/lib/subtitle_decoder.cc +++ b/src/lib/subtitle_decoder.cc @@ -19,7 +19,6 @@ #include <boost/shared_ptr.hpp> #include "subtitle_decoder.h" -#include "subtitle.h" using boost::shared_ptr; @@ -31,11 +30,10 @@ SubtitleDecoder::SubtitleDecoder (shared_ptr<const Film> f) /** 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. + * Image may be 0 to say that there is no current subtitle. */ void -SubtitleDecoder::subtitle (shared_ptr<TimedSubtitle> s) +SubtitleDecoder::subtitle (shared_ptr<Image> image, dcpomatic::Rect<double> rect, Time from, Time to) { - Subtitle (s); + Subtitle (image, rect, from, to); } diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h index 0c299f61f..628f4d60d 100644 --- a/src/lib/subtitle_decoder.h +++ b/src/lib/subtitle_decoder.h @@ -19,6 +19,8 @@ #include <boost/signals2.hpp> #include "decoder.h" +#include "rect.h" +#include "types.h" class Film; class TimedSubtitle; @@ -28,8 +30,8 @@ class SubtitleDecoder : public virtual Decoder public: SubtitleDecoder (boost::shared_ptr<const Film>); - boost::signals2::signal<void (boost::shared_ptr<TimedSubtitle>)> Subtitle; + boost::signals2::signal<void (boost::shared_ptr<Image>, dcpomatic::Rect<double>, Time, Time)> Subtitle; protected: - void subtitle (boost::shared_ptr<TimedSubtitle>); + 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/video_decoder.cc b/src/lib/video_decoder.cc index 0616cd437..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" diff --git a/src/lib/wscript b/src/lib/wscript index f646d9781..5c381b69c 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -44,7 +44,6 @@ sources = """ sndfile_content.cc sndfile_decoder.cc sound_processor.cc - subtitle.cc subtitle_content.cc subtitle_decoder.cc timer.cc |
