diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dcp.cc | 5 | ||||
| -rw-r--r-- | src/load_font.cc | 11 | ||||
| -rw-r--r-- | src/load_font.h | 3 | ||||
| -rw-r--r-- | src/mxf.cc | 2 | ||||
| -rw-r--r-- | src/subtitle_content.cc | 57 | ||||
| -rw-r--r-- | src/subtitle_content.h | 13 | ||||
| -rw-r--r-- | src/text.cc | 7 |
7 files changed, 80 insertions, 18 deletions
@@ -133,7 +133,7 @@ DCP::read (bool keep_going, ReadErrors* errors) if (root == "CompositionPlaylist") { _assets.push_back (shared_ptr<CPL> (new CPL (path))); } else if (root == "DCSubtitle") { - _assets.push_back (shared_ptr<SubtitleContent> (new SubtitleContent (path))); + _assets.push_back (shared_ptr<SubtitleContent> (new SubtitleContent (path, false))); } } else if (boost::algorithm::ends_with (path.string(), ".mxf")) { ASDCP::EssenceType_t type; @@ -154,6 +154,9 @@ DCP::read (bool keep_going, ReadErrors* errors) case ASDCP::ESS_JPEG_2000_S: _assets.push_back (shared_ptr<StereoPictureMXF> (new StereoPictureMXF (path))); break; + case ASDCP::ESS_TIMED_TEXT: + _assets.push_back (shared_ptr<SubtitleContent> (new SubtitleContent (path, true))); + break; default: throw DCPReadError ("Unknown MXF essence type"); } diff --git a/src/load_font.cc b/src/load_font.cc index 707f4a0b..b46569c8 100644 --- a/src/load_font.cc +++ b/src/load_font.cc @@ -20,11 +20,18 @@ #include "load_font.h" #include <libcxml/cxml.h> +using std::string; using boost::shared_ptr; +using boost::optional; using namespace dcp; LoadFont::LoadFont (boost::shared_ptr<const cxml::Node> node) { - id = node->string_attribute ("Id"); - uri = node->string_attribute ("URI"); + optional<string> x = node->optional_string_attribute ("Id"); + if (!x) { + x = node->optional_string_attribute ("ID"); + } + id = x.get_value_or (""); + + uri = node->optional_string_attribute ("URI"); } diff --git a/src/load_font.h b/src/load_font.h index 6319b1de..6d52a509 100644 --- a/src/load_font.h +++ b/src/load_font.h @@ -18,6 +18,7 @@ */ #include <boost/shared_ptr.hpp> +#include <boost/optional.hpp> namespace cxml { class Node; @@ -32,7 +33,7 @@ public: LoadFont (boost::shared_ptr<const cxml::Node> node); std::string id; - std::string uri; + boost::optional<std::string> uri; }; } @@ -148,7 +148,7 @@ void MXF::read_writer_info (ASDCP::WriterInfo const & info) { char buffer[64]; - Kumu::bin2UUIDhex (info.AssetUUID, 16, buffer, 64); + Kumu::bin2UUIDhex (info.AssetUUID, ASDCP::UUIDlen, buffer, sizeof (buffer)); _id = buffer; } diff --git a/src/subtitle_content.cc b/src/subtitle_content.cc index f338517e..0aaab9a2 100644 --- a/src/subtitle_content.cc +++ b/src/subtitle_content.cc @@ -24,6 +24,8 @@ #include "text.h" #include "load_font.h" #include "subtitle_string.h" +#include "AS_DCP.h" +#include "KM_util.h" #include <libxml++/nodes/element.h> #include <boost/lexical_cast.hpp> #include <boost/algorithm/string.hpp> @@ -40,15 +42,42 @@ using boost::lexical_cast; using boost::optional; using namespace dcp; -SubtitleContent::SubtitleContent (boost::filesystem::path file) +SubtitleContent::SubtitleContent (boost::filesystem::path file, bool mxf) : Content (file) , _need_sort (false) { - shared_ptr<cxml::Document> xml (new cxml::Document ("DCSubtitle")); - xml->read_file (file); + shared_ptr<cxml::Document> xml; - _id = xml->string_child ("SubtitleID"); - _movie_title = xml->string_child ("MovieTitle"); + if (mxf) { + ASDCP::TimedText::MXFReader reader; + Kumu::Result_t r = reader.OpenRead (file.string().c_str ()); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (MXFFileError ("could not open MXF file for reading", file, r)); + } + + string s; + reader.ReadTimedTextResource (s, 0, 0); + xml.reset (new cxml::Document ("SubtitleReel")); + stringstream t; + t << s; + xml->read_stream (t); + + ASDCP::WriterInfo info; + reader.FillWriterInfo (info); + + char buffer[64]; + Kumu::bin2UUIDhex (info.AssetUUID, ASDCP::UUIDlen, buffer, sizeof (buffer)); + _id = buffer; + + } else { + xml.reset (new cxml::Document ("DCSubtitle")); + xml->read_file (file); + _id = xml->string_child ("SubtitleID"); + } + + /* XXX: hacks aplenty in here; probably need separate parsers for DCSubtitle and SubtitleReel */ + + _movie_title = xml->optional_string_child ("MovieTitle"); _reel_number = xml->string_child ("ReelNumber"); _language = xml->string_child ("Language"); @@ -60,6 +89,12 @@ SubtitleContent::SubtitleContent (boost::filesystem::path file) /* Now make Subtitle objects to represent the raw XML nodes in a sane way. */ + + shared_ptr<cxml::Node> subtitle_list = xml->optional_node_child ("SubtitleList"); + if (subtitle_list) { + list<shared_ptr<dcp::Font> > font = type_children<dcp::Font> (subtitle_list, "Font"); + copy (font.begin(), font.end(), back_inserter (font_nodes)); + } ParseState parse_state; examine_font_nodes (xml, font_nodes, parse_state); @@ -180,7 +215,7 @@ SubtitleContent::font_id_to_name (string id) const return ""; } - if ((*i)->uri == "arial.ttf") { + if ((*i)->uri && (*i)->uri.get() == "arial.ttf") { return "Arial"; } @@ -220,7 +255,9 @@ SubtitleContent::xml_as_string () const root->set_attribute ("Version", "1.0"); root->add_child("SubtitleID")->add_child_text (_id); - root->add_child("MovieTitle")->add_child_text (_movie_title); + if (_movie_title) { + root->add_child("MovieTitle")->add_child_text (_movie_title.get ()); + } root->add_child("ReelNumber")->add_child_text (lexical_cast<string> (_reel_number)); root->add_child("Language")->add_child_text (_language); @@ -230,8 +267,10 @@ SubtitleContent::xml_as_string () const if (!_load_font_nodes.empty ()) { xmlpp::Element* load_font = root->add_child("LoadFont"); - load_font->set_attribute("Id", _load_font_nodes.front()->id); - load_font->set_attribute("URI", _load_font_nodes.front()->uri); + load_font->set_attribute ("Id", _load_font_nodes.front()->id); + if (_load_font_nodes.front()->uri) { + load_font->set_attribute ("URI", _load_font_nodes.front()->uri.get ()); + } } list<shared_ptr<SubtitleString> > sorted = _subtitles; diff --git a/src/subtitle_content.h b/src/subtitle_content.h index 410c5934..2c606921 100644 --- a/src/subtitle_content.h +++ b/src/subtitle_content.h @@ -34,12 +34,19 @@ class Subtitle; class LoadFont; /** @class SubtitleContent - * @brief A representation of an XML file containing subtitles. + * @brief A representation of an XML or MXF file containing subtitles. + * + * XXX: perhaps this should inhert from MXF, or there should be different + * classes for XML and MXF subs. */ class SubtitleContent : public Content { public: - SubtitleContent (boost::filesystem::path file); + /** Construct a SubtitleContent. + * @param file Filename. + * @param mxf true if the file is an MXF file, false for XML. + */ + SubtitleContent (boost::filesystem::path file, bool mxf); SubtitleContent (Fraction edit_rate, std::string movie_title, std::string language); bool equals ( @@ -98,7 +105,7 @@ private: ParseState& parse_state ); - std::string _movie_title; + boost::optional<std::string> _movie_title; /* strangely, this is sometimes a string */ std::string _reel_number; std::string _language; diff --git a/src/text.cc b/src/text.cc index 888cab29..6fbdbe6e 100644 --- a/src/text.cc +++ b/src/text.cc @@ -39,7 +39,12 @@ Text::Text (boost::shared_ptr<const cxml::Node> node) : v_align (CENTER) { text = node->content (); - v_position = node->number_attribute<float> ("VPosition"); + optional<float> x = node->optional_number_attribute<float> ("VPosition"); + if (!x) { + x = node->number_attribute<float> ("Vposition"); + } + v_position = x.get (); + optional<string> v = node->optional_string_attribute ("VAlign"); if (v) { v_align = string_to_valign (v.get ()); |
