Restore ability to read SMPTE subs from XML files.
authorCarl Hetherington <cth@carlh.net>
Sun, 5 Jul 2015 19:38:32 +0000 (20:38 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 5 Jul 2015 19:38:32 +0000 (20:38 +0100)
src/smpte_subtitle_asset.cc
src/smpte_subtitle_asset.h

index 5e39f8513eb5bcc79a786232494db6f581913aa0..1ef9e7ca8a95431319456246b058d9ee56fc4c9d 100644 (file)
@@ -31,6 +31,7 @@
 #include "util.h"
 #include "AS_DCP.h"
 #include "KM_util.h"
+#include "compose.hpp"
 #include <libxml++/libxml++.h>
 #include <boost/foreach.hpp>
 #include <boost/algorithm/string.hpp>
@@ -55,30 +56,39 @@ SMPTESubtitleAsset::SMPTESubtitleAsset ()
 
 }
 
-/** Construct a SMPTESubtitleAsset by reading an MXF file.
+/** Construct a SMPTESubtitleAsset by reading an MXF or XML file.
  *  @param file Filename.
  */
 SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file)
        : SubtitleAsset (file)
 {
-       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));
-       }
-
-       /* Read the subtitle XML */
-
-       string s;
-       reader.ReadTimedTextResource (s, 0, 0);
-       stringstream t;
-       t << s;
        shared_ptr<cxml::Document> xml (new cxml::Document ("SubtitleReel"));
-       xml->read_stream (t);
 
-       ASDCP::WriterInfo info;
-       reader.FillWriterInfo (info);
-       _id = read_writer_info (info);
+       shared_ptr<ASDCP::TimedText::MXFReader> reader (new ASDCP::TimedText::MXFReader ());
+       Kumu::Result_t r = reader->OpenRead (file.string().c_str ());
+
+       if (!ASDCP_FAILURE (r)) {
+               string s;
+               reader->ReadTimedTextResource (s, 0, 0);
+               stringstream t;
+               t << s;
+               xml->read_stream (t);
+               ASDCP::WriterInfo info;
+               reader->FillWriterInfo (info);
+               _id = read_writer_info (info);
+       } else {
+               reader.reset ();
+               try {
+                       xml->read_file (file);
+                       _id = xml->string_child ("Id").substr (9);
+               } catch (cxml::Error& e) {
+                       boost::throw_exception (
+                               DCPReadError (
+                                       String::compose ("could not read subtitles from %1; MXF failed with %2, XML failed with %3", file, static_cast<int> (r), e.what ())
+                                       )
+                               );
+               }
+       }
 
        _load_font_nodes = type_children<dcp::SMPTELoadFontNode> (xml, "LoadFont");
 
@@ -115,10 +125,16 @@ SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file)
 
        parse_subtitles (xml, font_nodes);
 
-       /* Read fonts */
+       if (reader) {
+               read_fonts (reader);
+       }
+}
 
+void
+SMPTESubtitleAsset::read_fonts (shared_ptr<ASDCP::TimedText::MXFReader> reader)
+{
        ASDCP::TimedText::TimedTextDescriptor text_descriptor;
-       reader.FillTimedTextDescriptor (text_descriptor);
+       reader->FillTimedTextDescriptor (text_descriptor);
        for (
                ASDCP::TimedText::ResourceList_t::const_iterator i = text_descriptor.ResourceList.begin();
                i != text_descriptor.ResourceList.end();
@@ -127,7 +143,7 @@ SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file)
                if (i->Type == ASDCP::TimedText::MT_OPENTYPE) {
                        ASDCP::TimedText::FrameBuffer buffer;
                        buffer.Capacity (10 * 1024 * 1024);
-                       reader.ReadAncillaryResource (i->ResourceID, buffer);
+                       reader->ReadAncillaryResource (i->ResourceID, buffer);
 
                        char id[64];
                        Kumu::bin2UUIDhex (i->ResourceID, ASDCP::UUIDlen, id, sizeof (id));
index 444c53e6c4a3395dbf74be5e8d982dc807992159..1b67dd15c989ba28161619547093877c685e569c 100644 (file)
 #include "mxf.h"
 #include <boost/filesystem.hpp>
 
+namespace ASDCP {
+       namespace TimedText {
+               class MXFReader;
+       }
+}
+
 namespace dcp {
 
 class SMPTELoadFontNode;
@@ -121,6 +127,8 @@ protected:
        }
 
 private:
+       void read_fonts (boost::shared_ptr<ASDCP::TimedText::MXFReader>);
+
        std::string _content_title_text;
        boost::optional<std::string> _language;
        boost::optional<std::string> _annotation_text;