summaryrefslogtreecommitdiff
path: root/src/dc_package.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2016-01-06 08:28:18 +0000
committerCarl Hetherington <cth@carlh.net>2016-01-10 13:09:45 +0000
commit93f29880839dc5589bb35f63260a7152ead7655f (patch)
tree865dd65298dd11d949efed2ac3f58f3564c7cc8f /src/dc_package.cc
parentd7965cce4c5f95da7971bce6f800739a4cd2f17d (diff)
Introduce dc::Package, changing lots of namespaces in the process.
Diffstat (limited to 'src/dc_package.cc')
-rw-r--r--src/dc_package.cc225
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;
+}