diff options
| author | Carl Hetherington <cth@carlh.net> | 2016-01-06 08:28:18 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2016-01-10 13:09:45 +0000 |
| commit | 93f29880839dc5589bb35f63260a7152ead7655f (patch) | |
| tree | 865dd65298dd11d949efed2ac3f58f3564c7cc8f /src/dc_package.cc | |
| parent | d7965cce4c5f95da7971bce6f800739a4cd2f17d (diff) | |
Introduce dc::Package, changing lots of namespaces in the process.
Diffstat (limited to 'src/dc_package.cc')
| -rw-r--r-- | src/dc_package.cc | 225 |
1 files changed, 88 insertions, 137 deletions
diff --git a/src/dc_package.cc b/src/dc_package.cc index a010cff1..e1c69b63 100644 --- a/src/dc_package.cc +++ b/src/dc_package.cc @@ -42,6 +42,7 @@ #include "dcp_assert.h" #include "reel_asset.h" #include "font_asset.h" +#include "package.h" #include <xmlsec/xmldsig.h> #include <xmlsec/app.h> #include <libxml++/libxml++.h> @@ -65,118 +66,22 @@ using boost::algorithm::starts_with; using namespace dcp::dc; Package::Package (boost::filesystem::path directory) - : _directory (directory) + : dcp::Package (directory) { - if (!boost::filesystem::exists (directory)) { - boost::filesystem::create_directories (directory); - } - - _directory = boost::filesystem::canonical (_directory); -} -template<class T> void -survivable_error (bool keep_going, dcp::dc::Package::ReadErrors* errors, T const & e) -{ - if (keep_going) { - if (errors) { - errors->push_back (shared_ptr<T> (new T (e))); - } - } else { - throw e; - } } void Package::read (bool keep_going, ReadErrors* errors) { - /* Read the ASSETMAP */ - - boost::filesystem::path asset_map_file; - if (boost::filesystem::exists (_directory / "ASSETMAP")) { - asset_map_file = _directory / "ASSETMAP"; - } else if (boost::filesystem::exists (_directory / "ASSETMAP.xml")) { - asset_map_file = _directory / "ASSETMAP.xml"; - } else { - boost::throw_exception (DCPReadError (String::compose ("could not find AssetMap file in `%1'", _directory.string()))); - } - - cxml::Document asset_map ("AssetMap"); - asset_map.read_file (asset_map_file); - list<shared_ptr<cxml::Node> > asset_nodes = asset_map.node_child("AssetList")->node_children ("Asset"); - map<string, boost::filesystem::path> 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")); - } - string p = i->node_child("ChunkList")->node_child("Chunk")->string_child ("Path"); - if (starts_with (p, "file://")) { - p = p.substr (7); - } - paths.insert (make_pair (remove_urn_uuid (i->string_child ("Id")), p)); - } - - /* Read all the assets from the asset map */ - /* XXX: I think we should be looking at the PKL here to decide type, not - the extension of the file. - */ - - /* Make a list of non-CPL assets so that we can resolve the references - from the CPLs. - */ - list<shared_ptr<Asset> > other_assets; - - for (map<string, boost::filesystem::path>::const_iterator i = paths.begin(); i != paths.end(); ++i) { - boost::filesystem::path path = _directory / i->second; - - if (!boost::filesystem::exists (path)) { - survivable_error (keep_going, errors, MissingAssetError (path)); - continue; - } - - if (boost::filesystem::extension (path) == ".xml") { - xmlpp::DomParser* p = new xmlpp::DomParser; - try { - p->parse_file (path.string()); - } catch (std::exception& e) { - delete p; - continue; - } - - string const root = p->get_document()->get_root_node()->get_name (); - delete p; - - if (root == "CompositionPlaylist") { - _cpls.push_back (shared_ptr<CPL> (new CPL (path))); - } else if (root == "DCSubtitle") { - other_assets.push_back (shared_ptr<InteropSubtitleAsset> (new InteropSubtitleAsset (path))); - } - } else if (boost::filesystem::extension (path) == ".mxf") { - ASDCP::EssenceType_t type; - if (ASDCP::EssenceType (path.string().c_str(), type) != ASDCP::RESULT_OK) { - throw DCPReadError ("Could not find essence type"); - } - switch (type) { - case ASDCP::ESS_UNKNOWN: - case ASDCP::ESS_MPEG2_VES: - throw DCPReadError ("MPEG2 video essences are not supported"); - case ASDCP::ESS_JPEG_2000: - other_assets.push_back (shared_ptr<MonoPictureAsset> (new MonoPictureAsset (path))); - break; - case ASDCP::ESS_PCM_24b_48k: - case ASDCP::ESS_PCM_24b_96k: - other_assets.push_back (shared_ptr<SoundAsset> (new SoundAsset (path))); - break; - case ASDCP::ESS_JPEG_2000_S: - other_assets.push_back (shared_ptr<StereoPictureAsset> (new StereoPictureAsset (path))); - break; - case ASDCP::ESS_TIMED_TEXT: - other_assets.push_back (shared_ptr<SMPTESubtitleAsset> (new SMPTESubtitleAsset (path))); - break; - default: - throw DCPReadError ("Unknown MXF essence type"); - } - } else if (boost::filesystem::extension (path) == ".ttf") { - other_assets.push_back (shared_ptr<FontAsset> (new FontAsset (i->first, path))); + list<shared_ptr<dcp::Asset> > other_assets; + + BOOST_FOREACH (shared_ptr<dcp::Asset> i, read_assetmap (keep_going, errors)) { + shared_ptr<CPL> cpl = dynamic_pointer_cast<CPL> (i); + if (cpl) { + _cpls.push_back (cpl); + } else { + other_assets.push_back (i); } } @@ -186,7 +91,7 @@ Package::read (bool keep_going, ReadErrors* errors) } void -Package::resolve_refs (list<shared_ptr<Asset> > assets) +Package::resolve_refs (list<shared_ptr<dcp::Asset> > assets) { BOOST_FOREACH (shared_ptr<CPL> i, cpls ()) { i->resolve_refs (assets); @@ -194,7 +99,7 @@ Package::resolve_refs (list<shared_ptr<Asset> > assets) } bool -Package::equals (Package const & other, EqualityOptions opt, NoteHandler note) const +Package::equals (Package const & other, dcp::EqualityOptions opt, dcp::NoteHandler note) const { list<shared_ptr<CPL> > a = cpls (); list<shared_ptr<CPL> > b = other.cpls (); @@ -253,14 +158,14 @@ Package::add (DecryptedKDM const & kdm) } boost::filesystem::path -Package::write_pkl (Standard standard, string pkl_uuid, XMLMetadata metadata, shared_ptr<const CertificateChain> signer) const +Package::write_pkl (dcp::Standard standard, string pkl_uuid, dcp::XMLMetadata metadata, shared_ptr<const CertificateChain> signer) const { boost::filesystem::path p = _directory; p /= String::compose ("pkl_%1.xml", pkl_uuid); xmlpp::Document doc; xmlpp::Element* pkl; - if (standard == INTEROP) { + if (standard == DCP_INTEROP) { pkl = doc.create_root_node("PackingList", "http://www.digicine.com/PROTO-ASDCP-PKL-20040311#"); } else { pkl = doc.create_root_node("PackingList", "http://www.smpte-ra.org/schemas/429-8/2007/PKL"); @@ -281,7 +186,7 @@ Package::write_pkl (Standard standard, string pkl_uuid, XMLMetadata metadata, sh pkl->add_child("Creator")->add_child_text (metadata.creator); xmlpp::Element* asset_list = pkl->add_child("AssetList"); - BOOST_FOREACH (shared_ptr<Asset> i, assets ()) { + BOOST_FOREACH (shared_ptr<dcp::Asset> i, assets ()) { i->write_to_pkl (asset_list, _directory, standard); } @@ -301,28 +206,29 @@ Package::write_volindex (Standard standard) const { boost::filesystem::path p = _directory; switch (standard) { - case INTEROP: + case DCP_INTEROP: p /= "VOLINDEX"; break; - case SMPTE: + case DCP_SMPTE: p /= "VOLINDEX.xml"; break; - default: + case IMP: + /* XXX */ DCP_ASSERT (false); + break; } xmlpp::Document doc; - xmlpp::Element* root; + xmlpp::Element* root = 0; switch (standard) { - case INTEROP: + case DCP_INTEROP: root = doc.create_root_node ("VolumeIndex", "http://www.digicine.com/PROTO-ASDCP-AM-20040311#"); break; - case SMPTE: + case DCP_SMPTE: + case IMP: root = doc.create_root_node ("VolumeIndex", "http://www.smpte-ra.org/schemas/429-9/2007/AM"); break; - default: - DCP_ASSERT (false); } root->add_child("Index")->add_child_text ("1"); @@ -330,53 +236,50 @@ Package::write_volindex (Standard standard) const } void -Package::write_assetmap (Standard standard, string pkl_uuid, int pkl_length, XMLMetadata metadata) const +Package::write_assetmap (Standard standard, string pkl_uuid, int pkl_length, dcp::XMLMetadata metadata) const { boost::filesystem::path p = _directory; switch (standard) { - case INTEROP: + case DCP_INTEROP: p /= "ASSETMAP"; break; - case SMPTE: + case DCP_SMPTE: + case IMP: p /= "ASSETMAP.xml"; break; - default: - DCP_ASSERT (false); } xmlpp::Document doc; - xmlpp::Element* root; + xmlpp::Element* root = 0; switch (standard) { - case INTEROP: + case DCP_INTEROP: root = doc.create_root_node ("AssetMap", "http://www.digicine.com/PROTO-ASDCP-AM-20040311#"); break; - case SMPTE: + case DCP_SMPTE: + case IMP: root = doc.create_root_node ("AssetMap", "http://www.smpte-ra.org/schemas/429-9/2007/AM"); break; - default: - DCP_ASSERT (false); } root->add_child("Id")->add_child_text ("urn:uuid:" + make_uuid()); root->add_child("AnnotationText")->add_child_text ("Created by " + metadata.creator); switch (standard) { - case INTEROP: + case DCP_INTEROP: root->add_child("VolumeCount")->add_child_text ("1"); root->add_child("IssueDate")->add_child_text (metadata.issue_date); root->add_child("Issuer")->add_child_text (metadata.issuer); root->add_child("Creator")->add_child_text (metadata.creator); break; - case SMPTE: + case DCP_SMPTE: + case IMP: root->add_child("Creator")->add_child_text (metadata.creator); root->add_child("VolumeCount")->add_child_text ("1"); root->add_child("IssueDate")->add_child_text (metadata.issue_date); root->add_child("Issuer")->add_child_text (metadata.issuer); break; - default: - DCP_ASSERT (false); } xmlpp::Node* asset_list = root->add_child ("AssetList"); @@ -391,7 +294,7 @@ Package::write_assetmap (Standard standard, string pkl_uuid, int pkl_length, XML chunk->add_child("Offset")->add_child_text ("0"); chunk->add_child("Length")->add_child_text (raw_convert<string> (pkl_length)); - BOOST_FOREACH (shared_ptr<Asset> i, assets ()) { + BOOST_FOREACH (shared_ptr<dcp::Asset> i, assets ()) { i->write_to_assetmap (asset_list, _directory); } @@ -407,7 +310,7 @@ Package::write_assetmap (Standard standard, string pkl_uuid, int pkl_length, XML void Package::write_xml ( Standard standard, - XMLMetadata metadata, + dcp::XMLMetadata metadata, shared_ptr<const CertificateChain> signer ) { @@ -430,14 +333,14 @@ Package::cpls () const } /** @return All assets (including CPLs) */ -list<shared_ptr<Asset> > +list<shared_ptr<dcp::Asset> > Package::assets () const { - list<shared_ptr<Asset> > assets; + list<shared_ptr<dcp::Asset> > assets; BOOST_FOREACH (shared_ptr<CPL> i, cpls ()) { assets.push_back (i); BOOST_FOREACH (shared_ptr<const ReelAsset> j, i->reel_assets ()) { - shared_ptr<Asset> o = j->asset_ref().asset (); + shared_ptr<dcp::Asset> o = j->asset_ref().asset (); assets.push_back (o); /* More Interop special-casing */ shared_ptr<InteropSubtitleAsset> sub = dynamic_pointer_cast<InteropSubtitleAsset> (o); @@ -449,3 +352,51 @@ Package::assets () const return assets; } + +shared_ptr<dcp::Asset> +Package::xml_asset_factory (boost::filesystem::path file, string root) const +{ + shared_ptr<dcp::Asset> asset; + + if (root == "CompositionPlaylist") { + asset.reset (new CPL (file)); + } else if (root == "DCSubtitle") { + asset.reset (new InteropSubtitleAsset (file)); + } + + return asset; +} + +shared_ptr<dcp::Asset> +Package::mxf_asset_factory (boost::filesystem::path file) const +{ + shared_ptr<dcp::Asset> asset; + + ASDCP::EssenceType_t type; + if (ASDCP::EssenceType (file.string().c_str(), type) != ASDCP::RESULT_OK) { + throw PackageReadError ("Could not find essence type"); + } + + switch (type) { + case ASDCP::ESS_UNKNOWN: + case ASDCP::ESS_MPEG2_VES: + throw PackageReadError ("MPEG2 video essences are not supported"); + case ASDCP::ESS_JPEG_2000: + asset.reset (new MonoPictureAsset (file)); + break; + case ASDCP::ESS_PCM_24b_48k: + case ASDCP::ESS_PCM_24b_96k: + asset.reset (new SoundAsset (file)); + break; + case ASDCP::ESS_JPEG_2000_S: + asset.reset (new StereoPictureAsset (file)); + break; + case ASDCP::ESS_TIMED_TEXT: + asset.reset (new SMPTESubtitleAsset (file)); + break; + default: + throw PackageReadError ("Unknown MXF essence type"); + } + + return asset; +} |
