Various tweaks for a real-life DCP.
authorCarl Hetherington <cth@carlh.net>
Sat, 11 Aug 2012 21:06:47 +0000 (22:06 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 11 Aug 2012 21:06:47 +0000 (22:06 +0100)
src/cpl.cc
src/dcp.cc
src/picture_asset.h
src/pkl.cc
src/pkl.h
src/xml.cc
src/xml.h

index b0bf6fcf98861634693658f5295940780baba402..a95218d6a939d560b6ec719e931cead59517f702 100644 (file)
@@ -1,3 +1,4 @@
+#include <iostream>
 #include "cpl.h"
 
 using namespace std;
@@ -12,10 +13,14 @@ CPL::CPL (string file)
        creator = string_node ("Creator");
        content_title_text = string_node ("ContentTitleText");
        content_kind = kind_node ("ContentKind");
-       content_version = sub_node<ContentVersion> ("ContentVersion");
+       content_version = optional_sub_node<ContentVersion> ("ContentVersion");
        ignore_node ("RatingList");
        reels = sub_nodes<Reel> ("ReelList", "Reel");
 
+       ignore_node ("Issuer");
+       ignore_node ("Signer");
+       ignore_node ("Signature");
+
        done ();
 }
 
@@ -49,13 +54,21 @@ MainPicture::MainPicture (xmlpp::Node const * node)
        : XMLNode (node)
 {
        id = string_node ("Id");
-       annotation_text = string_node ("AnnotationText");
+       annotation_text = optional_string_node ("AnnotationText");
        edit_rate = fraction_node ("EditRate");
        intrinsic_duration = int64_node ("IntrinsicDuration");
        entry_point = int64_node ("EntryPoint");
        duration = int64_node ("Duration");
        frame_rate = fraction_node ("FrameRate");
-       screen_aspect_ratio = fraction_node ("ScreenAspectRatio");
+       try {
+               screen_aspect_ratio = fraction_node ("ScreenAspectRatio");
+       } catch (XMLError& e) {
+               /* Maybe it's not a fraction */
+       }
+       float f = float_node ("ScreenAspectRatio");
+       screen_aspect_ratio = Fraction (f * 1000, 1000);
+
+       ignore_node ("Hash");
 
        done ();
 }
@@ -64,11 +77,13 @@ MainSound::MainSound (xmlpp::Node const * node)
        : XMLNode (node)
 {
        id = string_node ("Id");
-       annotation_text = string_node ("AnnotationText");
+       annotation_text = optional_string_node ("AnnotationText");
        edit_rate = fraction_node ("EditRate");
        intrinsic_duration = int64_node ("IntrinsicDuration");
        entry_point = int64_node ("EntryPoint");
        duration = int64_node ("Duration");
 
+       ignore_node ("Hash");
+       
        done ();
 }
index b6014941b823c03b3f37eb257e452a6473791342..99cc517a7c8c274c0a79301b3595b94b5a05f0e7 100644 (file)
@@ -25,7 +25,9 @@
 #include <fstream>
 #include <iomanip>
 #include <cassert>
+#include <iostream>
 #include <boost/filesystem.hpp>
+#include <libxml++/libxml++.h>
 #include "dcp.h"
 #include "asset.h"
 #include "sound_asset.h"
@@ -240,25 +242,49 @@ DCP::DCP (string directory)
        string asset_map_file;
 
        for (filesystem::directory_iterator i = filesystem::directory_iterator(directory); i != filesystem::directory_iterator(); ++i) {
+               
                string const t = i->path().string ();
-               if (ends_with (t, "_cpl.xml")) {
+
+               if (ends_with (t, ".mxf")) {
+                       continue;
+               }
+
+               xmlpp::DomParser* p = new xmlpp::DomParser;
+
+               try {
+                       p->parse_file (t);
+               } catch (std::exception& e) {
+                       delete p;
+                       continue;
+               }
+               
+               if (!p) {
+                       delete p;
+                       continue;
+               }
+
+               string const root = p->get_document()->get_root_node()->get_name ();
+               delete p;
+               
+               if (root == "CompositionPlaylist") {
                        if (cpl_file.empty ()) {
                                cpl_file = t;
                        } else {
                                throw DCPReadError ("duplicate CPLs found");
                        }
-               } else if (ends_with (t, "_pkl.xml")) {
+               } else if (root == "PackingList") {
                        if (pkl_file.empty ()) {
                                pkl_file = t;
                        } else {
                                throw DCPReadError ("duplicate PKLs found");
                        }
-               } else if (ends_with (t, "ASSETMAP.xml")) {
+               } else if (root == "AssetMap") {
                        if (asset_map_file.empty ()) {
                                asset_map_file = t;
                        } else {
                                throw DCPReadError ("duplicate AssetMaps found");
                        }
+                       asset_map_file = t;
                }
        }
 
@@ -310,10 +336,15 @@ DCP::DCP (string directory)
        _fps = cpl_assets->main_picture->frame_rate.numerator;
        _length = cpl_assets->main_picture->duration;
 
+       string n = cpl_assets->main_picture->annotation_text;
+       if (n.empty ()) {
+               n = pkl->asset_from_id(cpl_assets->main_picture->id)->original_file_name;
+       }
+
        _assets.push_back (shared_ptr<PictureAsset> (
                                   new PictureAsset (
                                           _directory,
-                                          cpl_assets->main_picture->annotation_text,
+                                          n,
                                           _fps,
                                           _length,
                                           cpl_assets->main_picture->screen_aspect_ratio.numerator,
@@ -321,11 +352,16 @@ DCP::DCP (string directory)
                                           )
                                   ));
 
+       n = cpl_assets->main_sound->annotation_text;
+       if (n.empty ()) {
+               n = pkl->asset_from_id(cpl_assets->main_sound->id)->original_file_name;
+       }
+       
        if (cpl_assets->main_sound) {
                _assets.push_back (shared_ptr<SoundAsset> (
                                           new SoundAsset (
                                                   _directory,
-                                                  cpl_assets->main_sound->annotation_text,
+                                                  n,
                                                   _fps,
                                                   _length
                                                   )
index 4e1801f9d2de22029e44972685cc5cea395ed501..18170f46e38efdf7dd81cb23c5f1bfe7086bd193 100644 (file)
@@ -87,6 +87,14 @@ public:
        std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityOptions opt) const;
 
        boost::shared_ptr<const PictureFrame> get_frame (int n) const;
+
+       int width () const {
+               return _width;
+       }
+
+       int height () const {
+               return _height;
+       }
        
 private:
        std::string path_from_list (int f, std::vector<std::string> const & files) const;
index 23a4f533d0b4d5bea115d7e6ee74ca4660ad5ab6..0ede1d57e08eafd3c6a46cfb4b8539744f6d57f3 100644 (file)
@@ -1,6 +1,8 @@
+#include <iostream>
 #include "pkl.h"
 
 using namespace std;
+using namespace boost;
 using namespace libdcp;
 
 PKL::PKL (string file)
@@ -22,5 +24,18 @@ PKLAsset::PKLAsset (xmlpp::Node const * node)
        hash = string_node ("Hash");
        size = int64_node ("Size");
        type = string_node ("Type");
+       original_file_name = optional_string_node ("OriginalFileName");
 }
        
+shared_ptr<PKLAsset>
+PKL::asset_from_id (string id) const
+{
+       for (list<shared_ptr<PKLAsset> >::const_iterator i = assets.begin (); i != assets.end(); ++i) {
+               if ((*i)->id == id) {
+                       return *i;
+               }
+       }
+
+       return shared_ptr<PKLAsset> ();
+}
+
index 56cda9664f01fc5d4f086713f765a29de08ca5d3..8c64f43bb55a39d42739b5dc7347fd6c1296eea2 100644 (file)
--- a/src/pkl.h
+++ b/src/pkl.h
@@ -14,6 +14,7 @@ public:
        std::string hash;
        int64_t size;
        std::string type;
+       std::string original_file_name;
 };
 
 class PKL : public XMLFile
@@ -21,6 +22,8 @@ class PKL : public XMLFile
 public:
        PKL (std::string file);
 
+       boost::shared_ptr<PKLAsset> asset_from_id (std::string id) const;
+
        std::string id;
        std::string annotation_text;
        std::string issue_date;
index 4ab6a2e7bcd5460009447ff83b5b31ed76b2422a..72dfe1bbcf0472acb3687730708965be89767e2a 100644 (file)
@@ -107,6 +107,27 @@ XMLNode::int64_node (string name)
        return lexical_cast<int64_t> (string_node (name));
 }
 
+int64_t
+XMLNode::optional_int64_node (string name)
+{
+       list<xmlpp::Node*> nodes = xml_nodes (name);
+       if (nodes.size() > 2) {
+               throw XMLError ("duplicate XML tag " + name);
+       }
+
+       if (nodes.empty ()) {
+               return 0;
+       }
+
+       return int64_node (name);
+}
+
+float
+XMLNode::float_node (string name)
+{
+       return lexical_cast<float> (string_node (name));
+}
+
 void
 XMLNode::ignore_node (string name)
 {
index 2469981c877d1d48b34fcacc4c6dddcc155c194d..e5667b8f10a16db269e128dabe75a763f304ab91 100644 (file)
--- a/src/xml.h
+++ b/src/xml.h
@@ -28,6 +28,8 @@ protected:
        ContentKind kind_node (std::string);
        Fraction fraction_node (std::string);
        int64_t int64_node (std::string);
+       int64_t optional_int64_node (std::string);
+       float float_node (std::string);
        void ignore_node (std::string);
        void done ();