--- /dev/null
+/*
+ Copyright (C) 2017-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "active_captions.h"
+#include "piece.h"
+#include "text_content.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+using std::list;
+using std::pair;
+using std::make_pair;
+using boost::weak_ptr;
+using boost::shared_ptr;
+using boost::optional;
+
+/** Get the subtitles that should be burnt into a given period.
+ * @param period Period of interest.
+ * @param always_burn_subtitles Always burn subtitles even if their content is not set to burn.
+ */
+list<PlayerCaption>
+ActiveCaptions::get_burnt (DCPTimePeriod period, bool always_burn_subtitles) const
+{
+ list<PlayerCaption> ps;
+
+ for (Map::const_iterator i = _data.begin(); i != _data.end(); ++i) {
+
+ shared_ptr<Piece> piece = i->first.lock ();
+ if (!piece) {
+ continue;
+ }
+
+ if (!piece->content->subtitle->use() || (!always_burn_subtitles && !piece->content->subtitle->burn())) {
+ /* Not burning this piece */
+ continue;
+ }
+
+ BOOST_FOREACH (Period j, i->second) {
+ DCPTimePeriod test (j.from, j.to.get_value_or(DCPTime::max()));
+ optional<DCPTimePeriod> overlap = period.overlap (test);
+ if (overlap && overlap->duration() > DCPTime(period.duration().get() / 2)) {
+ ps.push_back (j.subs);
+ }
+ }
+ }
+
+ return ps;
+}
+
+/** Remove subtitles that finish before a given time from our list.
+ * @param time Time to remove before.
+ */
+void
+ActiveCaptions::clear_before (DCPTime time)
+{
+ Map updated;
+ for (Map::const_iterator i = _data.begin(); i != _data.end(); ++i) {
+ list<Period> as;
+ BOOST_FOREACH (Period j, i->second) {
+ if (!j.to || j.to.get() >= time) {
+ as.push_back (j);
+ }
+ }
+ if (!as.empty ()) {
+ updated[i->first] = as;
+ }
+ }
+ _data = updated;
+}
+
+/** Add a new subtitle with a from time.
+ * @param piece Piece that the subtitle is from.
+ * @param ps Subtitles.
+ * @param from From time for these subtitles.
+ */
+void
+ActiveCaptions::add_from (weak_ptr<Piece> piece, PlayerCaption ps, DCPTime from)
+{
+ if (_data.find(piece) == _data.end()) {
+ _data[piece] = list<Period>();
+ }
+ _data[piece].push_back (Period (ps, from));
+}
+
+/** Add the to time for the last subtitle added from a piece.
+ * @param piece Piece that the subtitle is from.
+ * @param to To time for the last subtitle submitted to add_from for this piece.
+ * @return Return the corresponding subtitles and their from time.
+ */
+pair<PlayerCaption, DCPTime>
+ActiveCaptions::add_to (weak_ptr<Piece> piece, DCPTime to)
+{
+ DCPOMATIC_ASSERT (_data.find(piece) != _data.end());
+
+ _data[piece].back().to = to;
+
+ BOOST_FOREACH (TextCaption& i, _data[piece].back().subs.text) {
+ i.set_out (dcp::Time(to.seconds(), 1000));
+ }
+
+ return make_pair (_data[piece].back().subs, _data[piece].back().from);
+}
+
+/** @param piece A piece.
+ * @return true if we have any active subtitles from this piece.
+ */
+bool
+ActiveCaptions::have (weak_ptr<Piece> piece) const
+{
+ Map::const_iterator i = _data.find(piece);
+ if (i == _data.end()) {
+ return false;
+ }
+
+ return !i->second.empty();
+}
+
+void
+ActiveCaptions::clear ()
+{
+ _data.clear ();
+}
--- /dev/null
+/*
+ Copyright (C) 2017-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+/** @file src/lib/active_captions.h
+ * @brief ActiveCaptions class.
+ */
+
+#include "dcpomatic_time.h"
+#include "player_caption.h"
+#include <boost/noncopyable.hpp>
+#include <list>
+#include <map>
+
+class Piece;
+
+/** @class ActiveCaptions
+ * @brief A class to maintain information on active subtitles for Player.
+ */
+class ActiveCaptions : public boost::noncopyable
+{
+public:
+ std::list<PlayerCaption> get_burnt (DCPTimePeriod period, bool always_burn_subtitles) const;
+ void clear_before (DCPTime time);
+ void clear ();
+ void add_from (boost::weak_ptr<Piece> piece, PlayerCaption ps, DCPTime from);
+ std::pair<PlayerCaption, DCPTime> add_to (boost::weak_ptr<Piece> piece, DCPTime to);
+ bool have (boost::weak_ptr<Piece> piece) const;
+
+private:
+ class Period
+ {
+ public:
+ Period () {}
+
+ Period (PlayerCaption s, DCPTime f)
+ : subs (s)
+ , from (f)
+ {}
+
+ PlayerCaption subs;
+ DCPTime from;
+ boost::optional<DCPTime> to;
+ };
+
+ typedef std::map<boost::weak_ptr<Piece>, std::list<Period> > Map;
+
+ Map _data;
+};
+++ /dev/null
-/*
- Copyright (C) 2017-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "active_text.h"
-#include "piece.h"
-#include "text_content.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-
-using std::list;
-using std::pair;
-using std::make_pair;
-using boost::weak_ptr;
-using boost::shared_ptr;
-using boost::optional;
-
-/** Get the subtitles that should be burnt into a given period.
- * @param period Period of interest.
- * @param always_burn_subtitles Always burn subtitles even if their content is not set to burn.
- */
-list<PlayerText>
-ActiveText::get_burnt (DCPTimePeriod period, bool always_burn_subtitles) const
-{
- list<PlayerText> ps;
-
- for (Map::const_iterator i = _data.begin(); i != _data.end(); ++i) {
-
- shared_ptr<Piece> piece = i->first.lock ();
- if (!piece) {
- continue;
- }
-
- if (!piece->content->subtitle->use() || (!always_burn_subtitles && !piece->content->subtitle->burn())) {
- /* Not burning this piece */
- continue;
- }
-
- BOOST_FOREACH (Period j, i->second) {
- DCPTimePeriod test (j.from, j.to.get_value_or(DCPTime::max()));
- optional<DCPTimePeriod> overlap = period.overlap (test);
- if (overlap && overlap->duration() > DCPTime(period.duration().get() / 2)) {
- ps.push_back (j.subs);
- }
- }
- }
-
- return ps;
-}
-
-/** Remove subtitles that finish before a given time from our list.
- * @param time Time to remove before.
- */
-void
-ActiveText::clear_before (DCPTime time)
-{
- Map updated;
- for (Map::const_iterator i = _data.begin(); i != _data.end(); ++i) {
- list<Period> as;
- BOOST_FOREACH (Period j, i->second) {
- if (!j.to || j.to.get() >= time) {
- as.push_back (j);
- }
- }
- if (!as.empty ()) {
- updated[i->first] = as;
- }
- }
- _data = updated;
-}
-
-/** Add a new subtitle with a from time.
- * @param piece Piece that the subtitle is from.
- * @param ps Subtitles.
- * @param from From time for these subtitles.
- */
-void
-ActiveText::add_from (weak_ptr<Piece> piece, PlayerText ps, DCPTime from)
-{
- if (_data.find(piece) == _data.end()) {
- _data[piece] = list<Period>();
- }
- _data[piece].push_back (Period (ps, from));
-}
-
-/** Add the to time for the last subtitle added from a piece.
- * @param piece Piece that the subtitle is from.
- * @param to To time for the last subtitle submitted to add_from for this piece.
- * @return Return the corresponding subtitles and their from time.
- */
-pair<PlayerText, DCPTime>
-ActiveText::add_to (weak_ptr<Piece> piece, DCPTime to)
-{
- DCPOMATIC_ASSERT (_data.find(piece) != _data.end());
-
- _data[piece].back().to = to;
-
- BOOST_FOREACH (PlainText& i, _data[piece].back().subs.text) {
- i.set_out (dcp::Time(to.seconds(), 1000));
- }
-
- return make_pair (_data[piece].back().subs, _data[piece].back().from);
-}
-
-/** @param piece A piece.
- * @return true if we have any active subtitles from this piece.
- */
-bool
-ActiveText::have (weak_ptr<Piece> piece) const
-{
- Map::const_iterator i = _data.find(piece);
- if (i == _data.end()) {
- return false;
- }
-
- return !i->second.empty();
-}
-
-void
-ActiveText::clear ()
-{
- _data.clear ();
-}
+++ /dev/null
-/*
- Copyright (C) 2017-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-/** @file src/lib/active_text.h
- * @brief ActiveText class.
- */
-
-#include "dcpomatic_time.h"
-#include "player_text.h"
-#include <boost/noncopyable.hpp>
-#include <list>
-#include <map>
-
-class Piece;
-
-/** @class ActiveText
- * @brief A class to maintain information on active subtitles for Player.
- */
-class ActiveText : public boost::noncopyable
-{
-public:
- std::list<PlayerText> get_burnt (DCPTimePeriod period, bool always_burn_subtitles) const;
- void clear_before (DCPTime time);
- void clear ();
- void add_from (boost::weak_ptr<Piece> piece, PlayerText ps, DCPTime from);
- std::pair<PlayerText, DCPTime> add_to (boost::weak_ptr<Piece> piece, DCPTime to);
- bool have (boost::weak_ptr<Piece> piece) const;
-
-private:
- class Period
- {
- public:
- Period () {}
-
- Period (PlayerText s, DCPTime f)
- : subs (s)
- , from (f)
- {}
-
- PlayerText subs;
- DCPTime from;
- boost::optional<DCPTime> to;
- };
-
- typedef std::map<boost::weak_ptr<Piece>, std::list<Period> > Map;
-
- Map _data;
-};
#include "audio_content.h"
#include "image_content.h"
#include "atmos_mxf_content.h"
-#include "plain_text_file_content.h"
+#include "text_caption_file_content.h"
#include "dcp_content.h"
#include "dcp_text_content.h"
#include "util.h"
);
} else if (type == "SubRip" || type == "TextSubtitle") {
- content.reset (new PlainTextFileContent (film, node, version));
+ content.reset (new TextCaptionFileContent (film, node, version));
} else if (type == "DCP") {
content.reset (new DCPContent (film, node, version));
} else if (type == "DCPSubtitle") {
if (valid_image_file (path)) {
single.reset (new ImageContent (film, path));
} else if (ext == ".srt" || ext == ".ssa" || ext == ".ass") {
- single.reset (new PlainTextFileContent (film, path));
+ single.reset (new TextCaptionFileContent (film, path));
} else if (ext == ".xml") {
cxml::Document doc;
doc.read_file (path);
TextType _type;
};
-class ContentBitmapText : public ContentText
+class ContentBitmapCaption : public ContentText
{
public:
- ContentBitmapText (ContentTime f, TextType type, boost::shared_ptr<Image> im, dcpomatic::Rect<double> r)
+ ContentBitmapCaption (ContentTime f, TextType type, boost::shared_ptr<Image> im, dcpomatic::Rect<double> r)
: ContentText (f, type)
, sub (im, r)
{}
* as the dcp::SubtitleString timings are sometimes quite heavily quantised and this causes problems
* when we want to compare the quantised periods to the unquantised ones.
*/
-class ContentPlainText : public ContentText
+class ContentTextCaption : public ContentText
{
public:
- ContentPlainText (ContentTime f, TextType type, std::list<dcp::SubtitleString> s)
+ ContentTextCaption (ContentTime f, TextType type, std::list<dcp::SubtitleString> s)
: ContentText (f, type)
, subs (s)
{}
}
void
-DCPEncoder::text (PlayerText data, TextType type, DCPTimePeriod period)
+DCPEncoder::text (PlayerCaption data, TextType type, DCPTimePeriod period)
{
if (type == TEXT_CLOSED_CAPTION || _non_burnt_subtitles) {
_writer->write (data, type, period);
*/
#include "types.h"
-#include "player_text.h"
+#include "player_caption.h"
#include "encoder.h"
#include <boost/weak_ptr.hpp>
void video (boost::shared_ptr<PlayerVideo>, DCPTime);
void audio (boost::shared_ptr<AudioBuffers>, DCPTime);
- void text (PlayerText, TextType, DCPTimePeriod);
+ void text (PlayerCaption, TextType, DCPTimePeriod);
boost::shared_ptr<Writer> _writer;
boost::shared_ptr<J2KEncoder> _j2k_encoder;
#include "dcp_decoder.h"
#include "image_content.h"
#include "image_decoder.h"
-#include "plain_text_file_content.h"
-#include "plain_text_file_decoder.h"
+#include "text_caption_file_content.h"
+#include "text_caption_file_decoder.h"
#include "dcp_text_content.h"
#include "dcp_text_decoder.h"
#include "video_mxf_content.h"
return shared_ptr<Decoder> (new ImageDecoder (ic, log));
}
- shared_ptr<const PlainTextFileContent> rc = dynamic_pointer_cast<const PlainTextFileContent> (content);
+ shared_ptr<const TextCaptionFileContent> rc = dynamic_pointer_cast<const TextCaptionFileContent> (content);
if (rc) {
- return shared_ptr<Decoder> (new PlainTextFileDecoder (rc, log));
+ return shared_ptr<Decoder> (new TextCaptionFileDecoder (rc, log));
}
shared_ptr<const DCPTextContent> dsc = dynamic_pointer_cast<const DCPTextContent> (content);
#define DCPOMATIC_ENCODER_H
#include "types.h"
-#include "player_text.h"
+#include "player_caption.h"
#include <boost/weak_ptr.hpp>
#include <boost/signals2.hpp>
}
void
-FFmpegEncoder::subtitle (PlayerText, DCPTimePeriod)
+FFmpegEncoder::subtitle (PlayerCaption, DCPTimePeriod)
{
}
private:
void video (boost::shared_ptr<PlayerVideo>, DCPTime);
void audio (boost::shared_ptr<AudioBuffers>);
- void subtitle (PlayerText, DCPTimePeriod);
+ void subtitle (PlayerCaption, DCPTimePeriod);
void setup_video ();
void setup_audio ();
+++ /dev/null
-/*
- Copyright (C) 2016-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef DCPOMATIC_PLAIN_TEXT_H
-#define DCPOMATIC_PLAIN_TEXT_H
-
-#include <dcp/subtitle_string.h>
-
-/** A wrapper for SubtitleString which allows us to include settings that are not
- * applicable to true DCP subtitles. For example, we can set outline width for burn-in
- * but this cannot be specified in DCP XML.
- */
-class PlainText : public dcp::SubtitleString
-{
-public:
- explicit PlainText (dcp::SubtitleString dcp_)
- : dcp::SubtitleString (dcp_)
- , outline_width (2)
- {}
-
- PlainText (dcp::SubtitleString dcp_, int outline_width_)
- : dcp::SubtitleString (dcp_)
- , outline_width (outline_width_)
- {}
-
- int outline_width;
-};
-
-#endif
#include "plain_text_file.h"
#include "cross.h"
#include "exceptions.h"
-#include "plain_text_file_content.h"
+#include "text_caption_file_content.h"
#include <sub/subrip_reader.h>
#include <sub/ssa_reader.h>
#include <sub/collect.h>
using boost::optional;
using dcp::Data;
-PlainTextFile::PlainTextFile (shared_ptr<const PlainTextFileContent> content)
+TextCaptionFile::TextCaptionFile (shared_ptr<const TextCaptionFileContent> content)
{
Data in (content->path (0));
/** @return time of first subtitle, if there is one */
optional<ContentTime>
-PlainTextFile::first () const
+TextCaptionFile::first () const
{
if (_subtitles.empty()) {
return optional<ContentTime>();
}
ContentTime
-PlainTextFile::length () const
+TextCaptionFile::length () const
{
if (_subtitles.empty ()) {
return ContentTime ();
#include <boost/shared_ptr.hpp>
#include <vector>
-class PlainTextFileContent;
+class TextCaptionFileContent;
class plain_text_time_test;
class plain_text_coordinate_test;
class plain_text_content_test;
class plain_text_parse_test;
-/** @class PlainTextFile
- * @brief Base for PlainTextFile decoder and examiner.
+/** @class TextCaptionFile
+ * @brief Base for TextCaptionFile decoder and examiner.
*
* In fact this is sufficient for the examiner, so it's used as-is rather than deriving
- * a pointless PlainTextFileExaminer.
+ * a pointless TextCaptionFileExaminer.
*/
-class PlainTextFile
+class TextCaptionFile
{
public:
- explicit PlainTextFile (boost::shared_ptr<const PlainTextFileContent>);
+ explicit TextCaptionFile (boost::shared_ptr<const TextCaptionFileContent>);
boost::optional<ContentTime> first () const;
ContentTime length () const;
+++ /dev/null
-/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "plain_text_file_content.h"
-#include "util.h"
-#include "plain_text_file.h"
-#include "film.h"
-#include "font.h"
-#include "text_content.h"
-#include <dcp/raw_convert.h>
-#include <libxml++/libxml++.h>
-#include <iostream>
-
-#include "i18n.h"
-
-using std::string;
-using std::cout;
-using boost::shared_ptr;
-using dcp::raw_convert;
-
-PlainTextFileContent::PlainTextFileContent (shared_ptr<const Film> film, boost::filesystem::path path)
- : Content (film, path)
-{
- subtitle.reset (new TextContent (this));
-}
-
-PlainTextFileContent::PlainTextFileContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
- : Content (film, node)
- , _length (node->number_child<ContentTime::Type> ("Length"))
-{
- subtitle = TextContent::from_xml (this, node, version);
-}
-
-void
-PlainTextFileContent::examine (boost::shared_ptr<Job> job)
-{
- Content::examine (job);
- PlainTextFile s (shared_from_this ());
-
- /* Default to turning these subtitles on */
- subtitle->set_use (true);
-
- boost::mutex::scoped_lock lm (_mutex);
- _length = s.length ();
- subtitle->add_font (shared_ptr<Font> (new Font (TEXT_FONT_ID)));
-}
-
-string
-PlainTextFileContent::summary () const
-{
- return path_summary() + " " + _("[subtitles]");
-}
-
-string
-PlainTextFileContent::technical_summary () const
-{
- return Content::technical_summary() + " - " + _("Text subtitles");
-}
-
-void
-PlainTextFileContent::as_xml (xmlpp::Node* node, bool with_paths) const
-{
- node->add_child("Type")->add_child_text ("TextSubtitle");
- Content::as_xml (node, with_paths);
-
- if (subtitle) {
- subtitle->as_xml (node);
- }
-
- node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
-}
-
-DCPTime
-PlainTextFileContent::full_length () const
-{
- FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate ());
- return DCPTime (_length, frc);
-}
+++ /dev/null
-/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "content.h"
-
-class Job;
-
-/** @class PlainTextFileContent
- * @brief A SubRip, SSA or ASS file.
- */
-class PlainTextFileContent : public Content
-{
-public:
- PlainTextFileContent (boost::shared_ptr<const Film>, boost::filesystem::path);
- PlainTextFileContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
-
- boost::shared_ptr<PlainTextFileContent> shared_from_this () {
- return boost::dynamic_pointer_cast<PlainTextFileContent> (Content::shared_from_this ());
- }
-
- void examine (boost::shared_ptr<Job>);
- std::string summary () const;
- std::string technical_summary () const;
- void as_xml (xmlpp::Node *, bool with_paths) const;
- DCPTime full_length () const;
-
-private:
- ContentTime _length;
-};
+++ /dev/null
-/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "plain_text_file_decoder.h"
-#include "plain_text_file_content.h"
-#include "text_content.h"
-#include "text_decoder.h"
-#include <dcp/subtitle_string.h>
-#include <boost/foreach.hpp>
-#include <iostream>
-
-using std::list;
-using std::vector;
-using std::string;
-using std::cout;
-using std::max;
-using boost::shared_ptr;
-using boost::optional;
-using boost::dynamic_pointer_cast;
-
-PlainTextFileDecoder::PlainTextFileDecoder (shared_ptr<const PlainTextFileContent> content, shared_ptr<Log> log)
- : PlainTextFile (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
-PlainTextFileDecoder::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
-PlainTextFileDecoder::pass ()
-{
- if (_next >= _subtitles.size ()) {
- return true;
- }
-
- ContentTimePeriod const p = content_time_period (_subtitles[_next]);
- subtitle->emit_plain (p, _subtitles[_next]);
-
- ++_next;
- return false;
-}
-
-ContentTimePeriod
-PlainTextFileDecoder::content_time_period (sub::Subtitle s) const
-{
- return ContentTimePeriod (
- ContentTime::from_seconds (s.from.all_as_seconds()),
- ContentTime::from_seconds (s.to.all_as_seconds())
- );
-}
+++ /dev/null
-/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef DCPOMATIC_PLAIN_TEXT_FILE_DECODER_H
-#define DCPOMATIC_PLAIN_TEXT_FILE_DECODER_H
-
-#include "plain_text_file.h"
-#include "decoder.h"
-
-class PlainTextFileContent;
-class Log;
-
-class PlainTextFileDecoder : public Decoder, public PlainTextFile
-{
-public:
- PlainTextFileDecoder (boost::shared_ptr<const PlainTextFileContent>, boost::shared_ptr<Log> log);
-
- void seek (ContentTime time, bool accurate);
- bool pass ();
-
-private:
- ContentTimePeriod content_time_period (sub::Subtitle s) const;
-
- size_t _next;
-};
-
-#endif
int const vfr = _film->video_frame_rate();
- BOOST_FOREACH (PlayerText i, _active_text[TEXT_SUBTITLE].get_burnt (DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), _always_burn_subtitles)) {
+ BOOST_FOREACH (PlayerCaption i, _active_text[TEXT_SUBTITLE].get_burnt (DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), _always_burn_subtitles)) {
/* Image subtitles */
list<PositionImage> c = transform_bitmap_texts (i.image);
}
void
-Player::bitmap_text_start (weak_ptr<Piece> wp, ContentBitmapText subtitle)
+Player::bitmap_text_start (weak_ptr<Piece> wp, ContentBitmapCaption subtitle)
{
shared_ptr<Piece> piece = wp.lock ();
if (!piece) {
subtitle.sub.rectangle.width *= piece->content->subtitle->x_scale ();
subtitle.sub.rectangle.height *= piece->content->subtitle->y_scale ();
- PlayerText ps;
+ PlayerCaption ps;
ps.image.push_back (subtitle.sub);
DCPTime from (content_time_to_dcp (piece, subtitle.from()));
}
void
-Player::plain_text_start (weak_ptr<Piece> wp, ContentPlainText subtitle)
+Player::plain_text_start (weak_ptr<Piece> wp, ContentTextCaption subtitle)
{
shared_ptr<Piece> piece = wp.lock ();
if (!piece) {
return;
}
- PlayerText ps;
+ PlayerCaption ps;
DCPTime const from (content_time_to_dcp (piece, subtitle.from()));
if (from > piece->content->end()) {
}
s.set_in (dcp::Time(from.seconds(), 1000));
- ps.text.push_back (PlainText (s, piece->content->subtitle->outline_width()));
+ ps.text.push_back (TextCaption (s, piece->content->subtitle->outline_width()));
ps.add_fonts (piece->content->subtitle->fonts ());
}
return;
}
- pair<PlayerText, DCPTime> from = _active_text[type].add_to (wp, dcp_to);
+ pair<PlayerCaption, DCPTime> from = _active_text[type].add_to (wp, dcp_to);
if (piece->content->subtitle->use() && !_always_burn_subtitles && !piece->content->subtitle->burn()) {
Text (from.first, type, DCPTimePeriod (from.second, dcp_to));
#ifndef DCPOMATIC_PLAYER_H
#define DCPOMATIC_PLAYER_H
-#include "player_text.h"
-#include "active_text.h"
+#include "player_caption.h"
+#include "active_captions.h"
#include "content_text.h"
#include "film.h"
#include "content.h"
/** Emitted when a caption is ready. This signal may be emitted considerably
* after the corresponding Video.
*/
- boost::signals2::signal<void (PlayerText, TextType, DCPTimePeriod)> Text;
+ boost::signals2::signal<void (PlayerCaption, TextType, DCPTimePeriod)> Text;
private:
friend class PlayerWrapper;
boost::shared_ptr<PlayerVideo> black_player_video_frame (Eyes eyes) const;
void video (boost::weak_ptr<Piece>, ContentVideo);
void audio (boost::weak_ptr<Piece>, AudioStreamPtr, ContentAudio);
- void bitmap_text_start (boost::weak_ptr<Piece>, ContentBitmapText);
- void plain_text_start (boost::weak_ptr<Piece>, ContentPlainText);
+ void bitmap_text_start (boost::weak_ptr<Piece>, ContentBitmapCaption);
+ void plain_text_start (boost::weak_ptr<Piece>, ContentTextCaption);
void subtitle_stop (boost::weak_ptr<Piece>, ContentTime, TextType);
DCPTime one_video_frame () const;
void fill_audio (DCPTimePeriod period);
Empty _black;
Empty _silent;
- ActiveText _active_text[TEXT_COUNT];
+ ActiveCaptions _active_text[TEXT_COUNT];
boost::shared_ptr<AudioProcessor> _audio_processor;
boost::signals2::scoped_connection _film_changed_connection;
--- /dev/null
+/*
+ Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "player_caption.h"
+#include "font.h"
+#include <boost/foreach.hpp>
+
+using std::list;
+using boost::shared_ptr;
+
+void
+PlayerCaption::add_fonts (list<shared_ptr<Font> > fonts_)
+{
+ BOOST_FOREACH (shared_ptr<Font> i, fonts_) {
+ bool got = false;
+ BOOST_FOREACH (shared_ptr<Font> j, fonts) {
+ if (*i == *j) {
+ got = true;
+ }
+ }
+ if (!got) {
+ fonts.push_back (i);
+ }
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DCPOMATIC_PLAYER_TEXT_H
+#define DCPOMATIC_PLAYER_TEXT_H
+
+#include "bitmap_text.h"
+#include "dcpomatic_time.h"
+#include "text_caption.h"
+
+class Font;
+
+/** A set of text (subtitle/CCAP) which span the same time period */
+class PlayerCaption
+{
+public:
+ void add_fonts (std::list<boost::shared_ptr<Font> > fonts_);
+ std::list<boost::shared_ptr<Font> > fonts;
+
+ /** BitmapTexts, with their rectangles transformed as specified by their content */
+ std::list<BitmapText> image;
+ std::list<TextCaption> text;
+};
+
+#endif
+++ /dev/null
-/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "player_text.h"
-#include "font.h"
-#include <boost/foreach.hpp>
-
-using std::list;
-using boost::shared_ptr;
-
-void
-PlayerText::add_fonts (list<shared_ptr<Font> > fonts_)
-{
- BOOST_FOREACH (shared_ptr<Font> i, fonts_) {
- bool got = false;
- BOOST_FOREACH (shared_ptr<Font> j, fonts) {
- if (*i == *j) {
- got = true;
- }
- }
- if (!got) {
- fonts.push_back (i);
- }
- }
-}
+++ /dev/null
-/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- DCP-o-matic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef DCPOMATIC_PLAYER_TEXT_H
-#define DCPOMATIC_PLAYER_TEXT_H
-
-#include "bitmap_text.h"
-#include "dcpomatic_time.h"
-#include "plain_text.h"
-
-class Font;
-
-/** A set of text (subtitle/CCAP) which span the same time period */
-class PlayerText
-{
-public:
- void add_fonts (std::list<boost::shared_ptr<Font> > fonts_);
- std::list<boost::shared_ptr<Font> > fonts;
-
- /** BitmapTexts, with their rectangles transformed as specified by their content */
- std::list<BitmapText> image;
- std::list<PlainText> text;
-};
-
-#endif
}
void
-ReelWriter::write (PlayerText subs, TextType type, DCPTimePeriod period)
+ReelWriter::write (PlayerCaption subs, TextType type, DCPTimePeriod period)
{
/* XXX: we need separate libdcp asset types here and to know how different they are */
}
}
- BOOST_FOREACH (PlainText i, subs.text) {
+ BOOST_FOREACH (TextCaption i, subs.text) {
/* XXX: couldn't / shouldn't we use period here rather than getting time from the subtitle? */
i.set_in (i.in() - dcp::Time (_period.from.seconds(), i.in().tcr));
i.set_out (i.out() - dcp::Time (_period.from.seconds(), i.out().tcr));
#include "types.h"
#include "dcpomatic_time.h"
#include "referenced_reel_asset.h"
-#include "player_text.h"
+#include "player_caption.h"
#include <dcp/picture_asset_writer.h>
#include <boost/shared_ptr.hpp>
void fake_write (Frame frame, Eyes eyes, int size);
void repeat_write (Frame frame, Eyes eyes);
void write (boost::shared_ptr<const AudioBuffers> audio);
- void write (PlayerText text, TextType type, DCPTimePeriod period);
+ void write (PlayerCaption text, TextType type, DCPTimePeriod period);
void finish ();
boost::shared_ptr<dcp::Reel> create_reel (std::list<ReferencedReelAsset> const & refs, std::list<boost::shared_ptr<Font> > const & fonts);
static list<pair<FontFiles, string> > fc_config_fonts;
string
-marked_up (list<PlainText> subtitles, int target_height, float fade_factor)
+marked_up (list<TextCaption> subtitles, int target_height, float fade_factor)
{
string out;
- BOOST_FOREACH (PlainText const & i, subtitles) {
+ BOOST_FOREACH (TextCaption const & i, subtitles) {
out += "<span ";
if (i.italic()) {
out += "style=\"italic\" ";
* at the same time and with the same fade in/out.
*/
static PositionImage
-render_line (list<PlainText> subtitles, list<shared_ptr<Font> > fonts, dcp::Size target, DCPTime time, int frame_rate)
+render_line (list<TextCaption> subtitles, list<shared_ptr<Font> > fonts, dcp::Size target, DCPTime time, int frame_rate)
{
/* XXX: this method can only handle italic / bold changes mid-line,
nothing else yet.
* @param frame_rate DCP frame rate.
*/
list<PositionImage>
-render_text (list<PlainText> subtitles, list<shared_ptr<Font> > fonts, dcp::Size target, DCPTime time, int frame_rate)
+render_text (list<TextCaption> subtitles, list<shared_ptr<Font> > fonts, dcp::Size target, DCPTime time, int frame_rate)
{
- list<PlainText> pending;
+ list<TextCaption> pending;
list<PositionImage> images;
- BOOST_FOREACH (PlainText const & i, subtitles) {
+ BOOST_FOREACH (TextCaption const & i, subtitles) {
if (!pending.empty() && fabs (i.v_position() - pending.back().v_position()) > 1e-4) {
images.push_back (render_line (pending, fonts, target, time, frame_rate));
pending.clear ();
#include "position_image.h"
#include "dcpomatic_time.h"
-#include "plain_text.h"
+#include "text_caption.h"
#include <dcp/util.h>
class Font;
-std::string marked_up (std::list<PlainText> subtitles, int target_height, float fade_factor);
+std::string marked_up (std::list<TextCaption> subtitles, int target_height, float fade_factor);
std::list<PositionImage> render_text (
- std::list<PlainText>, std::list<boost::shared_ptr<Font> > fonts, dcp::Size, DCPTime, int
+ std::list<TextCaption>, std::list<boost::shared_ptr<Font> > fonts, dcp::Size, DCPTime, int
);
--- /dev/null
+/*
+ Copyright (C) 2016-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DCPOMATIC_PLAIN_TEXT_H
+#define DCPOMATIC_PLAIN_TEXT_H
+
+#include <dcp/subtitle_string.h>
+
+/** A wrapper for SubtitleString which allows us to include settings that are not
+ * applicable to true DCP subtitles. For example, we can set outline width for burn-in
+ * but this cannot be specified in DCP XML.
+ */
+class TextCaption : public dcp::SubtitleString
+{
+public:
+ explicit TextCaption (dcp::SubtitleString dcp_)
+ : dcp::SubtitleString (dcp_)
+ , outline_width (2)
+ {}
+
+ TextCaption (dcp::SubtitleString dcp_, int outline_width_)
+ : dcp::SubtitleString (dcp_)
+ , outline_width (outline_width_)
+ {}
+
+ int outline_width;
+};
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "text_caption_file_content.h"
+#include "util.h"
+#include "plain_text_file.h"
+#include "film.h"
+#include "font.h"
+#include "text_content.h"
+#include <dcp/raw_convert.h>
+#include <libxml++/libxml++.h>
+#include <iostream>
+
+#include "i18n.h"
+
+using std::string;
+using std::cout;
+using boost::shared_ptr;
+using dcp::raw_convert;
+
+TextCaptionFileContent::TextCaptionFileContent (shared_ptr<const Film> film, boost::filesystem::path path)
+ : Content (film, path)
+{
+ subtitle.reset (new TextContent (this));
+}
+
+TextCaptionFileContent::TextCaptionFileContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
+ : Content (film, node)
+ , _length (node->number_child<ContentTime::Type> ("Length"))
+{
+ subtitle = TextContent::from_xml (this, node, version);
+}
+
+void
+TextCaptionFileContent::examine (boost::shared_ptr<Job> job)
+{
+ Content::examine (job);
+ TextCaptionFile s (shared_from_this ());
+
+ /* Default to turning these subtitles on */
+ subtitle->set_use (true);
+
+ boost::mutex::scoped_lock lm (_mutex);
+ _length = s.length ();
+ subtitle->add_font (shared_ptr<Font> (new Font (TEXT_FONT_ID)));
+}
+
+string
+TextCaptionFileContent::summary () const
+{
+ return path_summary() + " " + _("[subtitles]");
+}
+
+string
+TextCaptionFileContent::technical_summary () const
+{
+ return Content::technical_summary() + " - " + _("Text subtitles");
+}
+
+void
+TextCaptionFileContent::as_xml (xmlpp::Node* node, bool with_paths) const
+{
+ node->add_child("Type")->add_child_text ("TextSubtitle");
+ Content::as_xml (node, with_paths);
+
+ if (subtitle) {
+ subtitle->as_xml (node);
+ }
+
+ node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
+}
+
+DCPTime
+TextCaptionFileContent::full_length () const
+{
+ FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate ());
+ return DCPTime (_length, frc);
+}
--- /dev/null
+/*
+ Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "content.h"
+
+class Job;
+
+/** @class TextCaptionFileContent
+ * @brief A SubRip, SSA or ASS file.
+ */
+class TextCaptionFileContent : public Content
+{
+public:
+ TextCaptionFileContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+ TextCaptionFileContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
+
+ boost::shared_ptr<TextCaptionFileContent> shared_from_this () {
+ return boost::dynamic_pointer_cast<TextCaptionFileContent> (Content::shared_from_this ());
+ }
+
+ void examine (boost::shared_ptr<Job>);
+ std::string summary () const;
+ std::string technical_summary () const;
+ void as_xml (xmlpp::Node *, bool with_paths) const;
+ DCPTime full_length () const;
+
+private:
+ ContentTime _length;
+};
--- /dev/null
+/*
+ Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "text_caption_file_decoder.h"
+#include "text_caption_file_content.h"
+#include "text_content.h"
+#include "text_decoder.h"
+#include <dcp/subtitle_string.h>
+#include <boost/foreach.hpp>
+#include <iostream>
+
+using std::list;
+using std::vector;
+using std::string;
+using std::cout;
+using std::max;
+using boost::shared_ptr;
+using boost::optional;
+using boost::dynamic_pointer_cast;
+
+TextCaptionFileDecoder::TextCaptionFileDecoder (shared_ptr<const TextCaptionFileContent> content, shared_ptr<Log> log)
+ : TextCaptionFile (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
+TextCaptionFileDecoder::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
+TextCaptionFileDecoder::pass ()
+{
+ if (_next >= _subtitles.size ()) {
+ return true;
+ }
+
+ ContentTimePeriod const p = content_time_period (_subtitles[_next]);
+ subtitle->emit_plain (p, _subtitles[_next]);
+
+ ++_next;
+ return false;
+}
+
+ContentTimePeriod
+TextCaptionFileDecoder::content_time_period (sub::Subtitle s) const
+{
+ return ContentTimePeriod (
+ ContentTime::from_seconds (s.from.all_as_seconds()),
+ ContentTime::from_seconds (s.to.all_as_seconds())
+ );
+}
--- /dev/null
+/*
+ Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef DCPOMATIC_PLAIN_TEXT_FILE_DECODER_H
+#define DCPOMATIC_PLAIN_TEXT_FILE_DECODER_H
+
+#include "plain_text_file.h"
+#include "decoder.h"
+
+class TextCaptionFileContent;
+class Log;
+
+class TextCaptionFileDecoder : public Decoder, public TextCaptionFile
+{
+public:
+ TextCaptionFileDecoder (boost::shared_ptr<const TextCaptionFileContent>, boost::shared_ptr<Log> log);
+
+ void seek (ContentTime time, bool accurate);
+ bool pass ();
+
+private:
+ ContentTimePeriod content_time_period (sub::Subtitle s) const;
+
+ size_t _next;
+};
+
+#endif
void
TextDecoder::emit_bitmap_start (ContentTime from, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
{
- BitmapStart (ContentBitmapText (from, _content->type(), image, rect));
+ BitmapStart (ContentBitmapCaption (from, _content->type(), image, rect));
_position = from;
}
}
}
- PlainStart (ContentPlainText (from, _content->type(), s));
+ PlainStart (ContentTextCaption (from, _content->type(), s));
_position = from;
}
return _content;
}
- boost::signals2::signal<void (ContentBitmapText)> BitmapStart;
- boost::signals2::signal<void (ContentPlainText)> PlainStart;
+ boost::signals2::signal<void (ContentBitmapCaption)> BitmapStart;
+ boost::signals2::signal<void (ContentTextCaption)> PlainStart;
boost::signals2::signal<void (ContentTime, TextType)> Stop;
private:
}
void
-Writer::write (PlayerText text, TextType type, DCPTimePeriod period)
+Writer::write (PlayerCaption text, TextType type, DCPTimePeriod period)
{
while (_text_reel[type]->period().to <= period.from) {
++_text_reel[type];
*/
#include "types.h"
-#include "player_text.h"
+#include "player_caption.h"
#include "exception_store.h"
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
bool can_repeat (Frame) const;
void repeat (Frame, Eyes);
void write (boost::shared_ptr<const AudioBuffers>, DCPTime time);
- void write (PlayerText text, TextType type, DCPTimePeriod period);
+ void write (PlayerCaption text, TextType type, DCPTimePeriod period);
void write (std::list<boost::shared_ptr<Font> > fonts);
void write (ReferencedReelAsset asset);
void finish ();
import i18n
sources = """
- active_text.cc
+ active_captions.cc
analyse_audio_job.cc
atmos_mxf_content.cc
audio_analysis.cc
mid_side_decoder.cc
overlaps.cc
player.cc
- player_text.cc
+ player_caption.cc
player_video.cc
playlist.cc
position_image.cc
text_content.cc
text_decoder.cc
plain_text_file.cc
- plain_text_file_content.cc
- plain_text_file_decoder.cc
+ text_caption_file_content.cc
+ text_caption_file_decoder.cc
timer.cc
transcode_job.cc
types.cc
#include "fonts_dialog.h"
#include "subtitle_appearance_dialog.h"
#include "lib/ffmpeg_content.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/ffmpeg_subtitle_stream.h"
#include "lib/dcp_text_content.h"
-#include "lib/plain_text_file_decoder.h"
+#include "lib/text_caption_file_decoder.h"
#include "lib/dcp_text_decoder.h"
#include "lib/dcp_content.h"
#include "lib/text_content.h"
BOOST_FOREACH (shared_ptr<Content> i, sel) {
/* These are the content types that could include subtitles */
shared_ptr<const FFmpegContent> fc = boost::dynamic_pointer_cast<const FFmpegContent> (i);
- shared_ptr<const PlainTextFileContent> sc = boost::dynamic_pointer_cast<const PlainTextFileContent> (i);
+ shared_ptr<const TextCaptionFileContent> sc = boost::dynamic_pointer_cast<const TextCaptionFileContent> (i);
shared_ptr<const DCPContent> dc = boost::dynamic_pointer_cast<const DCPContent> (i);
shared_ptr<const DCPTextContent> dsc = boost::dynamic_pointer_cast<const DCPTextContent> (i);
if (fc) {
#include "lib/config.h"
#include "lib/log.h"
#include "lib/compose.hpp"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/plain_text_file.h"
#include <wx/wx.h>
#include <wx/notebook.h>
BOOST_FOREACH (shared_ptr<Content> i, selected ()) {
DCPTime p;
p = i->position();
- if (dynamic_pointer_cast<PlainTextFileContent>(i) && i->paths_valid()) {
+ if (dynamic_pointer_cast<TextCaptionFileContent>(i) && i->paths_valid()) {
/* Rather special case; if we select a text subtitle file jump to its
first subtitle.
*/
- PlainTextFile ts (dynamic_pointer_cast<PlainTextFileContent>(i));
+ TextCaptionFile ts (dynamic_pointer_cast<TextCaptionFileContent>(i));
if (ts.first()) {
p += DCPTime(ts.first().get(), _film->active_frame_rate_change(i->position()));
}
#include "subtitle_appearance_dialog.h"
#include "rgba_colour_picker.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/text_content.h"
#include "lib/ffmpeg_subtitle_stream.h"
#include "lib/ffmpeg_content.h"
*/
-#include "lib/plain_text_file_decoder.h"
+#include "lib/text_caption_file_decoder.h"
#include "lib/content_text.h"
#include "lib/video_decoder.h"
#include "lib/audio_decoder.h"
#include "lib/film.h"
#include "lib/config.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/text_decoder.h"
#include "subtitle_view.h"
#include "film_viewer.h"
}
void
-SubtitleView::data_start (ContentPlainText cts)
+SubtitleView::data_start (ContentTextCaption cts)
{
BOOST_FOREACH (dcp::SubtitleString const & i, cts.subs) {
wxListItem list_item;
SubtitleView (wxWindow *, boost::shared_ptr<Film>, boost::shared_ptr<Content> content, boost::shared_ptr<Decoder>, FilmViewer* viewer);
private:
- void data_start (ContentPlainText cts);
+ void data_start (ContentTextCaption cts);
void data_stop (ContentTime time);
void subtitle_selected (wxListEvent &);
#include "lib/text_content.h"
#include "lib/dcp_text_content.h"
#include "lib/audio_content.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/video_content.h"
#include <dcp/locale_convert.h>
#include <boost/foreach.hpp>
film->set_container (Ratio::from_id ("185"));
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
- shared_ptr<PlainText> content (new PlainText (film, "test/data/subrip2.srt"));
+ shared_ptr<TextCaption> content (new TextCaption (film, "test/data/subrip2.srt"));
content->subtitle->set_use (true);
content->subtitle->set_burn (true);
film->examine_and_add_content (content);
film2->set_name ("frobozz");
shared_ptr<DCPContent> background_dcp (new DCPContent(film2, film->dir(film->dcp_name())));
film2->examine_and_add_content (background_dcp);
- shared_ptr<PlainText> sub = dynamic_pointer_cast<PlainText> (
+ shared_ptr<TextCaption> sub = dynamic_pointer_cast<TextCaption> (
content_factory(film2, "test/data/subrip2.srt").front()
);
sub->subtitle->set_burn (true);
using boost::shared_ptr;
using boost::optional;
-optional<ContentPlainText> stored;
+optional<ContentTextCaption> stored;
static void
-store (ContentPlainText sub)
+store (ContentTextCaption sub)
{
if (!stored) {
stored = sub;
shared_ptr<DCPDecoder> decoder (new DCPDecoder (content, film->log(), false));
decoder->subtitle->PlainStart.connect (bind (store, _1));
- stored = optional<ContentPlainText> ();
+ stored = optional<ContentTextCaption> ();
while (!decoder->pass() && !stored) {}
BOOST_REQUIRE (stored);
shared_ptr<DCPTextDecoder> decoder (new DCPTextDecoder (content, film->log()));
decoder->subtitle->PlainStart.connect (bind (store, _1));
- stored = optional<ContentPlainText> ();
+ stored = optional<ContentTextCaption> ();
while (!decoder->pass ()) {
if (stored && stored->from() == ContentTime(0)) {
BOOST_CHECK_EQUAL (stored->subs.front().text(), "<b>Hello world!</b>");
BOOST_REQUIRE (!wait_for_jobs ());
shared_ptr<DCPTextDecoder> decoder (new DCPTextDecoder (content, film->log()));
- stored = optional<ContentPlainText> ();
+ stored = optional<ContentTextCaption> ();
while (!decoder->pass ()) {
decoder->subtitle->PlainStart.connect (bind (store, _1));
if (stored && stored->from() == ContentTime::from_seconds(0.08)) {
#include "lib/image_content.h"
#include "lib/video_content.h"
#include "lib/audio_content.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/ratio.h"
#include "lib/transcode_job.h"
#include "lib/dcp_content.h"
film->set_container (Ratio::from_id ("185"));
film->set_audio_channels (6);
- shared_ptr<PlainTextFileContent> s (new PlainTextFileContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextCaptionFileContent> s (new TextCaptionFileContent (film, "test/data/subrip2.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
s->subtitle->set_colour (dcp::Colour (255, 255, 0));
film->examine_and_add_content (c);
BOOST_REQUIRE (!wait_for_jobs ());
- shared_ptr<PlainTextFileContent> s (new PlainTextFileContent (film, "test/data/subrip.srt"));
+ shared_ptr<TextCaptionFileContent> s (new TextCaptionFileContent (film, "test/data/subrip.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
s->subtitle->set_colour (dcp::Colour (255, 255, 0));
film->set_container (Ratio::from_id ("185"));
film->set_audio_channels (6);
- shared_ptr<PlainTextFileContent> s (new PlainTextFileContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextCaptionFileContent> s (new TextCaptionFileContent (film, "test/data/subrip2.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
s->subtitle->set_colour (dcp::Colour (255, 255, 0));
film->examine_and_add_content (c);
BOOST_REQUIRE (!wait_for_jobs ());
- shared_ptr<PlainTextFileContent> s (new PlainTextFileContent (film, "test/data/subrip.srt"));
+ shared_ptr<TextCaptionFileContent> s (new TextCaptionFileContent (film, "test/data/subrip.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
s->subtitle->set_colour (dcp::Colour (255, 255, 0));
#include "lib/player.h"
#include "lib/video_content.h"
#include "lib/image_content.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/content_factory.h"
#include "lib/dcp_content.h"
#include "lib/text_content.h"
film->examine_and_add_content (c);
BOOST_REQUIRE (!wait_for_jobs ());
- shared_ptr<PlainTextFileContent> s (new PlainTextFileContent (film, "test/data/subrip.srt"));
+ shared_ptr<TextCaptionFileContent> s (new TextCaptionFileContent (film, "test/data/subrip.srt"));
film->examine_and_add_content (s);
BOOST_REQUIRE (!wait_for_jobs ());
#include "lib/dcp_content_type.h"
#include "lib/dcp_content.h"
#include "lib/video_content.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/content_factory.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
shared_ptr<Content> dcp (new DCPContent (film, "test/data/reels_test2"));
film->examine_and_add_content (dcp);
- shared_ptr<Content> sub (new PlainTextFileContent (film, "test/data/subrip.srt"));
+ shared_ptr<Content> sub (new TextCaptionFileContent (film, "test/data/subrip.srt"));
film->examine_and_add_content (sub);
wait_for_jobs ();
content[i]->video->set_length (24);
}
- shared_ptr<PlainTextFileContent> subs (new PlainTextFileContent (film, "test/data/subrip3.srt"));
+ shared_ptr<TextCaptionFileContent> subs (new TextCaptionFileContent (film, "test/data/subrip3.srt"));
film->examine_and_add_content (subs);
wait_for_jobs ();
#include <boost/test/unit_test.hpp>
static void
-add (std::list<PlainText>& s, std::string text, bool italic, bool bold, bool underline)
+add (std::list<TextCaption>& s, std::string text, bool italic, bool bold, bool underline)
{
s.push_back (
- PlainText (
+ TextCaption (
dcp::SubtitleString (
boost::optional<std::string> (),
italic,
/** Test marked_up() in render_text.cc */
BOOST_AUTO_TEST_CASE (render_markup_test1)
{
- std::list<PlainText> s;
+ std::list<TextCaption> s;
add (s, "Hello", false, false, false);
BOOST_CHECK_EQUAL (marked_up (s, 1024, 1), "<span size=\"41472\" alpha=\"65535\" color=\"#FFFFFF\">Hello</span>");
}
/** Test marked_up() in render_text.cc */
BOOST_AUTO_TEST_CASE (render_markup_test2)
{
- std::list<PlainText> s;
+ std::list<TextCaption> s;
add (s, "Hello", false, true, false);
BOOST_CHECK_EQUAL (marked_up (s, 1024, 1), "<span weight=\"bold\" size=\"41472\" alpha=\"65535\" color=\"#FFFFFF\">Hello</span>");
}
/** Test marked_up() in render_text.cc */
BOOST_AUTO_TEST_CASE (render_markup_test3)
{
- std::list<PlainText> s;
+ std::list<TextCaption> s;
add (s, "Hello", true, true, false);
BOOST_CHECK_EQUAL (marked_up (s, 1024, 1), "<span style=\"italic\" weight=\"bold\" size=\"41472\" alpha=\"65535\" color=\"#FFFFFF\">Hello</span>");
}
/** Test marked_up() in render_text.cc */
BOOST_AUTO_TEST_CASE (render_markup_test4)
{
- std::list<PlainText> s;
+ std::list<TextCaption> s;
add (s, "Hello", true, true, true);
BOOST_CHECK_EQUAL (marked_up (s, 1024, 1), "<span style=\"italic\" weight=\"bold\" underline=\"single\" size=\"41472\" alpha=\"65535\" color=\"#FFFFFF\">Hello</span>");
}
/** Test marked_up() in render_text.cc */
BOOST_AUTO_TEST_CASE (render_markup_test5)
{
- std::list<PlainText> s;
+ std::list<TextCaption> s;
add (s, "Hello", false, true, false);
add (s, " world.", false, false, false);
BOOST_CHECK_EQUAL (marked_up (s, 1024, 1), "<span weight=\"bold\" size=\"41472\" alpha=\"65535\" color=\"#FFFFFF\">Hello</span><span size=\"41472\" alpha=\"65535\" color=\"#FFFFFF\"> world.</span>");
/** Test marked_up() in render_text.cc */
BOOST_AUTO_TEST_CASE (render_markup_test6)
{
- std::list<PlainText> s;
+ std::list<TextCaption> s;
add (s, "Hello", true, false, false);
add (s, " world ", false, false, false);
add (s, "we are bold.", false, true, false);
*/
#include "lib/film.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/dcp_content_type.h"
#include "lib/font.h"
#include "lib/ratio.h"
film->set_name ("frobozz");
film->set_audio_channels (6);
film->set_interop (false);
- shared_ptr<PlainTextFileContent> content (new PlainTextFileContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/subrip2.srt"));
film->examine_and_add_content (content);
wait_for_jobs ();
film->set_name ("frobozz");
film->set_audio_channels (6);
film->set_interop (false);
- shared_ptr<PlainTextFileContent> content (new PlainTextFileContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/subrip2.srt"));
film->examine_and_add_content (content);
wait_for_jobs ();
film->set_name ("frobozz");
film->set_interop (true);
film->set_audio_channels (6);
- shared_ptr<PlainTextFileContent> content (new PlainTextFileContent (film, private_data / "Ankoemmling_short.srt"));
+ shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, private_data / "Ankoemmling_short.srt"));
film->examine_and_add_content (content);
wait_for_jobs ();
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
film->set_interop (false);
- shared_ptr<PlainTextFileContent> content (new PlainTextFileContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/subrip2.srt"));
content->subtitle->set_use (true);
content->subtitle->set_burn (false);
film->examine_and_add_content (content);
film->set_name ("frobozz");
film->set_interop (true);
film->set_sequence (false);
- shared_ptr<PlainTextFileContent> content (new PlainTextFileContent (film, "test/data/subrip2.srt"));
+ shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/subrip2.srt"));
content->subtitle->set_use (true);
content->subtitle->set_burn (false);
film->examine_and_add_content (content);
{
shared_ptr<Film> film = new_test_film2 ("srt_subtitle_test6");
film->set_interop (false);
- shared_ptr<PlainTextFileContent> content (new PlainTextFileContent (film, "test/data/frames.srt"));
+ shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/frames.srt"));
content->subtitle->set_use (true);
content->subtitle->set_burn (false);
film->examine_and_add_content (content);
BOOST_AUTO_TEST_CASE (srt_subtitle_test4)
{
shared_ptr<Film> film = new_test_film ("subrip_render_test");
- shared_ptr<PlainTextFile> content (new PlainTextFile (film, "test/data/subrip.srt"));
+ shared_ptr<TextCaptionFile> content (new TextCaptionFile (film, "test/data/subrip.srt"));
content->examine (shared_ptr<Job> (), true);
BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471));
*/
#include "lib/film.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/dcp_content_type.h"
#include "lib/font.h"
#include "lib/ratio.h"
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
film->set_interop (true);
- shared_ptr<PlainTextFileContent> content (new PlainTextFileContent (film, private_data / "DKH_UT_EN20160601def.ssa"));
+ shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, private_data / "DKH_UT_EN20160601def.ssa"));
film->examine_and_add_content (content);
wait_for_jobs ();
#include "lib/film.h"
#include "lib/content_factory.h"
#include "lib/plain_text_file.h"
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include <boost/test/unit_test.hpp>
using boost::shared_ptr;
shared_ptr<Content> content = content_factory (film, "test/data/osx.srt").front ();
film->examine_and_add_content (content);
BOOST_REQUIRE (!wait_for_jobs ());
- shared_ptr<PlainTextFile> ts = dynamic_pointer_cast<PlainTextFile> (content);
+ shared_ptr<TextCaptionFile> ts = dynamic_pointer_cast<TextCaptionFile> (content);
BOOST_REQUIRE (ts);
/* Make sure we got the subtitle data from the file */
BOOST_REQUIRE_EQUAL (content->full_length().get(), 6052032);
*/
-#include "lib/plain_text_file_content.h"
+#include "lib/text_caption_file_content.h"
#include "lib/film.h"
#include "lib/ratio.h"
#include "lib/text_content.h"
film->set_container (Ratio::from_id ("185"));
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
- shared_ptr<PlainTextFileContent> content (new PlainTextFileContent (film, "test/data/subrip5.srt"));
+ shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/subrip5.srt"));
film->examine_and_add_content (content);
BOOST_REQUIRE (!wait_for_jobs ());
content->subtitle->set_use (true);