summaryrefslogtreecommitdiff
path: root/src/smpte_subtitle_asset.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/smpte_subtitle_asset.cc')
-rw-r--r--src/smpte_subtitle_asset.cc109
1 files changed, 106 insertions, 3 deletions
diff --git a/src/smpte_subtitle_asset.cc b/src/smpte_subtitle_asset.cc
index e5a083b1..40afc76d 100644
--- a/src/smpte_subtitle_asset.cc
+++ b/src/smpte_subtitle_asset.cc
@@ -24,13 +24,19 @@
#include "xml.h"
#include "AS_DCP.h"
#include "KM_util.h"
+#include "raw_convert.h"
+#include <libxml++/libxml++.h>
#include <boost/foreach.hpp>
+#include <boost/algorithm/string.hpp>
using std::string;
using std::list;
using std::stringstream;
using std::cout;
+using std::vector;
using boost::shared_ptr;
+using boost::split;
+using boost::is_any_of;
using namespace dcp;
SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file, bool mxf)
@@ -64,16 +70,37 @@ SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file, bool mxf)
_load_font_nodes = type_children<dcp::SMPTELoadFontNode> (xml, "LoadFont");
- int tcr = xml->number_child<int> ("TimeCodeRate");
+ _content_title_text = xml->string_child ("ContentTitleText");
+ _annotation_text = xml->optional_string_child ("AnnotationText");
+ _issue_date = LocalTime (xml->string_child ("IssueDate"));
+ _reel_number = xml->optional_number_child<int> ("ReelNumber");
+ _language = xml->optional_string_child ("Language");
+
+ /* This is supposed to be two numbers, but a single number has been seen in the wild */
+ string const er = xml->string_child ("EditRate");
+ vector<string> er_parts;
+ split (er_parts, er, is_any_of (" "));
+ if (er_parts.size() == 1) {
+ _edit_rate = Fraction (raw_convert<int> (er_parts[0]), 1);
+ } else if (er_parts.size() == 2) {
+ _edit_rate = Fraction (raw_convert<int> (er_parts[0]), raw_convert<int> (er_parts[1]));
+ } else {
+ throw XMLError ("malformed EditRate " + er);
+ }
+
+ _time_code_rate = xml->number_child<int> ("TimeCodeRate");
+ if (xml->optional_string_child ("StartTime")) {
+ _start_time = Time (xml->string_child ("StartTime"), _time_code_rate);
+ }
shared_ptr<cxml::Node> subtitle_list = xml->optional_node_child ("SubtitleList");
list<cxml::NodePtr> f = subtitle_list->node_children ("Font");
list<shared_ptr<dcp::FontNode> > font_nodes;
BOOST_FOREACH (cxml::NodePtr& i, f) {
- font_nodes.push_back (shared_ptr<FontNode> (new FontNode (i, tcr)));
+ font_nodes.push_back (shared_ptr<FontNode> (new FontNode (i, _time_code_rate)));
}
-
+
parse_common (xml, font_nodes);
}
@@ -92,3 +119,79 @@ SMPTESubtitleAsset::valid_mxf (boost::filesystem::path file)
Kumu::Result_t r = reader.OpenRead (file.string().c_str ());
return !ASDCP_FAILURE (r);
}
+
+Glib::ustring
+SMPTESubtitleAsset::xml_as_string () const
+{
+ xmlpp::Document doc;
+ xmlpp::Element* root = doc.create_root_node ("dcst:SubtitleReel");
+ root->set_namespace_declaration ("http://www.smpte-ra.org/schemas/428-7/2010/DCST", "dcst");
+ root->set_namespace_declaration ("http://www.w3.org/2001/XMLSchema", "xs");
+
+ root->add_child("ID", "dcst")->add_child_text (_id);
+ root->add_child("ContentTitleText", "dcst")->add_child_text (_content_title_text);
+ if (_annotation_text) {
+ root->add_child("AnnotationText", "dcst")->add_child_text (_annotation_text.get ());
+ }
+ root->add_child("IssueDate", "dcst")->add_child_text (_issue_date.as_string (true));
+ if (_reel_number) {
+ root->add_child("ReelNumber", "dcst")->add_child_text (raw_convert<string> (_reel_number.get ()));
+ }
+ if (_language) {
+ root->add_child("Language", "dcst")->add_child_text (_language.get ());
+ }
+ root->add_child("EditRate", "dcst")->add_child_text (_edit_rate.as_string ());
+ root->add_child("TimeCodeRate", "dcst")->add_child_text (raw_convert<string> (_time_code_rate));
+ if (_start_time) {
+ root->add_child("StartTime", "dcst")->add_child_text (_start_time.get().as_string ());
+ }
+
+ BOOST_FOREACH (shared_ptr<SMPTELoadFontNode> i, _load_font_nodes) {
+ xmlpp::Element* load_font = root->add_child("LoadFont", "dcst");
+ load_font->add_child_text (i->urn);
+ load_font->set_attribute ("ID", i->id);
+ }
+
+ subtitles_as_xml (root->add_child ("SubtitleList", "dcst"), _time_code_rate, "dcst");
+
+ return doc.write_to_string_formatted ("UTF-8");
+}
+
+/** Write this content to a MXF file */
+void
+SMPTESubtitleAsset::write (boost::filesystem::path p) const
+{
+ ASDCP::WriterInfo writer_info;
+ fill_writer_info (&writer_info, _id, SMPTE);
+
+ ASDCP::TimedText::TimedTextDescriptor descriptor;
+ descriptor.EditRate = ASDCP::Rational (_edit_rate.numerator, _edit_rate.denominator);
+ descriptor.EncodingName = "UTF-8";
+ descriptor.ResourceList.clear ();
+ descriptor.NamespaceName = "dcst";
+ memcpy (descriptor.AssetID, writer_info.AssetUUID, ASDCP::UUIDlen);
+ descriptor.ContainerDuration = latest_subtitle_out().as_editable_units (_edit_rate.numerator / _edit_rate.denominator);
+
+ /* XXX: fonts into descriptor? */
+
+ ASDCP::TimedText::MXFWriter writer;
+ Kumu::Result_t r = writer.OpenWrite (p.string().c_str(), writer_info, descriptor);
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (FileError ("could not open subtitle MXF for writing", p.string(), r));
+ }
+
+ /* XXX: no encryption */
+ writer.WriteTimedTextResource (xml_as_string ());
+
+ writer.Finalize ();
+
+ _file = p;
+}
+
+bool
+SMPTESubtitleAsset::equals (shared_ptr<const Asset> other_asset, EqualityOptions options, NoteHandler note) const
+{
+ /* XXX */
+ return false;
+}
+