summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-08-30 17:27:22 +0100
committerCarl Hetherington <cth@carlh.net>2013-08-30 17:27:22 +0100
commitff38c8737a36e5aced5f2dede5bccd2832fc446a (patch)
tree652a0548b76cfff2f4e7438c477cd4ac18f7a089
parentd0e025d26cab0eecfea1528343638dac69f363cd (diff)
Partial.rework-again
-rw-r--r--src/asset.cc13
-rw-r--r--src/asset_instance.cc114
-rw-r--r--src/asset_instance.h55
-rw-r--r--src/asset_list.cc87
-rw-r--r--src/asset_list.h48
-rw-r--r--src/cpl.cc206
-rw-r--r--src/cpl.h18
-rw-r--r--src/dcp.cc58
-rw-r--r--src/dcp.h33
-rw-r--r--src/picture_asset_instance.cc43
-rw-r--r--src/picture_asset_instance.h30
-rw-r--r--src/reel.cc50
-rw-r--r--src/reel.h6
-rw-r--r--src/wscript3
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;
+};
+
+}
diff --git a/src/cpl.cc b/src/cpl.cc
index f1c224b3..79d3b29c 100644
--- a/src/cpl.cc
+++ b/src/cpl.cc
@@ -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> ());
-}
diff --git a/src/cpl.h b/src/cpl.h
index dfc05c8e..62362c6f 100644
--- a/src/cpl.h
+++ b/src/cpl.h
@@ -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;
diff --git a/src/dcp.cc b/src/dcp.cc
index c16c1333..19bf1401 100644
--- a/src/dcp.cc
+++ b/src/dcp.cc
@@ -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));
-}
diff --git a/src/dcp.h b/src/dcp.h
index 8086f4de..bae8a823 100644
--- a/src/dcp.h
+++ b/src/dcp.h
@@ -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
diff --git a/src/reel.h b/src/reel.h
index a5e79331..1e1278d6 100644
--- a/src/reel.h
+++ b/src/reel.h
@@ -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