From 2cd9086c95686117ffbce92188d50d525ed488bb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 11 Aug 2012 22:06:47 +0100 Subject: Various tweaks for a real-life DCP. --- src/cpl.cc | 23 +++++++++++++++++++---- src/dcp.cc | 46 +++++++++++++++++++++++++++++++++++++++++----- src/picture_asset.h | 8 ++++++++ src/pkl.cc | 15 +++++++++++++++ src/pkl.h | 3 +++ src/xml.cc | 21 +++++++++++++++++++++ src/xml.h | 2 ++ 7 files changed, 109 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/cpl.cc b/src/cpl.cc index b0bf6fcf..a95218d6 100644 --- a/src/cpl.cc +++ b/src/cpl.cc @@ -1,3 +1,4 @@ +#include #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"); + content_version = optional_sub_node ("ContentVersion"); ignore_node ("RatingList"); reels = sub_nodes ("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 (); } diff --git a/src/dcp.cc b/src/dcp.cc index b6014941..99cc517a 100644 --- a/src/dcp.cc +++ b/src/dcp.cc @@ -25,7 +25,9 @@ #include #include #include +#include #include +#include #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 ( 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 ( new SoundAsset ( _directory, - cpl_assets->main_sound->annotation_text, + n, _fps, _length ) diff --git a/src/picture_asset.h b/src/picture_asset.h index 4e1801f9..18170f46 100644 --- a/src/picture_asset.h +++ b/src/picture_asset.h @@ -87,6 +87,14 @@ public: std::list equals (boost::shared_ptr other, EqualityOptions opt) const; boost::shared_ptr 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 const & files) const; diff --git a/src/pkl.cc b/src/pkl.cc index 23a4f533..0ede1d57 100644 --- a/src/pkl.cc +++ b/src/pkl.cc @@ -1,6 +1,8 @@ +#include #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 +PKL::asset_from_id (string id) const +{ + for (list >::const_iterator i = assets.begin (); i != assets.end(); ++i) { + if ((*i)->id == id) { + return *i; + } + } + + return shared_ptr (); +} + diff --git a/src/pkl.h b/src/pkl.h index 56cda966..8c64f43b 100644 --- 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 asset_from_id (std::string id) const; + std::string id; std::string annotation_text; std::string issue_date; diff --git a/src/xml.cc b/src/xml.cc index 4ab6a2e7..72dfe1bb 100644 --- a/src/xml.cc +++ b/src/xml.cc @@ -107,6 +107,27 @@ XMLNode::int64_node (string name) return lexical_cast (string_node (name)); } +int64_t +XMLNode::optional_int64_node (string name) +{ + list 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 (string_node (name)); +} + void XMLNode::ignore_node (string name) { diff --git a/src/xml.h b/src/xml.h index 2469981c..e5667b8f 100644 --- 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 (); -- cgit v1.2.3