Add SubtitleContent.
authorCarl Hetherington <cth@carlh.net>
Wed, 10 Jul 2013 15:46:08 +0000 (16:46 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 10 Jul 2013 15:46:08 +0000 (16:46 +0100)
13 files changed:
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_content.h
src/lib/film.cc
src/lib/film.h
src/lib/player.cc
src/lib/player.h
src/lib/subtitle_content.cc [new file with mode: 0644]
src/lib/subtitle_content.h [new file with mode: 0644]
src/lib/util.cc
src/lib/wscript
src/wx/film_editor.cc
src/wx/film_editor.h
src/wx/film_viewer.cc

index 1135cc9a3add1f07e2416bba28a279748120de8c..35f9f71f2fc98806c4d13089db93c34cb090b2dc 100644 (file)
@@ -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);
 
index c5ccee77a4509c55b87f374147a5333bdcd0685b..5b9f1f5792b240a604fc78719c09d1ed17698eb8 100644 (file)
@@ -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);
index 11fa879129f1b399d65348645bc4e0961b298c56..dad9d6808464cd8a57af6b2b9ac3125e1c50fe2d 100644 (file)
@@ -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"));
@@ -593,26 +585,6 @@ Film::set_with_subtitles (bool w)
        signal_changed (WITH_SUBTITLES);
 }
 
-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)
 {
index 5bb9acf297be8091ef7db70934eed336aa657c39..08fdc587b9754262bf40f362291bcb6a227d95ec 100644 (file)
@@ -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
index 2bafbdcd5736469d42ef187d3feca6c01cc44e1d..c615f0a8963212b659b443f47ac23145365b16c1 100644 (file)
@@ -26,6 +26,7 @@
 #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"
@@ -226,7 +227,7 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image
        
        if (_film->with_subtitles ()) {
                shared_ptr<Subtitle> sub;
-               if (_subtitle && _subtitle->displayed_at (time - _subtitle_offset)) {
+               if (_subtitle && _subtitle->displayed_at (time - _subtitle_content_time)) {
                        sub = _subtitle->subtitle ();
                }
                
@@ -234,7 +235,7 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image
                        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()
+                               sub->area(), _subtitle_offset, _subtitle_scale
                                );
                        
                        shared_ptr<Image> im = sub->image()->scale (tx.size(), _film->scaler(), true);
@@ -505,12 +506,7 @@ 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 ();
        }
 }
@@ -523,6 +519,11 @@ Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<TimedSubtitle>
                return;
        }
 
+       shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (piece->content);
+       assert (sc);
+
        _subtitle = sub;
-       _subtitle_offset = piece->content->start ();
+       _subtitle_content_time = piece->content->start ();
+       _subtitle_offset = sc->subtitle_offset ();
+       _subtitle_scale = sc->subtitle_scale ();
 }
index f96d5ac695f37ee8d4a2c9aba445286bd638a616..32ef25d47142a1e1489f7e49250164b08f2babdb 100644 (file)
@@ -111,7 +111,9 @@ private:
        std::map<boost::shared_ptr<AudioContent>, boost::shared_ptr<Resampler> > _resamplers;
 
        boost::shared_ptr<TimedSubtitle> _subtitle;
-       Time _subtitle_offset;
+       Time _subtitle_content_time;
+       int _subtitle_offset;
+       float _subtitle_scale;
 };
 
 #endif
diff --git a/src/lib/subtitle_content.cc b/src/lib/subtitle_content.cc
new file mode 100644 (file)
index 0000000..c8de988
--- /dev/null
@@ -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 (int o)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _subtitle_offset = o;
+       }
+       signal_changed (SubtitleContentProperty::SUBTITLE_OFFSET);
+}
+
+void
+SubtitleContent::set_subtitle_scale (float 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 (file)
index 0000000..5eb4e50
--- /dev/null
@@ -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 (int);
+       void set_subtitle_scale (float);
+
+       int subtitle_offset () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _subtitle_offset;
+       }
+
+       float 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.
+       */
+       int _subtitle_offset;
+       /** scale factor to apply to subtitles */
+       float _subtitle_scale;
+};
+
+#endif
index 2e4abe64dc30f2f49a4aad27c9b444d290ac7cb4..53c457898015f36908b6d3fc74094a20fd6043d1 100644 (file)
@@ -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.
index 34d44ec5b21a6cd62e9d6fcc1388aac8370ceabb..789db1551354693f7477500ebedb459519a58628 100644 (file)
@@ -44,8 +44,9 @@ sources = """
           sndfile_content.cc
           sndfile_decoder.cc
           sound_processor.cc
-          subtitle_decoder.cc
           subtitle.cc
+          subtitle_content.cc
+          subtitle_decoder.cc
           timer.cc
           transcode_job.cc
           transcoder.cc
index 31595116824f7d190eeea601efe6b33b1856e175..f63121201c675e113759f7c5718d1bb9aec76920 100644 (file)
@@ -527,21 +527,23 @@ FilmEditor::name_changed (wxCommandEvent &)
 void
 FilmEditor::subtitle_offset_changed (wxCommandEvent &)
 {
-       if (!_film) {
+       shared_ptr<SubtitleContent> c = selected_subtitle_content ();
+       if (!c) {
                return;
        }
 
-       _film->set_subtitle_offset (_subtitle_offset->GetValue ());
+       c->set_subtitle_offset (_subtitle_offset->GetValue ());
 }
 
 void
 FilmEditor::subtitle_scale_changed (wxCommandEvent &)
 {
-       if (!_film) {
+       shared_ptr<SubtitleContent> c = selected_subtitle_content ();
+       if (!c) {
                return;
        }
 
-       _film->set_subtitle_scale (_subtitle_scale->GetValue() / 100.0);
+       c->set_subtitle_scale (_subtitle_scale->GetValue() / 100.0);
 }
 
 void
@@ -626,12 +628,6 @@ FilmEditor::film_changed (Film::Property p)
                setup_subtitle_control_sensitivity ();
                setup_dcp_name ();
                break;
-       case Film::SUBTITLE_OFFSET:
-               checked_set (_subtitle_offset, _film->subtitle_offset ());
-               break;
-       case Film::SUBTITLE_SCALE:
-               checked_set (_subtitle_scale, _film->subtitle_scale() * 100);
-               break;
        case Film::COLOUR_LUT:
                checked_set (_colour_lut, _film->colour_lut ());
                break;
@@ -679,10 +675,12 @@ FilmEditor::film_content_changed (weak_ptr<Content> weak_content, int property)
        shared_ptr<Content> content = weak_content.lock ();
        shared_ptr<VideoContent> video_content;
        shared_ptr<AudioContent> audio_content;
+       shared_ptr<SubtitleContent> subtitle_content;
        shared_ptr<FFmpegContent> ffmpeg_content;
        if (content) {
                video_content = dynamic_pointer_cast<VideoContent> (content);
                audio_content = dynamic_pointer_cast<AudioContent> (content);
+               subtitle_content = dynamic_pointer_cast<SubtitleContent> (content);
                ffmpeg_content = dynamic_pointer_cast<FFmpegContent> (content);
        }
 
@@ -776,6 +774,10 @@ FilmEditor::film_content_changed (weak_ptr<Content> weak_content, int property)
                        }
                        _dcp_sizer->Layout ();
                }
+       } else if (property == SubtitleContentProperty::SUBTITLE_OFFSET) {
+               checked_set (_subtitle_offset, subtitle_content ? subtitle_content->subtitle_offset() : 0);
+       } else if (property == SubtitleContentProperty::SUBTITLE_SCALE) {
+               checked_set (_subtitle_scale, subtitle_content ? (subtitle_content->subtitle_scale() * 100) : 100);
        }
 }
 
@@ -861,8 +863,6 @@ FilmEditor::set_film (shared_ptr<Film> f)
        film_changed (Film::CONTAINER);
        film_changed (Film::SCALER);
        film_changed (Film::WITH_SUBTITLES);
-       film_changed (Film::SUBTITLE_OFFSET);
-       film_changed (Film::SUBTITLE_SCALE);
        film_changed (Film::COLOUR_LUT);
        film_changed (Film::J2K_BANDWIDTH);
        film_changed (Film::DCI_METADATA);
@@ -1270,6 +1270,17 @@ FilmEditor::selected_audio_content ()
        return dynamic_pointer_cast<AudioContent> (c);
 }
 
+shared_ptr<SubtitleContent>
+FilmEditor::selected_subtitle_content ()
+{
+       shared_ptr<Content> c = selected_content ();
+       if (!c) {
+               return shared_ptr<SubtitleContent> ();
+       }
+
+       return dynamic_pointer_cast<SubtitleContent> (c);
+}
+
 void
 FilmEditor::setup_scaling_description ()
 {
index 4b096a2e15242ac592280e6075da30e8798a6f7d..fdc6e077dbc7d48ed7a810daf90bc45047cfd428 100644 (file)
@@ -118,6 +118,7 @@ private:
        boost::shared_ptr<Content> selected_content ();
        boost::shared_ptr<VideoContent> selected_video_content ();
        boost::shared_ptr<AudioContent> selected_audio_content ();
+       boost::shared_ptr<SubtitleContent> selected_subtitle_content ();
 
        wxNotebook* _main_notebook;
        wxNotebook* _content_notebook;
index 185c3c53f8703d369117aff5a5e709345c211f30..f64020ba7817f6bb5bbf4fb3b57ca3b1370a5bd6 100644 (file)
@@ -301,7 +301,7 @@ FilmViewer::fetch_next_frame ()
 
        try {
                _got_frame = false;
-               while (!_got_frame && !_player->pass ());
+               while (!_got_frame && !_player->pass ()) {}
        } catch (DecodeError& e) {
                _play_button->SetValue (false);
                check_play_state ();