diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-08-30 17:27:22 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-08-30 17:27:22 +0100 |
| commit | ff38c8737a36e5aced5f2dede5bccd2832fc446a (patch) | |
| tree | 652a0548b76cfff2f4e7438c477cd4ac18f7a089 | |
| parent | d0e025d26cab0eecfea1528343638dac69f363cd (diff) | |
Partial.rework-again
| -rw-r--r-- | src/asset.cc | 13 | ||||
| -rw-r--r-- | src/asset_instance.cc | 114 | ||||
| -rw-r--r-- | src/asset_instance.h | 55 | ||||
| -rw-r--r-- | src/asset_list.cc | 87 | ||||
| -rw-r--r-- | src/asset_list.h | 48 | ||||
| -rw-r--r-- | src/cpl.cc | 206 | ||||
| -rw-r--r-- | src/cpl.h | 18 | ||||
| -rw-r--r-- | src/dcp.cc | 58 | ||||
| -rw-r--r-- | src/dcp.h | 33 | ||||
| -rw-r--r-- | src/picture_asset_instance.cc | 43 | ||||
| -rw-r--r-- | src/picture_asset_instance.h | 30 | ||||
| -rw-r--r-- | src/reel.cc | 50 | ||||
| -rw-r--r-- | src/reel.h | 6 | ||||
| -rw-r--r-- | src/wscript | 3 |
14 files changed, 447 insertions, 317 deletions
diff --git a/src/asset.cc b/src/asset.cc index 06b87953..3b81fe0a 100644 --- a/src/asset.cc +++ b/src/asset.cc @@ -107,18 +107,5 @@ Asset::compute_digest (boost::function<void (float)> progress) bool Asset::equals (shared_ptr<const Asset> other, EqualityOptions, boost::function<void (NoteType, string)> note) const { - if (_edit_rate != other->_edit_rate) { - note (ERROR, "asset edit rates differ"); - return false; - } - - if (_intrinsic_duration != other->_intrinsic_duration) { - note (ERROR, "asset intrinsic durations differ"); - } - - if (_duration != other->_duration) { - note (ERROR, "asset durations differ"); - } - return true; } diff --git a/src/asset_instance.cc b/src/asset_instance.cc new file mode 100644 index 00000000..6892ea8f --- /dev/null +++ b/src/asset_instance.cc @@ -0,0 +1,114 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <libcxml/cxml.h> +#include "asset_instance.h" + +using std::string; +using boost::shared_ptr; +using namespace libdcp; + +AssetInstance::AssetInstance (shared_ptr<cxml::Node> node) +{ + id = node->string_child ("Id"); + annotation_text = node->optional_string_child ("AnnotationText").get_value_or (""); + edit_rate = Fraction (node->string_child ("EditRate")); + intrinsic_duration = node->number_child<int64_t> ("IntrinsicDuration"); + entry_point = node->number_child<int64_t> ("EntryPoint"); + duration = node->number_child<int64_t> ("Duration"); + frame_rate = Fraction (node->string_child ("FrameRate")); + key_id = node->optional_string_child ("KeyId").get_value_or (""); + + node->ignore_child ("Hash"); + node->ignore_child ("ScreenAspectRatio"); + node->ignore_child ("Language"); + + node->done (); +} + +void +AssetInstance::write_to_cpl (xmlpp::Element* node, bool interop) const +{ + pair<string, string> const attr = cpl_node_attribute (interop); + xmlpp::Element* a = node->add_child (cpl_node_name ()); + if (!attr.first.empty ()) { + a->set_attribute (attr.first, attr.second); + } + a->add_child ("Id")->add_child_text ("urn:uuid:" + _uuid); + a->add_child ("AnnotationText")->add_child_text (_file_name); + a->add_child ("EditRate")->add_child_text (lexical_cast<string> (_edit_rate) + " 1"); + a->add_child ("IntrinsicDuration")->add_child_text (lexical_cast<string> (_intrinsic_duration)); + a->add_child ("EntryPoint")->add_child_text (lexical_cast<string> (_entry_point)); + a->add_child ("Duration")->add_child_text (lexical_cast<string> (_duration)); + if (_encrypted) { + a->add_child("KeyId")->add_child_text ("urn:uuid:" + _key_id); + } +} + +bool +AssetInstance::equals (shared_ptr<const AssetInstance> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const +{ + if (id != other->id) { + note (ERROR, "ids differ"); + return false; + } + + /* XXX: to do */ + std::string annotation_text; + + if (edit_rate != other->edit_rate) { + note (ERROR, "asset edit rates differ"); + return false; + } + + if (intrinsic_duration != other->intrinsic_duration) { + note (ERROR, "asset intrinsic durations differ"); + } + + if (duration != other->duration) { + note (ERROR, "asset durations differ"); + } + + Fraction edit_rate; + /** Duration of the whole thing */ + int64_t intrinsic_duration; + /** Start point in frames */ + int64_t entry_point; + /** Duration that will actually play */ + int64_t duration; + Fraction frame_rate; + std::string key_id; + + + shared_ptr<const MXFAsset> other_mxf = dynamic_pointer_cast<const MXFAsset> (other); + if (!other_mxf) { + note (ERROR, "comparing an MXF asset with a non-MXF asset"); + return false; + } + + if (_file_name != other_mxf->_file_name) { + note (ERROR, "MXF names differ"); + if (!opt.mxf_names_can_differ) { + return false; + } + } + + return true; + +} diff --git a/src/asset_instance.h b/src/asset_instance.h new file mode 100644 index 00000000..6bfdc4c7 --- /dev/null +++ b/src/asset_instance.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "types.h" + +namespace cxml { + class Node; +} + +namespace libdcp { + +class AssetInstance +{ +public: + AssetInstance () + : intrinsic_duration (0) + , entry_point (0) + , duration (0) + {} + + AssetInstance (boost::shared_ptr<cxml::Node>); + + virtual void write_to_cpl (xmlpp::Element* node, bool interop); + virtual bool equals (boost::shared_ptr<const AssetInstance> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const; + + std::string id; + std::string annotation_text; + Fraction edit_rate; + /** Duration of the whole thing */ + int64_t intrinsic_duration; + /** Start point in frames */ + int64_t entry_point; + /** Duration that will actually play */ + int64_t duration; + Fraction frame_rate; + std::string key_id; +}; + +} diff --git a/src/asset_list.cc b/src/asset_list.cc new file mode 100644 index 00000000..536c9f05 --- /dev/null +++ b/src/asset_list.cc @@ -0,0 +1,87 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "asset_list.h" +#include "asset_instance.h" +#include "xml.h" + +using std::string; +using boost::shared_ptr; +using namespace libdcp; + +AssetList::AssetList (shared_ptr<const cxml::Node> node) +{ + main_picture = optional_type_child<AssetInstance> (node, "MainPicture"); + main_stereoscopic_picture = optional_type_child<AssetInstance> (node, "MainStereoscopicPicture"); + main_sound = optional_type_child<AssetInstance> (node, "MainSound"); + main_subtitle = optional_type_child<AssetInstance> (node, "MainSubtitle"); + + node->done (); +} + +void +AssetList::write_to_cpl (xmlpp::Element* node, bool interop) const +{ + xmlpp::Element* asset_list = node->add_child ("AssetList"); + + if (main_picture) { + main_picture->write_to_cpl (asset_list, interop); + } + + if (main_sound) { + main_sound->write_to_cpl (asset_list, interop); + } + + if (main_subtitle) { + main_subtitle->write_to_cpl (asset_list, interop); + } +} + +bool +AssetList::equals (shared_ptr<const AssetList> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const +{ + if ((main_picture && !other->main_picture) || (!main_picture && other->main_picture)) { + note (ERROR, "reel has different assets"); + return false; + } + + if (main_picture && !main_picture->equals (other->main_picture, opt, note)) { + return false; + } + + if ((main_sound && !other->main_sound) || (!main_sound && other->main_sound)) { + note (ERROR, "reel has different assets"); + return false; + } + + if (main_sound && !main_sound->equals (other->main_sound, opt, note)) { + return false; + } + + if ((main_subtitle && !other->main_subtitle) || (!main_subtitle && other->main_subtitle)) { + note (ERROR, "reel has different assets"); + return false; + } + + if (main_subtitle && !main_subtitle->equals (other->main_subtitle, opt, note)) { + return false; + } + + return true; +} diff --git a/src/asset_list.h b/src/asset_list.h new file mode 100644 index 00000000..4a4a2799 --- /dev/null +++ b/src/asset_list.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <boost/shared_ptr.hpp> +#include <boost/function.hpp> +#include <libxml++/libxml++.h> +#include "types.h" + +namespace cxml { + class Node; +} + +namespace libdcp { + +class AssetInstance; + +class AssetList +{ +public: + AssetList () {} + AssetList (boost::shared_ptr<const cxml::Node> node); + + void write_to_cpl (xmlpp::Element *, bool) const; + bool equals (boost::shared_ptr<const AssetList>, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const; + + boost::shared_ptr<AssetInstance> main_picture; + boost::shared_ptr<AssetInstance> main_stereoscopic_picture; + boost::shared_ptr<AssetInstance> main_sound; + boost::shared_ptr<AssetInstance> main_subtitle; +}; + +} @@ -31,6 +31,7 @@ #include "encryption.h" #include "exceptions.h" #include "compose.hpp" +#include "xml.h" using std::string; using std::stringstream; @@ -54,147 +55,29 @@ CPL::CPL (string annotation_text_, string content_title_text_, ContentKind conte /** Construct a CPL object from a XML file. * @param file The CPL XML filename. - * @param asset_maps AssetMaps to look for assets in. - * @param require_mxfs true to throw an exception if a required MXF file does not exist. */ -CPL::CPL (boost::filesystem::path file, list<PathAssetMap> asset_maps, bool require_mxfs) +CPL::CPL (boost::filesystem::path file) : content_kind (FEATURE) { - /* Read the XML */ - shared_ptr<parse::CPL> cpl; - try { - cpl.reset (new parse::CPL (file.string ())); - } catch (FileError& e) { - boost::throw_exception (FileError ("could not load CPL file", file.string ())); - } - - /* Now cherry-pick the required bits into our own data structure */ + cxml::Document xml ("CompositionPlaylist"); + xml.read_file (file); - annotation_text = cpl->annotation_text; - content_title_text = cpl->content_title_text; - content_kind = cpl->content_kind; - /* Trim urn:uuid: off the front */ - _id = cpl->id.substr (9); - - for (list<shared_ptr<parse::Reel> >::iterator i = cpl->reels.begin(); i != cpl->reels.end(); ++i) { - - shared_ptr<parse::Picture> p; - - if ((*i)->asset_list->main_picture) { - p = (*i)->asset_list->main_picture; - } else { - p = (*i)->asset_list->main_stereoscopic_picture; - } - - shared_ptr<PictureAsset> picture; - shared_ptr<SoundAsset> sound; - shared_ptr<SubtitleAsset> subtitle; - - /* Some rather twisted logic to decide if we are 3D or not; - some DCPs give a MainStereoscopicPicture to indicate 3D, others - just have a FrameRate twice the EditRate and apparently - expect you to divine the fact that they are hence 3D. - */ - - if (!(*i)->asset_list->main_stereoscopic_picture && p->edit_rate == p->frame_rate) { - - pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, p->id); - - try { - picture.reset (new MonoPictureAsset ( - asset.first, - asset.second->chunks.front()->path - ) - ); - - picture->set_entry_point (p->entry_point); - picture->set_duration (p->duration); - if (p->key_id.length() > 9) { - /* Trim urn:uuid: */ - picture->set_key_id (p->key_id.substr (9)); - } - } catch (MXFFileError) { - if (require_mxfs) { - throw; - } - } - - } else { - try { - pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, p->id); - - picture.reset (new StereoPictureAsset ( - asset.first, - asset.second->chunks.front()->path, - p->edit_rate.numerator, - p->duration - ) - ); - - picture->set_entry_point (p->entry_point); - picture->set_duration (p->duration); - if (p->key_id.length() > 9) { - /* Trim urn:uuid: */ - picture->set_key_id (p->key_id.substr (9)); - } - - } catch (MXFFileError) { - if (require_mxfs) { - throw; - } - } - - } - - if ((*i)->asset_list->main_sound) { - - try { - pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, (*i)->asset_list->main_sound->id); - - sound.reset (new SoundAsset ( - asset.first, - asset.second->chunks.front()->path - ) - ); - - shared_ptr<parse::MainSound> s = (*i)->asset_list->main_sound; - - sound->set_entry_point (s->entry_point); - sound->set_duration (s->duration); - if (s->key_id.length() > 9) { - /* Trim urn:uuid: */ - sound->set_key_id (s->key_id.substr (9)); - } - } catch (MXFFileError) { - if (require_mxfs) { - throw; - } - } - } - - if ((*i)->asset_list->main_subtitle) { - - pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, (*i)->asset_list->main_subtitle->id); - - subtitle.reset (new SubtitleAsset ( - asset.first, - asset.second->chunks.front()->path - ) - ); - - subtitle->set_entry_point ((*i)->asset_list->main_subtitle->entry_point); - subtitle->set_duration ((*i)->asset_list->main_subtitle->duration); - } - - _reels.push_back (shared_ptr<Reel> (new Reel (picture, sound, subtitle))); - } -} - -void -CPL::add_reel (shared_ptr<Reel> reel) -{ - _reels.push_back (reel); + _id = xml.string_child("Id").substr (9); + annotation_text = xml.optional_string_child ("AnnotationText").get_value_or (""); + issue_date = xml.string_child ("IssueDate"); + creator = xml.optional_string_child ("Creator").get_value_or (""); + content_title_text = xml.string_child ("ContentTitleText"); + content_kind = content_kind_from_string (xml.string_child ("ContentKind")); + xml.ignore_child ("RatingList"); + reels = type_grand_children<Reel> (xml, "ReelList", "Reel"); + + xml.ignore_child ("ContentVersion"); + xml.ignore_child ("Issuer"); + xml.ignore_child ("Signer"); + xml.ignore_child ("Signature"); + + xml.done (); } void @@ -234,7 +117,7 @@ CPL::write_xml (boost::filesystem::path directory, bool interop, XMLMetadata con xmlpp::Element* reel_list = root->add_child ("ReelList"); - for (list<shared_ptr<Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) { + for (list<shared_ptr<Reel> >::const_iterator i = reels.begin(); i != reels.end(); ++i) { (*i)->write_to_cpl (reel_list, interop); } @@ -258,25 +141,6 @@ CPL::write_to_pkl (xmlpp::Node* node) const asset->add_child("Type")->add_child_text ("text/xml"); } -list<shared_ptr<const Asset> > -CPL::assets () const -{ - list<shared_ptr<const Asset> > a; - for (list<shared_ptr<Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) { - if ((*i)->main_picture ()) { - a.push_back ((*i)->main_picture ()); - } - if ((*i)->main_sound ()) { - a.push_back ((*i)->main_sound ()); - } - if ((*i)->main_subtitle ()) { - a.push_back ((*i)->main_subtitle ()); - } - } - - return a; -} - void CPL::write_to_assetmap (xmlpp::Node* node) const { @@ -314,15 +178,15 @@ CPL::equals (CPL const & other, EqualityOptions opt, boost::function<void (NoteT return false; } - if (_reels.size() != other._reels.size()) { - note (ERROR, String::compose ("reel counts differ (%1 vs %2)", _reels.size(), other._reels.size())); + if (reels.size() != other.reels.size()) { + note (ERROR, String::compose ("reel counts differ (%1 vs %2)", reels.size(), other.reels.size())); return false; } - list<shared_ptr<Reel> >::const_iterator a = _reels.begin (); - list<shared_ptr<Reel> >::const_iterator b = other._reels.begin (); + list<shared_ptr<Reel> >::const_iterator a = reels.begin (); + list<shared_ptr<Reel> >::const_iterator b = other.reels.begin (); - while (a != _reels.end ()) { + while (a != reels.end ()) { if (!(*a)->equals (*b, opt, note)) { return false; } @@ -402,6 +266,8 @@ CPL::make_kdm ( } } + #if 0 + XXX { xmlpp::Element* key_id_list = kdm_required_extensions->add_child("KeyIdList"); list<shared_ptr<const Asset> > a = assets(); @@ -413,6 +279,7 @@ CPL::make_kdm ( } } } + #endif { xmlpp::Element* forensic_mark_flag_list = kdm_required_extensions->add_child("ForensicMarkFlagList"); @@ -492,7 +359,7 @@ CPL::make_kdm ( bool CPL::encrypted () const { - for (list<shared_ptr<Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) { + for (list<shared_ptr<Reel> >::const_iterator i = reels.begin(); i != reels.end(); ++i) { if ((*i)->encrypted ()) { return true; } @@ -504,20 +371,7 @@ CPL::encrypted () const void CPL::add_kdm (KDM const & kdm) { - for (list<shared_ptr<Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) { + for (list<shared_ptr<Reel> >::const_iterator i = reels.begin(); i != reels.end(); ++i) { (*i)->add_kdm (kdm); } } - -pair<string, shared_ptr<const parse::AssetMapAsset> > -CPL::asset_from_id (list<PathAssetMap> asset_maps, string id) const -{ - for (list<PathAssetMap>::const_iterator i = asset_maps.begin(); i != asset_maps.end(); ++i) { - shared_ptr<parse::AssetMapAsset> a = i->second->asset_from_id (id); - if (a) { - return make_pair (i->first, a); - } - } - - return make_pair ("", shared_ptr<const parse::AssetMapAsset> ()); -} @@ -49,15 +49,7 @@ class CPL { public: CPL (std::string annotation_text, std::string content_title_text, ContentKind content_kind); - CPL (boost::filesystem::path file, std::list<PathAssetMap> asset_maps, bool require_mxfs = true); - - void add_reel (boost::shared_ptr<Reel> reel); - - std::list<boost::shared_ptr<Reel> > reels () const { - return _reels; - } - - std::list<boost::shared_ptr<const Asset> > assets () const; + CPL (boost::filesystem::path file); bool encrypted () const; @@ -87,16 +79,14 @@ public: /* Properties */ std::string annotation_text; + std::string issue_date; + std::string creator; std::string content_title_text; /** The type of the content, used by media servers to categorise things (e.g. feature, trailer, etc.) */ ContentKind content_kind; + std::list<boost::shared_ptr<Reel> > reels; private: - std::pair<std::string, boost::shared_ptr<const parse::AssetMapAsset> > asset_from_id (std::list<PathAssetMap>, std::string id) const; - - /** reels */ - std::list<boost::shared_ptr<Reel> > _reels; - /** our UUID */ std::string _id; @@ -69,7 +69,7 @@ DCP::DCP (string directory) void DCP::write_xml (bool interop, XMLMetadata const & metadata, shared_ptr<Encryption> crypt) const { - for (list<shared_ptr<CPL> >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + for (list<shared_ptr<CPL> >::const_iterator i = cpls.begin(); i != cpls.end(); ++i) { (*i)->write_xml (_directory, interop, metadata, crypt); } @@ -83,7 +83,7 @@ DCP::write_xml (bool interop, XMLMetadata const & metadata, shared_ptr<Encryptio std::string DCP::write_pkl (string pkl_uuid, bool interop, XMLMetadata const & metadata, shared_ptr<Encryption> crypt) const { - assert (!_cpls.empty ()); + assert (!cpls.empty ()); boost::filesystem::path p; p /= _directory; @@ -105,18 +105,17 @@ DCP::write_pkl (string pkl_uuid, bool interop, XMLMetadata const & metadata, sha pkl->add_child("Id")->add_child_text ("urn:uuid:" + pkl_uuid); /* XXX: this is a bit of a hack */ - pkl->add_child("AnnotationText")->add_child_text(_cpls.front()->annotation_text); + pkl->add_child("AnnotationText")->add_child_text(cpls.front()->annotation_text); pkl->add_child("IssueDate")->add_child_text (metadata.issue_date); pkl->add_child("Issuer")->add_child_text (metadata.issuer); pkl->add_child("Creator")->add_child_text (metadata.creator); xmlpp::Element* asset_list = pkl->add_child("AssetList"); - list<shared_ptr<const Asset> > a = assets (); - for (list<shared_ptr<const Asset> >::const_iterator i = a.begin(); i != a.end(); ++i) { + for (list<shared_ptr<const Asset> >::const_iterator i = assets.begin(); i != assets.end(); ++i) { (*i)->write_to_pkl (asset_list); } - for (list<shared_ptr<CPL> >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + for (list<shared_ptr<CPL> >::const_iterator i = cpls.begin(); i != cpls.end(); ++i) { (*i)->write_to_pkl (asset_list); } @@ -182,12 +181,11 @@ DCP::write_assetmap (string pkl_uuid, int pkl_length, bool interop, XMLMetadata chunk->add_child("Offset")->add_child_text ("0"); chunk->add_child("Length")->add_child_text (lexical_cast<string> (pkl_length)); - for (list<shared_ptr<CPL> >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + for (list<shared_ptr<CPL> >::const_iterator i = cpls.begin(); i != cpls.end(); ++i) { (*i)->write_to_assetmap (asset_list); } - list<shared_ptr<const Asset> > a = assets (); - for (list<shared_ptr<const Asset> >::const_iterator i = a.begin(); i != a.end(); ++i) { + for (list<shared_ptr<const Asset> >::const_iterator i = assets.begin(); i != assets.end(); ++i) { (*i)->write_to_assetmap (asset_list); } @@ -272,28 +270,26 @@ DCP::read (bool require_mxfs) /* Cross-check */ /* XXX */ - _asset_maps.push_back (make_pair (boost::filesystem::absolute (_directory).string(), asset_map)); - for (list<string>::iterator i = files.cpls.begin(); i != files.cpls.end(); ++i) { boost::filesystem::path p; p /= _directory; p /= *i; - _cpls.push_back (shared_ptr<CPL> (new CPL (p, _asset_maps, require_mxfs))); + cpls.push_back (shared_ptr<CPL> (new CPL (p))); } } bool DCP::equals (DCP const & other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const { - if (_cpls.size() != other._cpls.size()) { + if (cpls.size() != other.cpls.size()) { note (ERROR, "CPL counts differ"); return false; } - list<shared_ptr<CPL> >::const_iterator a = _cpls.begin (); - list<shared_ptr<CPL> >::const_iterator b = other._cpls.begin (); + list<shared_ptr<CPL> >::const_iterator a = cpls.begin (); + list<shared_ptr<CPL> >::const_iterator b = other.cpls.begin (); - while (a != _cpls.end ()) { + while (a != cpls.end ()) { if (!(*a)->equals (*b->get(), opt, note)) { return false; } @@ -304,12 +300,6 @@ DCP::equals (DCP const & other, EqualityOptions opt, boost::function<void (NoteT return true; } -void -DCP::add_cpl (shared_ptr<CPL> cpl) -{ - _cpls.push_back (cpl); -} - class AssetComparator { public: @@ -318,24 +308,10 @@ public: } }; -list<shared_ptr<const Asset> > -DCP::assets () const -{ - list<shared_ptr<const Asset> > a; - for (list<shared_ptr<CPL> >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { - list<shared_ptr<const Asset> > t = (*i)->assets (); - a.merge (t); - } - - a.sort (AssetComparator ()); - a.unique (); - return a; -} - bool DCP::encrypted () const { - for (list<shared_ptr<CPL> >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + for (list<shared_ptr<CPL> >::const_iterator i = cpls.begin(); i != cpls.end(); ++i) { if ((*i)->encrypted ()) { return true; } @@ -349,7 +325,7 @@ DCP::add_kdm (KDM const & kdm) { list<KDMCipher> ciphers = kdm.ciphers (); - for (list<shared_ptr<CPL> >::iterator i = _cpls.begin(); i != _cpls.end(); ++i) { + for (list<shared_ptr<CPL> >::iterator i = cpls.begin(); i != cpls.end(); ++i) { for (list<KDMCipher>::iterator j = ciphers.begin(); j != ciphers.end(); ++j) { if (j->cpl_id() == (*i)->id()) { (*i)->add_kdm (kdm); @@ -357,9 +333,3 @@ DCP::add_kdm (KDM const & kdm) } } } - -void -DCP::add_assets_from (DCP const & ov) -{ - copy (ov._asset_maps.begin(), ov._asset_maps.end(), back_inserter (_asset_maps)); -} @@ -91,26 +91,6 @@ public: */ bool equals (DCP const & other, EqualityOptions options, boost::function<void (NoteType, std::string)> note) const; - /** Add a CPL to this DCP. - * @param cpl CPL to add. - */ - void add_cpl (boost::shared_ptr<CPL> cpl); - - /** @return The list of CPLs in this DCP */ - std::list<boost::shared_ptr<CPL> > cpls () const { - return _cpls; - } - - /** Add another DCP as a source of assets for this DCP. This should be called before - * ::read() on the DCP that needs the extra assets. For example - * - * DCP original_version ("my_dcp_OV"); - * DCP supplemental ("my_dcp_VF"); - * supplemental.add_assets_from (original_version); - * supplemental.read (); - */ - void add_assets_from (libdcp::DCP const &); - bool encrypted () const; void add_kdm (KDM const &); @@ -120,6 +100,10 @@ public: */ boost::signals2::signal<void (float)> Progress; + std::list<boost::shared_ptr<CPL> > cpls; + /** Assets that are written to this DCP (and not just referenced) */ + std::list<boost::shared_ptr<const Asset> > assets; + private: /** Write the PKL file. @@ -136,9 +120,6 @@ private: */ void write_assetmap (std::string pkl_uuid, int pkl_length, bool, XMLMetadata const &) const; - /** @return Assets in all the CPLs in this DCP */ - std::list<boost::shared_ptr<const Asset> > assets () const; - struct Files { std::list<std::string> cpls; std::string pkl; @@ -147,12 +128,8 @@ private: /** the directory that we are writing to */ std::string _directory; - /** our CPLs */ - std::list<boost::shared_ptr<CPL> > _cpls; - - std::list<PathAssetMap> _asset_maps; }; - + } #endif diff --git a/src/picture_asset_instance.cc b/src/picture_asset_instance.cc new file mode 100644 index 00000000..339944d3 --- /dev/null +++ b/src/picture_asset_instance.cc @@ -0,0 +1,43 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "picture_asset_instance.h" + +using namespace libdcp; + +void +PictureAssetInstance::write_to_cpl (xmlpp::Element* node, bool interop) const +{ + AssetInstance::write_to_cpl (node, interop); + + xmlpp::Node::NodeList c = node->get_children (); + xmlpp::Node::NodeList::iterator i = c.begin(); + while (i != c.end() && (*i)->get_name() != cpl_node_name ()) { + ++i; + } + + assert (i != c.end ()); + + (*i)->add_child ("FrameRate")->add_child_text (lexical_cast<string> (_edit_rate * edit_rate_factor ()) + " 1"); + if (interop) { + (*i)->add_child ("ScreenAspectRatio")->add_child_text (lexical_cast<string> (float (_size.width) / _size.height)); + } else { + (*i)->add_child ("ScreenAspectRatio")->add_child_text (lexical_cast<string> (_size.width) + " " + lexical_cast<string> (_size.height)); + } +} diff --git a/src/picture_asset_instance.h b/src/picture_asset_instance.h new file mode 100644 index 00000000..35127e0b --- /dev/null +++ b/src/picture_asset_instance.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "asset_instance.h" + +namespace libdcp { + +class PictureAssetInstance : public AssetInstance +{ +public: + libdcp::Size size; +}; + +} diff --git a/src/reel.cc b/src/reel.cc index 43c934ea..fc6cbd49 100644 --- a/src/reel.cc +++ b/src/reel.cc @@ -31,57 +31,23 @@ using std::cout; using boost::shared_ptr; using namespace libdcp; +Reel::Reel (shared_ptr<cxml::Node> node) +{ + asset_list = type_child<AssetList> (node, "AssetList"); +} + void Reel::write_to_cpl (xmlpp::Element* node, bool interop) const { xmlpp::Element* reel = node->add_child ("Reel"); reel->add_child("Id")->add_child_text ("urn:uuid:" + make_uuid()); - xmlpp::Element* asset_list = reel->add_child ("AssetList"); - - if (_main_picture) { - _main_picture->write_to_cpl (asset_list, interop); - } - - if (_main_sound) { - _main_sound->write_to_cpl (asset_list, interop); - } - - if (_main_subtitle) { - _main_subtitle->write_to_cpl (asset_list, interop); - } + asset_list->write_to_cpl (reel, interop); } bool -Reel::equals (boost::shared_ptr<const Reel> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const +Reel::equals (shared_ptr<const Reel> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const { - if ((_main_picture && !other->_main_picture) || (!_main_picture && other->_main_picture)) { - note (ERROR, "reel has different assets"); - return false; - } - - if (_main_picture && !_main_picture->equals (other->_main_picture, opt, note)) { - return false; - } - - if ((_main_sound && !other->_main_sound) || (!_main_sound && other->_main_sound)) { - note (ERROR, "reel has different assets"); - return false; - } - - if (_main_sound && !_main_sound->equals (other->_main_sound, opt, note)) { - return false; - } - - if ((_main_subtitle && !other->_main_subtitle) || (!_main_subtitle && other->_main_subtitle)) { - note (ERROR, "reel has different assets"); - return false; - } - - if (_main_subtitle && !_main_subtitle->equals (other->_main_subtitle, opt, note)) { - return false; - } - - return true; + return asset_list->equals (other.asset_list, opt, note); } bool @@ -30,6 +30,10 @@ namespace xmlpp { class Node; } +namespace cxml { + class Node; +} + namespace libdcp { class PictureAsset; @@ -50,6 +54,8 @@ public: , _main_sound (sound) , _main_subtitle (subtitle) {} + + Reel (boost::shared_ptr<cxml::Node>); boost::shared_ptr<const PictureAsset> main_picture () const { return _main_picture; diff --git a/src/wscript b/src/wscript index 98b0169b..7b649442 100644 --- a/src/wscript +++ b/src/wscript @@ -12,6 +12,8 @@ def build(bld): obj.source = """ argb_frame.cc asset.cc + asset_list.cc + asset_instance.cc certificates.cc colour_matrix.cc crypt_chain.cc @@ -25,6 +27,7 @@ def build(bld): mxf_asset.cc picture_asset.cc picture_asset_writer.cc + picture_asset_instance.cc picture_frame.cc rec709_linearised_gamma_lut.cc reel.cc |
