summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-07-11 14:29:55 +0100
committerCarl Hetherington <cth@carlh.net>2013-07-11 14:29:55 +0100
commitb655bd3359e9a014da68cd9f61e2a5b1d233247d (patch)
tree42ab16fdc9621fd0314a71f051804cdacd1cb823 /src/lib
parente64acff7da897cd03d88aa9e8e21682545a61cc2 (diff)
parent2514ffcd1adcca4fc8e3db894afb5cdc6c857e94 (diff)
Merge branch '1.0' of /home/carl/git/dvdomatic into 1.0
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/combiner.cc74
-rw-r--r--src/lib/content.h1
-rw-r--r--src/lib/decoder.h2
-rw-r--r--src/lib/ffmpeg_content.cc4
-rw-r--r--src/lib/ffmpeg_content.h3
-rw-r--r--src/lib/ffmpeg_decoder.cc94
-rw-r--r--src/lib/ffmpeg_decoder.h4
-rw-r--r--src/lib/film.cc28
-rw-r--r--src/lib/film.h20
-rw-r--r--src/lib/image.cc4
-rw-r--r--src/lib/image.h5
-rw-r--r--src/lib/player.cc104
-rw-r--r--src/lib/player.h18
-rw-r--r--src/lib/position.h46
-rw-r--r--src/lib/rect.h79
-rw-r--r--src/lib/server.cc1
-rw-r--r--src/lib/subtitle.cc149
-rw-r--r--src/lib/subtitle.h81
-rw-r--r--src/lib/subtitle_content.cc72
-rw-r--r--src/lib/subtitle_content.h62
-rw-r--r--src/lib/subtitle_decoder.cc39
-rw-r--r--src/lib/subtitle_decoder.h37
-rw-r--r--src/lib/types.cc22
-rw-r--r--src/lib/types.h62
-rw-r--r--src/lib/util.cc4
-rw-r--r--src/lib/video_decoder.cc21
-rw-r--r--src/lib/wscript3
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