diff options
| author | Carl Hetherington <cth@carlh.net> | 2018-09-25 09:41:32 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2018-09-25 09:41:32 +0100 |
| commit | 6ff5bc54fafcb9332609912514c287ac332ab7e5 (patch) | |
| tree | f1458b2735af96eaa4352601762337c2e1812ef4 /src | |
| parent | df56c3975454d935b8457d8a8bc1615388db305c (diff) | |
Cope with multiple PKLs in a DCP.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dcp.cc | 57 | ||||
| -rw-r--r-- | src/dcp.h | 10 | ||||
| -rw-r--r-- | src/pkl.cc | 9 | ||||
| -rw-r--r-- | src/pkl.h | 4 | ||||
| -rw-r--r-- | src/verify.cc | 21 |
5 files changed, 63 insertions, 38 deletions
@@ -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> > @@ -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; @@ -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>(); } @@ -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; } |
