Left surround
Right surround
*/
- std::vector<std::string> sound_files;
+ std::vector<boost::filesystem::path> sound_files;
sound_files.push_back ("examples/sine_440_-12dB.wav");
sound_files.push_back ("examples/sine_880_-12dB.wav");
using namespace boost;
using namespace libdcp;
-Asset::Asset (string directory, string file_name, int edit_rate, int intrinsic_duration)
+Asset::Asset (boost::filesystem::path directory, string file_name, int edit_rate, int intrinsic_duration)
: _directory (directory)
, _file_name (file_name)
, _uuid (make_uuid ())
* @param directory Directory where our XML or MXF file is.
* @param file_name Name of our file within directory, or empty to make one up based on UUID.
*/
- Asset (std::string directory, std::string file_name = "", int edit_rate = 0, int intrinsic_duration = 0);
+ Asset (boost::filesystem::path directory, std::string file_name = "", int edit_rate = 0, int intrinsic_duration = 0);
virtual ~Asset() {}
std::string digest () const;
/** Directory that our MXF or XML file is in */
- std::string _directory;
+ boost::filesystem::path _directory;
/** Name of our MXF or XML file */
std::string _file_name;
/** Our UUID */
shared_ptr<const MXFAsset> mxf = boost::dynamic_pointer_cast<const MXFAsset> (*i);
if (mxf) {
xml_kdm->authenticated_private.encrypted_keys.push_back (
- KDMKey (signer, cpl->id (), mxf->key_id (), not_valid_before, not_valid_after, mxf->key().get()).encrypted_base64 (recipient_cert)
+ KDMKey (
+ signer, cpl->id (), mxf->key_type (), mxf->key_id (),
+ not_valid_before, not_valid_after, mxf->key().get()
+ ).encrypted_base64 (recipient_cert)
);
}
}
return doc->write_to_string_formatted ("UTF-8");
}
-KDMKey::KDMKey (shared_ptr<const Signer> signer, string cpl_id, string key_id, boost::posix_time::ptime from, boost::posix_time::ptime until, Key key)
+KDMKey::KDMKey (
+ shared_ptr<const Signer> signer, string cpl_id, string key_type, string key_id, boost::posix_time::ptime from, boost::posix_time::ptime until, Key key
+ )
: _cpl_id (cpl_id)
+ , _key_type (key_type)
, _key_id (key_id)
, _not_valid_before (ptime_to_string (from))
, _not_valid_after (ptime_to_string (until))
string
KDMKey::encrypted_base64 (shared_ptr<const Certificate> recipient_cert) const
{
+ assert (_key_type.length() == 4);
+ assert (_not_valid_before.length() == 25);
+ assert (_not_valid_after.length() == 25);
+
/* XXX: SMPTE only */
uint8_t block[138];
uint8_t* p = block;
/* Encrypt using the projector's public key */
RSA* rsa = recipient_cert->public_key ();
unsigned char encrypted[RSA_size(rsa)];
- int const encrypted_len = RSA_public_encrypt (138, block, encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
+ int const encrypted_len = RSA_public_encrypt (p - block, block, encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
if (encrypted_len == -1) {
throw MiscError (String::compose ("Could not encrypt KDM (%1)", ERR_error_string (ERR_get_error(), 0)));
}
/* Lazy overallocation */
char out[encrypted_len * 2];
- return Kumu::base64encode (block, 138, out, 138 * 2);
+ return Kumu::base64encode (encrypted, encrypted_len, out, encrypted_len * 2);
}
string
KDMKey (
boost::shared_ptr<const Signer> signer,
- std::string cpl_id, std::string key_id, boost::posix_time::ptime from, boost::posix_time::ptime until, Key key
+ std::string cpl_id, std::string key_type, std::string key_id, boost::posix_time::ptime from, boost::posix_time::ptime until, Key key
);
KDMKey (KDMKey const &);
using boost::dynamic_pointer_cast;
using namespace libdcp;
-MXFAsset::MXFAsset (string directory, string file_name)
+MXFAsset::MXFAsset (boost::filesystem::path directory, string file_name)
: Asset (directory, file_name)
, _progress (0)
, _encryption_context (0)
}
-MXFAsset::MXFAsset (string directory, string file_name, boost::signals2::signal<void (float)>* progress, int edit_rate, int intrinsic_duration)
+MXFAsset::MXFAsset (boost::filesystem::path directory, string file_name, boost::signals2::signal<void (float)>* progress, int edit_rate, int intrinsic_duration)
: Asset (directory, file_name, edit_rate, intrinsic_duration)
, _progress (progress)
, _encryption_context (0)
* @param directory Directory where MXF file is.
* @param file_name Name of MXF file.
*/
- MXFAsset (std::string directory, std::string file_name);
+ MXFAsset (boost::filesystem::path directory, std::string file_name);
/** Construct an MXFAsset.
* This class will not write anything to disk in this constructor, but subclasses may.
* @param intrinsic_duration Duration of the whole asset in frames.
*/
MXFAsset (
- std::string directory,
+ boost::filesystem::path directory,
std::string file_name,
boost::signals2::signal<void (float)>* progress,
int edit_rate,
using boost::lexical_cast;
using namespace libdcp;
-PictureAsset::PictureAsset (string directory, string mxf_name, boost::signals2::signal<void (float)>* progress, int fps, int intrinsic_duration, Size size)
+PictureAsset::PictureAsset (
+ boost::filesystem::path directory, string mxf_name, boost::signals2::signal<void (float)>* progress, int fps, int intrinsic_duration, Size size
+ )
: MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration)
, _size (size)
{
}
-PictureAsset::PictureAsset (string directory, string mxf_name)
+PictureAsset::PictureAsset (boost::filesystem::path directory, string mxf_name)
: MXFAsset (directory, mxf_name)
{
MonoPictureAsset::MonoPictureAsset (
- boost::function<string (int)> get_path,
- string directory,
+ boost::function<boost::filesystem::path (int)> get_path,
+ boost::filesystem::path directory,
string mxf_name,
boost::signals2::signal<void (float)>* progress,
int fps,
}
MonoPictureAsset::MonoPictureAsset (
- vector<string> const & files,
- string directory,
+ vector<boost::filesystem::path> const & files,
+ boost::filesystem::path directory,
string mxf_name,
boost::signals2::signal<void (float)>* progress,
int fps,
construct (boost::bind (&MonoPictureAsset::path_from_list, this, _1, files), interop, metadata);
}
-MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name, int fps, Size size)
+MonoPictureAsset::MonoPictureAsset (boost::filesystem::path directory, string mxf_name, int fps, Size size)
: PictureAsset (directory, mxf_name, 0, fps, 0, size)
{
}
-MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name)
+MonoPictureAsset::MonoPictureAsset (boost::filesystem::path directory, string mxf_name)
: PictureAsset (directory, mxf_name)
{
ASDCP::JP2K::MXFReader reader;
}
void
-MonoPictureAsset::construct (boost::function<string (int)> get_path, bool interop, MXFMetadata const & metadata)
+MonoPictureAsset::construct (boost::function<boost::filesystem::path (int)> get_path, bool interop, MXFMetadata const & metadata)
{
ASDCP::JP2K::CodestreamParser j2k_parser;
ASDCP::JP2K::FrameBuffer frame_buffer (4 * Kumu::Megabyte);
for (int i = 0; i < _intrinsic_duration; ++i) {
- string const path = get_path (i);
+ boost::filesystem::path const path = get_path (i);
if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (path.c_str(), frame_buffer))) {
boost::throw_exception (FileError ("could not open JPEG2000 file for reading", path));
}
}
-string
-MonoPictureAsset::path_from_list (int f, vector<string> const & files) const
+boost::filesystem::path
+MonoPictureAsset::path_from_list (int f, vector<boost::filesystem::path> const & files) const
{
return files[f];
}
}
-StereoPictureAsset::StereoPictureAsset (string directory, string mxf_name, int fps, int intrinsic_duration)
+StereoPictureAsset::StereoPictureAsset (boost::filesystem::path directory, string mxf_name, int fps, int intrinsic_duration)
: PictureAsset (directory, mxf_name, 0, fps, intrinsic_duration, Size (0, 0))
{
ASDCP::JP2K::MXFSReader reader;
return "MDIK";
}
-StereoPictureAsset::StereoPictureAsset (string directory, string mxf_name, int fps, Size size)
+StereoPictureAsset::StereoPictureAsset (boost::filesystem::path directory, string mxf_name, int fps, Size size)
: PictureAsset (directory, mxf_name, 0, fps, 0, size)
{
* @param directory Directory where MXF file is.
* @param mxf_name Name of MXF file.
*/
- PictureAsset (std::string directory, std::string mxf_name);
+ PictureAsset (boost::filesystem::path directory, std::string mxf_name);
/** Construct a PictureAsset.
* This class will not write anything to disk in this constructor, but subclasses may.
* @param size Size of video frame images in pixels.
*/
PictureAsset (
- std::string directory,
+ boost::filesystem::path directory,
std::string mxf_name,
boost::signals2::signal<void (float)>* progress,
int fps,
* @param size Size of images in pixels.
*/
MonoPictureAsset (
- std::vector<std::string> const & files,
- std::string directory,
+ std::vector<boost::filesystem::path> const & files,
+ boost::filesystem::path directory,
std::string mxf_name,
boost::signals2::signal<void (float)>* progress,
int fps,
* @param size Size of images in pixels.
*/
MonoPictureAsset (
- boost::function<std::string (int)> get_path,
- std::string directory,
+ boost::function<boost::filesystem::path (int)> get_path,
+ boost::filesystem::path directory,
std::string mxf_name,
boost::signals2::signal<void (float)>* progress,
int fps,
* @param directory Directory that the MXF is in.
* @param mxf_name The filename of the MXF within `directory'.
*/
- MonoPictureAsset (std::string directory, std::string mxf_name);
+ MonoPictureAsset (boost::filesystem::path directory, std::string mxf_name);
/** Construct a MonoPictureAsset for progressive writing using
* start_write() and a MonoPictureAssetWriter.
* @param fps Video frames per second.
* @param size Size in pixels that the picture frames will be.
*/
- MonoPictureAsset (std::string directory, std::string mxf_name, int fps, Size size);
+ MonoPictureAsset (boost::filesystem::path directory, std::string mxf_name, int fps, Size size);
/** Start a progressive write to a MonoPictureAsset */
boost::shared_ptr<PictureAssetWriter> start_write (bool, bool, MXFMetadata const & metadata = MXFMetadata ());
bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
private:
- std::string path_from_list (int f, std::vector<std::string> const & files) const;
- void construct (boost::function<std::string (int)>, bool, MXFMetadata const &);
+ boost::filesystem::path path_from_list (int f, std::vector<boost::filesystem::path> const & files) const;
+ void construct (boost::function<boost::filesystem::path (int)>, bool, MXFMetadata const &);
std::string cpl_node_name () const;
int edit_rate_factor () const;
};
class StereoPictureAsset : public PictureAsset
{
public:
- StereoPictureAsset (std::string directory, std::string mxf_name, int fps, int intrinsic_duration);
+ StereoPictureAsset (boost::filesystem::path directory, std::string mxf_name, int fps, int intrinsic_duration);
/** Construct a StereoPictureAsset for progressive writing using
* start_write() and a StereoPictureAssetWriter.
* @param fps Video frames per second.
* @param size Size in pixels that the picture frames will be.
*/
- StereoPictureAsset (std::string directory, std::string mxf_name, int fps, Size size);
+ StereoPictureAsset (boost::filesystem::path directory, std::string mxf_name, int fps, Size size);
/** Start a progressive write to a StereoPictureAsset */
boost::shared_ptr<PictureAssetWriter> start_write (bool, bool, MXFMetadata const & metadata = MXFMetadata ());
using namespace libdcp;
SoundAsset::SoundAsset (
- vector<string> const & files,
- string directory,
+ vector<boost::filesystem::path> const & files,
+ boost::filesystem::path directory,
string mxf_name,
boost::signals2::signal<void (float)>* progress,
int fps,
}
SoundAsset::SoundAsset (
- boost::function<string (Channel)> get_path,
- string directory,
+ boost::function<boost::filesystem::path (Channel)> get_path,
+ boost::filesystem::path directory,
string mxf_name,
boost::signals2::signal<void (float)>* progress,
int fps,
construct (get_path, interop, metadata);
}
-SoundAsset::SoundAsset (string directory, string mxf_name)
+SoundAsset::SoundAsset (boost::filesystem::path directory, string mxf_name)
: MXFAsset (directory, mxf_name)
, _channels (0)
{
_intrinsic_duration = desc.ContainerDuration;
}
-SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int channels, int sampling_rate)
+SoundAsset::SoundAsset (boost::filesystem::path directory, string mxf_name, int fps, int channels, int sampling_rate)
: MXFAsset (directory, mxf_name, 0, fps, 0)
, _channels (channels)
, _sampling_rate (sampling_rate)
}
-string
-SoundAsset::path_from_channel (Channel channel, vector<string> const & files)
+boost::filesystem::path
+SoundAsset::path_from_channel (Channel channel, vector<boost::filesystem::path> const & files)
{
unsigned int const c = int (channel);
assert (c < files.size ());
}
void
-SoundAsset::construct (boost::function<string (Channel)> get_path, bool interop, MXFMetadata const & metadata)
+SoundAsset::construct (boost::function<boost::filesystem::path (Channel)> get_path, bool interop, MXFMetadata const & metadata)
{
ASDCP::Rational asdcp_edit_rate (_edit_rate, 1);
for (int i = 0; i < _channels; ++i) {
- string const path = get_path (channels[i]);
+ boost::filesystem::path const path = get_path (channels[i]);
if (ASDCP_FAILURE (pcm_parser_channel[i].OpenRead (path.c_str(), asdcp_edit_rate))) {
boost::throw_exception (FileError ("could not open WAV file for reading", path));
* Note that this is different to entry_point in that the asset will contain no data before start_frame.
*/
SoundAsset (
- std::vector<std::string> const & files,
- std::string directory,
+ std::vector<boost::filesystem::path> const & files,
+ boost::filesystem::path directory,
std::string mxf_name,
boost::signals2::signal<void (float)>* progress,
int fps,
* @param channels Number of audio channels.
*/
SoundAsset (
- boost::function<std::string (Channel)> get_path,
- std::string directory,
+ boost::function<boost::filesystem::path (Channel)> get_path,
+ boost::filesystem::path directory,
std::string mxf_name,
boost::signals2::signal<void (float)>* progress,
int fps,
);
SoundAsset (
- std::string directory,
+ boost::filesystem::path directory,
std::string mxf_name
);
SoundAsset (
- std::string directory,
+ boost::filesystem::path directory,
std::string mxf_name,
int fps,
int channels,
private:
std::string key_type () const;
- void construct (boost::function<std::string (Channel)> get_path, bool interop, MXFMetadata const &);
- std::string path_from_channel (Channel channel, std::vector<std::string> const & files);
+ void construct (boost::function<boost::filesystem::path (Channel)> get_path, bool interop, MXFMetadata const &);
+ boost::filesystem::path path_from_channel (Channel channel, std::vector<boost::filesystem::path> const & files);
std::string cpl_node_name () const;
/** Number of channels in the asset */
libdcp::DCP d ("build/test/fred");
/* Random filename that does not exist */
- vector<string> p;
+ vector<boost::filesystem::path> p;
p.push_back ("frobozz");
/* Trying to create video/audio MXFs using a non-existant file should throw an exception */
--- /dev/null
+/*
+ Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <iostream>
+#include <boost/test/unit_test.hpp>
+#include "certificates.h"
+#include "kdm.h"
+#include "signer.h"
+#include "picture_asset.h"
+#include "sound_asset.h"
+#include "reel.h"
+#include "test.h"
+#include "cpl.h"
+#include "picture_frame.h"
+#include "argb_frame.h"
+
+using boost::shared_ptr;
+
+/* Build an encrypted picture MXF and a KDM for it and check that the KDM can be decrypted */
+BOOST_AUTO_TEST_CASE (round_trip_test)
+{
+ libdcp::CertificateChain chain;
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("build/test/signer/ca.self-signed.pem"))));
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("build/test/signer/intermediate.signed.pem"))));
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("build/test/signer/leaf.signed.pem"))));
+
+ shared_ptr<libdcp::Signer> signer (
+ new libdcp::Signer (
+ chain,
+ "test/data/signer.key"
+ )
+ );
+
+ boost::filesystem::path work_dir = "build/test/round_trip_test";
+ boost::filesystem::create_directory (work_dir);
+
+ libdcp::MXFMetadata mxf_metadata;
+
+ shared_ptr<libdcp::MonoPictureAsset> asset_A (
+ new libdcp::MonoPictureAsset (j2c, work_dir, "video.mxf", 0, 24, 24, libdcp::Size (32, 32), false, mxf_metadata)
+ );
+
+ libdcp::Key key;
+
+ asset_A->set_key (key);
+
+ shared_ptr<libdcp::CPL> cpl (new libdcp::CPL (work_dir, "A Test DCP", libdcp::FEATURE, 24, 24));
+ cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (asset_A, shared_ptr<libdcp::SoundAsset> (), shared_ptr<libdcp::SubtitleAsset> ())));
+
+ /* A KDM using our certificate chain's leaf key pair */
+ libdcp::KDM kdm_A (
+ cpl,
+ signer,
+ signer->certificates().leaf(),
+ boost::posix_time::time_from_string ("2013-01-01 00:00:00"),
+ boost::posix_time::time_from_string ("2013-01-08 00:00:00"),
+ "libdcp",
+ "2012-07-17T04:45:18+00:00"
+ );
+
+ boost::filesystem::path const kdm_file = work_dir / "kdm.xml";
+
+ kdm_A.as_xml (kdm_file);
+
+ /* Reload the KDM, using our private key to decrypt it */
+ libdcp::KDM kdm_B (kdm_file, "build/test/signer/leaf.key");
+
+ /* Reload the picture MXF */
+ shared_ptr<libdcp::MonoPictureAsset> asset_B (
+ new libdcp::MonoPictureAsset (work_dir, "video.mxf")
+ );
+
+ asset_B->set_key (kdm_B.keys().front().key());
+
+ shared_ptr<libdcp::ARGBFrame> frame_A = asset_A->get_frame(0)->argb_frame ();
+ shared_ptr<libdcp::ARGBFrame> frame_B = asset_B->get_frame(0)->argb_frame ();
+ BOOST_CHECK_EQUAL (frame_A->size().width, frame_B->size().width);
+ BOOST_CHECK_EQUAL (frame_A->size().height, frame_B->size().height);
+ BOOST_CHECK_EQUAL (memcmp (frame_A->data(), frame_B->data(), frame_A->size().width * frame_A->size().height), 0);
+}
BOOST_GLOBAL_FIXTURE (TestConfig);
-string
+boost::filesystem::path
j2c (int)
{
return "test/data/32x32_red_square.j2c";
}
-string
+boost::filesystem::path
wav (libdcp::Channel)
{
return "test/data/1s_24-bit_48k_silence.wav";
*/
-extern std::string j2c (int);
-extern std::string wav (libdcp::Channel);
+extern boost::filesystem::path j2c (int);
+extern boost::filesystem::path wav (libdcp::Channel);
extern std::string test_corpus;
kdm_test.cc
subtitle_tests.cc
util_test.cc
+ round_trip_test.cc
"""
obj.target = 'tests'
obj.install_path = ''