summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2018-09-25 09:41:32 +0100
committerCarl Hetherington <cth@carlh.net>2018-09-25 09:41:32 +0100
commit6ff5bc54fafcb9332609912514c287ac332ab7e5 (patch)
treef1458b2735af96eaa4352601762337c2e1812ef4 /src
parentdf56c3975454d935b8457d8a8bc1615388db305c (diff)
Cope with multiple PKLs in a DCP.
Diffstat (limited to 'src')
-rw-r--r--src/dcp.cc57
-rw-r--r--src/dcp.h10
-rw-r--r--src/pkl.cc9
-rw-r--r--src/pkl.h4
-rw-r--r--src/verify.cc21
5 files changed, 63 insertions, 38 deletions
diff --git a/src/dcp.cc b/src/dcp.cc
index fa8ffabf..08febadc 100644
--- a/src/dcp.cc
+++ b/src/dcp.cc
@@ -134,7 +134,7 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx
list<shared_ptr<cxml::Node> > asset_nodes = asset_map.node_child("AssetList")->node_children ("Asset");
map<string, boost::filesystem::path> paths;
- optional<boost::filesystem::path> pkl_path;
+ list<boost::filesystem::path> pkl_paths;
BOOST_FOREACH (shared_ptr<cxml::Node> i, asset_nodes) {
if (i->node_child("ChunkList")->node_children("Chunk").size() != 1) {
boost::throw_exception (XMLError ("unsupported asset chunk count"));
@@ -146,7 +146,7 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx
switch (*_standard) {
case INTEROP:
if (i->optional_node_child("PackingList")) {
- pkl_path = p;
+ pkl_paths.push_back (p);
} else {
paths.insert (make_pair (remove_urn_uuid (i->string_child ("Id")), p));
}
@@ -155,7 +155,7 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx
{
optional<string> pkl_bool = i->optional_string_child("PackingList");
if (pkl_bool && *pkl_bool == "true") {
- pkl_path = p;
+ pkl_paths.push_back (p);
} else {
paths.insert (make_pair (remove_urn_uuid (i->string_child ("Id")), p));
}
@@ -164,11 +164,13 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx
}
}
- if (!pkl_path) {
- boost::throw_exception (XMLError ("No packing list found in asset map"));
+ if (pkl_paths.empty()) {
+ boost::throw_exception (XMLError ("No packing lists found in asset map"));
}
- _pkl.reset (new PKL (_directory / *pkl_path));
+ BOOST_FOREACH (boost::filesystem::path i, pkl_paths) {
+ _pkls.push_back (shared_ptr<PKL>(new PKL(_directory / i)));
+ }
/* Read all the assets from the asset map */
@@ -185,9 +187,17 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx
continue;
}
- string const pkl_type = _pkl->type(i->first);
+ optional<string> pkl_type;
+ BOOST_FOREACH (shared_ptr<PKL> j, _pkls) {
+ pkl_type = j->type(i->first);
+ if (pkl_type) {
+ break;
+ }
+ }
- if (pkl_type == CPL::static_pkl_type(*_standard) || pkl_type == InteropSubtitleAsset::static_pkl_type(*_standard)) {
+ DCP_ASSERT (pkl_type);
+
+ if (*pkl_type == CPL::static_pkl_type(*_standard) || *pkl_type == InteropSubtitleAsset::static_pkl_type(*_standard)) {
xmlpp::DomParser* p = new xmlpp::DomParser;
try {
p->parse_file (path.string());
@@ -212,10 +222,10 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx
other_assets.push_back (shared_ptr<InteropSubtitleAsset> (new InteropSubtitleAsset (path)));
}
} else if (
- pkl_type == PictureAsset::static_pkl_type(*_standard) ||
- pkl_type == SoundAsset::static_pkl_type(*_standard) ||
- pkl_type == AtmosAsset::static_pkl_type(*_standard) ||
- pkl_type == SMPTESubtitleAsset::static_pkl_type(*_standard)
+ *pkl_type == PictureAsset::static_pkl_type(*_standard) ||
+ *pkl_type == SoundAsset::static_pkl_type(*_standard) ||
+ *pkl_type == AtmosAsset::static_pkl_type(*_standard) ||
+ *pkl_type == SMPTESubtitleAsset::static_pkl_type(*_standard)
) {
/* XXX: asdcplib does not appear to support discovery of read MXFs standard
@@ -258,12 +268,12 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx
default:
throw DCPReadError (String::compose ("Unknown MXF essence type %1 in %2", int(type), path.string()));
}
- } else if (pkl_type == FontAsset::static_pkl_type(*_standard)) {
+ } else if (*pkl_type == FontAsset::static_pkl_type(*_standard)) {
other_assets.push_back (shared_ptr<FontAsset> (new FontAsset (i->first, path)));
- } else if (pkl_type == "image/png") {
+ } else if (*pkl_type == "image/png") {
/* It's an Interop PNG subtitle; let it go */
} else {
- throw DCPReadError (String::compose("Unknown asset type %1 in PKL", pkl_type));
+ throw DCPReadError (String::compose("Unknown asset type %1 in PKL", *pkl_type));
}
}
@@ -468,20 +478,25 @@ DCP::write_xml (
i->write_xml (_directory / (name_format.get(values, "_" + i->id() + ".xml")), standard, signer);
}
- if (!_pkl) {
- _pkl.reset (new PKL (standard, metadata.annotation_text, metadata.issue_date, metadata.issuer, metadata.creator));
+ shared_ptr<PKL> pkl;
+
+ if (_pkls.empty()) {
+ pkl.reset (new PKL (standard, metadata.annotation_text, metadata.issue_date, metadata.issuer, metadata.creator));
+ _pkls.push_back (pkl);
BOOST_FOREACH (shared_ptr<Asset> i, assets ()) {
- i->add_to_pkl (_pkl, _directory);
+ i->add_to_pkl (pkl, _directory);
}
+ } else {
+ pkl = _pkls.front ();
}
NameFormat::Map values;
values['t'] = "pkl";
- boost::filesystem::path pkl_path = _directory / name_format.get(values, "_" + _pkl->id() + ".xml");
- _pkl->write (pkl_path, signer);
+ boost::filesystem::path pkl_path = _directory / name_format.get(values, "_" + pkl->id() + ".xml");
+ pkl->write (pkl_path, signer);
write_volindex (standard);
- write_assetmap (standard, _pkl->id(), pkl_path, metadata);
+ write_assetmap (standard, pkl->id(), pkl_path, metadata);
}
list<shared_ptr<CPL> >
diff --git a/src/dcp.h b/src/dcp.h
index 9c97e6aa..b47daf55 100644
--- a/src/dcp.h
+++ b/src/dcp.h
@@ -129,11 +129,11 @@ public:
return _directory;
}
- /** @return PKL if this DCP was read from an existing one, or if write_xml() has been called on it.
- * If neither is true, this method returns 0.
+ /** @return PKLs if this DCP was read from an existing one, or if write_xml() has been called on it.
+ * If neither is true, this method returns an empty list.
*/
- boost::shared_ptr<PKL> pkl () const {
- return _pkl;
+ std::list<boost::shared_ptr<PKL> > pkls () const {
+ return _pkls;
}
static std::vector<boost::filesystem::path> directories_from_files (std::vector<boost::filesystem::path> files);
@@ -152,7 +152,7 @@ private:
boost::filesystem::path _directory;
/** the CPLs that make up this DCP */
std::list<boost::shared_ptr<CPL> > _cpls;
- boost::shared_ptr<PKL> _pkl;
+ std::list<boost::shared_ptr<PKL> > _pkls;
/** Standard of DCP that was read in */
boost::optional<Standard> _standard;
diff --git a/src/pkl.cc b/src/pkl.cc
index 621cf465..43c7d092 100644
--- a/src/pkl.cc
+++ b/src/pkl.cc
@@ -42,6 +42,7 @@
using std::string;
using boost::shared_ptr;
+using boost::optional;
using namespace dcp;
static string const pkl_interop_ns = "http://www.digicine.com/PROTO-ASDCP-PKL-20040311#";
@@ -115,7 +116,7 @@ PKL::write (boost::filesystem::path file, shared_ptr<const CertificateChain> sig
doc.write_to_file (file.string(), "UTF-8");
}
-string
+optional<string>
PKL::hash (string id) const
{
BOOST_FOREACH (shared_ptr<Asset> i, _asset_list) {
@@ -124,10 +125,10 @@ PKL::hash (string id) const
}
}
- DCP_ASSERT (false);
+ return optional<string>();
}
-string
+optional<string>
PKL::type (string id) const
{
BOOST_FOREACH (shared_ptr<Asset> i, _asset_list) {
@@ -136,5 +137,5 @@ PKL::type (string id) const
}
}
- DCP_ASSERT (false);
+ return optional<string>();
}
diff --git a/src/pkl.h b/src/pkl.h
index aa78ae21..bc71279e 100644
--- a/src/pkl.h
+++ b/src/pkl.h
@@ -60,8 +60,8 @@ public:
return _standard;
}
- std::string hash (std::string id) const;
- std::string type (std::string id) const;
+ boost::optional<std::string> hash (std::string id) const;
+ boost::optional<std::string> type (std::string id) const;
void add_asset (std::string id, boost::optional<std::string> annotation_text, std::string hash, int64_t size, std::string type);
void write (boost::filesystem::path file, boost::shared_ptr<const CertificateChain> signer) const;
diff --git a/src/verify.cc b/src/verify.cc
index db655954..984cdf4a 100644
--- a/src/verify.cc
+++ b/src/verify.cc
@@ -64,19 +64,28 @@ verify_asset (shared_ptr<DCP> dcp, shared_ptr<ReelAsset> reel_asset, function<vo
{
string const actual_hash = reel_asset->asset_ref()->hash(progress);
- shared_ptr<PKL> pkl = dcp->pkl();
- /* We've read this DCP in so it must have a PKL */
- DCP_ASSERT (pkl);
+ list<shared_ptr<PKL> > pkls = dcp->pkls();
+ /* We've read this DCP in so it must have at least one PKL */
+ DCP_ASSERT (!pkls.empty());
shared_ptr<Asset> asset = reel_asset->asset_ref().asset();
- string const pkl_hash = pkl->hash (reel_asset->asset_ref()->id());
+
+ optional<string> pkl_hash;
+ BOOST_FOREACH (shared_ptr<PKL> i, pkls) {
+ pkl_hash = i->hash (reel_asset->asset_ref()->id());
+ if (pkl_hash) {
+ break;
+ }
+ }
+
+ DCP_ASSERT (pkl_hash);
optional<string> cpl_hash = reel_asset->hash();
- if (cpl_hash && *cpl_hash != pkl_hash) {
+ if (cpl_hash && *cpl_hash != *pkl_hash) {
return RESULT_CPL_PKL_DIFFER;
}
- if (actual_hash != pkl_hash) {
+ if (actual_hash != *pkl_hash) {
return RESULT_BAD;
}