From: Carl Hetherington Date: Mon, 11 Jun 2018 22:50:59 +0000 (+0100) Subject: Rename Subtitle -> Text X-Git-Tag: v2.13.36~30 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=d7ac100c0eb1b5efdcfbec59be870fd869252840 Rename Subtitle -> Text 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 --- diff --git a/src/lib/active_subtitles.cc b/src/lib/active_subtitles.cc index bc34a8942..f1d201798 100644 --- a/src/lib/active_subtitles.cc +++ b/src/lib/active_subtitles.cc @@ -20,7 +20,7 @@ #include "active_subtitles.h" #include "piece.h" -#include "subtitle_content.h" +#include "text_content.h" #include #include diff --git a/src/lib/content.cc b/src/lib/content.cc index 2e4e77f8d..1a8bc9eb2 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -27,7 +27,7 @@ #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" diff --git a/src/lib/content.h b/src/lib/content.h index ea764907a..63d03fd71 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -182,7 +182,7 @@ public: boost::shared_ptr video; boost::shared_ptr audio; - boost::shared_ptr subtitle; + boost::shared_ptr subtitle; void signal_changed (int); diff --git a/src/lib/content_factory.cc b/src/lib/content_factory.cc index 51dc4e1b3..14ca579e9 100644 --- a/src/lib/content_factory.cc +++ b/src/lib/content_factory.cc @@ -26,9 +26,9 @@ #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" @@ -88,11 +88,11 @@ content_factory (shared_ptr film, cxml::NodePtr node, int version, l ); } 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") { @@ -210,16 +210,16 @@ content_factory (shared_ptr film, boost::filesystem::path path) 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)) { diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc index ad1f07718..d4891ad45 100644 --- a/src/lib/dcp_content.cc +++ b/src/lib/dcp_content.cc @@ -28,7 +28,7 @@ #include "overlaps.h" #include "compose.hpp" #include "dcp_decoder.h" -#include "subtitle_content.h" +#include "text_content.h" #include #include #include @@ -81,7 +81,7 @@ DCPContent::DCPContent (shared_ptr film, cxml::ConstNodePtr node, in { 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 ( @@ -179,7 +179,7 @@ DCPContent::examine (shared_ptr job) 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 (); } diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 9893cf7fc..03bd95d90 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -24,7 +24,7 @@ #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 @@ -64,7 +64,7 @@ DCPDecoder::DCPDecoder (shared_ptr c, shared_ptr log, boo } 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 > cpl_list = cpls (); diff --git a/src/lib/dcp_encoder.cc b/src/lib/dcp_encoder.cc index f1e819083..9121e9d53 100644 --- a/src/lib/dcp_encoder.cc +++ b/src/lib/dcp_encoder.cc @@ -35,7 +35,7 @@ #include "writer.h" #include "compose.hpp" #include "referenced_reel_asset.h" -#include "subtitle_content.h" +#include "text_content.h" #include "player_video.h" #include #include diff --git a/src/lib/dcp_subtitle_content.cc b/src/lib/dcp_subtitle_content.cc deleted file mode 100644 index 8fee0b2ed..000000000 --- a/src/lib/dcp_subtitle_content.cc +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (C) 2014-2015 Carl Hetherington - - 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 . - -*/ - -#include "font.h" -#include "dcp_subtitle_content.h" -#include "film.h" -#include "subtitle_content.h" -#include -#include -#include -#include -#include -#include - -#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 film, boost::filesystem::path path) - : Content (film, path) -{ - subtitle.reset (new SubtitleContent (this)); -} - -DCPSubtitleContent::DCPSubtitleContent (shared_ptr film, cxml::ConstNodePtr node, int version) - : Content (film, node) - , _length (node->number_child ("Length")) -{ - subtitle = SubtitleContent::from_xml (this, node, version); -} - -void -DCPSubtitleContent::examine (shared_ptr job) -{ - Content::examine (job); - - shared_ptr sc = load (path (0)); - - shared_ptr iop = dynamic_pointer_cast (sc); - shared_ptr smpte = dynamic_pointer_cast (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 i, sc->load_font_nodes ()) { - subtitle->add_font (shared_ptr (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 (_length.get ())); -} diff --git a/src/lib/dcp_subtitle_content.h b/src/lib/dcp_subtitle_content.h deleted file mode 100644 index 36945adcd..000000000 --- a/src/lib/dcp_subtitle_content.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2014-2016 Carl Hetherington - - 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 . - -*/ - -#include "dcp_subtitle.h" -#include "content.h" - -class DCPSubtitleContent : public DCPSubtitle, public Content -{ -public: - DCPSubtitleContent (boost::shared_ptr, boost::filesystem::path); - DCPSubtitleContent (boost::shared_ptr, cxml::ConstNodePtr, int); - - void examine (boost::shared_ptr); - 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; -}; diff --git a/src/lib/dcp_subtitle_decoder.cc b/src/lib/dcp_subtitle_decoder.cc deleted file mode 100644 index 46256e93e..000000000 --- a/src/lib/dcp_subtitle_decoder.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright (C) 2014-2018 Carl Hetherington - - 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 . - -*/ - -#include "dcp_subtitle_decoder.h" -#include "dcp_subtitle_content.h" -#include -#include - -using std::list; -using std::cout; -using boost::shared_ptr; -using boost::dynamic_pointer_cast; -using boost::bind; - -DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr content, shared_ptr log) -{ - shared_ptr 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 >::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 s; - ContentTimePeriod const p = content_time_period (*_next); - - while (_next != _subtitles.end () && content_time_period (*_next) == p) { - shared_ptr ns = dynamic_pointer_cast(*_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 s) const -{ - return ContentTimePeriod ( - ContentTime::from_seconds (s->in().as_seconds ()), - ContentTime::from_seconds (s->out().as_seconds ()) - ); -} diff --git a/src/lib/dcp_subtitle_decoder.h b/src/lib/dcp_subtitle_decoder.h deleted file mode 100644 index 0756a278f..000000000 --- a/src/lib/dcp_subtitle_decoder.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2014 Carl Hetherington - - 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 . - -*/ - -#include "subtitle_decoder.h" -#include "dcp_subtitle.h" - -class DCPSubtitleContent; - -class DCPSubtitleDecoder : public DCPSubtitle, public Decoder -{ -public: - DCPSubtitleDecoder (boost::shared_ptr, boost::shared_ptr log); - - bool pass (); - void seek (ContentTime time, bool accurate); - -private: - ContentTimePeriod content_time_period (boost::shared_ptr s) const; - - std::list > _subtitles; - std::list >::const_iterator _next; -}; diff --git a/src/lib/dcp_text_content.cc b/src/lib/dcp_text_content.cc new file mode 100644 index 000000000..9e7524be3 --- /dev/null +++ b/src/lib/dcp_text_content.cc @@ -0,0 +1,114 @@ +/* + Copyright (C) 2014-2015 Carl Hetherington + + 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 . + +*/ + +#include "font.h" +#include "dcp_text_content.h" +#include "film.h" +#include "text_content.h" +#include +#include +#include +#include +#include +#include + +#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 film, boost::filesystem::path path) + : Content (film, path) +{ + subtitle.reset (new TextContent (this)); +} + +DCPTextContent::DCPTextContent (shared_ptr film, cxml::ConstNodePtr node, int version) + : Content (film, node) + , _length (node->number_child ("Length")) +{ + subtitle = TextContent::from_xml (this, node, version); +} + +void +DCPTextContent::examine (shared_ptr job) +{ + Content::examine (job); + + shared_ptr sc = load (path (0)); + + shared_ptr iop = dynamic_pointer_cast (sc); + shared_ptr smpte = dynamic_pointer_cast (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 i, sc->load_font_nodes ()) { + subtitle->add_font (shared_ptr (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 (_length.get ())); +} diff --git a/src/lib/dcp_text_content.h b/src/lib/dcp_text_content.h new file mode 100644 index 000000000..894cc0384 --- /dev/null +++ b/src/lib/dcp_text_content.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2014-2016 Carl Hetherington + + 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 . + +*/ + +#include "dcp_subtitle.h" +#include "content.h" + +class DCPTextContent : public DCPSubtitle, public Content +{ +public: + DCPTextContent (boost::shared_ptr, boost::filesystem::path); + DCPTextContent (boost::shared_ptr, cxml::ConstNodePtr, int); + + void examine (boost::shared_ptr); + 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; +}; diff --git a/src/lib/dcp_text_decoder.cc b/src/lib/dcp_text_decoder.cc new file mode 100644 index 000000000..741bbb8bc --- /dev/null +++ b/src/lib/dcp_text_decoder.cc @@ -0,0 +1,95 @@ +/* + Copyright (C) 2014-2018 Carl Hetherington + + 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 . + +*/ + +#include "dcp_text_decoder.h" +#include "dcp_text_content.h" +#include +#include + +using std::list; +using std::cout; +using boost::shared_ptr; +using boost::dynamic_pointer_cast; +using boost::bind; + +DCPTextDecoder::DCPTextDecoder (shared_ptr content, shared_ptr log) +{ + shared_ptr 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 >::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 s; + ContentTimePeriod const p = content_time_period (*_next); + + while (_next != _subtitles.end () && content_time_period (*_next) == p) { + shared_ptr ns = dynamic_pointer_cast(*_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 s) const +{ + return ContentTimePeriod ( + ContentTime::from_seconds (s->in().as_seconds ()), + ContentTime::from_seconds (s->out().as_seconds ()) + ); +} diff --git a/src/lib/dcp_text_decoder.h b/src/lib/dcp_text_decoder.h new file mode 100644 index 000000000..f1b51b823 --- /dev/null +++ b/src/lib/dcp_text_decoder.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2014 Carl Hetherington + + 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 . + +*/ + +#include "text_decoder.h" +#include "dcp_subtitle.h" + +class DCPTextContent; + +class DCPTextDecoder : public DCPSubtitle, public Decoder +{ +public: + DCPTextDecoder (boost::shared_ptr, boost::shared_ptr log); + + bool pass (); + void seek (ContentTime time, bool accurate); + +private: + ContentTimePeriod content_time_period (boost::shared_ptr s) const; + + std::list > _subtitles; + std::list >::const_iterator _next; +}; diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index 502273de1..e7e6b8620 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -21,7 +21,7 @@ #include "decoder.h" #include "video_decoder.h" #include "audio_decoder.h" -#include "subtitle_decoder.h" +#include "text_decoder.h" #include #include diff --git a/src/lib/decoder.h b/src/lib/decoder.h index d87ff610a..27f0b1141 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -32,7 +32,7 @@ class Decoded; class VideoDecoder; class AudioDecoder; -class SubtitleDecoder; +class TextDecoder; class DecoderPart; /** @class Decoder. @@ -45,7 +45,7 @@ public: boost::shared_ptr video; boost::shared_ptr audio; - boost::shared_ptr subtitle; + boost::shared_ptr 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. diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc index b675f9473..1a0af1b2c 100644 --- a/src/lib/decoder_factory.cc +++ b/src/lib/decoder_factory.cc @@ -24,10 +24,10 @@ #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 @@ -54,14 +54,14 @@ decoder_factory (shared_ptr content, shared_ptr log, bool fa return shared_ptr (new ImageDecoder (ic, log)); } - shared_ptr rc = dynamic_pointer_cast (content); + shared_ptr rc = dynamic_pointer_cast (content); if (rc) { - return shared_ptr (new TextSubtitleDecoder (rc, log)); + return shared_ptr (new TextTextDecoder (rc, log)); } - shared_ptr dsc = dynamic_pointer_cast (content); + shared_ptr dsc = dynamic_pointer_cast (content); if (dsc) { - return shared_ptr (new DCPSubtitleDecoder (dsc, log)); + return shared_ptr (new DCPTextDecoder (dsc, log)); } shared_ptr vmc = dynamic_pointer_cast (content); diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index cbeebd817..e18977944 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -32,7 +32,7 @@ #include "log.h" #include "exceptions.h" #include "frame_rate_change.h" -#include "subtitle_content.h" +#include "text_content.h" #include #include extern "C" { @@ -85,7 +85,7 @@ FFmpegContent::FFmpegContent (shared_ptr film, cxml::ConstNodePtr no { 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 c = node->node_children ("SubtitleStream"); for (list::const_iterator i = c.begin(); i != c.end(); ++i) { @@ -163,7 +163,7 @@ FFmpegContent::FFmpegContent (shared_ptr film, vector ref = dynamic_pointer_cast (c[0]); @@ -303,7 +303,7 @@ FFmpegContent::examine (shared_ptr job) _subtitle_streams = examiner->subtitle_streams (); if (!_subtitle_streams.empty ()) { - subtitle.reset (new SubtitleContent (this)); + subtitle.reset (new TextContent (this)); _subtitle_stream = _subtitle_streams.front (); } diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 0746458e5..4d10f8ef7 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -28,7 +28,7 @@ #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" @@ -39,7 +39,7 @@ #include "film.h" #include "audio_decoder.h" #include "compose.hpp" -#include "subtitle_content.h" +#include "text_content.h" #include "audio_content.h" #include #include @@ -99,7 +99,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr c, shared_ptr 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); diff --git a/src/lib/film.cc b/src/lib/film.cc index 98ae2e59b..0be1ddd7b 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -46,7 +46,7 @@ #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" diff --git a/src/lib/hints.cc b/src/lib/hints.cc index 91aabdd56..d29002ad5 100644 --- a/src/lib/hints.cc +++ b/src/lib/hints.cc @@ -23,7 +23,7 @@ #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" diff --git a/src/lib/image_subtitle.h b/src/lib/image_subtitle.h index f82c5b194..e0687e581 100644 --- a/src/lib/image_subtitle.h +++ b/src/lib/image_subtitle.h @@ -39,7 +39,7 @@ public: * 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 rectangle; diff --git a/src/lib/player.cc b/src/lib/player.cc index df58ed223..b701deb5e 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -40,8 +40,8 @@ #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" @@ -210,9 +210,9 @@ Player::playlist_content_changed (weak_ptr w, int property, bool freque 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 ) { @@ -221,17 +221,17 @@ Player::playlist_content_changed (weak_ptr w, int property, bool freque 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 || diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 3376a55ea..13b4d7337 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -20,7 +20,7 @@ #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" diff --git a/src/lib/subtitle_content.cc b/src/lib/subtitle_content.cc deleted file mode 100644 index cd9363839..000000000 --- a/src/lib/subtitle_content.cc +++ /dev/null @@ -1,515 +0,0 @@ -/* - Copyright (C) 2013-2018 Carl Hetherington - - 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 . - -*/ - -#include "subtitle_content.h" -#include "util.h" -#include "exceptions.h" -#include "font.h" -#include "content.h" -#include -#include -#include -#include -#include - -#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::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 (); - } - - /* Otherwise we can drop through to the newer logic */ - } - - if (!node->optional_number_child("SubtitleXOffset") && !node->optional_number_child("SubtitleOffset")) { - return shared_ptr (); - } - - return shared_ptr (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("LineSpacing").get_value_or (1)) - , _outline_width (node->optional_number_child("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 ("SubtitleXOffset"); - _y_offset = node->number_child ("SubtitleYOffset"); - } else { - _y_offset = node->number_child ("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 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 ("SubtitleXScale"); - _y_scale = node->number_child ("SubtitleYScale"); - } else { - _x_scale = _y_scale = node->number_child ("SubtitleScale"); - } - - optional r = node->optional_number_child("Red"); - optional g = node->optional_number_child("Green"); - optional b = node->optional_number_child("Blue"); - if (r && g && b) { - _colour = dcp::Colour (*r, *g, *b); - } - - if (version >= 36) { - optional er = node->optional_number_child("EffectRed"); - optional eg = node->optional_number_child("EffectGreen"); - optional eb = node->optional_number_child("EffectBlue"); - if (er && eg && eb) { - _effect_colour = dcp::Colour (*er, *eg, *eb); - } - } else { - _effect_colour = dcp::Colour ( - node->optional_number_child("OutlineRed").get_value_or(255), - node->optional_number_child("OutlineGreen").get_value_or(255), - node->optional_number_child("OutlineBlue").get_value_or(255) - ); - } - - optional fi = node->optional_number_child("SubtitleFadeIn"); - if (fi) { - _fade_in = ContentTime (*fi); - } - optional fo = node->optional_number_child("SubtitleFadeOut"); - if (fo) { - _fade_out = ContentTime (*fo); - } - - _language = node->optional_string_child ("SubtitleLanguage").get_value_or (""); - - list fonts = node->node_children ("Font"); - for (list::const_iterator i = fonts.begin(); i != fonts.end(); ++i) { - _fonts.push_back (shared_ptr (new Font (*i))); - } - - connect_to_fonts (); -} - -SubtitleContent::SubtitleContent (Content* parent, vector > c) - : ContentPart (parent) -{ - shared_ptr ref = c[0]->subtitle; - DCPOMATIC_ASSERT (ref); - list > 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 > fonts = c[i]->subtitle->fonts (); - if (fonts.size() != ref_fonts.size()) { - throw JoinError (_("Content to be joined must use the same fonts.")); - } - - list >::const_iterator j = ref_fonts.begin (); - list >::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 (_x_offset)); - root->add_child("SubtitleYOffset")->add_child_text (raw_convert (_y_offset)); - root->add_child("SubtitleXScale")->add_child_text (raw_convert (_x_scale)); - root->add_child("SubtitleYScale")->add_child_text (raw_convert (_y_scale)); - root->add_child("SubtitleLanguage")->add_child_text (_language); - if (_colour) { - root->add_child("Red")->add_child_text (raw_convert (_colour->r)); - root->add_child("Green")->add_child_text (raw_convert (_colour->g)); - root->add_child("Blue")->add_child_text (raw_convert (_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 (_effect_colour->r)); - root->add_child("EffectGreen")->add_child_text (raw_convert (_effect_colour->g)); - root->add_child("EffectBlue")->add_child_text (raw_convert (_effect_colour->b)); - } - root->add_child("LineSpacing")->add_child_text (raw_convert (_line_spacing)); - if (_fade_in) { - root->add_child("SubtitleFadeIn")->add_child_text (raw_convert (_fade_in->get())); - } - if (_fade_out) { - root->add_child("SubtitleFadeOut")->add_child_text (raw_convert (_fade_out->get())); - } - root->add_child("OutlineWidth")->add_child_text (raw_convert (_outline_width)); - - for (list >::const_iterator i = _fonts.begin(); i != _fonts.end(); ++i) { - (*i)->as_xml (root->add_child("Font")); - } -} - -string -SubtitleContent::identifier () const -{ - string s = raw_convert (x_scale()) - + "_" + raw_convert (y_scale()) - + "_" + raw_convert (x_offset()) - + "_" + raw_convert (y_offset()) - + "_" + raw_convert (line_spacing()) - + "_" + raw_convert (fade_in().get_value_or(ContentTime()).get()) - + "_" + raw_convert (fade_out().get_value_or(ContentTime()).get()) - + "_" + raw_convert (outline_width()) - + "_" + raw_convert (colour().get_value_or(dcp::Colour(255, 255, 255)).to_argb_string()) - + "_" + raw_convert (dcp::effect_to_string(effect().get_value_or(dcp::NONE))) - + "_" + raw_convert (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 f, _fonts) { - for (int i = 0; i < FontFiles::VARIANTS; ++i) { - s += "_" + f->file(static_cast(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) -{ - _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 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(), SubtitleContentProperty::COLOUR); -} - -void -SubtitleContent::set_effect (dcp::Effect e) -{ - maybe_set (_effect, e, SubtitleContentProperty::EFFECT); -} - -void -SubtitleContent::unset_effect () -{ - maybe_set (_effect, optional(), 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(), 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(), 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(), 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 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); -} diff --git a/src/lib/subtitle_content.h b/src/lib/subtitle_content.h deleted file mode 100644 index b64e4787b..000000000 --- a/src/lib/subtitle_content.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - Copyright (C) 2013-2018 Carl Hetherington - - 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 . - -*/ - -#ifndef DCPOMATIC_SUBTITLE_CONTENT_H -#define DCPOMATIC_SUBTITLE_CONTENT_H - -#include "content_part.h" -#include -#include -#include - -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 >); - - void as_xml (xmlpp::Node *) const; - std::string identifier () const; - void take_settings_from (boost::shared_ptr c); - - void add_font (boost::shared_ptr 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 > fonts () const { - boost::mutex::scoped_lock lm (_mutex); - return _fonts; - } - - std::string language () const { - boost::mutex::scoped_lock lm (_mutex); - return _language; - } - - boost::optional colour () const { - boost::mutex::scoped_lock lm (_mutex); - return _colour; - } - - boost::optional effect () const { - boost::mutex::scoped_lock lm (_mutex); - return _effect; - } - - boost::optional 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 fade_in () const { - boost::mutex::scoped_lock lm (_mutex); - return _fade_in; - } - - boost::optional 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 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 _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 > _fonts; - boost::optional _colour; - boost::optional _effect; - boost::optional _effect_colour; - /** scaling factor for line spacing; 1 is "standard", < 1 is closer together, > 1 is further apart */ - double _line_spacing; - boost::optional _fade_in; - boost::optional _fade_out; - int _outline_width; -}; - -#endif diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc deleted file mode 100644 index 32cae6acc..000000000 --- a/src/lib/subtitle_decoder.cc +++ /dev/null @@ -1,257 +0,0 @@ -/* - Copyright (C) 2013-2017 Carl Hetherington - - 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 . - -*/ - -#include "subtitle_decoder.h" -#include "subtitle_content.h" -#include "util.h" -#include "log.h" -#include "compose.hpp" -#include -#include -#include -#include -#include - -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 c, - shared_ptr 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, dcpomatic::Rect rect) -{ - ImageStart (ContentImageSubtitle (from, image, rect)); - _position = from; -} - -void -SubtitleDecoder::emit_text_start (ContentTime from, list 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 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 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 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 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 (); -} diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h deleted file mode 100644 index c1f171b1f..000000000 --- a/src/lib/subtitle_decoder.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2013-2017 Carl Hetherington - - 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 . - -*/ - -#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 -#include - -namespace sub { - class Subtitle; -} - -class Image; - -class SubtitleDecoder : public DecoderPart -{ -public: - SubtitleDecoder ( - Decoder* parent, - boost::shared_ptr, - boost::shared_ptr log, - ContentTime first - ); - - ContentTime position () const { - return _position; - } - - void emit_image_start (ContentTime from, boost::shared_ptr image, dcpomatic::Rect rect); - void emit_text_start (ContentTime from, std::list s); - void emit_text_start (ContentTime from, sub::Subtitle const & subtitle); - void emit_text (ContentTimePeriod period, std::list s); - void emit_text (ContentTimePeriod period, sub::Subtitle const & subtitle); - void emit_stop (ContentTime to); - - void seek (); - - boost::shared_ptr content () const { - return _content; - } - - boost::signals2::signal ImageStart; - boost::signals2::signal TextStart; - boost::signals2::signal Stop; - -private: - boost::shared_ptr _content; - ContentTime _position; -}; - -#endif diff --git a/src/lib/text_content.cc b/src/lib/text_content.cc new file mode 100644 index 000000000..9eae63519 --- /dev/null +++ b/src/lib/text_content.cc @@ -0,0 +1,515 @@ +/* + Copyright (C) 2013-2018 Carl Hetherington + + 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 . + +*/ + +#include "text_content.h" +#include "util.h" +#include "exceptions.h" +#include "font.h" +#include "content.h" +#include +#include +#include +#include +#include + +#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::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 (); + } + + /* Otherwise we can drop through to the newer logic */ + } + + if (!node->optional_number_child("SubtitleXOffset") && !node->optional_number_child("SubtitleOffset")) { + return shared_ptr (); + } + + return shared_ptr (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("LineSpacing").get_value_or (1)) + , _outline_width (node->optional_number_child("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 ("SubtitleXOffset"); + _y_offset = node->number_child ("SubtitleYOffset"); + } else { + _y_offset = node->number_child ("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 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 ("SubtitleXScale"); + _y_scale = node->number_child ("SubtitleYScale"); + } else { + _x_scale = _y_scale = node->number_child ("SubtitleScale"); + } + + optional r = node->optional_number_child("Red"); + optional g = node->optional_number_child("Green"); + optional b = node->optional_number_child("Blue"); + if (r && g && b) { + _colour = dcp::Colour (*r, *g, *b); + } + + if (version >= 36) { + optional er = node->optional_number_child("EffectRed"); + optional eg = node->optional_number_child("EffectGreen"); + optional eb = node->optional_number_child("EffectBlue"); + if (er && eg && eb) { + _effect_colour = dcp::Colour (*er, *eg, *eb); + } + } else { + _effect_colour = dcp::Colour ( + node->optional_number_child("OutlineRed").get_value_or(255), + node->optional_number_child("OutlineGreen").get_value_or(255), + node->optional_number_child("OutlineBlue").get_value_or(255) + ); + } + + optional fi = node->optional_number_child("SubtitleFadeIn"); + if (fi) { + _fade_in = ContentTime (*fi); + } + optional fo = node->optional_number_child("SubtitleFadeOut"); + if (fo) { + _fade_out = ContentTime (*fo); + } + + _language = node->optional_string_child ("SubtitleLanguage").get_value_or (""); + + list fonts = node->node_children ("Font"); + for (list::const_iterator i = fonts.begin(); i != fonts.end(); ++i) { + _fonts.push_back (shared_ptr (new Font (*i))); + } + + connect_to_fonts (); +} + +TextContent::TextContent (Content* parent, vector > c) + : ContentPart (parent) +{ + shared_ptr ref = c[0]->subtitle; + DCPOMATIC_ASSERT (ref); + list > 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 > fonts = c[i]->subtitle->fonts (); + if (fonts.size() != ref_fonts.size()) { + throw JoinError (_("Content to be joined must use the same fonts.")); + } + + list >::const_iterator j = ref_fonts.begin (); + list >::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 (_x_offset)); + root->add_child("SubtitleYOffset")->add_child_text (raw_convert (_y_offset)); + root->add_child("SubtitleXScale")->add_child_text (raw_convert (_x_scale)); + root->add_child("SubtitleYScale")->add_child_text (raw_convert (_y_scale)); + root->add_child("SubtitleLanguage")->add_child_text (_language); + if (_colour) { + root->add_child("Red")->add_child_text (raw_convert (_colour->r)); + root->add_child("Green")->add_child_text (raw_convert (_colour->g)); + root->add_child("Blue")->add_child_text (raw_convert (_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 (_effect_colour->r)); + root->add_child("EffectGreen")->add_child_text (raw_convert (_effect_colour->g)); + root->add_child("EffectBlue")->add_child_text (raw_convert (_effect_colour->b)); + } + root->add_child("LineSpacing")->add_child_text (raw_convert (_line_spacing)); + if (_fade_in) { + root->add_child("SubtitleFadeIn")->add_child_text (raw_convert (_fade_in->get())); + } + if (_fade_out) { + root->add_child("SubtitleFadeOut")->add_child_text (raw_convert (_fade_out->get())); + } + root->add_child("OutlineWidth")->add_child_text (raw_convert (_outline_width)); + + for (list >::const_iterator i = _fonts.begin(); i != _fonts.end(); ++i) { + (*i)->as_xml (root->add_child("Font")); + } +} + +string +TextContent::identifier () const +{ + string s = raw_convert (x_scale()) + + "_" + raw_convert (y_scale()) + + "_" + raw_convert (x_offset()) + + "_" + raw_convert (y_offset()) + + "_" + raw_convert (line_spacing()) + + "_" + raw_convert (fade_in().get_value_or(ContentTime()).get()) + + "_" + raw_convert (fade_out().get_value_or(ContentTime()).get()) + + "_" + raw_convert (outline_width()) + + "_" + raw_convert (colour().get_value_or(dcp::Colour(255, 255, 255)).to_argb_string()) + + "_" + raw_convert (dcp::effect_to_string(effect().get_value_or(dcp::NONE))) + + "_" + raw_convert (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 f, _fonts) { + for (int i = 0; i < FontFiles::VARIANTS; ++i) { + s += "_" + f->file(static_cast(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) +{ + _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 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(), TextContentProperty::COLOUR); +} + +void +TextContent::set_effect (dcp::Effect e) +{ + maybe_set (_effect, e, TextContentProperty::EFFECT); +} + +void +TextContent::unset_effect () +{ + maybe_set (_effect, optional(), 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(), 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(), 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(), 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 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); +} diff --git a/src/lib/text_content.h b/src/lib/text_content.h new file mode 100644 index 000000000..941184388 --- /dev/null +++ b/src/lib/text_content.h @@ -0,0 +1,204 @@ +/* + Copyright (C) 2013-2018 Carl Hetherington + + 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 . + +*/ + +#ifndef DCPOMATIC_SUBTITLE_CONTENT_H +#define DCPOMATIC_SUBTITLE_CONTENT_H + +#include "content_part.h" +#include +#include +#include + +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 >); + + void as_xml (xmlpp::Node *) const; + std::string identifier () const; + void take_settings_from (boost::shared_ptr c); + + void add_font (boost::shared_ptr 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 > fonts () const { + boost::mutex::scoped_lock lm (_mutex); + return _fonts; + } + + std::string language () const { + boost::mutex::scoped_lock lm (_mutex); + return _language; + } + + boost::optional colour () const { + boost::mutex::scoped_lock lm (_mutex); + return _colour; + } + + boost::optional effect () const { + boost::mutex::scoped_lock lm (_mutex); + return _effect; + } + + boost::optional 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 fade_in () const { + boost::mutex::scoped_lock lm (_mutex); + return _fade_in; + } + + boost::optional 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 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 _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 > _fonts; + boost::optional _colour; + boost::optional _effect; + boost::optional _effect_colour; + /** scaling factor for line spacing; 1 is "standard", < 1 is closer together, > 1 is further apart */ + double _line_spacing; + boost::optional _fade_in; + boost::optional _fade_out; + int _outline_width; +}; + +#endif diff --git a/src/lib/text_decoder.cc b/src/lib/text_decoder.cc new file mode 100644 index 000000000..56a7e1e15 --- /dev/null +++ b/src/lib/text_decoder.cc @@ -0,0 +1,257 @@ +/* + Copyright (C) 2013-2017 Carl Hetherington + + 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 . + +*/ + +#include "text_decoder.h" +#include "text_content.h" +#include "util.h" +#include "log.h" +#include "compose.hpp" +#include +#include +#include +#include +#include + +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 c, + shared_ptr 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, dcpomatic::Rect rect) +{ + ImageStart (ContentImageSubtitle (from, image, rect)); + _position = from; +} + +void +TextDecoder::emit_text_start (ContentTime from, list 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 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 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 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 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 (); +} diff --git a/src/lib/text_decoder.h b/src/lib/text_decoder.h new file mode 100644 index 000000000..d9d351d92 --- /dev/null +++ b/src/lib/text_decoder.h @@ -0,0 +1,74 @@ +/* + Copyright (C) 2013-2017 Carl Hetherington + + 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 . + +*/ + +#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 +#include + +namespace sub { + class Subtitle; +} + +class Image; + +class TextDecoder : public DecoderPart +{ +public: + TextDecoder ( + Decoder* parent, + boost::shared_ptr, + boost::shared_ptr log, + ContentTime first + ); + + ContentTime position () const { + return _position; + } + + void emit_image_start (ContentTime from, boost::shared_ptr image, dcpomatic::Rect rect); + void emit_text_start (ContentTime from, std::list s); + void emit_text_start (ContentTime from, sub::Subtitle const & subtitle); + void emit_text (ContentTimePeriod period, std::list s); + void emit_text (ContentTimePeriod period, sub::Subtitle const & subtitle); + void emit_stop (ContentTime to); + + void seek (); + + boost::shared_ptr content () const { + return _content; + } + + boost::signals2::signal ImageStart; + boost::signals2::signal TextStart; + boost::signals2::signal Stop; + +private: + boost::shared_ptr _content; + ContentTime _position; +}; + +#endif diff --git a/src/lib/text_file.cc b/src/lib/text_file.cc new file mode 100644 index 000000000..b6a07574b --- /dev/null +++ b/src/lib/text_file.cc @@ -0,0 +1,96 @@ +/* + Copyright (C) 2014-2016 Carl Hetherington + + 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 . + +*/ + +#include "text_file.h" +#include "cross.h" +#include "exceptions.h" +#include "text_file_content.h" +#include +#include +#include +#include +#include +#include + +#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 content) +{ + Data in (content->path (0)); + + UErrorCode status = U_ZERO_ERROR; + UCharsetDetector* detector = ucsdet_open (&status); + ucsdet_setText (detector, reinterpret_cast (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 utf16 (new uint16_t[in.size() * 2]); + int const utf16_len = ucnv_toUChars ( + to_utf16, reinterpret_cast(utf16.get()), in.size() * 2, + reinterpret_cast (in.data().get()), in.size(), + &status + ); + + UConverter* to_utf8 = ucnv_open ("UTF-8", &status); + /* Another guess */ + scoped_array utf8 (new char[utf16_len * 2]); + ucnv_fromUChars (to_utf8, utf8.get(), utf16_len * 2, reinterpret_cast(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 > (reader->subtitles ()); + } + + delete reader; +} + +ContentTime +TextFile::length () const +{ + if (_subtitles.empty ()) { + return ContentTime (); + } + + return ContentTime::from_seconds (_subtitles.back().to.all_as_seconds ()); +} diff --git a/src/lib/text_file.h b/src/lib/text_file.h new file mode 100644 index 000000000..346571fc1 --- /dev/null +++ b/src/lib/text_file.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2014-2016 Carl Hetherington + + 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 . + +*/ + +#ifndef DCPOMATIC_TEXT_SUBTITLE_H +#define DCPOMATIC_TEXT_SUBTITLE_H + +#include "dcpomatic_time.h" +#include +#include +#include + +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); + + ContentTime length () const; + +protected: + std::vector _subtitles; +}; + +#endif diff --git a/src/lib/text_file_decoder.cc b/src/lib/text_file_decoder.cc new file mode 100644 index 000000000..1dba3acd0 --- /dev/null +++ b/src/lib/text_file_decoder.cc @@ -0,0 +1,84 @@ +/* + Copyright (C) 2014-2016 Carl Hetherington + + 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 . + +*/ + +#include "text_file_decoder.h" +#include "text_file_content.h" +#include "text_content.h" +#include +#include +#include + +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 content, shared_ptr 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()) + ); +} diff --git a/src/lib/text_file_decoder.h b/src/lib/text_file_decoder.h new file mode 100644 index 000000000..cd279ba92 --- /dev/null +++ b/src/lib/text_file_decoder.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2014-2016 Carl Hetherington + + 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 . + +*/ + +#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, boost::shared_ptr log); + + void seek (ContentTime time, bool accurate); + bool pass (); + +private: + ContentTimePeriod content_time_period (sub::Subtitle s) const; + + size_t _next; +}; + +#endif diff --git a/src/lib/text_subtitle.cc b/src/lib/text_subtitle.cc index 972e74b66..35acb9022 100644 --- a/src/lib/text_subtitle.cc +++ b/src/lib/text_subtitle.cc @@ -21,7 +21,7 @@ #include "text_subtitle.h" #include "cross.h" #include "exceptions.h" -#include "text_subtitle_content.h" +#include "text_text_content.h" #include #include #include @@ -39,7 +39,7 @@ using boost::scoped_array; using boost::optional; using dcp::Data; -TextSubtitle::TextSubtitle (shared_ptr content) +TextSubtitle::TextSubtitle (shared_ptr content) { Data in (content->path (0)); diff --git a/src/lib/text_subtitle.h b/src/lib/text_subtitle.h index c72486ca0..0cd33c9fb 100644 --- a/src/lib/text_subtitle.h +++ b/src/lib/text_subtitle.h @@ -26,16 +26,16 @@ #include #include -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); + explicit TextSubtitle (boost::shared_ptr); boost::optional first () const; ContentTime length () const; diff --git a/src/lib/text_subtitle_content.cc b/src/lib/text_subtitle_content.cc deleted file mode 100644 index 08722a065..000000000 --- a/src/lib/text_subtitle_content.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright (C) 2014-2016 Carl Hetherington - - 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 . - -*/ - -#include "text_subtitle_content.h" -#include "util.h" -#include "text_subtitle.h" -#include "film.h" -#include "font.h" -#include "subtitle_content.h" -#include -#include -#include - -#include "i18n.h" - -using std::string; -using std::cout; -using boost::shared_ptr; -using dcp::raw_convert; - -TextSubtitleContent::TextSubtitleContent (shared_ptr film, boost::filesystem::path path) - : Content (film, path) -{ - subtitle.reset (new SubtitleContent (this)); -} - -TextSubtitleContent::TextSubtitleContent (shared_ptr film, cxml::ConstNodePtr node, int version) - : Content (film, node) - , _length (node->number_child ("Length")) -{ - subtitle = SubtitleContent::from_xml (this, node, version); -} - -void -TextSubtitleContent::examine (boost::shared_ptr 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 (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 (_length.get ())); -} - -DCPTime -TextSubtitleContent::full_length () const -{ - FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate ()); - return DCPTime (_length, frc); -} diff --git a/src/lib/text_subtitle_content.h b/src/lib/text_subtitle_content.h deleted file mode 100644 index fd0bad12a..000000000 --- a/src/lib/text_subtitle_content.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2014-2016 Carl Hetherington - - 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 . - -*/ - -#include "content.h" - -class Job; - -/** @class TextSubtitleContent - * @brief SubRip or SSA subtitles. - */ -class TextSubtitleContent : public Content -{ -public: - TextSubtitleContent (boost::shared_ptr, boost::filesystem::path); - TextSubtitleContent (boost::shared_ptr, cxml::ConstNodePtr, int); - - boost::shared_ptr shared_from_this () { - return boost::dynamic_pointer_cast (Content::shared_from_this ()); - } - - void examine (boost::shared_ptr); - 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; -}; diff --git a/src/lib/text_subtitle_decoder.cc b/src/lib/text_subtitle_decoder.cc deleted file mode 100644 index 6188d524f..000000000 --- a/src/lib/text_subtitle_decoder.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (C) 2014-2016 Carl Hetherington - - 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 . - -*/ - -#include "text_subtitle_decoder.h" -#include "text_subtitle_content.h" -#include "subtitle_content.h" -#include -#include -#include - -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 content, shared_ptr 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()) - ); -} diff --git a/src/lib/text_subtitle_decoder.h b/src/lib/text_subtitle_decoder.h deleted file mode 100644 index 72bb89b77..000000000 --- a/src/lib/text_subtitle_decoder.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2014-2016 Carl Hetherington - - 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 . - -*/ - -#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, boost::shared_ptr log); - - void seek (ContentTime time, bool accurate); - bool pass (); - -private: - ContentTimePeriod content_time_period (sub::Subtitle s) const; - - size_t _next; -}; - -#endif diff --git a/src/lib/text_text_content.cc b/src/lib/text_text_content.cc new file mode 100644 index 000000000..1ff66c490 --- /dev/null +++ b/src/lib/text_text_content.cc @@ -0,0 +1,95 @@ +/* + Copyright (C) 2014-2016 Carl Hetherington + + 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 . + +*/ + +#include "text_text_content.h" +#include "util.h" +#include "text_subtitle.h" +#include "film.h" +#include "font.h" +#include "text_content.h" +#include +#include +#include + +#include "i18n.h" + +using std::string; +using std::cout; +using boost::shared_ptr; +using dcp::raw_convert; + +TextTextContent::TextTextContent (shared_ptr film, boost::filesystem::path path) + : Content (film, path) +{ + subtitle.reset (new TextContent (this)); +} + +TextTextContent::TextTextContent (shared_ptr film, cxml::ConstNodePtr node, int version) + : Content (film, node) + , _length (node->number_child ("Length")) +{ + subtitle = TextContent::from_xml (this, node, version); +} + +void +TextTextContent::examine (boost::shared_ptr 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 (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 (_length.get ())); +} + +DCPTime +TextTextContent::full_length () const +{ + FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate ()); + return DCPTime (_length, frc); +} diff --git a/src/lib/text_text_content.h b/src/lib/text_text_content.h new file mode 100644 index 000000000..ccc86fbbf --- /dev/null +++ b/src/lib/text_text_content.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2014-2016 Carl Hetherington + + 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 . + +*/ + +#include "content.h" + +class Job; + +/** @class TextTextContent + * @brief SubRip or SSA subtitles. + */ +class TextTextContent : public Content +{ +public: + TextTextContent (boost::shared_ptr, boost::filesystem::path); + TextTextContent (boost::shared_ptr, cxml::ConstNodePtr, int); + + boost::shared_ptr shared_from_this () { + return boost::dynamic_pointer_cast (Content::shared_from_this ()); + } + + void examine (boost::shared_ptr); + 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; +}; diff --git a/src/lib/text_text_decoder.cc b/src/lib/text_text_decoder.cc new file mode 100644 index 000000000..2ae5cd38e --- /dev/null +++ b/src/lib/text_text_decoder.cc @@ -0,0 +1,88 @@ +/* + Copyright (C) 2014-2016 Carl Hetherington + + 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 . + +*/ + +#include "text_text_decoder.h" +#include "text_text_content.h" +#include "text_content.h" +#include +#include +#include + +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 content, shared_ptr 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()) + ); +} diff --git a/src/lib/text_text_decoder.h b/src/lib/text_text_decoder.h new file mode 100644 index 000000000..daaf2fcfe --- /dev/null +++ b/src/lib/text_text_decoder.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2014-2016 Carl Hetherington + + 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 . + +*/ + +#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, boost::shared_ptr log); + + void seek (ContentTime time, bool accurate); + bool pass (); + +private: + ContentTimePeriod content_time_period (sub::Subtitle s) const; + + size_t _next; +}; + +#endif diff --git a/src/lib/types.h b/src/lib/types.h index dfce6aec5..af2171718 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -31,7 +31,7 @@ class Content; class VideoContent; class AudioContent; -class SubtitleContent; +class TextContent; class FFmpegContent; namespace cxml { diff --git a/src/lib/wscript b/src/lib/wscript index b6784dbaa..4a7132e48 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -55,8 +55,8 @@ sources = """ 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 @@ -132,11 +132,11 @@ sources = """ 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 diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 64c11281c..934e57505 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -71,7 +71,7 @@ #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 #include #include diff --git a/src/tools/dcpomatic_player.cc b/src/tools/dcpomatic_player.cc index 29195777e..3f56f4752 100644 --- a/src/tools/dcpomatic_player.cc +++ b/src/tools/dcpomatic_player.cc @@ -27,7 +27,7 @@ #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" diff --git a/src/wx/content_panel.cc b/src/wx/content_panel.cc index 4adeb90a4..2c0f35f6c 100644 --- a/src/wx/content_panel.cc +++ b/src/wx/content_panel.cc @@ -28,7 +28,7 @@ #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" @@ -39,7 +39,7 @@ #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 #include @@ -258,11 +258,11 @@ ContentPanel::selection_changed () BOOST_FOREACH (shared_ptr i, selected ()) { DCPTime p; p = i->position(); - if (dynamic_pointer_cast(i) && i->paths_valid()) { + if (dynamic_pointer_cast(i) && i->paths_valid()) { /* Rather special case; if we select a text subtitle file jump to its first subtitle. */ - TextSubtitle ts (dynamic_pointer_cast(i)); + TextSubtitle ts (dynamic_pointer_cast(i)); if (ts.first()) { p += DCPTime(ts.first().get(), _film->active_frame_rate_change(i->position())); } diff --git a/src/wx/dcp_panel.cc b/src/wx/dcp_panel.cc index f2783af6b..5a380ec4e 100644 --- a/src/wx/dcp_panel.cc +++ b/src/wx/dcp_panel.cc @@ -32,7 +32,7 @@ #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 @@ -433,8 +433,8 @@ void 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 || diff --git a/src/wx/fonts_dialog.cc b/src/wx/fonts_dialog.cc index c85d18e34..c295ec327 100644 --- a/src/wx/fonts_dialog.cc +++ b/src/wx/fonts_dialog.cc @@ -24,7 +24,7 @@ #include "font_files_dialog.h" #include "lib/font.h" #include "lib/content.h" -#include "lib/subtitle_content.h" +#include "lib/text_content.h" #include #include #include diff --git a/src/wx/subtitle_appearance_dialog.cc b/src/wx/subtitle_appearance_dialog.cc index 8ae479746..f78ed9ab5 100644 --- a/src/wx/subtitle_appearance_dialog.cc +++ b/src/wx/subtitle_appearance_dialog.cc @@ -20,8 +20,8 @@ #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 diff --git a/src/wx/subtitle_panel.cc b/src/wx/subtitle_panel.cc index 1a42c1f57..da7891ca8 100644 --- a/src/wx/subtitle_panel.cc +++ b/src/wx/subtitle_panel.cc @@ -26,13 +26,13 @@ #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 #include @@ -209,22 +209,22 @@ SubtitlePanel::film_content_changed (int property) } } 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) { @@ -265,9 +265,9 @@ SubtitlePanel::setup_sensitivity () BOOST_FOREACH (shared_ptr i, sel) { /* These are the content types that could include subtitles */ shared_ptr fc = boost::dynamic_pointer_cast (i); - shared_ptr sc = boost::dynamic_pointer_cast (i); + shared_ptr sc = boost::dynamic_pointer_cast (i); shared_ptr dc = boost::dynamic_pointer_cast (i); - shared_ptr dsc = boost::dynamic_pointer_cast (i); + shared_ptr dsc = boost::dynamic_pointer_cast (i); if (fc) { if (fc->subtitle) { ++ffmpeg_subs; @@ -383,15 +383,15 @@ void 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); } diff --git a/src/wx/subtitle_view.cc b/src/wx/subtitle_view.cc index cedf273d4..7efe10d0c 100644 --- a/src/wx/subtitle_view.cc +++ b/src/wx/subtitle_view.cc @@ -18,13 +18,13 @@ */ -#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" diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index e96b474cf..d0a898b18 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -25,7 +25,7 @@ #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" @@ -34,7 +34,7 @@ #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 @@ -229,7 +229,7 @@ Timeline::recreate_views () } if (i->subtitle) { - _views.push_back (shared_ptr (new TimelineSubtitleContentView (*this, i))); + _views.push_back (shared_ptr (new TimelineTextContentView (*this, i))); } if (dynamic_pointer_cast (i)) { @@ -375,7 +375,7 @@ Timeline::assign_tracks () /* Subtitle */ - int const subtitle_tracks = place (_views, _tracks); + int const subtitle_tracks = place (_views, _tracks); /* Atmos */ diff --git a/src/wx/timeline_subtitle_content_view.cc b/src/wx/timeline_subtitle_content_view.cc deleted file mode 100644 index f5c78525e..000000000 --- a/src/wx/timeline_subtitle_content_view.cc +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 2013-2016 Carl Hetherington - - 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 . - -*/ - -#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 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 c = _content.lock (); - DCPOMATIC_ASSERT (c); - return c->subtitle && c->subtitle->use(); -} diff --git a/src/wx/timeline_subtitle_content_view.h b/src/wx/timeline_subtitle_content_view.h deleted file mode 100644 index a7a15f923..000000000 --- a/src/wx/timeline_subtitle_content_view.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2013-2016 Carl Hetherington - - 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 . - -*/ - -#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 c); - -private: - bool active () const; - wxColour background_colour () const; - wxColour foreground_colour () const; -}; diff --git a/src/wx/timeline_text_content_view.cc b/src/wx/timeline_text_content_view.cc new file mode 100644 index 000000000..b4820bfea --- /dev/null +++ b/src/wx/timeline_text_content_view.cc @@ -0,0 +1,59 @@ +/* + Copyright (C) 2013-2016 Carl Hetherington + + 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 . + +*/ + +#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 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 c = _content.lock (); + DCPOMATIC_ASSERT (c); + return c->subtitle && c->subtitle->use(); +} diff --git a/src/wx/timeline_text_content_view.h b/src/wx/timeline_text_content_view.h new file mode 100644 index 000000000..540a90607 --- /dev/null +++ b/src/wx/timeline_text_content_view.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2013-2016 Carl Hetherington + + 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 . + +*/ + +#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 c); + +private: + bool active () const; + wxColour background_colour () const; + wxColour foreground_colour () const; +}; diff --git a/src/wx/timing_panel.cc b/src/wx/timing_panel.cc index 4006c5d3e..315ead524 100644 --- a/src/wx/timing_panel.cc +++ b/src/wx/timing_panel.cc @@ -26,10 +26,10 @@ #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 #include diff --git a/src/wx/wscript b/src/wx/wscript index b5210bace..d5adafebe 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -109,7 +109,7 @@ sources = """ 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 diff --git a/test/burnt_subtitle_test.cc b/test/burnt_subtitle_test.cc index 184be5a82..f0e60284b 100644 --- a/test/burnt_subtitle_test.cc +++ b/test/burnt_subtitle_test.cc @@ -23,12 +23,12 @@ * @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" @@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_subrip) film->set_container (Ratio::from_id ("185")); film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR")); film->set_name ("frobozz"); - shared_ptr content (new TextSubtitleContent (film, "test/data/subrip2.srt")); + shared_ptr content (new TextTextContent (film, "test/data/subrip2.srt")); content->subtitle->set_use (true); content->subtitle->set_burn (true); film->examine_and_add_content (content); @@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_dcp) film->set_container (Ratio::from_id ("185")); film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR")); film->set_name ("frobozz"); - shared_ptr content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml")); + shared_ptr content (new DCPTextContent (film, "test/data/dcp_sub.xml")); content->subtitle->set_use (true); film->examine_and_add_content (content); wait_for_jobs (); @@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_onto_dcp) film2->set_name ("frobozz"); shared_ptr background_dcp (new DCPContent(film2, film->dir(film->dcp_name()))); film2->examine_and_add_content (background_dcp); - shared_ptr sub = dynamic_pointer_cast ( + shared_ptr sub = dynamic_pointer_cast ( content_factory(film2, "test/data/subrip2.srt").front() ); sub->subtitle->set_burn (true); diff --git a/test/dcp_subtitle_test.cc b/test/dcp_subtitle_test.cc index 283fe8fcd..c57d694d0 100644 --- a/test/dcp_subtitle_test.cc +++ b/test/dcp_subtitle_test.cc @@ -25,16 +25,16 @@ #include #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 @@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test) film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR")); film->set_name ("frobozz"); film->set_interop (false); - shared_ptr content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml")); + shared_ptr content (new DCPTextContent (film, "test/data/dcp_sub.xml")); film->examine_and_add_content (content); BOOST_REQUIRE (!wait_for_jobs ()); @@ -109,11 +109,11 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test2) film->set_container (Ratio::from_id ("185")); film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR")); film->set_name ("frobozz"); - shared_ptr content (new DCPSubtitleContent (film, "test/data/dcp_sub2.xml")); + shared_ptr content (new DCPTextContent (film, "test/data/dcp_sub2.xml")); film->examine_and_add_content (content); BOOST_REQUIRE (!wait_for_jobs ()); - shared_ptr decoder (new DCPSubtitleDecoder (content, film->log())); + shared_ptr decoder (new DCPTextDecoder (content, film->log())); decoder->subtitle->TextStart.connect (bind (store, _1)); stored = optional (); @@ -132,14 +132,14 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test3) film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR")); film->set_name ("frobozz"); film->set_interop (true); - shared_ptr content (new DCPSubtitleContent (film, "test/data/dcp_sub3.xml")); + shared_ptr 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 decoder (new DCPSubtitleDecoder (content, film->log())); + shared_ptr decoder (new DCPTextDecoder (content, film->log())); stored = optional (); while (!decoder->pass ()) { decoder->subtitle->TextStart.connect (bind (store, _1)); diff --git a/test/ffmpeg_encoder_test.cc b/test/ffmpeg_encoder_test.cc index fc53ee40c..cfe607b8d 100644 --- a/test/ffmpeg_encoder_test.cc +++ b/test/ffmpeg_encoder_test.cc @@ -24,11 +24,11 @@ #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 @@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test6) film->set_container (Ratio::from_id ("185")); film->set_audio_channels (6); - shared_ptr s (new TextSubtitleContent (film, "test/data/subrip2.srt")); + shared_ptr 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)); @@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test7) film->examine_and_add_content (c); BOOST_REQUIRE (!wait_for_jobs ()); - shared_ptr s (new TextSubtitleContent (film, "test/data/subrip.srt")); + shared_ptr 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)); @@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test2) film->set_container (Ratio::from_id ("185")); film->set_audio_channels (6); - shared_ptr s (new TextSubtitleContent (film, "test/data/subrip2.srt")); + shared_ptr 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)); @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test3) film->examine_and_add_content (c); BOOST_REQUIRE (!wait_for_jobs ()); - shared_ptr s (new TextSubtitleContent (film, "test/data/subrip.srt")); + shared_ptr 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)); diff --git a/test/import_dcp_test.cc b/test/import_dcp_test.cc index 1f5247392..c12f15fa1 100644 --- a/test/import_dcp_test.cc +++ b/test/import_dcp_test.cc @@ -25,7 +25,7 @@ #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" diff --git a/test/player_test.cc b/test/player_test.cc index 52f3097cb..f59205e16 100644 --- a/test/player_test.cc +++ b/test/player_test.cc @@ -31,10 +31,10 @@ #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" @@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE (player_interleave_test) film->examine_and_add_content (c); BOOST_REQUIRE (!wait_for_jobs ()); - shared_ptr s (new TextSubtitleContent (film, "test/data/subrip.srt")); + shared_ptr s (new TextTextContent (film, "test/data/subrip.srt")); film->examine_and_add_content (s); BOOST_REQUIRE (!wait_for_jobs ()); diff --git a/test/reels_test.cc b/test/reels_test.cc index d705d8769..f793cef1d 100644 --- a/test/reels_test.cc +++ b/test/reels_test.cc @@ -30,7 +30,7 @@ #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 @@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE (reels_test3) shared_ptr dcp (new DCPContent (film, "test/data/reels_test2")); film->examine_and_add_content (dcp); - shared_ptr sub (new TextSubtitleContent (film, "test/data/subrip.srt")); + shared_ptr sub (new TextTextContent (film, "test/data/subrip.srt")); film->examine_and_add_content (sub); wait_for_jobs (); @@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE (reels_test4) content[i]->video->set_length (24); } - shared_ptr subs (new TextSubtitleContent (film, "test/data/subrip3.srt")); + shared_ptr subs (new TextTextContent (film, "test/data/subrip3.srt")); film->examine_and_add_content (subs); wait_for_jobs (); diff --git a/test/remake_id_test.cc b/test/remake_id_test.cc index 43ed16ebb..e7e9c67b2 100644 --- a/test/remake_id_test.cc +++ b/test/remake_id_test.cc @@ -20,7 +20,7 @@ #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" diff --git a/test/remake_with_subtitle_test.cc b/test/remake_with_subtitle_test.cc index bc6d41798..4e286523f 100644 --- a/test/remake_with_subtitle_test.cc +++ b/test/remake_with_subtitle_test.cc @@ -20,7 +20,7 @@ #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 diff --git a/test/srt_subtitle_test.cc b/test/srt_subtitle_test.cc index 7c89749e2..d931cf803 100644 --- a/test/srt_subtitle_test.cc +++ b/test/srt_subtitle_test.cc @@ -24,11 +24,11 @@ */ #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 #include @@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test) film->set_name ("frobozz"); film->set_audio_channels (6); film->set_interop (false); - shared_ptr content (new TextSubtitleContent (film, "test/data/subrip2.srt")); + shared_ptr content (new TextTextContent (film, "test/data/subrip2.srt")); film->examine_and_add_content (content); wait_for_jobs (); @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test2) film->set_name ("frobozz"); film->set_audio_channels (6); film->set_interop (false); - shared_ptr content (new TextSubtitleContent (film, "test/data/subrip2.srt")); + shared_ptr content (new TextTextContent (film, "test/data/subrip2.srt")); film->examine_and_add_content (content); wait_for_jobs (); @@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test3) film->set_name ("frobozz"); film->set_interop (true); film->set_audio_channels (6); - shared_ptr content (new TextSubtitleContent (film, private_data / "Ankoemmling_short.srt")); + shared_ptr content (new TextTextContent (film, private_data / "Ankoemmling_short.srt")); film->examine_and_add_content (content); wait_for_jobs (); @@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test4) film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR")); film->set_name ("frobozz"); film->set_interop (false); - shared_ptr content (new TextSubtitleContent (film, "test/data/subrip2.srt")); + shared_ptr content (new TextTextContent (film, "test/data/subrip2.srt")); content->subtitle->set_use (true); content->subtitle->set_burn (false); film->examine_and_add_content (content); @@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test5) film->set_name ("frobozz"); film->set_interop (true); film->set_sequence (false); - shared_ptr content (new TextSubtitleContent (film, "test/data/subrip2.srt")); + shared_ptr content (new TextTextContent (film, "test/data/subrip2.srt")); content->subtitle->set_use (true); content->subtitle->set_burn (false); film->examine_and_add_content (content); @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test6) { shared_ptr film = new_test_film2 ("srt_subtitle_test6"); film->set_interop (false); - shared_ptr content (new TextSubtitleContent (film, "test/data/frames.srt")); + shared_ptr content (new TextTextContent (film, "test/data/frames.srt")); content->subtitle->set_use (true); content->subtitle->set_burn (false); film->examine_and_add_content (content); @@ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test6) BOOST_AUTO_TEST_CASE (srt_subtitle_test4) { shared_ptr film = new_test_film ("subrip_render_test"); - shared_ptr content (new TextSubtitleContent (film, "test/data/subrip.srt")); + shared_ptr content (new TextTextContent (film, "test/data/subrip.srt")); content->examine (shared_ptr (), true); BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471)); diff --git a/test/ssa_subtitle_test.cc b/test/ssa_subtitle_test.cc index bf460247c..b8d7a7c91 100644 --- a/test/ssa_subtitle_test.cc +++ b/test/ssa_subtitle_test.cc @@ -24,11 +24,11 @@ */ #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 #include @@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE (ssa_subtitle_test1) film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR")); film->set_name ("frobozz"); film->set_interop (true); - shared_ptr content (new TextSubtitleContent (film, private_data / "DKH_UT_EN20160601def.ssa")); + shared_ptr content (new TextTextContent (film, private_data / "DKH_UT_EN20160601def.ssa")); film->examine_and_add_content (content); wait_for_jobs (); diff --git a/test/subtitle_reel_number_test.cc b/test/subtitle_reel_number_test.cc index 3eede3a88..749ef9e73 100644 --- a/test/subtitle_reel_number_test.cc +++ b/test/subtitle_reel_number_test.cc @@ -18,10 +18,10 @@ */ -#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 @@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE (subtitle_reel_number_test) film->set_container (Ratio::from_id ("185")); film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR")); film->set_name ("frobozz"); - shared_ptr content (new TextSubtitleContent (film, "test/data/subrip5.srt")); + shared_ptr content (new TextTextContent (film, "test/data/subrip5.srt")); film->examine_and_add_content (content); BOOST_REQUIRE (!wait_for_jobs ()); content->subtitle->set_use (true); diff --git a/test/subtitle_trim_test.cc b/test/subtitle_trim_test.cc index 33bcf823f..1174eb583 100644 --- a/test/subtitle_trim_test.cc +++ b/test/subtitle_trim_test.cc @@ -19,7 +19,7 @@ */ #include "lib/film.h" -#include "lib/dcp_subtitle_content.h" +#include "lib/dcp_text_content.h" #include "test.h" #include @@ -29,7 +29,7 @@ using boost::shared_ptr; BOOST_AUTO_TEST_CASE (subtitle_trim_test1) { shared_ptr film = new_test_film2 ("subtitle_trim_test1"); - shared_ptr content (new DCPSubtitleContent (film, "test/data/dcp_sub5.xml")); + shared_ptr content (new DCPTextContent (film, "test/data/dcp_sub5.xml")); film->examine_and_add_content (content); BOOST_REQUIRE (!wait_for_jobs ()); diff --git a/test/vf_kdm_test.cc b/test/vf_kdm_test.cc index 8b6e215ba..1ed5ac810 100644 --- a/test/vf_kdm_test.cc +++ b/test/vf_kdm_test.cc @@ -25,7 +25,7 @@ #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"