: Content (f, p)
, VideoContent (f, p)
, AudioContent (f, p)
+ , SubtitleContent (f, p)
{
}
: 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) {
: Content (o)
, VideoContent (o)
, AudioContent (o)
+ , SubtitleContent (o)
, _subtitle_streams (o._subtitle_streams)
, _subtitle_stream (o._subtitle_stream)
, _audio_streams (o._audio_streams)
Content::as_xml (node);
VideoContent::as_xml (node);
AudioContent::as_xml (node);
+ SubtitleContent::as_xml (node);
boost::mutex::scoped_lock lm (_mutex);
#include <boost/enable_shared_from_this.hpp>
#include "video_content.h"
#include "audio_content.h"
+#include "subtitle_content.h"
class Filter;
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);
, _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 ())
, _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)
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"));
_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"));
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)
{
CONTAINER,
SCALER,
WITH_SUBTITLES,
- SUBTITLE_OFFSET,
- SUBTITLE_SCALE,
COLOUR_LUT,
J2K_BANDWIDTH,
DCI_METADATA,
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;
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);
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
#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"
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 ();
}
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);
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 ();
}
}
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 ();
}
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
--- /dev/null
+/*
+ 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);
+}
--- /dev/null
+/*
+ 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
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.
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
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
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;
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);
}
}
_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);
}
}
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);
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 ()
{
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;
try {
_got_frame = false;
- while (!_got_frame && !_player->pass ());
+ while (!_got_frame && !_player->pass ()) {}
} catch (DecodeError& e) {
_play_button->SetValue (false);
check_play_state ();