/* Now we can create the sound asset using these files */
boost::shared_ptr<libdcp::SoundAsset> sound_asset (
- new libdcp::SoundAsset (sound_files, "My Film DCP", "audio.mxf", 0, 24, 48, false)
- new libdcp::SoundAsset (sound_files, "My Film DCP", "audio.mxf", 0, 24, 48, 0)
++ new libdcp::SoundAsset (sound_files, "My Film DCP", "audio.mxf", 0, 24, 48, 0, false)
);
/* Now that we have the assets, we can create a Reel to put them in and add it to the CPL */
#include <cassert>
#include <iostream>
#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+ #include <boost/algorithm/string.hpp>
#include <libxml++/libxml++.h>
+#include <xmlsec/xmldsig.h>
+#include <xmlsec/app.h>
#include "dcp.h"
#include "asset.h"
#include "sound_asset.h"
stringstream s;
s << _uuid << "_cpl.xml";
p /= s.str();
- ofstream os (p.string().c_str());
-
- os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<CompositionPlaylist xmlns=\"http://www.smpte-ra.org/schemas/429-7/2006/CPL\">\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _name << "</AnnotationText>\n"
- << " <IssueDate>" << Metadata::instance()->issue_date << "</IssueDate>\n"
- << " <Creator>" << Metadata::instance()->creator << "</Creator>\n"
- << " <ContentTitleText>" << _name << "</ContentTitleText>\n"
- << " <ContentKind>" << content_kind_to_string (_content_kind) << "</ContentKind>\n"
- << " <ContentVersion>\n"
- << " <Id>urn:uri:" << _uuid << "_" << Metadata::instance()->issue_date << "</Id>\n"
- << " <LabelText>" << _uuid << "_" << Metadata::instance()->issue_date << "</LabelText>\n"
- << " </ContentVersion>\n"
- << " <RatingList/>\n"
- << " <ReelList>\n";
-
+
+ xmlpp::Document doc;
+ xmlpp::Element* cpl = doc.create_root_node("CompositionPlaylist", "http://www.smpte-ra.org/schemas/429-7/2006/CPL");
+
+ if (crypt) {
+ cpl->set_namespace_declaration ("http://www.w3.org/2000/09/xmldsig#", "dsig");
+ }
+
+ cpl->add_child("Id")->add_child_text ("urn:uuid:" + _uuid);
+ cpl->add_child("AnnotationText")->add_child_text (_name);
+ cpl->add_child("IssueDate")->add_child_text (Metadata::instance()->issue_date);
+ cpl->add_child("Creator")->add_child_text (Metadata::instance()->creator);
+ cpl->add_child("ContentTitleText")->add_child_text (_name);
+ cpl->add_child("ContentKind")->add_child_text (content_kind_to_string (_content_kind));
+
+ {
+ xmlpp::Element* cv = cpl->add_child ("ContentVersion");
+ cv->add_child("Id")->add_child_text ("urn:uri:" + _uuid + "_" + Metadata::instance()->issue_date);
+ cv->add_child("LabelText")->add_child_text (_uuid + "_" + Metadata::instance()->issue_date);
+ }
+
+ cpl->add_child("RatingList");
+
+ xmlpp::Element* reel_list = cpl->add_child("ReelList");
for (list<shared_ptr<const Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) {
- (*i)->write_to_cpl (os);
+ (*i)->write_to_cpl (reel_list);
}
- os << " </ReelList>\n"
- << "</CompositionPlaylist>\n";
+ if (crypt) {
+ sign (cpl, crypt->certificates, crypt->signer_key);
+ }
- os.close ();
+ doc.write_to_file_formatted (p.string(), "UTF-8");
- _digest = make_digest (p.string (), 0);
+ _digest = make_digest (p.string ());
_length = boost::filesystem::file_size (p.string ());
}
class Reel;
class AssetMap;
+class Encryption
+{
+public:
+ Encryption (CertificateChain c, std::string const & k)
+ : certificates (c)
+ , signer_key (k)
+ {}
+
+ CertificateChain certificates;
+ std::string signer_key;
+};
+
+ /** @brief A CPL within a DCP */
class CPL
{
public:
}
if (_main_subtitle) {
- _main_subtitle->write_to_cpl (s);
+ _main_subtitle->write_to_cpl (asset_list);
}
+
+ s << " </AssetList>\n"
+ << " </Reel>\n";
}
bool
using namespace libdcp;
SoundAsset::SoundAsset (
- vector<string> const & files, string directory, string mxf_name, boost::signals2::signal<void (float)>* progress, int fps, int length, bool encrypted
- vector<string> const & files, string directory, string mxf_name, boost::signals2::signal<void (float)>* progress, int fps, int length, int start_frame
++ vector<string> const & files,
++ string directory,
++ string mxf_name,
++ boost::signals2::signal<void (float)>* progress,
++ int fps,
++ int length,
++ int start_frame,
++ bool encrypted
)
- : MXFAsset (directory, mxf_name, progress, fps, 0, length)
+ : MXFAsset (directory, mxf_name, progress, fps, 0, length, encrypted)
, _channels (files.size ())
, _sampling_rate (0)
+ , _start_frame (start_frame)
{
+ assert (_channels);
+
construct (boost::bind (&SoundAsset::path_from_channel, this, _1, files));
}
string directory,
string mxf_name,
boost::signals2::signal<void (float)>* progress,
- int fps, int length, int channels, bool encrypted
- int fps, int length, int start_frame, int channels
++ int fps,
++ int length,
++ int start_frame,
++ int channels,
++ bool encrypted
)
- : MXFAsset (directory, mxf_name, progress, fps, 0, length)
+ : MXFAsset (directory, mxf_name, progress, fps, 0, length, encrypted)
, _channels (channels)
, _sampling_rate (0)
+ , _start_frame (start_frame)
{
+ assert (_channels);
+
construct (get_path);
}
SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int entry_point, int length)
- : MXFAsset (directory, mxf_name, 0, fps, entry_point, length)
+ : MXFAsset (directory, mxf_name, 0, fps, entry_point, length, false)
, _channels (0)
+ , _start_frame (0)
{
ASDCP::PCM::MXFReader reader;
if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
* @param progress Signal to inform of progress.
* @param fps Frames per second.
* @param length Length in frames.
+ * @param start_frame Frame in the source to start writing from.
+ * @param encrypted true if asset should be encrypted.
*/
SoundAsset (
std::vector<std::string> const & files,
boost::signals2::signal<void (float)>* progress,
int fps,
int length,
+ int start_frame
+ bool encrypted
);
/** Construct a SoundAsset, generating the MXF from some WAV files.
* @param progress Signal to inform of progress.
* @param fps Frames per second.
* @param length Length in frames.
+ * @param start_frame Frame in the source to start writing from.
* @param channels Number of audio channels.
+ * @param encrypted true if asset should be encrypted.
*/
SoundAsset (
boost::function<std::string (Channel)> get_path,
boost::signals2::signal<void (float)>* progress,
int fps,
int length,
- int channels
+ int start_frame,
+ int channels,
+ bool encrypted
);
SoundAsset (
#include <openjpeg.h>
#include "types.h"
+namespace xmlpp {
+ class Element;
+}
+
namespace libdcp {
-class ARGBFrame;
+class ARGBFrame;
+class CertificateChain;
- /** Create a UUID.
- * @return UUID.
- */
extern std::string make_uuid ();
-
- /** Create a digest for a file.
- * @param filename File name.
- * @param progress If non-0, a signal which will be emitted periodically to update
- * progress; the parameter will start at 0.5 and proceed to 1.
- * @return Digest.
- */
- extern std::string make_digest (std::string filename, boost::signals2::signal<void (float)>* progress);
-
+ extern std::string make_digest (std::string filename);
extern std::string content_kind_to_string (ContentKind kind);
extern ContentKind content_kind_from_string (std::string kind);
- extern bool starts_with (std::string big, std::string little);
- extern bool ends_with (std::string big, std::string little);
extern bool empty_or_white_space (std::string s);
-
extern opj_image_t* decompress_j2k (uint8_t* data, int64_t size, int reduce);
extern boost::shared_ptr<ARGBFrame> xyz_to_rgb (opj_image_t* xyz_frame);
&(d.Progress),
24,
24,
- 2
+ 0,
+ 2,
+ false
));
cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
vector<string> p;
p.push_back ("frobozz");
- BOOST_CHECK_THROW (new libdcp::MonoPictureAsset (p, "build/test/fred", "video.mxf", &d.Progress, 24, 24, 32, 32, false), libdcp::FileError);
- BOOST_CHECK_THROW (new libdcp::SoundAsset (p, "build/test/fred", "audio.mxf", &d.Progress, 24, 24, false), libdcp::FileError);
- BOOST_CHECK_THROW (new libdcp::MonoPictureAsset (p, "build/test/bar", "video.mxf", &d.Progress, 24, 24, 32, 32), libdcp::FileError);
- BOOST_CHECK_THROW (new libdcp::SoundAsset (p, "build/test/bar", "audio.mxf", &d.Progress, 24, 24, 0), libdcp::FileError);
++ BOOST_CHECK_THROW (new libdcp::MonoPictureAsset (p, "build/test/bar", "video.mxf", &d.Progress, 24, 24, 32, 32, false), libdcp::FileError);
++ BOOST_CHECK_THROW (new libdcp::SoundAsset (p, "build/test/bar", "audio.mxf", &d.Progress, 24, 24, 0, false), libdcp::FileError);
}
BOOST_AUTO_TEST_CASE (read_dcp)