sed -i "s/SubtitleContent/TextContent/g" src/lib/*.cc src/lib/*.h src/wx/*.cc src/wx/*.h src/tools/*.cc test/*.cc
sed -i "s/SubtitleDecoder/TextDecoder/g" src/lib/*.cc src/lib/*.h src/wx/*.cc src/wx/*.h src/tools/*.cc test/*.cc
sed -i "s/subtitle_content/text_content/g" src/lib/*.cc src/lib/*.h src/wx/*.cc src/wx/*.h src/tools/*.cc test/*.cc src/lib/wscript src/wx/wscript
sed -i "s/subtitle_decoder/text_decoder/g" src/lib/*.cc src/lib/*.h src/wx/*.cc src/wx/*.h src/tools/*.cc test/*.cc src/lib/wscript
mv src/lib/subtitle_decoder.cc src/lib/text_decoder.cc
mv src/lib/subtitle_decoder.h src/lib/text_decoder.h
mv src/lib/subtitle_content.cc src/lib/text_content.cc
mv src/lib/subtitle_content.h src/lib/text_content.h
mv src/lib/dcp_subtitle_decoder.cc src/lib/dcp_text_decoder.cc
mv src/lib/dcp_subtitle_decoder.h src/lib/dcp_text_decoder.h
mv src/lib/dcp_subtitle_content.cc src/lib/dcp_text_content.cc
mv src/lib/dcp_subtitle_content.h src/lib/dcp_text_content.h
mv src/lib/text_subtitle_content.cc src/lib/text_text_content.cc
mv src/lib/text_subtitle_content.h src/lib/text_text_content.h
mv src/lib/text_subtitle_decoder.cc src/lib/text_text_decoder.cc
mv src/lib/text_subtitle_decoder.h src/lib/text_text_decoder.h
mv src/wx/timeline_subtitle_content_view.cc src/wx/timeline_text_content_view.cc
mv src/wx/timeline_subtitle_content_view.h src/wx/timeline_text_content_view.h
#include "active_subtitles.h"
#include "piece.h"
-#include "subtitle_content.h"
+#include "text_content.h"
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include "content_factory.h"
#include "video_content.h"
#include "audio_content.h"
-#include "subtitle_content.h"
+#include "text_content.h"
#include "exceptions.h"
#include "film.h"
#include "job.h"
boost::shared_ptr<VideoContent> video;
boost::shared_ptr<AudioContent> audio;
- boost::shared_ptr<SubtitleContent> subtitle;
+ boost::shared_ptr<TextContent> subtitle;
void signal_changed (int);
#include "audio_content.h"
#include "image_content.h"
#include "atmos_mxf_content.h"
-#include "text_subtitle_content.h"
+#include "text_text_content.h"
#include "dcp_content.h"
-#include "dcp_subtitle_content.h"
+#include "dcp_text_content.h"
#include "util.h"
#include "ffmpeg_audio_stream.h"
#include "video_mxf_content.h"
);
} else if (type == "SubRip" || type == "TextSubtitle") {
- content.reset (new TextSubtitleContent (film, node, version));
+ content.reset (new TextTextContent (film, node, version));
} else if (type == "DCP") {
content.reset (new DCPContent (film, node, version));
} else if (type == "DCPSubtitle") {
- content.reset (new DCPSubtitleContent (film, node, version));
+ content.reset (new DCPTextContent (film, node, version));
} else if (type == "VideoMXF") {
content.reset (new VideoMXFContent (film, node, version));
} else if (type == "AtmosMXF") {
if (valid_image_file (path)) {
single.reset (new ImageContent (film, path));
} else if (ext == ".srt" || ext == ".ssa" || ext == ".ass") {
- single.reset (new TextSubtitleContent (film, path));
+ single.reset (new TextTextContent (film, path));
} else if (ext == ".xml") {
cxml::Document doc;
doc.read_file (path);
if (doc.root_name() == "DCinemaSecurityMessage") {
throw KDMAsContentError ();
}
- single.reset (new DCPSubtitleContent (film, path));
+ single.reset (new DCPTextContent (film, path));
} else if (ext == ".mxf" && dcp::SMPTESubtitleAsset::valid_mxf (path)) {
- single.reset (new DCPSubtitleContent (film, path));
+ single.reset (new DCPTextContent (film, path));
} else if (ext == ".mxf" && VideoMXFContent::valid_mxf (path)) {
single.reset (new VideoMXFContent (film, path));
} else if (ext == ".mxf" && AtmosMXFContent::valid_mxf (path)) {
#include "overlaps.h"
#include "compose.hpp"
#include "dcp_decoder.h"
-#include "subtitle_content.h"
+#include "text_content.h"
#include <dcp/dcp.h>
#include <dcp/raw_convert.h>
#include <dcp/exceptions.h>
{
video = VideoContent::from_xml (this, node, version);
audio = AudioContent::from_xml (this, node, version);
- subtitle = SubtitleContent::from_xml (this, node, version);
+ subtitle = TextContent::from_xml (this, node, version);
if (video && audio) {
audio->set_stream (
boost::mutex::scoped_lock lm (_mutex);
_name = examiner->name ();
if (examiner->has_subtitles ()) {
- subtitle.reset (new SubtitleContent (this));
+ subtitle.reset (new TextContent (this));
} else {
subtitle.reset ();
}
#include "video_decoder.h"
#include "audio_decoder.h"
#include "j2k_image_proxy.h"
-#include "subtitle_decoder.h"
+#include "text_decoder.h"
#include "image.h"
#include "config.h"
#include <dcp/dcp.h>
}
if (c->subtitle) {
/* XXX: this time here should be the time of the first subtitle, not 0 */
- subtitle.reset (new SubtitleDecoder (this, c->subtitle, log, ContentTime()));
+ subtitle.reset (new TextDecoder (this, c->subtitle, log, ContentTime()));
}
list<shared_ptr<dcp::CPL> > cpl_list = cpls ();
#include "writer.h"
#include "compose.hpp"
#include "referenced_reel_asset.h"
-#include "subtitle_content.h"
+#include "text_content.h"
#include "player_video.h"
#include <boost/signals2.hpp>
#include <boost/foreach.hpp>
+++ /dev/null
-/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "font.h"
-#include "dcp_subtitle_content.h"
-#include "film.h"
-#include "subtitle_content.h"
-#include <dcp/raw_convert.h>
-#include <dcp/interop_subtitle_asset.h>
-#include <dcp/smpte_subtitle_asset.h>
-#include <dcp/interop_load_font_node.h>
-#include <libxml++/libxml++.h>
-#include <boost/foreach.hpp>
-
-#include "i18n.h"
-
-using std::string;
-using std::list;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using dcp::raw_convert;
-
-DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, boost::filesystem::path path)
- : Content (film, path)
-{
- subtitle.reset (new SubtitleContent (this));
-}
-
-DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
- : Content (film, node)
- , _length (node->number_child<ContentTime::Type> ("Length"))
-{
- subtitle = SubtitleContent::from_xml (this, node, version);
-}
-
-void
-DCPSubtitleContent::examine (shared_ptr<Job> job)
-{
- Content::examine (job);
-
- shared_ptr<dcp::SubtitleAsset> sc = load (path (0));
-
- shared_ptr<dcp::InteropSubtitleAsset> iop = dynamic_pointer_cast<dcp::InteropSubtitleAsset> (sc);
- shared_ptr<dcp::SMPTESubtitleAsset> smpte = dynamic_pointer_cast<dcp::SMPTESubtitleAsset> (sc);
- if (smpte) {
- set_video_frame_rate (smpte->edit_rate().numerator);
- }
-
- boost::mutex::scoped_lock lm (_mutex);
-
- /* Default to turning these subtitles on */
- subtitle->set_use (true);
-
- if (iop) {
- subtitle->set_language (iop->language ());
- } else if (smpte) {
- subtitle->set_language (smpte->language().get_value_or (""));
- }
-
- _length = ContentTime::from_seconds (sc->latest_subtitle_out().as_seconds ());
-
- BOOST_FOREACH (shared_ptr<dcp::LoadFontNode> i, sc->load_font_nodes ()) {
- subtitle->add_font (shared_ptr<Font> (new Font (i->id)));
- }
-}
-
-DCPTime
-DCPSubtitleContent::full_length () const
-{
- FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate());
- return DCPTime (_length, frc);
-}
-
-string
-DCPSubtitleContent::summary () const
-{
- return path_summary() + " " + _("[subtitles]");
-}
-
-string
-DCPSubtitleContent::technical_summary () const
-{
- return Content::technical_summary() + " - " + _("DCP XML subtitles");
-}
-
-void
-DCPSubtitleContent::as_xml (xmlpp::Node* node, bool with_paths) const
-{
- node->add_child("Type")->add_child_text ("DCPSubtitle");
- Content::as_xml (node, with_paths);
-
- if (subtitle) {
- subtitle->as_xml (node);
- }
-
- node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
-}
+++ /dev/null
-/*
- Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "dcp_subtitle.h"
-#include "content.h"
-
-class DCPSubtitleContent : public DCPSubtitle, public Content
-{
-public:
- DCPSubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path);
- DCPSubtitleContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
-
- void examine (boost::shared_ptr<Job>);
- std::string summary () const;
- std::string technical_summary () const;
- void as_xml (xmlpp::Node *, bool with_paths) const;
- DCPTime full_length () const;
-
-private:
- ContentTime _length;
-};
+++ /dev/null
-/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "dcp_subtitle_decoder.h"
-#include "dcp_subtitle_content.h"
-#include <dcp/interop_subtitle_asset.h>
-#include <iostream>
-
-using std::list;
-using std::cout;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using boost::bind;
-
-DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr<const DCPSubtitleContent> content, shared_ptr<Log> log)
-{
- shared_ptr<dcp::SubtitleAsset> c (load (content->path (0)));
- _subtitles = c->subtitles ();
- _next = _subtitles.begin ();
-
- ContentTime first;
- if (_next != _subtitles.end()) {
- first = content_time_period(*_next).from;
- }
- subtitle.reset (new SubtitleDecoder (this, content->subtitle, log, first));
-}
-
-void
-DCPSubtitleDecoder::seek (ContentTime time, bool accurate)
-{
- Decoder::seek (time, accurate);
-
- _next = _subtitles.begin ();
- list<shared_ptr<dcp::Subtitle> >::const_iterator i = _subtitles.begin ();
- while (i != _subtitles.end() && ContentTime::from_seconds ((*_next)->in().as_seconds()) < time) {
- ++i;
- }
-}
-
-bool
-DCPSubtitleDecoder::pass ()
-{
- if (_next == _subtitles.end ()) {
- return true;
- }
-
- /* Gather all subtitles with the same time period that are next
- on the list. We must emit all subtitles for the same time
- period with the same text_subtitle() call otherwise the
- SubtitleDecoder will assume there is nothing else at the
- time of emit the first.
- */
-
- list<dcp::SubtitleString> s;
- ContentTimePeriod const p = content_time_period (*_next);
-
- while (_next != _subtitles.end () && content_time_period (*_next) == p) {
- shared_ptr<dcp::SubtitleString> ns = dynamic_pointer_cast<dcp::SubtitleString>(*_next);
- if (ns) {
- s.push_back (*ns);
- ++_next;
- }
-
- /* XXX: image subtitles */
- }
-
- subtitle->emit_text (p, s);
- return false;
-}
-
-ContentTimePeriod
-DCPSubtitleDecoder::content_time_period (shared_ptr<dcp::Subtitle> s) const
-{
- return ContentTimePeriod (
- ContentTime::from_seconds (s->in().as_seconds ()),
- ContentTime::from_seconds (s->out().as_seconds ())
- );
-}
+++ /dev/null
-/*
- Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "subtitle_decoder.h"
-#include "dcp_subtitle.h"
-
-class DCPSubtitleContent;
-
-class DCPSubtitleDecoder : public DCPSubtitle, public Decoder
-{
-public:
- DCPSubtitleDecoder (boost::shared_ptr<const DCPSubtitleContent>, boost::shared_ptr<Log> log);
-
- bool pass ();
- void seek (ContentTime time, bool accurate);
-
-private:
- ContentTimePeriod content_time_period (boost::shared_ptr<dcp::Subtitle> s) const;
-
- std::list<boost::shared_ptr<dcp::Subtitle> > _subtitles;
- std::list<boost::shared_ptr<dcp::Subtitle> >::const_iterator _next;
-};
--- /dev/null
+/*
+ Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "font.h"
+#include "dcp_text_content.h"
+#include "film.h"
+#include "text_content.h"
+#include <dcp/raw_convert.h>
+#include <dcp/interop_subtitle_asset.h>
+#include <dcp/smpte_subtitle_asset.h>
+#include <dcp/interop_load_font_node.h>
+#include <libxml++/libxml++.h>
+#include <boost/foreach.hpp>
+
+#include "i18n.h"
+
+using std::string;
+using std::list;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using dcp::raw_convert;
+
+DCPTextContent::DCPTextContent (shared_ptr<const Film> film, boost::filesystem::path path)
+ : Content (film, path)
+{
+ subtitle.reset (new TextContent (this));
+}
+
+DCPTextContent::DCPTextContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
+ : Content (film, node)
+ , _length (node->number_child<ContentTime::Type> ("Length"))
+{
+ subtitle = TextContent::from_xml (this, node, version);
+}
+
+void
+DCPTextContent::examine (shared_ptr<Job> job)
+{
+ Content::examine (job);
+
+ shared_ptr<dcp::SubtitleAsset> sc = load (path (0));
+
+ shared_ptr<dcp::InteropSubtitleAsset> iop = dynamic_pointer_cast<dcp::InteropSubtitleAsset> (sc);
+ shared_ptr<dcp::SMPTESubtitleAsset> smpte = dynamic_pointer_cast<dcp::SMPTESubtitleAsset> (sc);
+ if (smpte) {
+ set_video_frame_rate (smpte->edit_rate().numerator);
+ }
+
+ boost::mutex::scoped_lock lm (_mutex);
+
+ /* Default to turning these subtitles on */
+ subtitle->set_use (true);
+
+ if (iop) {
+ subtitle->set_language (iop->language ());
+ } else if (smpte) {
+ subtitle->set_language (smpte->language().get_value_or (""));
+ }
+
+ _length = ContentTime::from_seconds (sc->latest_subtitle_out().as_seconds ());
+
+ BOOST_FOREACH (shared_ptr<dcp::LoadFontNode> i, sc->load_font_nodes ()) {
+ subtitle->add_font (shared_ptr<Font> (new Font (i->id)));
+ }
+}
+
+DCPTime
+DCPTextContent::full_length () const
+{
+ FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate());
+ return DCPTime (_length, frc);
+}
+
+string
+DCPTextContent::summary () const
+{
+ return path_summary() + " " + _("[subtitles]");
+}
+
+string
+DCPTextContent::technical_summary () const
+{
+ return Content::technical_summary() + " - " + _("DCP XML subtitles");
+}
+
+void
+DCPTextContent::as_xml (xmlpp::Node* node, bool with_paths) const
+{
+ node->add_child("Type")->add_child_text ("DCPSubtitle");
+ Content::as_xml (node, with_paths);
+
+ if (subtitle) {
+ subtitle->as_xml (node);
+ }
+
+ node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
+}
--- /dev/null
+/*
+ Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "dcp_subtitle.h"
+#include "content.h"
+
+class DCPTextContent : public DCPSubtitle, public Content
+{
+public:
+ DCPTextContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+ DCPTextContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
+
+ void examine (boost::shared_ptr<Job>);
+ std::string summary () const;
+ std::string technical_summary () const;
+ void as_xml (xmlpp::Node *, bool with_paths) const;
+ DCPTime full_length () const;
+
+private:
+ ContentTime _length;
+};
--- /dev/null
+/*
+ Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "dcp_text_decoder.h"
+#include "dcp_text_content.h"
+#include <dcp/interop_subtitle_asset.h>
+#include <iostream>
+
+using std::list;
+using std::cout;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using boost::bind;
+
+DCPTextDecoder::DCPTextDecoder (shared_ptr<const DCPTextContent> content, shared_ptr<Log> log)
+{
+ shared_ptr<dcp::SubtitleAsset> c (load (content->path (0)));
+ _subtitles = c->subtitles ();
+ _next = _subtitles.begin ();
+
+ ContentTime first;
+ if (_next != _subtitles.end()) {
+ first = content_time_period(*_next).from;
+ }
+ subtitle.reset (new TextDecoder (this, content->subtitle, log, first));
+}
+
+void
+DCPTextDecoder::seek (ContentTime time, bool accurate)
+{
+ Decoder::seek (time, accurate);
+
+ _next = _subtitles.begin ();
+ list<shared_ptr<dcp::Subtitle> >::const_iterator i = _subtitles.begin ();
+ while (i != _subtitles.end() && ContentTime::from_seconds ((*_next)->in().as_seconds()) < time) {
+ ++i;
+ }
+}
+
+bool
+DCPTextDecoder::pass ()
+{
+ if (_next == _subtitles.end ()) {
+ return true;
+ }
+
+ /* Gather all subtitles with the same time period that are next
+ on the list. We must emit all subtitles for the same time
+ period with the same text_subtitle() call otherwise the
+ TextDecoder will assume there is nothing else at the
+ time of emit the first.
+ */
+
+ list<dcp::SubtitleString> s;
+ ContentTimePeriod const p = content_time_period (*_next);
+
+ while (_next != _subtitles.end () && content_time_period (*_next) == p) {
+ shared_ptr<dcp::SubtitleString> ns = dynamic_pointer_cast<dcp::SubtitleString>(*_next);
+ if (ns) {
+ s.push_back (*ns);
+ ++_next;
+ }
+
+ /* XXX: image subtitles */
+ }
+
+ subtitle->emit_text (p, s);
+ return false;
+}
+
+ContentTimePeriod
+DCPTextDecoder::content_time_period (shared_ptr<dcp::SubtitleString> s) const
+{
+ return ContentTimePeriod (
+ ContentTime::from_seconds (s->in().as_seconds ()),
+ ContentTime::from_seconds (s->out().as_seconds ())
+ );
+}
--- /dev/null
+/*
+ Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "text_decoder.h"
+#include "dcp_subtitle.h"
+
+class DCPTextContent;
+
+class DCPTextDecoder : public DCPSubtitle, public Decoder
+{
+public:
+ DCPTextDecoder (boost::shared_ptr<const DCPTextContent>, boost::shared_ptr<Log> log);
+
+ bool pass ();
+ void seek (ContentTime time, bool accurate);
+
+private:
+ ContentTimePeriod content_time_period (boost::shared_ptr<dcp::Subtitle> s) const;
+
+ std::list<boost::shared_ptr<dcp::Subtitle> > _subtitles;
+ std::list<boost::shared_ptr<dcp::Subtitle> >::const_iterator _next;
+};
#include "decoder.h"
#include "video_decoder.h"
#include "audio_decoder.h"
-#include "subtitle_decoder.h"
+#include "text_decoder.h"
#include <boost/optional.hpp>
#include <iostream>
class Decoded;
class VideoDecoder;
class AudioDecoder;
-class SubtitleDecoder;
+class TextDecoder;
class DecoderPart;
/** @class Decoder.
boost::shared_ptr<VideoDecoder> video;
boost::shared_ptr<AudioDecoder> audio;
- boost::shared_ptr<SubtitleDecoder> subtitle;
+ boost::shared_ptr<TextDecoder> subtitle;
/** Do some decoding and perhaps emit video, audio or subtitle data.
* @return true if this decoder will emit no more data unless a seek() happens.
#include "dcp_decoder.h"
#include "image_content.h"
#include "image_decoder.h"
-#include "text_subtitle_content.h"
-#include "text_subtitle_decoder.h"
-#include "dcp_subtitle_content.h"
-#include "dcp_subtitle_decoder.h"
+#include "text_text_content.h"
+#include "text_text_decoder.h"
+#include "dcp_text_content.h"
+#include "dcp_text_decoder.h"
#include "video_mxf_content.h"
#include "video_mxf_decoder.h"
#include <boost/foreach.hpp>
return shared_ptr<Decoder> (new ImageDecoder (ic, log));
}
- shared_ptr<const TextSubtitleContent> rc = dynamic_pointer_cast<const TextSubtitleContent> (content);
+ shared_ptr<const TextTextContent> rc = dynamic_pointer_cast<const TextTextContent> (content);
if (rc) {
- return shared_ptr<Decoder> (new TextSubtitleDecoder (rc, log));
+ return shared_ptr<Decoder> (new TextTextDecoder (rc, log));
}
- shared_ptr<const DCPSubtitleContent> dsc = dynamic_pointer_cast<const DCPSubtitleContent> (content);
+ shared_ptr<const DCPTextContent> dsc = dynamic_pointer_cast<const DCPTextContent> (content);
if (dsc) {
- return shared_ptr<Decoder> (new DCPSubtitleDecoder (dsc, log));
+ return shared_ptr<Decoder> (new DCPTextDecoder (dsc, log));
}
shared_ptr<const VideoMXFContent> vmc = dynamic_pointer_cast<const VideoMXFContent> (content);
#include "log.h"
#include "exceptions.h"
#include "frame_rate_change.h"
-#include "subtitle_content.h"
+#include "text_content.h"
#include <dcp/raw_convert.h>
#include <libcxml/cxml.h>
extern "C" {
{
video = VideoContent::from_xml (this, node, version);
audio = AudioContent::from_xml (this, node, version);
- subtitle = SubtitleContent::from_xml (this, node, version);
+ subtitle = TextContent::from_xml (this, node, version);
list<cxml::NodePtr> c = node->node_children ("SubtitleStream");
for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) {
audio.reset (new AudioContent (this, c));
}
if (need_subtitle) {
- subtitle.reset (new SubtitleContent (this, c));
+ subtitle.reset (new TextContent (this, c));
}
shared_ptr<FFmpegContent> ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
_subtitle_streams = examiner->subtitle_streams ();
if (!_subtitle_streams.empty ()) {
- subtitle.reset (new SubtitleContent (this));
+ subtitle.reset (new TextContent (this));
_subtitle_stream = _subtitle_streams.front ();
}
#include "util.h"
#include "log.h"
#include "ffmpeg_decoder.h"
-#include "subtitle_decoder.h"
+#include "text_decoder.h"
#include "ffmpeg_audio_stream.h"
#include "ffmpeg_subtitle_stream.h"
#include "video_filter_graph.h"
#include "film.h"
#include "audio_decoder.h"
#include "compose.hpp"
-#include "subtitle_content.h"
+#include "text_content.h"
#include "audio_content.h"
#include <dcp/subtitle_string.h>
#include <sub/ssa_reader.h>
if (c->subtitle) {
/* XXX: this time here should be the time of the first subtitle, not 0 */
- subtitle.reset (new SubtitleDecoder (this, c->subtitle, log, ContentTime()));
+ subtitle.reset (new TextDecoder (this, c->subtitle, log, ContentTime()));
}
_next_time.resize (_format_context->nb_streams);
#include "screen.h"
#include "audio_content.h"
#include "video_content.h"
-#include "subtitle_content.h"
+#include "text_content.h"
#include "ffmpeg_content.h"
#include "dcp_content.h"
#include "screen_kdm.h"
#include "film.h"
#include "content.h"
#include "video_content.h"
-#include "subtitle_content.h"
+#include "text_content.h"
#include "audio_processor.h"
#include "font.h"
#include "ratio.h"
* proportions of the image size; e.g. rectangle.x = 0.5 would mean that
* the rectangle starts half-way across the video.
*
- * This rectangle may or may not have had a SubtitleContent's offsets and
+ * This rectangle may or may not have had a TextContent's offsets and
* scale applied to it, depending on context.
*/
dcpomatic::Rect<double> rectangle;
#include "decoder.h"
#include "video_decoder.h"
#include "audio_decoder.h"
-#include "subtitle_content.h"
-#include "subtitle_decoder.h"
+#include "text_content.h"
+#include "text_decoder.h"
#include "ffmpeg_content.h"
#include "audio_content.h"
#include "content_subtitle.h"
property == AudioContentProperty::STREAMS ||
property == DCPContentProperty::NEEDS_ASSETS ||
property == DCPContentProperty::NEEDS_KDM ||
- property == SubtitleContentProperty::COLOUR ||
- property == SubtitleContentProperty::EFFECT ||
- property == SubtitleContentProperty::EFFECT_COLOUR ||
+ property == TextContentProperty::COLOUR ||
+ property == TextContentProperty::EFFECT ||
+ property == TextContentProperty::EFFECT_COLOUR ||
property == FFmpegContentProperty::SUBTITLE_STREAM ||
property == FFmpegContentProperty::FILTERS
) {
Changed (property, frequent);
} else if (
- property == SubtitleContentProperty::LINE_SPACING ||
- property == SubtitleContentProperty::OUTLINE_WIDTH ||
- property == SubtitleContentProperty::Y_SCALE ||
- property == SubtitleContentProperty::FADE_IN ||
- property == SubtitleContentProperty::FADE_OUT ||
+ property == TextContentProperty::LINE_SPACING ||
+ property == TextContentProperty::OUTLINE_WIDTH ||
+ property == TextContentProperty::Y_SCALE ||
+ property == TextContentProperty::FADE_IN ||
+ property == TextContentProperty::FADE_OUT ||
property == ContentProperty::VIDEO_FRAME_RATE ||
- property == SubtitleContentProperty::USE ||
- property == SubtitleContentProperty::X_OFFSET ||
- property == SubtitleContentProperty::Y_OFFSET ||
- property == SubtitleContentProperty::X_SCALE ||
- property == SubtitleContentProperty::FONTS ||
+ property == TextContentProperty::USE ||
+ property == TextContentProperty::X_OFFSET ||
+ property == TextContentProperty::Y_OFFSET ||
+ property == TextContentProperty::X_SCALE ||
+ property == TextContentProperty::FONTS ||
property == VideoContentProperty::CROP ||
property == VideoContentProperty::SCALE ||
property == VideoContentProperty::FADE_IN ||
#include "playlist.h"
#include "video_content.h"
-#include "subtitle_content.h"
+#include "text_content.h"
#include "ffmpeg_decoder.h"
#include "ffmpeg_content.h"
#include "image_decoder.h"
+++ /dev/null
-/*
- Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "subtitle_content.h"
-#include "util.h"
-#include "exceptions.h"
-#include "font.h"
-#include "content.h"
-#include <dcp/raw_convert.h>
-#include <libcxml/cxml.h>
-#include <libxml++/libxml++.h>
-#include <boost/foreach.hpp>
-#include <iostream>
-
-#include "i18n.h"
-
-using std::string;
-using std::vector;
-using std::cout;
-using std::list;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using boost::optional;
-using dcp::raw_convert;
-
-int const SubtitleContentProperty::X_OFFSET = 500;
-int const SubtitleContentProperty::Y_OFFSET = 501;
-int const SubtitleContentProperty::X_SCALE = 502;
-int const SubtitleContentProperty::Y_SCALE = 503;
-int const SubtitleContentProperty::USE = 504;
-int const SubtitleContentProperty::BURN = 505;
-int const SubtitleContentProperty::LANGUAGE = 506;
-int const SubtitleContentProperty::FONTS = 507;
-int const SubtitleContentProperty::COLOUR = 508;
-int const SubtitleContentProperty::EFFECT = 509;
-int const SubtitleContentProperty::EFFECT_COLOUR = 510;
-int const SubtitleContentProperty::LINE_SPACING = 511;
-int const SubtitleContentProperty::FADE_IN = 512;
-int const SubtitleContentProperty::FADE_OUT = 513;
-int const SubtitleContentProperty::OUTLINE_WIDTH = 514;
-
-SubtitleContent::SubtitleContent (Content* parent)
- : ContentPart (parent)
- , _use (false)
- , _burn (false)
- , _x_offset (0)
- , _y_offset (0)
- , _x_scale (1)
- , _y_scale (1)
- , _line_spacing (1)
- , _outline_width (2)
-{
-
-}
-
-shared_ptr<SubtitleContent>
-SubtitleContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version)
-{
- if (version < 34) {
- /* With old metadata FFmpeg content has the subtitle-related tags even with no
- subtitle streams, so check for that.
- */
- if (node->string_child("Type") == "FFmpeg" && node->node_children("SubtitleStream").empty()) {
- return shared_ptr<SubtitleContent> ();
- }
-
- /* Otherwise we can drop through to the newer logic */
- }
-
- if (!node->optional_number_child<double>("SubtitleXOffset") && !node->optional_number_child<double>("SubtitleOffset")) {
- return shared_ptr<SubtitleContent> ();
- }
-
- return shared_ptr<SubtitleContent> (new SubtitleContent (parent, node, version));
-}
-
-SubtitleContent::SubtitleContent (Content* parent, cxml::ConstNodePtr node, int version)
- : ContentPart (parent)
- , _use (false)
- , _burn (false)
- , _x_offset (0)
- , _y_offset (0)
- , _x_scale (1)
- , _y_scale (1)
- , _line_spacing (node->optional_number_child<double>("LineSpacing").get_value_or (1))
- , _outline_width (node->optional_number_child<int>("OutlineWidth").get_value_or (2))
-{
- if (version >= 32) {
- _use = node->bool_child ("UseSubtitles");
- _burn = node->bool_child ("BurnSubtitles");
- }
-
- if (version >= 7) {
- _x_offset = node->number_child<double> ("SubtitleXOffset");
- _y_offset = node->number_child<double> ("SubtitleYOffset");
- } else {
- _y_offset = node->number_child<double> ("SubtitleOffset");
- }
-
- if (node->optional_bool_child("Outline").get_value_or(false)) {
- _effect = dcp::BORDER;
- } else if (node->optional_bool_child("Shadow").get_value_or(false)) {
- _effect = dcp::SHADOW;
- } else {
- _effect = dcp::NONE;
- }
-
- optional<string> effect = node->optional_string_child("Effect");
- if (effect) {
- if (*effect == "none") {
- _effect = dcp::NONE;
- } else if (*effect == "outline") {
- _effect = dcp::BORDER;
- } else if (*effect == "shadow") {
- _effect = dcp::SHADOW;
- }
- }
-
- if (version >= 10) {
- _x_scale = node->number_child<double> ("SubtitleXScale");
- _y_scale = node->number_child<double> ("SubtitleYScale");
- } else {
- _x_scale = _y_scale = node->number_child<double> ("SubtitleScale");
- }
-
- optional<int> r = node->optional_number_child<int>("Red");
- optional<int> g = node->optional_number_child<int>("Green");
- optional<int> b = node->optional_number_child<int>("Blue");
- if (r && g && b) {
- _colour = dcp::Colour (*r, *g, *b);
- }
-
- if (version >= 36) {
- optional<int> er = node->optional_number_child<int>("EffectRed");
- optional<int> eg = node->optional_number_child<int>("EffectGreen");
- optional<int> eb = node->optional_number_child<int>("EffectBlue");
- if (er && eg && eb) {
- _effect_colour = dcp::Colour (*er, *eg, *eb);
- }
- } else {
- _effect_colour = dcp::Colour (
- node->optional_number_child<int>("OutlineRed").get_value_or(255),
- node->optional_number_child<int>("OutlineGreen").get_value_or(255),
- node->optional_number_child<int>("OutlineBlue").get_value_or(255)
- );
- }
-
- optional<Frame> fi = node->optional_number_child<Frame>("SubtitleFadeIn");
- if (fi) {
- _fade_in = ContentTime (*fi);
- }
- optional<Frame> fo = node->optional_number_child<Frame>("SubtitleFadeOut");
- if (fo) {
- _fade_out = ContentTime (*fo);
- }
-
- _language = node->optional_string_child ("SubtitleLanguage").get_value_or ("");
-
- list<cxml::NodePtr> fonts = node->node_children ("Font");
- for (list<cxml::NodePtr>::const_iterator i = fonts.begin(); i != fonts.end(); ++i) {
- _fonts.push_back (shared_ptr<Font> (new Font (*i)));
- }
-
- connect_to_fonts ();
-}
-
-SubtitleContent::SubtitleContent (Content* parent, vector<shared_ptr<Content> > c)
- : ContentPart (parent)
-{
- shared_ptr<SubtitleContent> ref = c[0]->subtitle;
- DCPOMATIC_ASSERT (ref);
- list<shared_ptr<Font> > ref_fonts = ref->fonts ();
-
- for (size_t i = 1; i < c.size(); ++i) {
-
- if (c[i]->subtitle->use() != ref->use()) {
- throw JoinError (_("Content to be joined must have the same 'use subtitles' setting."));
- }
-
- if (c[i]->subtitle->burn() != ref->burn()) {
- throw JoinError (_("Content to be joined must have the same 'burn subtitles' setting."));
- }
-
- if (c[i]->subtitle->x_offset() != ref->x_offset()) {
- throw JoinError (_("Content to be joined must have the same subtitle X offset."));
- }
-
- if (c[i]->subtitle->y_offset() != ref->y_offset()) {
- throw JoinError (_("Content to be joined must have the same subtitle Y offset."));
- }
-
- if (c[i]->subtitle->x_scale() != ref->x_scale()) {
- throw JoinError (_("Content to be joined must have the same subtitle X scale."));
- }
-
- if (c[i]->subtitle->y_scale() != ref->y_scale()) {
- throw JoinError (_("Content to be joined must have the same subtitle Y scale."));
- }
-
- if (c[i]->subtitle->line_spacing() != ref->line_spacing()) {
- throw JoinError (_("Content to be joined must have the same subtitle line spacing."));
- }
-
- if ((c[i]->subtitle->fade_in() != ref->fade_in()) || (c[i]->subtitle->fade_out() != ref->fade_out())) {
- throw JoinError (_("Content to be joined must have the same subtitle fades."));
- }
-
- if ((c[i]->subtitle->outline_width() != ref->outline_width())) {
- throw JoinError (_("Content to be joined must have the same outline width."));
- }
-
- list<shared_ptr<Font> > fonts = c[i]->subtitle->fonts ();
- if (fonts.size() != ref_fonts.size()) {
- throw JoinError (_("Content to be joined must use the same fonts."));
- }
-
- list<shared_ptr<Font> >::const_iterator j = ref_fonts.begin ();
- list<shared_ptr<Font> >::const_iterator k = fonts.begin ();
-
- while (j != ref_fonts.end ()) {
- if (**j != **k) {
- throw JoinError (_("Content to be joined must use the same fonts."));
- }
- ++j;
- ++k;
- }
- }
-
- _use = ref->use ();
- _burn = ref->burn ();
- _x_offset = ref->x_offset ();
- _y_offset = ref->y_offset ();
- _x_scale = ref->x_scale ();
- _y_scale = ref->y_scale ();
- _language = ref->language ();
- _fonts = ref_fonts;
- _line_spacing = ref->line_spacing ();
- _fade_in = ref->fade_in ();
- _fade_out = ref->fade_out ();
- _outline_width = ref->outline_width ();
-
- connect_to_fonts ();
-}
-
-/** _mutex must not be held on entry */
-void
-SubtitleContent::as_xml (xmlpp::Node* root) const
-{
- boost::mutex::scoped_lock lm (_mutex);
-
- root->add_child("UseSubtitles")->add_child_text (_use ? "1" : "0");
- root->add_child("BurnSubtitles")->add_child_text (_burn ? "1" : "0");
- root->add_child("SubtitleXOffset")->add_child_text (raw_convert<string> (_x_offset));
- root->add_child("SubtitleYOffset")->add_child_text (raw_convert<string> (_y_offset));
- root->add_child("SubtitleXScale")->add_child_text (raw_convert<string> (_x_scale));
- root->add_child("SubtitleYScale")->add_child_text (raw_convert<string> (_y_scale));
- root->add_child("SubtitleLanguage")->add_child_text (_language);
- if (_colour) {
- root->add_child("Red")->add_child_text (raw_convert<string> (_colour->r));
- root->add_child("Green")->add_child_text (raw_convert<string> (_colour->g));
- root->add_child("Blue")->add_child_text (raw_convert<string> (_colour->b));
- }
- if (_effect) {
- switch (*_effect) {
- case dcp::NONE:
- root->add_child("Effect")->add_child_text("none");
- break;
- case dcp::BORDER:
- root->add_child("Effect")->add_child_text("outline");
- break;
- case dcp::SHADOW:
- root->add_child("Effect")->add_child_text("shadow");
- break;
- }
- }
- if (_effect_colour) {
- root->add_child("EffectRed")->add_child_text (raw_convert<string> (_effect_colour->r));
- root->add_child("EffectGreen")->add_child_text (raw_convert<string> (_effect_colour->g));
- root->add_child("EffectBlue")->add_child_text (raw_convert<string> (_effect_colour->b));
- }
- root->add_child("LineSpacing")->add_child_text (raw_convert<string> (_line_spacing));
- if (_fade_in) {
- root->add_child("SubtitleFadeIn")->add_child_text (raw_convert<string> (_fade_in->get()));
- }
- if (_fade_out) {
- root->add_child("SubtitleFadeOut")->add_child_text (raw_convert<string> (_fade_out->get()));
- }
- root->add_child("OutlineWidth")->add_child_text (raw_convert<string> (_outline_width));
-
- for (list<shared_ptr<Font> >::const_iterator i = _fonts.begin(); i != _fonts.end(); ++i) {
- (*i)->as_xml (root->add_child("Font"));
- }
-}
-
-string
-SubtitleContent::identifier () const
-{
- string s = raw_convert<string> (x_scale())
- + "_" + raw_convert<string> (y_scale())
- + "_" + raw_convert<string> (x_offset())
- + "_" + raw_convert<string> (y_offset())
- + "_" + raw_convert<string> (line_spacing())
- + "_" + raw_convert<string> (fade_in().get_value_or(ContentTime()).get())
- + "_" + raw_convert<string> (fade_out().get_value_or(ContentTime()).get())
- + "_" + raw_convert<string> (outline_width())
- + "_" + raw_convert<string> (colour().get_value_or(dcp::Colour(255, 255, 255)).to_argb_string())
- + "_" + raw_convert<string> (dcp::effect_to_string(effect().get_value_or(dcp::NONE)))
- + "_" + raw_convert<string> (effect_colour().get_value_or(dcp::Colour(0, 0, 0)).to_argb_string());
-
- /* XXX: I suppose really _fonts shouldn't be in here, since not all
- types of subtitle content involve fonts.
- */
- BOOST_FOREACH (shared_ptr<Font> f, _fonts) {
- for (int i = 0; i < FontFiles::VARIANTS; ++i) {
- s += "_" + f->file(static_cast<FontFiles::Variant>(i)).get_value_or("Default").string();
- }
- }
-
- /* The language is for metadata only, and doesn't affect
- how this content looks.
- */
-
- return s;
-}
-
-void
-SubtitleContent::add_font (shared_ptr<Font> font)
-{
- _fonts.push_back (font);
- connect_to_fonts ();
-}
-
-void
-SubtitleContent::connect_to_fonts ()
-{
- BOOST_FOREACH (boost::signals2::connection& i, _font_connections) {
- i.disconnect ();
- }
-
- _font_connections.clear ();
-
- BOOST_FOREACH (shared_ptr<Font> i, _fonts) {
- _font_connections.push_back (i->Changed.connect (boost::bind (&SubtitleContent::font_changed, this)));
- }
-}
-
-void
-SubtitleContent::font_changed ()
-{
- _parent->signal_changed (SubtitleContentProperty::FONTS);
-}
-
-void
-SubtitleContent::set_colour (dcp::Colour colour)
-{
- maybe_set (_colour, colour, SubtitleContentProperty::COLOUR);
-}
-
-void
-SubtitleContent::unset_colour ()
-{
- maybe_set (_colour, optional<dcp::Colour>(), SubtitleContentProperty::COLOUR);
-}
-
-void
-SubtitleContent::set_effect (dcp::Effect e)
-{
- maybe_set (_effect, e, SubtitleContentProperty::EFFECT);
-}
-
-void
-SubtitleContent::unset_effect ()
-{
- maybe_set (_effect, optional<dcp::Effect>(), SubtitleContentProperty::EFFECT);
-}
-
-void
-SubtitleContent::set_effect_colour (dcp::Colour colour)
-{
- maybe_set (_effect_colour, colour, SubtitleContentProperty::EFFECT_COLOUR);
-}
-
-void
-SubtitleContent::unset_effect_colour ()
-{
- maybe_set (_effect_colour, optional<dcp::Colour>(), SubtitleContentProperty::EFFECT_COLOUR);
-}
-
-void
-SubtitleContent::set_use (bool u)
-{
- maybe_set (_use, u, SubtitleContentProperty::USE);
-}
-
-void
-SubtitleContent::set_burn (bool b)
-{
- maybe_set (_burn, b, SubtitleContentProperty::BURN);
-}
-
-void
-SubtitleContent::set_x_offset (double o)
-{
- maybe_set (_x_offset, o, SubtitleContentProperty::X_OFFSET);
-}
-
-void
-SubtitleContent::set_y_offset (double o)
-{
- maybe_set (_y_offset, o, SubtitleContentProperty::Y_OFFSET);
-}
-
-void
-SubtitleContent::set_x_scale (double s)
-{
- maybe_set (_x_scale, s, SubtitleContentProperty::X_SCALE);
-}
-
-void
-SubtitleContent::set_y_scale (double s)
-{
- maybe_set (_y_scale, s, SubtitleContentProperty::Y_SCALE);
-}
-
-void
-SubtitleContent::set_language (string language)
-{
- maybe_set (_language, language, SubtitleContentProperty::LANGUAGE);
-}
-
-void
-SubtitleContent::set_line_spacing (double s)
-{
- maybe_set (_line_spacing, s, SubtitleContentProperty::LINE_SPACING);
-}
-
-void
-SubtitleContent::set_fade_in (ContentTime t)
-{
- maybe_set (_fade_in, t, SubtitleContentProperty::FADE_IN);
-}
-
-void
-SubtitleContent::unset_fade_in ()
-{
- maybe_set (_fade_in, optional<ContentTime>(), SubtitleContentProperty::FADE_IN);
-}
-
-void
-SubtitleContent::set_fade_out (ContentTime t)
-{
- maybe_set (_fade_out, t, SubtitleContentProperty::FADE_OUT);
-}
-
-void
-SubtitleContent::unset_fade_out ()
-{
- maybe_set (_fade_out, optional<ContentTime>(), SubtitleContentProperty::FADE_OUT);
-}
-
-void
-SubtitleContent::set_outline_width (int w)
-{
- maybe_set (_outline_width, w, SubtitleContentProperty::OUTLINE_WIDTH);
-}
-
-void
-SubtitleContent::take_settings_from (shared_ptr<const SubtitleContent> c)
-{
- set_use (c->_use);
- set_burn (c->_burn);
- set_x_offset (c->_x_offset);
- set_y_offset (c->_y_offset);
- set_x_scale (c->_x_scale);
- set_y_scale (c->_y_scale);
- maybe_set (_fonts, c->_fonts, SubtitleContentProperty::FONTS);
- if (c->_colour) {
- set_colour (*c->_colour);
- } else {
- unset_colour ();
- }
- if (c->_effect) {
- set_effect (*c->_effect);
- }
- if (c->_effect_colour) {
- set_effect_colour (*c->_effect_colour);
- } else {
- unset_effect_colour ();
- }
- set_line_spacing (c->_line_spacing);
- if (c->_fade_in) {
- set_fade_in (*c->_fade_in);
- }
- if (c->_fade_out) {
- set_fade_out (*c->_fade_out);
- }
- set_outline_width (c->_outline_width);
-}
+++ /dev/null
-/*
- Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef DCPOMATIC_SUBTITLE_CONTENT_H
-#define DCPOMATIC_SUBTITLE_CONTENT_H
-
-#include "content_part.h"
-#include <libcxml/cxml.h>
-#include <dcp/types.h>
-#include <boost/signals2.hpp>
-
-class Font;
-
-class SubtitleContentProperty
-{
-public:
- static int const X_OFFSET;
- static int const Y_OFFSET;
- static int const X_SCALE;
- static int const Y_SCALE;
- static int const USE;
- static int const BURN;
- static int const LANGUAGE;
- static int const FONTS;
- static int const COLOUR;
- static int const EFFECT;
- static int const EFFECT_COLOUR;
- static int const LINE_SPACING;
- static int const FADE_IN;
- static int const FADE_OUT;
- static int const OUTLINE_WIDTH;
-};
-
-/** @class SubtitleContent
- * @brief Description of how some subtitle content should be presented.
- *
- * There are `image' subtitles (bitmaps) and `text' subtitles (plain text),
- * and not all of the settings in this class correspond to both types.
- */
-class SubtitleContent : public ContentPart
-{
-public:
- explicit SubtitleContent (Content* parent);
- SubtitleContent (Content* parent, std::vector<boost::shared_ptr<Content> >);
-
- void as_xml (xmlpp::Node *) const;
- std::string identifier () const;
- void take_settings_from (boost::shared_ptr<const SubtitleContent> c);
-
- void add_font (boost::shared_ptr<Font> font);
-
- void set_use (bool);
- void set_burn (bool);
- void set_x_offset (double);
- void set_y_offset (double);
- void set_x_scale (double);
- void set_y_scale (double);
- void set_language (std::string language);
- void set_colour (dcp::Colour);
- void unset_colour ();
- void set_effect (dcp::Effect);
- void unset_effect ();
- void set_effect_colour (dcp::Colour);
- void unset_effect_colour ();
- void set_line_spacing (double s);
- void set_fade_in (ContentTime);
- void unset_fade_in ();
- void set_fade_out (ContentTime);
- void set_outline_width (int);
- void unset_fade_out ();
-
- bool use () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _use;
- }
-
- bool burn () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _burn;
- }
-
- double x_offset () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _x_offset;
- }
-
- double y_offset () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _y_offset;
- }
-
- double x_scale () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _x_scale;
- }
-
- double y_scale () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _y_scale;
- }
-
- std::list<boost::shared_ptr<Font> > fonts () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _fonts;
- }
-
- std::string language () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _language;
- }
-
- boost::optional<dcp::Colour> colour () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _colour;
- }
-
- boost::optional<dcp::Effect> effect () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _effect;
- }
-
- boost::optional<dcp::Colour> effect_colour () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _effect_colour;
- }
-
- double line_spacing () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _line_spacing;
- }
-
- boost::optional<ContentTime> fade_in () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _fade_in;
- }
-
- boost::optional<ContentTime> fade_out () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _fade_out;
- }
-
- int outline_width () const {
- boost::mutex::scoped_lock lm (_mutex);
- return _outline_width;
- }
-
- static boost::shared_ptr<SubtitleContent> from_xml (Content* parent, cxml::ConstNodePtr, int version);
-
-protected:
- /** subtitle language (e.g. "German") or empty if it is not known */
- std::string _language;
-
-private:
- friend struct ffmpeg_pts_offset_test;
-
- SubtitleContent (Content* parent, cxml::ConstNodePtr, int version);
- void font_changed ();
- void connect_to_fonts ();
-
- std::list<boost::signals2::connection> _font_connections;
-
- bool _use;
- bool _burn;
- /** x offset for placing subtitles, as a proportion of the container width;
- * +ve is further right, -ve is further left.
- */
- double _x_offset;
- /** y offset for placing subtitles, as a proportion of the container height;
- * +ve is further down the frame, -ve is further up.
- */
- double _y_offset;
- /** x scale factor to apply to subtitles */
- double _x_scale;
- /** y scale factor to apply to subtitles */
- double _y_scale;
- std::list<boost::shared_ptr<Font> > _fonts;
- boost::optional<dcp::Colour> _colour;
- boost::optional<dcp::Effect> _effect;
- boost::optional<dcp::Colour> _effect_colour;
- /** scaling factor for line spacing; 1 is "standard", < 1 is closer together, > 1 is further apart */
- double _line_spacing;
- boost::optional<ContentTime> _fade_in;
- boost::optional<ContentTime> _fade_out;
- int _outline_width;
-};
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2013-2017 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "subtitle_decoder.h"
-#include "subtitle_content.h"
-#include "util.h"
-#include "log.h"
-#include "compose.hpp"
-#include <sub/subtitle.h>
-#include <boost/shared_ptr.hpp>
-#include <boost/foreach.hpp>
-#include <boost/algorithm/string.hpp>
-#include <iostream>
-
-using std::list;
-using std::cout;
-using std::string;
-using std::min;
-using boost::shared_ptr;
-using boost::optional;
-using boost::function;
-
-SubtitleDecoder::SubtitleDecoder (
- Decoder* parent,
- shared_ptr<const SubtitleContent> c,
- shared_ptr<Log> log,
- ContentTime first
- )
- : DecoderPart (parent, log)
- , _content (c)
- , _position (first)
-{
-
-}
-
-/** Called by subclasses when an image subtitle is starting.
- * @param from From time of the subtitle.
- * @param image Subtitle image.
- * @param rect Area expressed as a fraction of the video frame that this subtitle
- * is for (e.g. a width of 0.5 means the width of the subtitle is half the width
- * of the video frame)
- */
-void
-SubtitleDecoder::emit_image_start (ContentTime from, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
-{
- ImageStart (ContentImageSubtitle (from, image, rect));
- _position = from;
-}
-
-void
-SubtitleDecoder::emit_text_start (ContentTime from, list<dcp::SubtitleString> s)
-{
- BOOST_FOREACH (dcp::SubtitleString& i, s) {
- /* We must escape < and > in strings, otherwise they might confuse our subtitle
- renderer (which uses some HTML-esque markup to do bold/italic etc.)
- */
- string t = i.text ();
- boost::algorithm::replace_all (t, "<", "<");
- boost::algorithm::replace_all (t, ">", ">");
- i.set_text (t);
-
- /* Set any forced appearance */
- if (content()->colour()) {
- i.set_colour (*content()->colour());
- }
- if (content()->effect_colour()) {
- i.set_effect_colour (*content()->effect_colour());
- }
- if (content()->effect()) {
- i.set_effect (*content()->effect());
- }
- if (content()->fade_in()) {
- i.set_fade_up_time (dcp::Time(content()->fade_in()->seconds(), 1000));
- }
- if (content()->fade_out()) {
- i.set_fade_down_time (dcp::Time(content()->fade_out()->seconds(), 1000));
- }
- }
-
- TextStart (ContentTextSubtitle (from, s));
- _position = from;
-}
-
-void
-SubtitleDecoder::emit_text_start (ContentTime from, sub::Subtitle const & subtitle)
-{
- /* See if our next subtitle needs to be vertically placed on screen by us */
- bool needs_placement = false;
- optional<int> bottom_line;
- BOOST_FOREACH (sub::Line i, subtitle.lines) {
- if (!i.vertical_position.reference || i.vertical_position.reference.get() == sub::TOP_OF_SUBTITLE) {
- needs_placement = true;
- DCPOMATIC_ASSERT (i.vertical_position.line);
- if (!bottom_line || bottom_line.get() < i.vertical_position.line.get()) {
- bottom_line = i.vertical_position.line.get();
- }
- }
- }
-
- /* Find the lowest proportional position */
- optional<float> lowest_proportional;
- BOOST_FOREACH (sub::Line i, subtitle.lines) {
- if (i.vertical_position.proportional) {
- if (!lowest_proportional) {
- lowest_proportional = i.vertical_position.proportional;
- } else {
- lowest_proportional = min (lowest_proportional.get(), i.vertical_position.proportional.get());
- }
- }
- }
-
- list<dcp::SubtitleString> out;
- BOOST_FOREACH (sub::Line i, subtitle.lines) {
- BOOST_FOREACH (sub::Block j, i.blocks) {
-
- if (!j.font_size.specified()) {
- /* Fallback default font size if no other has been specified */
- j.font_size.set_points (48);
- }
-
- float v_position;
- dcp::VAlign v_align;
- if (needs_placement) {
- DCPOMATIC_ASSERT (i.vertical_position.line);
- /* This 1.015 is an arbitrary value to lift the bottom sub off the bottom
- of the screen a bit to a pleasing degree.
- */
- v_position = 1.015 -
- (1 + bottom_line.get() - i.vertical_position.line.get())
- * 1.2 * content()->line_spacing() * content()->y_scale() * j.font_size.proportional (72 * 11);
-
- v_align = dcp::VALIGN_TOP;
- } else {
- DCPOMATIC_ASSERT (i.vertical_position.proportional);
- DCPOMATIC_ASSERT (i.vertical_position.reference);
- v_position = i.vertical_position.proportional.get();
-
- if (lowest_proportional) {
- /* Adjust line spacing */
- v_position = ((v_position - lowest_proportional.get()) * content()->line_spacing()) + lowest_proportional.get();
- }
-
- switch (i.vertical_position.reference.get()) {
- case sub::TOP_OF_SCREEN:
- v_align = dcp::VALIGN_TOP;
- break;
- case sub::VERTICAL_CENTRE_OF_SCREEN:
- v_align = dcp::VALIGN_CENTER;
- break;
- case sub::BOTTOM_OF_SCREEN:
- v_align = dcp::VALIGN_BOTTOM;
- break;
- default:
- v_align = dcp::VALIGN_TOP;
- break;
- }
- }
-
- dcp::HAlign h_align;
- switch (i.horizontal_position.reference) {
- case sub::LEFT_OF_SCREEN:
- h_align = dcp::HALIGN_LEFT;
- break;
- case sub::HORIZONTAL_CENTRE_OF_SCREEN:
- h_align = dcp::HALIGN_CENTER;
- break;
- case sub::RIGHT_OF_SCREEN:
- h_align = dcp::HALIGN_RIGHT;
- break;
- default:
- h_align = dcp::HALIGN_CENTER;
- break;
- }
-
- /* The idea here (rightly or wrongly) is that we set the appearance based on the
- values in the libsub objects, and these are overridden with values from the
- content by the other emit_text_start() above.
- */
-
- out.push_back (
- dcp::SubtitleString (
- string(TEXT_FONT_ID),
- j.italic,
- j.bold,
- j.underline,
- j.colour.dcp(),
- j.font_size.points (72 * 11),
- 1.0,
- dcp::Time (from.seconds(), 1000),
- /* XXX: hmm; this is a bit ugly (we don't know the to time yet) */
- dcp::Time (),
- i.horizontal_position.proportional,
- h_align,
- v_position,
- v_align,
- dcp::DIRECTION_LTR,
- j.text,
- dcp::NONE,
- j.effect_colour.get_value_or(sub::Colour(0, 0, 0)).dcp(),
- /* Hack: we should use subtitle.fade_up and subtitle.fade_down here
- but the times of these often don't have a frame rate associated
- with them so the sub::Time won't convert them to milliseconds without
- throwing an exception. Since only DCP subs fill those in (and we don't
- use libsub for DCP subs) we can cheat by just putting 0 in here.
- */
- dcp::Time (),
- dcp::Time ()
- )
- );
- }
- }
-
- emit_text_start (from, out);
-}
-
-void
-SubtitleDecoder::emit_stop (ContentTime to)
-{
- Stop (to);
-}
-
-void
-SubtitleDecoder::emit_text (ContentTimePeriod period, list<dcp::SubtitleString> s)
-{
- emit_text_start (period.from, s);
- emit_stop (period.to);
-}
-
-void
-SubtitleDecoder::emit_text (ContentTimePeriod period, sub::Subtitle const & s)
-{
- emit_text_start (period.from, s);
- emit_stop (period.to);
-}
-
-void
-SubtitleDecoder::seek ()
-{
- _position = ContentTime ();
-}
+++ /dev/null
-/*
- Copyright (C) 2013-2017 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef DCPOMATIC_SUBTITLE_DECODER_H
-#define DCPOMATIC_SUBTITLE_DECODER_H
-
-#include "decoder.h"
-#include "rect.h"
-#include "types.h"
-#include "content_subtitle.h"
-#include "decoder_part.h"
-#include <dcp/subtitle_string.h>
-#include <boost/signals2.hpp>
-
-namespace sub {
- class Subtitle;
-}
-
-class Image;
-
-class SubtitleDecoder : public DecoderPart
-{
-public:
- SubtitleDecoder (
- Decoder* parent,
- boost::shared_ptr<const SubtitleContent>,
- boost::shared_ptr<Log> log,
- ContentTime first
- );
-
- ContentTime position () const {
- return _position;
- }
-
- void emit_image_start (ContentTime from, boost::shared_ptr<Image> image, dcpomatic::Rect<double> rect);
- void emit_text_start (ContentTime from, std::list<dcp::SubtitleString> s);
- void emit_text_start (ContentTime from, sub::Subtitle const & subtitle);
- void emit_text (ContentTimePeriod period, std::list<dcp::SubtitleString> s);
- void emit_text (ContentTimePeriod period, sub::Subtitle const & subtitle);
- void emit_stop (ContentTime to);
-
- void seek ();
-
- boost::shared_ptr<const SubtitleContent> content () const {
- return _content;
- }
-
- boost::signals2::signal<void (ContentImageSubtitle)> ImageStart;
- boost::signals2::signal<void (ContentTextSubtitle)> TextStart;
- boost::signals2::signal<void (ContentTime)> Stop;
-
-private:
- boost::shared_ptr<const SubtitleContent> _content;
- ContentTime _position;
-};
-
-#endif
--- /dev/null
+/*
+ Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "text_content.h"
+#include "util.h"
+#include "exceptions.h"
+#include "font.h"
+#include "content.h"
+#include <dcp/raw_convert.h>
+#include <libcxml/cxml.h>
+#include <libxml++/libxml++.h>
+#include <boost/foreach.hpp>
+#include <iostream>
+
+#include "i18n.h"
+
+using std::string;
+using std::vector;
+using std::cout;
+using std::list;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using boost::optional;
+using dcp::raw_convert;
+
+int const TextContentProperty::X_OFFSET = 500;
+int const TextContentProperty::Y_OFFSET = 501;
+int const TextContentProperty::X_SCALE = 502;
+int const TextContentProperty::Y_SCALE = 503;
+int const TextContentProperty::USE = 504;
+int const TextContentProperty::BURN = 505;
+int const TextContentProperty::LANGUAGE = 506;
+int const TextContentProperty::FONTS = 507;
+int const TextContentProperty::COLOUR = 508;
+int const TextContentProperty::EFFECT = 509;
+int const TextContentProperty::EFFECT_COLOUR = 510;
+int const TextContentProperty::LINE_SPACING = 511;
+int const TextContentProperty::FADE_IN = 512;
+int const TextContentProperty::FADE_OUT = 513;
+int const TextContentProperty::OUTLINE_WIDTH = 514;
+
+TextContent::TextContent (Content* parent)
+ : ContentPart (parent)
+ , _use (false)
+ , _burn (false)
+ , _x_offset (0)
+ , _y_offset (0)
+ , _x_scale (1)
+ , _y_scale (1)
+ , _line_spacing (1)
+ , _outline_width (2)
+{
+
+}
+
+shared_ptr<TextContent>
+TextContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version)
+{
+ if (version < 34) {
+ /* With old metadata FFmpeg content has the subtitle-related tags even with no
+ subtitle streams, so check for that.
+ */
+ if (node->string_child("Type") == "FFmpeg" && node->node_children("SubtitleStream").empty()) {
+ return shared_ptr<TextContent> ();
+ }
+
+ /* Otherwise we can drop through to the newer logic */
+ }
+
+ if (!node->optional_number_child<double>("SubtitleXOffset") && !node->optional_number_child<double>("SubtitleOffset")) {
+ return shared_ptr<TextContent> ();
+ }
+
+ return shared_ptr<TextContent> (new TextContent (parent, node, version));
+}
+
+TextContent::TextContent (Content* parent, cxml::ConstNodePtr node, int version)
+ : ContentPart (parent)
+ , _use (false)
+ , _burn (false)
+ , _x_offset (0)
+ , _y_offset (0)
+ , _x_scale (1)
+ , _y_scale (1)
+ , _line_spacing (node->optional_number_child<double>("LineSpacing").get_value_or (1))
+ , _outline_width (node->optional_number_child<int>("OutlineWidth").get_value_or (2))
+{
+ if (version >= 32) {
+ _use = node->bool_child ("UseSubtitles");
+ _burn = node->bool_child ("BurnSubtitles");
+ }
+
+ if (version >= 7) {
+ _x_offset = node->number_child<double> ("SubtitleXOffset");
+ _y_offset = node->number_child<double> ("SubtitleYOffset");
+ } else {
+ _y_offset = node->number_child<double> ("SubtitleOffset");
+ }
+
+ if (node->optional_bool_child("Outline").get_value_or(false)) {
+ _effect = dcp::BORDER;
+ } else if (node->optional_bool_child("Shadow").get_value_or(false)) {
+ _effect = dcp::SHADOW;
+ } else {
+ _effect = dcp::NONE;
+ }
+
+ optional<string> effect = node->optional_string_child("Effect");
+ if (effect) {
+ if (*effect == "none") {
+ _effect = dcp::NONE;
+ } else if (*effect == "outline") {
+ _effect = dcp::BORDER;
+ } else if (*effect == "shadow") {
+ _effect = dcp::SHADOW;
+ }
+ }
+
+ if (version >= 10) {
+ _x_scale = node->number_child<double> ("SubtitleXScale");
+ _y_scale = node->number_child<double> ("SubtitleYScale");
+ } else {
+ _x_scale = _y_scale = node->number_child<double> ("SubtitleScale");
+ }
+
+ optional<int> r = node->optional_number_child<int>("Red");
+ optional<int> g = node->optional_number_child<int>("Green");
+ optional<int> b = node->optional_number_child<int>("Blue");
+ if (r && g && b) {
+ _colour = dcp::Colour (*r, *g, *b);
+ }
+
+ if (version >= 36) {
+ optional<int> er = node->optional_number_child<int>("EffectRed");
+ optional<int> eg = node->optional_number_child<int>("EffectGreen");
+ optional<int> eb = node->optional_number_child<int>("EffectBlue");
+ if (er && eg && eb) {
+ _effect_colour = dcp::Colour (*er, *eg, *eb);
+ }
+ } else {
+ _effect_colour = dcp::Colour (
+ node->optional_number_child<int>("OutlineRed").get_value_or(255),
+ node->optional_number_child<int>("OutlineGreen").get_value_or(255),
+ node->optional_number_child<int>("OutlineBlue").get_value_or(255)
+ );
+ }
+
+ optional<Frame> fi = node->optional_number_child<Frame>("SubtitleFadeIn");
+ if (fi) {
+ _fade_in = ContentTime (*fi);
+ }
+ optional<Frame> fo = node->optional_number_child<Frame>("SubtitleFadeOut");
+ if (fo) {
+ _fade_out = ContentTime (*fo);
+ }
+
+ _language = node->optional_string_child ("SubtitleLanguage").get_value_or ("");
+
+ list<cxml::NodePtr> fonts = node->node_children ("Font");
+ for (list<cxml::NodePtr>::const_iterator i = fonts.begin(); i != fonts.end(); ++i) {
+ _fonts.push_back (shared_ptr<Font> (new Font (*i)));
+ }
+
+ connect_to_fonts ();
+}
+
+TextContent::TextContent (Content* parent, vector<shared_ptr<Content> > c)
+ : ContentPart (parent)
+{
+ shared_ptr<TextContent> ref = c[0]->subtitle;
+ DCPOMATIC_ASSERT (ref);
+ list<shared_ptr<Font> > ref_fonts = ref->fonts ();
+
+ for (size_t i = 1; i < c.size(); ++i) {
+
+ if (c[i]->subtitle->use() != ref->use()) {
+ throw JoinError (_("Content to be joined must have the same 'use subtitles' setting."));
+ }
+
+ if (c[i]->subtitle->burn() != ref->burn()) {
+ throw JoinError (_("Content to be joined must have the same 'burn subtitles' setting."));
+ }
+
+ if (c[i]->subtitle->x_offset() != ref->x_offset()) {
+ throw JoinError (_("Content to be joined must have the same subtitle X offset."));
+ }
+
+ if (c[i]->subtitle->y_offset() != ref->y_offset()) {
+ throw JoinError (_("Content to be joined must have the same subtitle Y offset."));
+ }
+
+ if (c[i]->subtitle->x_scale() != ref->x_scale()) {
+ throw JoinError (_("Content to be joined must have the same subtitle X scale."));
+ }
+
+ if (c[i]->subtitle->y_scale() != ref->y_scale()) {
+ throw JoinError (_("Content to be joined must have the same subtitle Y scale."));
+ }
+
+ if (c[i]->subtitle->line_spacing() != ref->line_spacing()) {
+ throw JoinError (_("Content to be joined must have the same subtitle line spacing."));
+ }
+
+ if ((c[i]->subtitle->fade_in() != ref->fade_in()) || (c[i]->subtitle->fade_out() != ref->fade_out())) {
+ throw JoinError (_("Content to be joined must have the same subtitle fades."));
+ }
+
+ if ((c[i]->subtitle->outline_width() != ref->outline_width())) {
+ throw JoinError (_("Content to be joined must have the same outline width."));
+ }
+
+ list<shared_ptr<Font> > fonts = c[i]->subtitle->fonts ();
+ if (fonts.size() != ref_fonts.size()) {
+ throw JoinError (_("Content to be joined must use the same fonts."));
+ }
+
+ list<shared_ptr<Font> >::const_iterator j = ref_fonts.begin ();
+ list<shared_ptr<Font> >::const_iterator k = fonts.begin ();
+
+ while (j != ref_fonts.end ()) {
+ if (**j != **k) {
+ throw JoinError (_("Content to be joined must use the same fonts."));
+ }
+ ++j;
+ ++k;
+ }
+ }
+
+ _use = ref->use ();
+ _burn = ref->burn ();
+ _x_offset = ref->x_offset ();
+ _y_offset = ref->y_offset ();
+ _x_scale = ref->x_scale ();
+ _y_scale = ref->y_scale ();
+ _language = ref->language ();
+ _fonts = ref_fonts;
+ _line_spacing = ref->line_spacing ();
+ _fade_in = ref->fade_in ();
+ _fade_out = ref->fade_out ();
+ _outline_width = ref->outline_width ();
+
+ connect_to_fonts ();
+}
+
+/** _mutex must not be held on entry */
+void
+TextContent::as_xml (xmlpp::Node* root) const
+{
+ boost::mutex::scoped_lock lm (_mutex);
+
+ root->add_child("UseSubtitles")->add_child_text (_use ? "1" : "0");
+ root->add_child("BurnSubtitles")->add_child_text (_burn ? "1" : "0");
+ root->add_child("SubtitleXOffset")->add_child_text (raw_convert<string> (_x_offset));
+ root->add_child("SubtitleYOffset")->add_child_text (raw_convert<string> (_y_offset));
+ root->add_child("SubtitleXScale")->add_child_text (raw_convert<string> (_x_scale));
+ root->add_child("SubtitleYScale")->add_child_text (raw_convert<string> (_y_scale));
+ root->add_child("SubtitleLanguage")->add_child_text (_language);
+ if (_colour) {
+ root->add_child("Red")->add_child_text (raw_convert<string> (_colour->r));
+ root->add_child("Green")->add_child_text (raw_convert<string> (_colour->g));
+ root->add_child("Blue")->add_child_text (raw_convert<string> (_colour->b));
+ }
+ if (_effect) {
+ switch (*_effect) {
+ case dcp::NONE:
+ root->add_child("Effect")->add_child_text("none");
+ break;
+ case dcp::BORDER:
+ root->add_child("Effect")->add_child_text("outline");
+ break;
+ case dcp::SHADOW:
+ root->add_child("Effect")->add_child_text("shadow");
+ break;
+ }
+ }
+ if (_effect_colour) {
+ root->add_child("EffectRed")->add_child_text (raw_convert<string> (_effect_colour->r));
+ root->add_child("EffectGreen")->add_child_text (raw_convert<string> (_effect_colour->g));
+ root->add_child("EffectBlue")->add_child_text (raw_convert<string> (_effect_colour->b));
+ }
+ root->add_child("LineSpacing")->add_child_text (raw_convert<string> (_line_spacing));
+ if (_fade_in) {
+ root->add_child("SubtitleFadeIn")->add_child_text (raw_convert<string> (_fade_in->get()));
+ }
+ if (_fade_out) {
+ root->add_child("SubtitleFadeOut")->add_child_text (raw_convert<string> (_fade_out->get()));
+ }
+ root->add_child("OutlineWidth")->add_child_text (raw_convert<string> (_outline_width));
+
+ for (list<shared_ptr<Font> >::const_iterator i = _fonts.begin(); i != _fonts.end(); ++i) {
+ (*i)->as_xml (root->add_child("Font"));
+ }
+}
+
+string
+TextContent::identifier () const
+{
+ string s = raw_convert<string> (x_scale())
+ + "_" + raw_convert<string> (y_scale())
+ + "_" + raw_convert<string> (x_offset())
+ + "_" + raw_convert<string> (y_offset())
+ + "_" + raw_convert<string> (line_spacing())
+ + "_" + raw_convert<string> (fade_in().get_value_or(ContentTime()).get())
+ + "_" + raw_convert<string> (fade_out().get_value_or(ContentTime()).get())
+ + "_" + raw_convert<string> (outline_width())
+ + "_" + raw_convert<string> (colour().get_value_or(dcp::Colour(255, 255, 255)).to_argb_string())
+ + "_" + raw_convert<string> (dcp::effect_to_string(effect().get_value_or(dcp::NONE)))
+ + "_" + raw_convert<string> (effect_colour().get_value_or(dcp::Colour(0, 0, 0)).to_argb_string());
+
+ /* XXX: I suppose really _fonts shouldn't be in here, since not all
+ types of subtitle content involve fonts.
+ */
+ BOOST_FOREACH (shared_ptr<Font> f, _fonts) {
+ for (int i = 0; i < FontFiles::VARIANTS; ++i) {
+ s += "_" + f->file(static_cast<FontFiles::Variant>(i)).get_value_or("Default").string();
+ }
+ }
+
+ /* The language is for metadata only, and doesn't affect
+ how this content looks.
+ */
+
+ return s;
+}
+
+void
+TextContent::add_font (shared_ptr<Font> font)
+{
+ _fonts.push_back (font);
+ connect_to_fonts ();
+}
+
+void
+TextContent::connect_to_fonts ()
+{
+ BOOST_FOREACH (boost::signals2::connection& i, _font_connections) {
+ i.disconnect ();
+ }
+
+ _font_connections.clear ();
+
+ BOOST_FOREACH (shared_ptr<Font> i, _fonts) {
+ _font_connections.push_back (i->Changed.connect (boost::bind (&TextContent::font_changed, this)));
+ }
+}
+
+void
+TextContent::font_changed ()
+{
+ _parent->signal_changed (TextContentProperty::FONTS);
+}
+
+void
+TextContent::set_colour (dcp::Colour colour)
+{
+ maybe_set (_colour, colour, TextContentProperty::COLOUR);
+}
+
+void
+TextContent::unset_colour ()
+{
+ maybe_set (_colour, optional<dcp::Colour>(), TextContentProperty::COLOUR);
+}
+
+void
+TextContent::set_effect (dcp::Effect e)
+{
+ maybe_set (_effect, e, TextContentProperty::EFFECT);
+}
+
+void
+TextContent::unset_effect ()
+{
+ maybe_set (_effect, optional<dcp::Effect>(), TextContentProperty::EFFECT);
+}
+
+void
+TextContent::set_effect_colour (dcp::Colour colour)
+{
+ maybe_set (_effect_colour, colour, TextContentProperty::EFFECT_COLOUR);
+}
+
+void
+TextContent::unset_effect_colour ()
+{
+ maybe_set (_effect_colour, optional<dcp::Colour>(), TextContentProperty::EFFECT_COLOUR);
+}
+
+void
+TextContent::set_use (bool u)
+{
+ maybe_set (_use, u, TextContentProperty::USE);
+}
+
+void
+TextContent::set_burn (bool b)
+{
+ maybe_set (_burn, b, TextContentProperty::BURN);
+}
+
+void
+TextContent::set_x_offset (double o)
+{
+ maybe_set (_x_offset, o, TextContentProperty::X_OFFSET);
+}
+
+void
+TextContent::set_y_offset (double o)
+{
+ maybe_set (_y_offset, o, TextContentProperty::Y_OFFSET);
+}
+
+void
+TextContent::set_x_scale (double s)
+{
+ maybe_set (_x_scale, s, TextContentProperty::X_SCALE);
+}
+
+void
+TextContent::set_y_scale (double s)
+{
+ maybe_set (_y_scale, s, TextContentProperty::Y_SCALE);
+}
+
+void
+TextContent::set_language (string language)
+{
+ maybe_set (_language, language, TextContentProperty::LANGUAGE);
+}
+
+void
+TextContent::set_line_spacing (double s)
+{
+ maybe_set (_line_spacing, s, TextContentProperty::LINE_SPACING);
+}
+
+void
+TextContent::set_fade_in (ContentTime t)
+{
+ maybe_set (_fade_in, t, TextContentProperty::FADE_IN);
+}
+
+void
+TextContent::unset_fade_in ()
+{
+ maybe_set (_fade_in, optional<ContentTime>(), TextContentProperty::FADE_IN);
+}
+
+void
+TextContent::set_fade_out (ContentTime t)
+{
+ maybe_set (_fade_out, t, TextContentProperty::FADE_OUT);
+}
+
+void
+TextContent::unset_fade_out ()
+{
+ maybe_set (_fade_out, optional<ContentTime>(), TextContentProperty::FADE_OUT);
+}
+
+void
+TextContent::set_outline_width (int w)
+{
+ maybe_set (_outline_width, w, TextContentProperty::OUTLINE_WIDTH);
+}
+
+void
+TextContent::take_settings_from (shared_ptr<const TextContent> c)
+{
+ set_use (c->_use);
+ set_burn (c->_burn);
+ set_x_offset (c->_x_offset);
+ set_y_offset (c->_y_offset);
+ set_x_scale (c->_x_scale);
+ set_y_scale (c->_y_scale);
+ maybe_set (_fonts, c->_fonts, TextContentProperty::FONTS);
+ if (c->_colour) {
+ set_colour (*c->_colour);
+ } else {
+ unset_colour ();
+ }
+ if (c->_effect) {
+ set_effect (*c->_effect);
+ }
+ if (c->_effect_colour) {
+ set_effect_colour (*c->_effect_colour);
+ } else {
+ unset_effect_colour ();
+ }
+ set_line_spacing (c->_line_spacing);
+ if (c->_fade_in) {
+ set_fade_in (*c->_fade_in);
+ }
+ if (c->_fade_out) {
+ set_fade_out (*c->_fade_out);
+ }
+ set_outline_width (c->_outline_width);
+}
--- /dev/null
+/*
+ Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DCPOMATIC_SUBTITLE_CONTENT_H
+#define DCPOMATIC_SUBTITLE_CONTENT_H
+
+#include "content_part.h"
+#include <libcxml/cxml.h>
+#include <dcp/types.h>
+#include <boost/signals2.hpp>
+
+class Font;
+
+class TextContentProperty
+{
+public:
+ static int const X_OFFSET;
+ static int const Y_OFFSET;
+ static int const X_SCALE;
+ static int const Y_SCALE;
+ static int const USE;
+ static int const BURN;
+ static int const LANGUAGE;
+ static int const FONTS;
+ static int const COLOUR;
+ static int const EFFECT;
+ static int const EFFECT_COLOUR;
+ static int const LINE_SPACING;
+ static int const FADE_IN;
+ static int const FADE_OUT;
+ static int const OUTLINE_WIDTH;
+};
+
+/** @class TextContent
+ * @brief Description of how some subtitle content should be presented.
+ *
+ * There are `image' subtitles (bitmaps) and `text' subtitles (plain text),
+ * and not all of the settings in this class correspond to both types.
+ */
+class TextContent : public ContentPart
+{
+public:
+ explicit TextContent (Content* parent);
+ TextContent (Content* parent, std::vector<boost::shared_ptr<Content> >);
+
+ void as_xml (xmlpp::Node *) const;
+ std::string identifier () const;
+ void take_settings_from (boost::shared_ptr<const TextContent> c);
+
+ void add_font (boost::shared_ptr<Font> font);
+
+ void set_use (bool);
+ void set_burn (bool);
+ void set_x_offset (double);
+ void set_y_offset (double);
+ void set_x_scale (double);
+ void set_y_scale (double);
+ void set_language (std::string language);
+ void set_colour (dcp::Colour);
+ void unset_colour ();
+ void set_effect (dcp::Effect);
+ void unset_effect ();
+ void set_effect_colour (dcp::Colour);
+ void unset_effect_colour ();
+ void set_line_spacing (double s);
+ void set_fade_in (ContentTime);
+ void unset_fade_in ();
+ void set_fade_out (ContentTime);
+ void set_outline_width (int);
+ void unset_fade_out ();
+
+ bool use () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _use;
+ }
+
+ bool burn () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _burn;
+ }
+
+ double x_offset () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _x_offset;
+ }
+
+ double y_offset () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _y_offset;
+ }
+
+ double x_scale () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _x_scale;
+ }
+
+ double y_scale () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _y_scale;
+ }
+
+ std::list<boost::shared_ptr<Font> > fonts () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _fonts;
+ }
+
+ std::string language () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _language;
+ }
+
+ boost::optional<dcp::Colour> colour () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _colour;
+ }
+
+ boost::optional<dcp::Effect> effect () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _effect;
+ }
+
+ boost::optional<dcp::Colour> effect_colour () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _effect_colour;
+ }
+
+ double line_spacing () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _line_spacing;
+ }
+
+ boost::optional<ContentTime> fade_in () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _fade_in;
+ }
+
+ boost::optional<ContentTime> fade_out () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _fade_out;
+ }
+
+ int outline_width () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ return _outline_width;
+ }
+
+ static boost::shared_ptr<TextContent> from_xml (Content* parent, cxml::ConstNodePtr, int version);
+
+protected:
+ /** subtitle language (e.g. "German") or empty if it is not known */
+ std::string _language;
+
+private:
+ friend struct ffmpeg_pts_offset_test;
+
+ TextContent (Content* parent, cxml::ConstNodePtr, int version);
+ void font_changed ();
+ void connect_to_fonts ();
+
+ std::list<boost::signals2::connection> _font_connections;
+
+ bool _use;
+ bool _burn;
+ /** x offset for placing subtitles, as a proportion of the container width;
+ * +ve is further right, -ve is further left.
+ */
+ double _x_offset;
+ /** y offset for placing subtitles, as a proportion of the container height;
+ * +ve is further down the frame, -ve is further up.
+ */
+ double _y_offset;
+ /** x scale factor to apply to subtitles */
+ double _x_scale;
+ /** y scale factor to apply to subtitles */
+ double _y_scale;
+ std::list<boost::shared_ptr<Font> > _fonts;
+ boost::optional<dcp::Colour> _colour;
+ boost::optional<dcp::Effect> _effect;
+ boost::optional<dcp::Colour> _effect_colour;
+ /** scaling factor for line spacing; 1 is "standard", < 1 is closer together, > 1 is further apart */
+ double _line_spacing;
+ boost::optional<ContentTime> _fade_in;
+ boost::optional<ContentTime> _fade_out;
+ int _outline_width;
+};
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2013-2017 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "text_decoder.h"
+#include "text_content.h"
+#include "util.h"
+#include "log.h"
+#include "compose.hpp"
+#include <sub/subtitle.h>
+#include <boost/shared_ptr.hpp>
+#include <boost/foreach.hpp>
+#include <boost/algorithm/string.hpp>
+#include <iostream>
+
+using std::list;
+using std::cout;
+using std::string;
+using std::min;
+using boost::shared_ptr;
+using boost::optional;
+using boost::function;
+
+TextDecoder::TextDecoder (
+ Decoder* parent,
+ shared_ptr<const TextContent> c,
+ shared_ptr<Log> log,
+ ContentTime first
+ )
+ : DecoderPart (parent, log)
+ , _content (c)
+ , _position (first)
+{
+
+}
+
+/** Called by subclasses when an image subtitle is starting.
+ * @param from From time of the subtitle.
+ * @param image Subtitle image.
+ * @param rect Area expressed as a fraction of the video frame that this subtitle
+ * is for (e.g. a width of 0.5 means the width of the subtitle is half the width
+ * of the video frame)
+ */
+void
+TextDecoder::emit_image_start (ContentTime from, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
+{
+ ImageStart (ContentImageSubtitle (from, image, rect));
+ _position = from;
+}
+
+void
+TextDecoder::emit_text_start (ContentTime from, list<dcp::SubtitleString> s)
+{
+ BOOST_FOREACH (dcp::SubtitleString& i, s) {
+ /* We must escape < and > in strings, otherwise they might confuse our subtitle
+ renderer (which uses some HTML-esque markup to do bold/italic etc.)
+ */
+ string t = i.text ();
+ boost::algorithm::replace_all (t, "<", "<");
+ boost::algorithm::replace_all (t, ">", ">");
+ i.set_text (t);
+
+ /* Set any forced appearance */
+ if (content()->colour()) {
+ i.set_colour (*content()->colour());
+ }
+ if (content()->effect_colour()) {
+ i.set_effect_colour (*content()->effect_colour());
+ }
+ if (content()->effect()) {
+ i.set_effect (*content()->effect());
+ }
+ if (content()->fade_in()) {
+ i.set_fade_up_time (dcp::Time(content()->fade_in()->seconds(), 1000));
+ }
+ if (content()->fade_out()) {
+ i.set_fade_down_time (dcp::Time(content()->fade_out()->seconds(), 1000));
+ }
+ }
+
+ TextStart (ContentTextSubtitle (from, s));
+ _position = from;
+}
+
+void
+TextDecoder::emit_text_start (ContentTime from, sub::Subtitle const & subtitle)
+{
+ /* See if our next subtitle needs to be vertically placed on screen by us */
+ bool needs_placement = false;
+ optional<int> bottom_line;
+ BOOST_FOREACH (sub::Line i, subtitle.lines) {
+ if (!i.vertical_position.reference || i.vertical_position.reference.get() == sub::TOP_OF_SUBTITLE) {
+ needs_placement = true;
+ DCPOMATIC_ASSERT (i.vertical_position.line);
+ if (!bottom_line || bottom_line.get() < i.vertical_position.line.get()) {
+ bottom_line = i.vertical_position.line.get();
+ }
+ }
+ }
+
+ /* Find the lowest proportional position */
+ optional<float> lowest_proportional;
+ BOOST_FOREACH (sub::Line i, subtitle.lines) {
+ if (i.vertical_position.proportional) {
+ if (!lowest_proportional) {
+ lowest_proportional = i.vertical_position.proportional;
+ } else {
+ lowest_proportional = min (lowest_proportional.get(), i.vertical_position.proportional.get());
+ }
+ }
+ }
+
+ list<dcp::SubtitleString> out;
+ BOOST_FOREACH (sub::Line i, subtitle.lines) {
+ BOOST_FOREACH (sub::Block j, i.blocks) {
+
+ if (!j.font_size.specified()) {
+ /* Fallback default font size if no other has been specified */
+ j.font_size.set_points (48);
+ }
+
+ float v_position;
+ dcp::VAlign v_align;
+ if (needs_placement) {
+ DCPOMATIC_ASSERT (i.vertical_position.line);
+ /* This 1.015 is an arbitrary value to lift the bottom sub off the bottom
+ of the screen a bit to a pleasing degree.
+ */
+ v_position = 1.015 -
+ (1 + bottom_line.get() - i.vertical_position.line.get())
+ * 1.2 * content()->line_spacing() * content()->y_scale() * j.font_size.proportional (72 * 11);
+
+ v_align = dcp::VALIGN_TOP;
+ } else {
+ DCPOMATIC_ASSERT (i.vertical_position.proportional);
+ DCPOMATIC_ASSERT (i.vertical_position.reference);
+ v_position = i.vertical_position.proportional.get();
+
+ if (lowest_proportional) {
+ /* Adjust line spacing */
+ v_position = ((v_position - lowest_proportional.get()) * content()->line_spacing()) + lowest_proportional.get();
+ }
+
+ switch (i.vertical_position.reference.get()) {
+ case sub::TOP_OF_SCREEN:
+ v_align = dcp::VALIGN_TOP;
+ break;
+ case sub::VERTICAL_CENTRE_OF_SCREEN:
+ v_align = dcp::VALIGN_CENTER;
+ break;
+ case sub::BOTTOM_OF_SCREEN:
+ v_align = dcp::VALIGN_BOTTOM;
+ break;
+ default:
+ v_align = dcp::VALIGN_TOP;
+ break;
+ }
+ }
+
+ dcp::HAlign h_align;
+ switch (i.horizontal_position.reference) {
+ case sub::LEFT_OF_SCREEN:
+ h_align = dcp::HALIGN_LEFT;
+ break;
+ case sub::HORIZONTAL_CENTRE_OF_SCREEN:
+ h_align = dcp::HALIGN_CENTER;
+ break;
+ case sub::RIGHT_OF_SCREEN:
+ h_align = dcp::HALIGN_RIGHT;
+ break;
+ default:
+ h_align = dcp::HALIGN_CENTER;
+ break;
+ }
+
+ /* The idea here (rightly or wrongly) is that we set the appearance based on the
+ values in the libsub objects, and these are overridden with values from the
+ content by the other emit_text_start() above.
+ */
+
+ out.push_back (
+ dcp::SubtitleString (
+ string(TEXT_FONT_ID),
+ j.italic,
+ j.bold,
+ j.underline,
+ j.colour.dcp(),
+ j.font_size.points (72 * 11),
+ 1.0,
+ dcp::Time (from.seconds(), 1000),
+ /* XXX: hmm; this is a bit ugly (we don't know the to time yet) */
+ dcp::Time (),
+ i.horizontal_position.proportional,
+ h_align,
+ v_position,
+ v_align,
+ dcp::DIRECTION_LTR,
+ j.text,
+ dcp::NONE,
+ j.effect_colour.get_value_or(sub::Colour(0, 0, 0)).dcp(),
+ /* Hack: we should use subtitle.fade_up and subtitle.fade_down here
+ but the times of these often don't have a frame rate associated
+ with them so the sub::Time won't convert them to milliseconds without
+ throwing an exception. Since only DCP subs fill those in (and we don't
+ use libsub for DCP subs) we can cheat by just putting 0 in here.
+ */
+ dcp::Time (),
+ dcp::Time ()
+ )
+ );
+ }
+ }
+
+ emit_text_start (from, out);
+}
+
+void
+TextDecoder::emit_stop (ContentTime to)
+{
+ Stop (to);
+}
+
+void
+TextDecoder::emit_text (ContentTimePeriod period, list<dcp::SubtitleString> s)
+{
+ emit_text_start (period.from, s);
+ emit_stop (period.to);
+}
+
+void
+TextDecoder::emit_text (ContentTimePeriod period, sub::Subtitle const & s)
+{
+ emit_text_start (period.from, s);
+ emit_stop (period.to);
+}
+
+void
+TextDecoder::seek ()
+{
+ _position = ContentTime ();
+}
--- /dev/null
+/*
+ Copyright (C) 2013-2017 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DCPOMATIC_SUBTITLE_DECODER_H
+#define DCPOMATIC_SUBTITLE_DECODER_H
+
+#include "decoder.h"
+#include "rect.h"
+#include "types.h"
+#include "content_subtitle.h"
+#include "decoder_part.h"
+#include <dcp/subtitle_string.h>
+#include <boost/signals2.hpp>
+
+namespace sub {
+ class Subtitle;
+}
+
+class Image;
+
+class TextDecoder : public DecoderPart
+{
+public:
+ TextDecoder (
+ Decoder* parent,
+ boost::shared_ptr<const TextContent>,
+ boost::shared_ptr<Log> log,
+ ContentTime first
+ );
+
+ ContentTime position () const {
+ return _position;
+ }
+
+ void emit_image_start (ContentTime from, boost::shared_ptr<Image> image, dcpomatic::Rect<double> rect);
+ void emit_text_start (ContentTime from, std::list<dcp::SubtitleString> s);
+ void emit_text_start (ContentTime from, sub::Subtitle const & subtitle);
+ void emit_text (ContentTimePeriod period, std::list<dcp::SubtitleString> s);
+ void emit_text (ContentTimePeriod period, sub::Subtitle const & subtitle);
+ void emit_stop (ContentTime to);
+
+ void seek ();
+
+ boost::shared_ptr<const TextContent> content () const {
+ return _content;
+ }
+
+ boost::signals2::signal<void (ContentImageSubtitle)> ImageStart;
+ boost::signals2::signal<void (ContentTextSubtitle)> TextStart;
+ boost::signals2::signal<void (ContentTime)> Stop;
+
+private:
+ boost::shared_ptr<const TextContent> _content;
+ ContentTime _position;
+};
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "text_file.h"
+#include "cross.h"
+#include "exceptions.h"
+#include "text_file_content.h"
+#include <sub/subrip_reader.h>
+#include <sub/ssa_reader.h>
+#include <sub/collect.h>
+#include <unicode/ucsdet.h>
+#include <unicode/ucnv.h>
+#include <iostream>
+
+#include "i18n.h"
+
+using std::vector;
+using std::cout;
+using std::string;
+using boost::shared_ptr;
+using boost::scoped_array;
+using dcp::Data;
+
+TextFile::TextFile (shared_ptr<const TextFileContent> content)
+{
+ Data in (content->path (0));
+
+ UErrorCode status = U_ZERO_ERROR;
+ UCharsetDetector* detector = ucsdet_open (&status);
+ ucsdet_setText (detector, reinterpret_cast<const char *> (in.data().get()), in.size(), &status);
+
+ UCharsetMatch const * match = ucsdet_detect (detector, &status);
+ char const * in_charset = ucsdet_getName (match, &status);
+
+ UConverter* to_utf16 = ucnv_open (in_charset, &status);
+ /* This is a guess; I think we should be able to encode any input in 4 times its input size */
+ scoped_array<uint16_t> utf16 (new uint16_t[in.size() * 2]);
+ int const utf16_len = ucnv_toUChars (
+ to_utf16, reinterpret_cast<UChar*>(utf16.get()), in.size() * 2,
+ reinterpret_cast<const char *> (in.data().get()), in.size(),
+ &status
+ );
+
+ UConverter* to_utf8 = ucnv_open ("UTF-8", &status);
+ /* Another guess */
+ scoped_array<char> utf8 (new char[utf16_len * 2]);
+ ucnv_fromUChars (to_utf8, utf8.get(), utf16_len * 2, reinterpret_cast<UChar*>(utf16.get()), utf16_len, &status);
+
+ ucsdet_close (detector);
+ ucnv_close (to_utf16);
+ ucnv_close (to_utf8);
+
+ sub::Reader* reader = 0;
+
+ string ext = content->path(0).extension().string();
+ transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
+
+ if (ext == ".srt") {
+ reader = new sub::SubripReader (utf8.get());
+ } else if (ext == ".ssa" || ext == ".ass") {
+ reader = new sub::SSAReader (utf8.get());
+ }
+
+ if (reader) {
+ _subtitles = sub::collect<vector<sub::Subtitle> > (reader->subtitles ());
+ }
+
+ delete reader;
+}
+
+ContentTime
+TextFile::length () const
+{
+ if (_subtitles.empty ()) {
+ return ContentTime ();
+ }
+
+ return ContentTime::from_seconds (_subtitles.back().to.all_as_seconds ());
+}
--- /dev/null
+/*
+ Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DCPOMATIC_TEXT_SUBTITLE_H
+#define DCPOMATIC_TEXT_SUBTITLE_H
+
+#include "dcpomatic_time.h"
+#include <sub/subtitle.h>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+class TextFileContent;
+class text_file_time_test;
+class text_file_coordinate_test;
+class text_text_content_test;
+class text_file_parse_test;
+
+class TextFile
+{
+public:
+ explicit TextFile (boost::shared_ptr<const TextFileContent>);
+
+ ContentTime length () const;
+
+protected:
+ std::vector<sub::Subtitle> _subtitles;
+};
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "text_file_decoder.h"
+#include "text_file_content.h"
+#include "text_content.h"
+#include <dcp/subtitle_string.h>
+#include <boost/foreach.hpp>
+#include <iostream>
+
+using std::list;
+using std::vector;
+using std::string;
+using std::cout;
+using std::max;
+using boost::shared_ptr;
+using boost::optional;
+using boost::dynamic_pointer_cast;
+
+TextTextDecoder::TextTextDecoder (shared_ptr<const TextFileContent> content, shared_ptr<Log> log)
+ : TextFile (content)
+ , _next (0)
+{
+ subtitle.reset (new TextDecoder (this, content->subtitle, log));
+}
+
+void
+TextTextDecoder::seek (ContentTime time, bool accurate)
+{
+ /* It's worth back-tracking a little here as decoding is cheap and it's nice if we don't miss
+ too many subtitles when seeking.
+ */
+ time -= ContentTime::from_seconds (5);
+ if (time < ContentTime()) {
+ time = ContentTime();
+ }
+
+ Decoder::seek (time, accurate);
+
+ _next = 0;
+ while (_next < _subtitles.size() && ContentTime::from_seconds (_subtitles[_next].from.all_as_seconds ()) < time) {
+ ++_next;
+ }
+}
+
+bool
+TextTextDecoder::pass ()
+{
+ if (_next >= _subtitles.size ()) {
+ return true;
+ }
+
+ ContentTimePeriod const p = content_time_period (_subtitles[_next]);
+ subtitle->emit_text (p, _subtitles[_next]);
+
+ ++_next;
+ return false;
+}
+
+ContentTimePeriod
+TextTextDecoder::content_time_period (sub::Subtitle s) const
+{
+ return ContentTimePeriod (
+ ContentTime::from_seconds (s.from.all_as_seconds()),
+ ContentTime::from_seconds (s.to.all_as_seconds())
+ );
+}
--- /dev/null
+/*
+ Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DCPOMATIC_TEXT_SUBTITLE_DECODER_H
+#define DCPOMATIC_TEXT_SUBTITLE_DECODER_H
+
+#include "text_decoder.h"
+#include "text_file.h"
+
+class TextFileContent;
+
+class TextTextDecoder : public Decoder, public TextFile
+{
+public:
+ TextTextDecoder (boost::shared_ptr<const TextFileContent>, boost::shared_ptr<Log> log);
+
+ void seek (ContentTime time, bool accurate);
+ bool pass ();
+
+private:
+ ContentTimePeriod content_time_period (sub::Subtitle s) const;
+
+ size_t _next;
+};
+
+#endif
#include "text_subtitle.h"
#include "cross.h"
#include "exceptions.h"
-#include "text_subtitle_content.h"
+#include "text_text_content.h"
#include <sub/subrip_reader.h>
#include <sub/ssa_reader.h>
#include <sub/collect.h>
using boost::optional;
using dcp::Data;
-TextSubtitle::TextSubtitle (shared_ptr<const TextSubtitleContent> content)
+TextSubtitle::TextSubtitle (shared_ptr<const TextTextContent> content)
{
Data in (content->path (0));
#include <boost/shared_ptr.hpp>
#include <vector>
-class TextSubtitleContent;
+class TextTextContent;
class text_subtitle_time_test;
class text_subtitle_coordinate_test;
-class text_subtitle_content_test;
+class text_text_content_test;
class text_subtitle_parse_test;
class TextSubtitle
{
public:
- explicit TextSubtitle (boost::shared_ptr<const TextSubtitleContent>);
+ explicit TextSubtitle (boost::shared_ptr<const TextTextContent>);
boost::optional<ContentTime> first () const;
ContentTime length () const;
+++ /dev/null
-/*
- Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "text_subtitle_content.h"
-#include "util.h"
-#include "text_subtitle.h"
-#include "film.h"
-#include "font.h"
-#include "subtitle_content.h"
-#include <dcp/raw_convert.h>
-#include <libxml++/libxml++.h>
-#include <iostream>
-
-#include "i18n.h"
-
-using std::string;
-using std::cout;
-using boost::shared_ptr;
-using dcp::raw_convert;
-
-TextSubtitleContent::TextSubtitleContent (shared_ptr<const Film> film, boost::filesystem::path path)
- : Content (film, path)
-{
- subtitle.reset (new SubtitleContent (this));
-}
-
-TextSubtitleContent::TextSubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
- : Content (film, node)
- , _length (node->number_child<ContentTime::Type> ("Length"))
-{
- subtitle = SubtitleContent::from_xml (this, node, version);
-}
-
-void
-TextSubtitleContent::examine (boost::shared_ptr<Job> job)
-{
- Content::examine (job);
- TextSubtitle s (shared_from_this ());
-
- /* Default to turning these subtitles on */
- subtitle->set_use (true);
-
- boost::mutex::scoped_lock lm (_mutex);
- _length = s.length ();
- subtitle->add_font (shared_ptr<Font> (new Font (TEXT_FONT_ID)));
-}
-
-string
-TextSubtitleContent::summary () const
-{
- return path_summary() + " " + _("[subtitles]");
-}
-
-string
-TextSubtitleContent::technical_summary () const
-{
- return Content::technical_summary() + " - " + _("Text subtitles");
-}
-
-void
-TextSubtitleContent::as_xml (xmlpp::Node* node, bool with_paths) const
-{
- node->add_child("Type")->add_child_text ("TextSubtitle");
- Content::as_xml (node, with_paths);
-
- if (subtitle) {
- subtitle->as_xml (node);
- }
-
- node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
-}
-
-DCPTime
-TextSubtitleContent::full_length () const
-{
- FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate ());
- return DCPTime (_length, frc);
-}
+++ /dev/null
-/*
- Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "content.h"
-
-class Job;
-
-/** @class TextSubtitleContent
- * @brief SubRip or SSA subtitles.
- */
-class TextSubtitleContent : public Content
-{
-public:
- TextSubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path);
- TextSubtitleContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
-
- boost::shared_ptr<TextSubtitleContent> shared_from_this () {
- return boost::dynamic_pointer_cast<TextSubtitleContent> (Content::shared_from_this ());
- }
-
- void examine (boost::shared_ptr<Job>);
- std::string summary () const;
- std::string technical_summary () const;
- void as_xml (xmlpp::Node *, bool with_paths) const;
- DCPTime full_length () const;
-
-private:
- ContentTime _length;
-};
+++ /dev/null
-/*
- Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "text_subtitle_decoder.h"
-#include "text_subtitle_content.h"
-#include "subtitle_content.h"
-#include <dcp/subtitle_string.h>
-#include <boost/foreach.hpp>
-#include <iostream>
-
-using std::list;
-using std::vector;
-using std::string;
-using std::cout;
-using std::max;
-using boost::shared_ptr;
-using boost::optional;
-using boost::dynamic_pointer_cast;
-
-TextSubtitleDecoder::TextSubtitleDecoder (shared_ptr<const TextSubtitleContent> content, shared_ptr<Log> log)
- : TextSubtitle (content)
- , _next (0)
-{
- ContentTime first;
- if (!_subtitles.empty()) {
- first = content_time_period(_subtitles[0]).from;
- }
- subtitle.reset (new SubtitleDecoder (this, content->subtitle, log, first));
-}
-
-void
-TextSubtitleDecoder::seek (ContentTime time, bool accurate)
-{
- /* It's worth back-tracking a little here as decoding is cheap and it's nice if we don't miss
- too many subtitles when seeking.
- */
- time -= ContentTime::from_seconds (5);
- if (time < ContentTime()) {
- time = ContentTime();
- }
-
- Decoder::seek (time, accurate);
-
- _next = 0;
- while (_next < _subtitles.size() && ContentTime::from_seconds (_subtitles[_next].from.all_as_seconds ()) < time) {
- ++_next;
- }
-}
-
-bool
-TextSubtitleDecoder::pass ()
-{
- if (_next >= _subtitles.size ()) {
- return true;
- }
-
- ContentTimePeriod const p = content_time_period (_subtitles[_next]);
- subtitle->emit_text (p, _subtitles[_next]);
-
- ++_next;
- return false;
-}
-
-ContentTimePeriod
-TextSubtitleDecoder::content_time_period (sub::Subtitle s) const
-{
- return ContentTimePeriod (
- ContentTime::from_seconds (s.from.all_as_seconds()),
- ContentTime::from_seconds (s.to.all_as_seconds())
- );
-}
+++ /dev/null
-/*
- Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef DCPOMATIC_TEXT_SUBTITLE_DECODER_H
-#define DCPOMATIC_TEXT_SUBTITLE_DECODER_H
-
-#include "subtitle_decoder.h"
-#include "text_subtitle.h"
-
-class TextSubtitleContent;
-
-class TextSubtitleDecoder : public Decoder, public TextSubtitle
-{
-public:
- TextSubtitleDecoder (boost::shared_ptr<const TextSubtitleContent>, boost::shared_ptr<Log> log);
-
- void seek (ContentTime time, bool accurate);
- bool pass ();
-
-private:
- ContentTimePeriod content_time_period (sub::Subtitle s) const;
-
- size_t _next;
-};
-
-#endif
--- /dev/null
+/*
+ Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "text_text_content.h"
+#include "util.h"
+#include "text_subtitle.h"
+#include "film.h"
+#include "font.h"
+#include "text_content.h"
+#include <dcp/raw_convert.h>
+#include <libxml++/libxml++.h>
+#include <iostream>
+
+#include "i18n.h"
+
+using std::string;
+using std::cout;
+using boost::shared_ptr;
+using dcp::raw_convert;
+
+TextTextContent::TextTextContent (shared_ptr<const Film> film, boost::filesystem::path path)
+ : Content (film, path)
+{
+ subtitle.reset (new TextContent (this));
+}
+
+TextTextContent::TextTextContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
+ : Content (film, node)
+ , _length (node->number_child<ContentTime::Type> ("Length"))
+{
+ subtitle = TextContent::from_xml (this, node, version);
+}
+
+void
+TextTextContent::examine (boost::shared_ptr<Job> job)
+{
+ Content::examine (job);
+ TextSubtitle s (shared_from_this ());
+
+ /* Default to turning these subtitles on */
+ subtitle->set_use (true);
+
+ boost::mutex::scoped_lock lm (_mutex);
+ _length = s.length ();
+ subtitle->add_font (shared_ptr<Font> (new Font (TEXT_FONT_ID)));
+}
+
+string
+TextTextContent::summary () const
+{
+ return path_summary() + " " + _("[subtitles]");
+}
+
+string
+TextTextContent::technical_summary () const
+{
+ return Content::technical_summary() + " - " + _("Text subtitles");
+}
+
+void
+TextTextContent::as_xml (xmlpp::Node* node, bool with_paths) const
+{
+ node->add_child("Type")->add_child_text ("TextSubtitle");
+ Content::as_xml (node, with_paths);
+
+ if (subtitle) {
+ subtitle->as_xml (node);
+ }
+
+ node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
+}
+
+DCPTime
+TextTextContent::full_length () const
+{
+ FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate ());
+ return DCPTime (_length, frc);
+}
--- /dev/null
+/*
+ Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "content.h"
+
+class Job;
+
+/** @class TextTextContent
+ * @brief SubRip or SSA subtitles.
+ */
+class TextTextContent : public Content
+{
+public:
+ TextTextContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+ TextTextContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
+
+ boost::shared_ptr<TextTextContent> shared_from_this () {
+ return boost::dynamic_pointer_cast<TextTextContent> (Content::shared_from_this ());
+ }
+
+ void examine (boost::shared_ptr<Job>);
+ std::string summary () const;
+ std::string technical_summary () const;
+ void as_xml (xmlpp::Node *, bool with_paths) const;
+ DCPTime full_length () const;
+
+private:
+ ContentTime _length;
+};
--- /dev/null
+/*
+ Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "text_text_decoder.h"
+#include "text_text_content.h"
+#include "text_content.h"
+#include <dcp/subtitle_string.h>
+#include <boost/foreach.hpp>
+#include <iostream>
+
+using std::list;
+using std::vector;
+using std::string;
+using std::cout;
+using std::max;
+using boost::shared_ptr;
+using boost::optional;
+using boost::dynamic_pointer_cast;
+
+TextTextDecoder::TextTextDecoder (shared_ptr<const TextTextContent> content, shared_ptr<Log> log)
+ : TextSubtitle (content)
+ , _next (0)
+{
+ ContentTime first;
+ if (!_subtitles.empty()) {
+ first = content_time_period(_subtitles[0]).from;
+ }
+ subtitle.reset (new TextDecoder (this, content->subtitle, log, first));
+}
+
+void
+TextTextDecoder::seek (ContentTime time, bool accurate)
+{
+ /* It's worth back-tracking a little here as decoding is cheap and it's nice if we don't miss
+ too many subtitles when seeking.
+ */
+ time -= ContentTime::from_seconds (5);
+ if (time < ContentTime()) {
+ time = ContentTime();
+ }
+
+ Decoder::seek (time, accurate);
+
+ _next = 0;
+ while (_next < _subtitles.size() && ContentTime::from_seconds (_subtitles[_next].from.all_as_seconds ()) < time) {
+ ++_next;
+ }
+}
+
+bool
+TextTextDecoder::pass ()
+{
+ if (_next >= _subtitles.size ()) {
+ return true;
+ }
+
+ ContentTimePeriod const p = content_time_period (_subtitles[_next]);
+ subtitle->emit_text (p, _subtitles[_next]);
+
+ ++_next;
+ return false;
+}
+
+ContentTimePeriod
+TextTextDecoder::content_time_period (sub::Subtitle s) const
+{
+ return ContentTimePeriod (
+ ContentTime::from_seconds (s.from.all_as_seconds()),
+ ContentTime::from_seconds (s.to.all_as_seconds())
+ );
+}
--- /dev/null
+/*
+ Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DCPOMATIC_TEXT_SUBTITLE_DECODER_H
+#define DCPOMATIC_TEXT_SUBTITLE_DECODER_H
+
+#include "text_decoder.h"
+#include "text_subtitle.h"
+
+class TextTextContent;
+
+class TextTextDecoder : public Decoder, public TextSubtitle
+{
+public:
+ TextTextDecoder (boost::shared_ptr<const TextTextContent>, boost::shared_ptr<Log> log);
+
+ void seek (ContentTime time, bool accurate);
+ bool pass ();
+
+private:
+ ContentTimePeriod content_time_period (sub::Subtitle s) const;
+
+ size_t _next;
+};
+
+#endif
class Content;
class VideoContent;
class AudioContent;
-class SubtitleContent;
+class TextContent;
class FFmpegContent;
namespace cxml {
dcp_encoder.cc
dcp_examiner.cc
dcp_subtitle.cc
- dcp_subtitle_content.cc
- dcp_subtitle_decoder.cc
+ dcp_text_content.cc
+ dcp_text_decoder.cc
dcp_video.cc
dcpomatic_socket.cc
dcpomatic_time.cc
server.cc
shuffler.cc
string_log_entry.cc
- subtitle_content.cc
- subtitle_decoder.cc
+ text_content.cc
+ text_decoder.cc
text_subtitle.cc
- text_subtitle_content.cc
- text_subtitle_decoder.cc
+ text_text_content.cc
+ text_text_decoder.cc
timer.cc
transcode_job.cc
types.cc
#include "lib/transcode_job.h"
#include "lib/dkdm_wrapper.h"
#include "lib/audio_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include <dcp/exceptions.h>
#include <dcp/raw_convert.h>
#include <wx/generic/aboutdlgg.h>
#include "lib/job_manager.h"
#include "lib/job.h"
#include "lib/video_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/ratio.h"
#include "lib/verify_dcp_job.h"
#include "lib/dcp_examiner.h"
#include "image_sequence_dialog.h"
#include "film_viewer.h"
#include "lib/audio_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/video_content.h"
#include "lib/ffmpeg_content.h"
#include "lib/content_factory.h"
#include "lib/config.h"
#include "lib/log.h"
#include "lib/compose.hpp"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
#include "lib/text_subtitle.h"
#include <wx/wx.h>
#include <wx/notebook.h>
BOOST_FOREACH (shared_ptr<Content> i, selected ()) {
DCPTime p;
p = i->position();
- if (dynamic_pointer_cast<TextSubtitleContent>(i) && i->paths_valid()) {
+ if (dynamic_pointer_cast<TextTextContent>(i) && i->paths_valid()) {
/* Rather special case; if we select a text subtitle file jump to its
first subtitle.
*/
- TextSubtitle ts (dynamic_pointer_cast<TextSubtitleContent>(i));
+ TextSubtitle ts (dynamic_pointer_cast<TextTextContent>(i));
if (ts.first()) {
p += DCPTime(ts.first().get(), _film->active_frame_rate_change(i->position()));
}
#include "lib/ffmpeg_content.h"
#include "lib/audio_processor.h"
#include "lib/video_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/dcp_content.h"
#include "lib/audio_content.h"
#include <dcp/locale_convert.h>
DCPPanel::film_content_changed (int property)
{
if (property == AudioContentProperty::STREAMS ||
- property == SubtitleContentProperty::USE ||
- property == SubtitleContentProperty::BURN ||
+ property == TextContentProperty::USE ||
+ property == TextContentProperty::BURN ||
property == VideoContentProperty::SCALE ||
property == DCPContentProperty::REFERENCE_VIDEO ||
property == DCPContentProperty::REFERENCE_AUDIO ||
#include "font_files_dialog.h"
#include "lib/font.h"
#include "lib/content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include <wx/wx.h>
#include <boost/foreach.hpp>
#include <iostream>
#include "subtitle_appearance_dialog.h"
#include "rgba_colour_picker.h"
-#include "lib/text_subtitle_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_text_content.h"
+#include "lib/text_content.h"
#include "lib/ffmpeg_subtitle_stream.h"
#include "lib/ffmpeg_content.h"
#include <wx/wx.h>
#include "fonts_dialog.h"
#include "subtitle_appearance_dialog.h"
#include "lib/ffmpeg_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
#include "lib/ffmpeg_subtitle_stream.h"
-#include "lib/dcp_subtitle_content.h"
-#include "lib/text_subtitle_decoder.h"
-#include "lib/dcp_subtitle_decoder.h"
+#include "lib/dcp_text_content.h"
+#include "lib/text_text_decoder.h"
+#include "lib/dcp_text_decoder.h"
#include "lib/dcp_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/decoder_factory.h"
#include <wx/spinctrl.h>
#include <boost/foreach.hpp>
}
}
setup_sensitivity ();
- } else if (property == SubtitleContentProperty::USE) {
+ } else if (property == TextContentProperty::USE) {
checked_set (_use, scs ? scs->subtitle->use() : false);
setup_sensitivity ();
- } else if (property == SubtitleContentProperty::BURN) {
+ } else if (property == TextContentProperty::BURN) {
checked_set (_burn, scs ? scs->subtitle->burn() : false);
- } else if (property == SubtitleContentProperty::X_OFFSET) {
+ } else if (property == TextContentProperty::X_OFFSET) {
checked_set (_x_offset, scs ? lrint (scs->subtitle->x_offset() * 100) : 0);
- } else if (property == SubtitleContentProperty::Y_OFFSET) {
+ } else if (property == TextContentProperty::Y_OFFSET) {
checked_set (_y_offset, scs ? lrint (scs->subtitle->y_offset() * 100) : 0);
- } else if (property == SubtitleContentProperty::X_SCALE) {
+ } else if (property == TextContentProperty::X_SCALE) {
checked_set (_x_scale, scs ? lrint (scs->subtitle->x_scale() * 100) : 100);
- } else if (property == SubtitleContentProperty::Y_SCALE) {
+ } else if (property == TextContentProperty::Y_SCALE) {
checked_set (_y_scale, scs ? lrint (scs->subtitle->y_scale() * 100) : 100);
- } else if (property == SubtitleContentProperty::LINE_SPACING) {
+ } else if (property == TextContentProperty::LINE_SPACING) {
checked_set (_line_spacing, scs ? lrint (scs->subtitle->line_spacing() * 100) : 100);
- } else if (property == SubtitleContentProperty::LANGUAGE) {
+ } else if (property == TextContentProperty::LANGUAGE) {
checked_set (_language, scs ? scs->subtitle->language() : "");
} else if (property == DCPContentProperty::REFERENCE_SUBTITLE) {
if (scs) {
BOOST_FOREACH (shared_ptr<Content> i, sel) {
/* These are the content types that could include subtitles */
shared_ptr<const FFmpegContent> fc = boost::dynamic_pointer_cast<const FFmpegContent> (i);
- shared_ptr<const TextSubtitleContent> sc = boost::dynamic_pointer_cast<const TextSubtitleContent> (i);
+ shared_ptr<const TextTextContent> sc = boost::dynamic_pointer_cast<const TextTextContent> (i);
shared_ptr<const DCPContent> dc = boost::dynamic_pointer_cast<const DCPContent> (i);
- shared_ptr<const DCPSubtitleContent> dsc = boost::dynamic_pointer_cast<const DCPSubtitleContent> (i);
+ shared_ptr<const DCPTextContent> dsc = boost::dynamic_pointer_cast<const DCPTextContent> (i);
if (fc) {
if (fc->subtitle) {
++ffmpeg_subs;
SubtitlePanel::content_selection_changed ()
{
film_content_changed (FFmpegContentProperty::SUBTITLE_STREAMS);
- film_content_changed (SubtitleContentProperty::USE);
- film_content_changed (SubtitleContentProperty::BURN);
- film_content_changed (SubtitleContentProperty::X_OFFSET);
- film_content_changed (SubtitleContentProperty::Y_OFFSET);
- film_content_changed (SubtitleContentProperty::X_SCALE);
- film_content_changed (SubtitleContentProperty::Y_SCALE);
- film_content_changed (SubtitleContentProperty::LINE_SPACING);
- film_content_changed (SubtitleContentProperty::LANGUAGE);
- film_content_changed (SubtitleContentProperty::FONTS);
+ film_content_changed (TextContentProperty::USE);
+ film_content_changed (TextContentProperty::BURN);
+ film_content_changed (TextContentProperty::X_OFFSET);
+ film_content_changed (TextContentProperty::Y_OFFSET);
+ film_content_changed (TextContentProperty::X_SCALE);
+ film_content_changed (TextContentProperty::Y_SCALE);
+ film_content_changed (TextContentProperty::LINE_SPACING);
+ film_content_changed (TextContentProperty::LANGUAGE);
+ film_content_changed (TextContentProperty::FONTS);
film_content_changed (DCPContentProperty::REFERENCE_SUBTITLE);
}
*/
-#include "lib/text_subtitle_decoder.h"
+#include "lib/text_text_decoder.h"
#include "lib/content_subtitle.h"
#include "lib/video_decoder.h"
#include "lib/audio_decoder.h"
#include "lib/film.h"
-#include "lib/text_subtitle_content.h"
#include "lib/config.h"
+#include "lib/text_text_content.h"
#include "subtitle_view.h"
#include "film_viewer.h"
#include "wx_util.h"
#include "timeline_labels_view.h"
#include "timeline_video_content_view.h"
#include "timeline_audio_content_view.h"
-#include "timeline_subtitle_content_view.h"
+#include "timeline_text_content_view.h"
#include "timeline_atmos_content_view.h"
#include "content_panel.h"
#include "wx_util.h"
#include "lib/image_content.h"
#include "lib/timer.h"
#include "lib/audio_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/video_content.h"
#include "lib/atmos_mxf_content.h"
#include <wx/graphics.h>
}
if (i->subtitle) {
- _views.push_back (shared_ptr<TimelineView> (new TimelineSubtitleContentView (*this, i)));
+ _views.push_back (shared_ptr<TimelineView> (new TimelineTextContentView (*this, i)));
}
if (dynamic_pointer_cast<AtmosMXFContent> (i)) {
/* Subtitle */
- int const subtitle_tracks = place<TimelineSubtitleContentView> (_views, _tracks);
+ int const subtitle_tracks = place<TimelineTextContentView> (_views, _tracks);
/* Atmos */
+++ /dev/null
-/*
- Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "timeline_subtitle_content_view.h"
-#include "lib/subtitle_content.h"
-#include "lib/content.h"
-
-using boost::shared_ptr;
-
-TimelineSubtitleContentView::TimelineSubtitleContentView (Timeline& tl, shared_ptr<Content> c)
- : TimelineContentView (tl, c)
-{
-
-}
-
-wxColour
-TimelineSubtitleContentView::background_colour () const
-{
- if (!active ()) {
- return wxColour (210, 210, 210, 128);
- }
-
- return wxColour (163, 255, 154, 255);
-}
-
-wxColour
-TimelineSubtitleContentView::foreground_colour () const
-{
- if (!active ()) {
- return wxColour (180, 180, 180, 128);
- }
-
- return wxColour (0, 0, 0, 255);
-}
-
-bool
-TimelineSubtitleContentView::active () const
-{
- shared_ptr<Content> c = _content.lock ();
- DCPOMATIC_ASSERT (c);
- return c->subtitle && c->subtitle->use();
-}
+++ /dev/null
-/*
- Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "timeline_content_view.h"
-
-class SubtitleContent;
-
-/** @class TimelineSubtitleContentView
- * @brief Timeline view for SubtitleContent.
- */
-class TimelineSubtitleContentView : public TimelineContentView
-{
-public:
- TimelineSubtitleContentView (Timeline& tl, boost::shared_ptr<Content> c);
-
-private:
- bool active () const;
- wxColour background_colour () const;
- wxColour foreground_colour () const;
-};
--- /dev/null
+/*
+ Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "timeline_text_content_view.h"
+#include "lib/text_content.h"
+#include "lib/content.h"
+
+using boost::shared_ptr;
+
+TimelineTextContentView::TimelineTextContentView (Timeline& tl, shared_ptr<Content> c)
+ : TimelineContentView (tl, c)
+{
+
+}
+
+wxColour
+TimelineTextContentView::background_colour () const
+{
+ if (!active ()) {
+ return wxColour (210, 210, 210, 128);
+ }
+
+ return wxColour (163, 255, 154, 255);
+}
+
+wxColour
+TimelineTextContentView::foreground_colour () const
+{
+ if (!active ()) {
+ return wxColour (180, 180, 180, 128);
+ }
+
+ return wxColour (0, 0, 0, 255);
+}
+
+bool
+TimelineTextContentView::active () const
+{
+ shared_ptr<Content> c = _content.lock ();
+ DCPOMATIC_ASSERT (c);
+ return c->subtitle && c->subtitle->use();
+}
--- /dev/null
+/*
+ Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "timeline_content_view.h"
+
+class TextContent;
+
+/** @class TimelineTextContentView
+ * @brief Timeline view for TextContent.
+ */
+class TimelineTextContentView : public TimelineContentView
+{
+public:
+ TimelineTextContentView (Timeline& tl, boost::shared_ptr<Content> c);
+
+private:
+ bool active () const;
+ wxColour background_colour () const;
+ wxColour foreground_colour () const;
+};
#include "move_to_dialog.h"
#include "lib/content.h"
#include "lib/image_content.h"
-#include "lib/subtitle_content.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/text_content.h"
+#include "lib/dcp_text_content.h"
#include "lib/audio_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
#include "lib/video_content.h"
#include <dcp/locale_convert.h>
#include <boost/foreach.hpp>
timeline_dialog.cc
timeline_audio_content_view.cc
timeline_labels_view.cc
- timeline_subtitle_content_view.cc
+ timeline_text_content_view.cc
timeline_reels_view.cc
timeline_time_axis_view.cc
timeline_video_content_view.cc
* @ingroup specific
*/
-#include "lib/text_subtitle_content.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/text_text_content.h"
+#include "lib/dcp_text_content.h"
#include "lib/film.h"
#include "lib/ratio.h"
#include "lib/dcp_content_type.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/dcp_content.h"
#include "lib/content_factory.h"
#include "lib/config.h"
film->set_container (Ratio::from_id ("185"));
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
content->subtitle->set_use (true);
content->subtitle->set_burn (true);
film->examine_and_add_content (content);
film->set_container (Ratio::from_id ("185"));
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
- shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml"));
+ shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub.xml"));
content->subtitle->set_use (true);
film->examine_and_add_content (content);
wait_for_jobs ();
film2->set_name ("frobozz");
shared_ptr<DCPContent> background_dcp (new DCPContent(film2, film->dir(film->dcp_name())));
film2->examine_and_add_content (background_dcp);
- shared_ptr<TextSubtitleContent> sub = dynamic_pointer_cast<TextSubtitleContent> (
+ shared_ptr<TextTextContent> sub = dynamic_pointer_cast<TextTextContent> (
content_factory(film2, "test/data/subrip2.srt").front()
);
sub->subtitle->set_burn (true);
#include <boost/test/unit_test.hpp>
#include "lib/film.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/dcp_text_content.h"
#include "lib/dcp_content.h"
#include "lib/ratio.h"
#include "lib/dcp_decoder.h"
#include "lib/dcp_content_type.h"
-#include "lib/dcp_subtitle_decoder.h"
-#include "lib/subtitle_content.h"
+#include "lib/dcp_text_decoder.h"
+#include "lib/text_content.h"
#include "lib/content_subtitle.h"
-#include "lib/subtitle_decoder.h"
#include "lib/font.h"
+#include "lib/text_decoder.h"
#include "test.h"
#include <iostream>
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
film->set_interop (false);
- shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml"));
+ shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub.xml"));
film->examine_and_add_content (content);
BOOST_REQUIRE (!wait_for_jobs ());
film->set_container (Ratio::from_id ("185"));
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
- shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub2.xml"));
+ shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub2.xml"));
film->examine_and_add_content (content);
BOOST_REQUIRE (!wait_for_jobs ());
- shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder (content, film->log()));
+ shared_ptr<DCPTextDecoder> decoder (new DCPTextDecoder (content, film->log()));
decoder->subtitle->TextStart.connect (bind (store, _1));
stored = optional<ContentTextSubtitle> ();
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
film->set_interop (true);
- shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub3.xml"));
+ shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub3.xml"));
film->examine_and_add_content (content);
BOOST_REQUIRE (!wait_for_jobs ());
film->make_dcp ();
BOOST_REQUIRE (!wait_for_jobs ());
- shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder (content, film->log()));
+ shared_ptr<DCPTextDecoder> decoder (new DCPTextDecoder (content, film->log()));
stored = optional<ContentTextSubtitle> ();
while (!decoder->pass ()) {
decoder->subtitle->TextStart.connect (bind (store, _1));
#include "lib/image_content.h"
#include "lib/video_content.h"
#include "lib/audio_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
#include "lib/ratio.h"
#include "lib/transcode_job.h"
#include "lib/dcp_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/compose.hpp"
#include "test.h"
#include <boost/test/unit_test.hpp>
film->set_container (Ratio::from_id ("185"));
film->set_audio_channels (6);
- shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip2.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
s->subtitle->set_colour (dcp::Colour (255, 255, 0));
film->examine_and_add_content (c);
BOOST_REQUIRE (!wait_for_jobs ());
- shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip.srt"));
+ shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
s->subtitle->set_colour (dcp::Colour (255, 255, 0));
film->set_container (Ratio::from_id ("185"));
film->set_audio_channels (6);
- shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip2.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
s->subtitle->set_colour (dcp::Colour (255, 255, 0));
film->examine_and_add_content (c);
BOOST_REQUIRE (!wait_for_jobs ());
- shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip.srt"));
+ shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
s->subtitle->set_colour (dcp::Colour (255, 255, 0));
#include "test.h"
#include "lib/film.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/dcp_text_content.h"
#include "lib/ratio.h"
#include "lib/dcp_content_type.h"
#include "lib/dcp_content.h"
#include "lib/player.h"
#include "lib/video_content.h"
#include "lib/image_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
#include "lib/content_factory.h"
#include "lib/dcp_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/butler.h"
#include "lib/compose.hpp"
#include "test.h"
film->examine_and_add_content (c);
BOOST_REQUIRE (!wait_for_jobs ());
- shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip.srt"));
+ shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
#include "lib/dcp_content_type.h"
#include "lib/dcp_content.h"
#include "lib/video_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
#include "lib/content_factory.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
shared_ptr<Content> dcp (new DCPContent (film, "test/data/reels_test2"));
film->examine_and_add_content (dcp);
- shared_ptr<Content> sub (new TextSubtitleContent (film, "test/data/subrip.srt"));
+ shared_ptr<Content> sub (new TextTextContent (film, "test/data/subrip.srt"));
film->examine_and_add_content (sub);
wait_for_jobs ();
content[i]->video->set_length (24);
}
- shared_ptr<TextSubtitleContent> subs (new TextSubtitleContent (film, "test/data/subrip3.srt"));
+ shared_ptr<TextTextContent> subs (new TextTextContent (film, "test/data/subrip3.srt"));
film->examine_and_add_content (subs);
wait_for_jobs ();
#include "lib/ffmpeg_content.h"
#include "lib/content_factory.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/job_manager.h"
#include "lib/film.h"
#include "lib/dcp_content.h"
#include "lib/ffmpeg_content.h"
#include "lib/content_factory.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/film.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
*/
#include "lib/film.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
#include "lib/dcp_content_type.h"
#include "lib/font.h"
#include "lib/ratio.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
film->set_name ("frobozz");
film->set_audio_channels (6);
film->set_interop (false);
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
film->examine_and_add_content (content);
wait_for_jobs ();
film->set_name ("frobozz");
film->set_audio_channels (6);
film->set_interop (false);
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
film->examine_and_add_content (content);
wait_for_jobs ();
film->set_name ("frobozz");
film->set_interop (true);
film->set_audio_channels (6);
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, private_data / "Ankoemmling_short.srt"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, private_data / "Ankoemmling_short.srt"));
film->examine_and_add_content (content);
wait_for_jobs ();
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
film->set_interop (false);
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
content->subtitle->set_use (true);
content->subtitle->set_burn (false);
film->examine_and_add_content (content);
film->set_name ("frobozz");
film->set_interop (true);
film->set_sequence (false);
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
content->subtitle->set_use (true);
content->subtitle->set_burn (false);
film->examine_and_add_content (content);
{
shared_ptr<Film> film = new_test_film2 ("srt_subtitle_test6");
film->set_interop (false);
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/frames.srt"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/frames.srt"));
content->subtitle->set_use (true);
content->subtitle->set_burn (false);
film->examine_and_add_content (content);
BOOST_AUTO_TEST_CASE (srt_subtitle_test4)
{
shared_ptr<Film> film = new_test_film ("subrip_render_test");
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip.srt"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip.srt"));
content->examine (shared_ptr<Job> (), true);
BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471));
*/
#include "lib/film.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
#include "lib/dcp_content_type.h"
#include "lib/font.h"
#include "lib/ratio.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
film->set_interop (true);
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, private_data / "DKH_UT_EN20160601def.ssa"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, private_data / "DKH_UT_EN20160601def.ssa"));
film->examine_and_add_content (content);
wait_for_jobs ();
*/
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
#include "lib/film.h"
#include "lib/ratio.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
#include "lib/dcp_content_type.h"
#include "test.h"
#include <dcp/cpl.h>
film->set_container (Ratio::from_id ("185"));
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
- shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip5.srt"));
+ shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip5.srt"));
film->examine_and_add_content (content);
BOOST_REQUIRE (!wait_for_jobs ());
content->subtitle->set_use (true);
*/
#include "lib/film.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/dcp_text_content.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE (subtitle_trim_test1)
{
shared_ptr<Film> film = new_test_film2 ("subtitle_trim_test1");
- shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub5.xml"));
+ shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub5.xml"));
film->examine_and_add_content (content);
BOOST_REQUIRE (!wait_for_jobs ());
#include "test.h"
#include "lib/film.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/dcp_text_content.h"
#include "lib/ratio.h"
#include "lib/dcp_content_type.h"
#include "lib/dcp_content.h"