X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fcpl.cc;h=bd29573a03df4bd73efb0470f37f886dda7874bb;hb=1bb067620edd3fb0db37894975f3a19d595697db;hp=30995a6130eee5819aa23ef91e4b142fb6f32e5d;hpb=a353528b070fe264ce60220b4af07d0561494def;p=libdcp.git diff --git a/src/cpl.cc b/src/cpl.cc index 30995a61..bd29573a 100644 --- a/src/cpl.cc +++ b/src/cpl.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington + Copyright (C) 2012-2013 Carl Hetherington 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 @@ -37,8 +37,11 @@ using std::stringstream; using std::ofstream; using std::ostream; using std::list; +using std::pair; +using std::make_pair; using boost::shared_ptr; using boost::lexical_cast; +using boost::optional; using namespace libdcp; CPL::CPL (string directory, string name, ContentKind content_kind, int length, int frames_per_second) @@ -54,10 +57,10 @@ CPL::CPL (string directory, string name, ContentKind content_kind, int length, i /** Construct a CPL object from a XML file. * @param directory The directory containing this CPL's DCP. * @param file The CPL XML filename. - * @param asset_map The corresponding asset map. + * @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 (string directory, string file, shared_ptr asset_map, bool require_mxfs) +CPL::CPL (string directory, string file, list asset_maps, bool require_mxfs) : _directory (directory) , _content_kind (FEATURE) , _length (0) @@ -79,7 +82,7 @@ CPL::CPL (string directory, string file, shared_ptrid.substr (9); - for (list >::iterator i = cpl->reels.begin(); i != cpl->reels.end(); ++i) { + for (list >::iterator i = cpl->reels.begin(); i != cpl->reels.end(); ++i) { shared_ptr p; @@ -104,10 +107,12 @@ CPL::CPL (string directory, string file, shared_ptrasset_list->main_stereoscopic_picture && p->edit_rate == p->frame_rate) { + pair > asset = asset_from_id (asset_maps, p->id); + try { picture.reset (new MonoPictureAsset ( - _directory, - asset_map->asset_from_id (p->id)->chunks.front()->path + asset.first, + asset.second->chunks.front()->path ) ); @@ -125,9 +130,11 @@ CPL::CPL (string directory, string file, shared_ptr > asset = asset_from_id (asset_maps, p->id); + picture.reset (new StereoPictureAsset ( - _directory, - asset_map->asset_from_id (p->id)->chunks.front()->path, + asset.first, + asset.second->chunks.front()->path, _fps, p->duration ) @@ -151,9 +158,11 @@ CPL::CPL (string directory, string file, shared_ptrasset_list->main_sound) { try { + pair > asset = asset_from_id (asset_maps, (*i)->asset_list->main_sound->id); + sound.reset (new SoundAsset ( - _directory, - asset_map->asset_from_id ((*i)->asset_list->main_sound->id)->chunks.front()->path + asset.first, + asset.second->chunks.front()->path ) ); @@ -174,9 +183,11 @@ CPL::CPL (string directory, string file, shared_ptrasset_list->main_subtitle) { + pair > asset = asset_from_id (asset_maps, (*i)->asset_list->main_subtitle->id); + subtitle.reset (new SubtitleAsset ( - _directory, - asset_map->asset_from_id ((*i)->asset_list->main_subtitle->id)->chunks.front()->path + asset.first, + asset.second->chunks.front()->path ) ); @@ -195,7 +206,7 @@ CPL::add_reel (shared_ptr reel) } void -CPL::write_xml (XMLMetadata const & metadata, shared_ptr crypt) const +CPL::write_xml (bool interop, XMLMetadata const & metadata, shared_ptr crypt) const { boost::filesystem::path p; p /= _directory; @@ -204,7 +215,12 @@ CPL::write_xml (XMLMetadata const & metadata, shared_ptr crypt) cons p /= s.str(); xmlpp::Document doc; - xmlpp::Element* root = doc.create_root_node ("CompositionPlaylist", "http://www.smpte-ra.org/schemas/429-7/2006/CPL"); + xmlpp::Element* root; + if (interop) { + root = doc.create_root_node ("CompositionPlaylist", "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#"); + } else { + root = doc.create_root_node ("CompositionPlaylist", "http://www.smpte-ra.org/schemas/429-7/2006/CPL"); + } if (crypt) { root->set_namespace_declaration ("http://www.w3.org/2000/09/xmldsig#", "dsig"); @@ -213,6 +229,7 @@ CPL::write_xml (XMLMetadata const & metadata, shared_ptr crypt) cons root->add_child("Id")->add_child_text ("urn:uuid:" + _id); root->add_child("AnnotationText")->add_child_text (_name); 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); root->add_child("ContentTitleText")->add_child_text (_name); root->add_child("ContentKind")->add_child_text (content_kind_to_string (_content_kind)); @@ -223,19 +240,19 @@ CPL::write_xml (XMLMetadata const & metadata, shared_ptr crypt) cons } root->add_child("RatingList"); - xmlpp::Node* reel_list = root->add_child ("ReelList"); + xmlpp::Element* reel_list = root->add_child ("ReelList"); for (list >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) { - (*i)->write_to_cpl (reel_list); + (*i)->write_to_cpl (reel_list, interop); } if (crypt) { - sign (root, crypt->certificates, crypt->signer_key); + sign (root, crypt->certificates, crypt->signer_key, interop); } doc.write_to_file_formatted (p.string (), "UTF-8"); - _digest = make_digest (p.string ()); + _digest = make_digest (p.string (), 0); _length = boost::filesystem::file_size (p.string ()); } @@ -305,9 +322,7 @@ CPL::equals (CPL const & other, EqualityOptions opt, boost::function recipient_cert, boost::posix_time::ptime from, boost::posix_time::ptime until, + bool interop, MXFMetadata const & mxf_metadata, XMLMetadata const & xml_metadata ) const @@ -354,14 +370,15 @@ CPL::make_kdm ( xmlAddID (0, doc->cobj(), (const xmlChar *) "ID_AuthenticatedPublic", authenticated_public->get_attribute("Id")->cobj()); authenticated_public->add_child("MessageId")->add_child_text ("urn:uuid:" + make_uuid()); + /* XXX: this should probably be different if interop == true */ authenticated_public->add_child("MessageType")->add_child_text ("http://www.smpte-ra.org/430-1/2006/KDM#kdm-key-type"); authenticated_public->add_child("AnnotationText")->add_child_text (mxf_metadata.product_name); authenticated_public->add_child("IssueDate")->add_child_text (xml_metadata.issue_date); { xmlpp::Element* signer = authenticated_public->add_child("Signer"); - signer->add_child("X509IssuerName", "ds")->add_child_text (recipient_cert->issuer()); - signer->add_child("X509SerialNumber", "ds")->add_child_text (recipient_cert->serial()); + signer->add_child("X509IssuerName", "ds")->add_child_text (certificates.leaf()->issuer()); + signer->add_child("X509SerialNumber", "ds")->add_child_text (certificates.leaf()->serial()); } { @@ -451,9 +468,17 @@ CPL::make_kdm ( signed_info->add_child("CanonicalizationMethod", "ds")->set_attribute( "Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" ); - signed_info->add_child("SignatureMethod", "ds")->set_attribute( - "Algorithm", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" - ); + + if (interop) { + signed_info->add_child("SignatureMethod", "ds")->set_attribute( + "Algorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1" + ); + } else { + signed_info->add_child("SignatureMethod", "ds")->set_attribute( + "Algorithm", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" + ); + } + { xmlpp::Element* reference = signed_info->add_child("Reference", "ds"); reference->set_attribute("URI", "#ID_AuthenticatedPublic"); @@ -495,3 +520,16 @@ CPL::add_kdm (KDM const & kdm) (*i)->add_kdm (kdm); } } + +pair > +CPL::asset_from_id (list asset_maps, string id) const +{ + for (list::const_iterator i = asset_maps.begin(); i != asset_maps.end(); ++i) { + shared_ptr a = i->second->asset_from_id (id); + if (a) { + return make_pair (i->first, a); + } + } + + return make_pair ("", shared_ptr ()); +}