/* And add the CPL to the DCP */
dcp.add_cpl (cpl);
- /* Now make a `picture asset'. This is a collection of the JPEG2000 files that make up the picture, one per frame.
- Here we're using a function (video_frame) to obtain the name of the JPEG2000 file for each frame.
+ /* Now make a `picture asset'. This is a collection of the JPEG2000 files that make up the picture; one per frame.
+ First, create the object.
+ */
+
+ boost::shared_ptr<libdcp::MonoPictureAsset> picture_asset (
+ new libdcp::MonoPictureAsset ("My Film DCP", "video.mxf")
+ );
+
+ /* Now set up its parameters; we have the frame rate, the
+ number of frames and the resolution of the frames;
+ 1998x1080 is the DCI Flat specification for 2K projectors.
+ */
+ picture_asset->set_edit_rate (24);
+ picture_asset->set_intrinsic_duration (24);
+ picture_asset->set_size (libdcp::Size (1998, 1080));
+
+ /* Now we can create the asset itself. Here using a function (video_frame) to obtain the name of the JPEG2000 file for each frame.
The result will be an MXF file written to the directory "My Film DCP" (which should be the same as the DCP's
directory above) called "video.mxf".
-
- The other parameters specify the entry_point (the frame at which the projector should start showing the picture),
- the frame rate, the number of frames and the resolution of the frames; 1998x1080 is the DCI Flat specification
- for 2K projectors.
*/
- boost::shared_ptr<libdcp::MonoPictureAsset> picture_asset (
- new libdcp::MonoPictureAsset (video_frame, "My Film DCP", "video.mxf", 0, 24, 48, libdcp::Size (1998, 1080), false)
- );
+
+ picture_asset->create (video_frame);
/* Now we will create a `sound asset', which is made up of a WAV file for each channel of audio. Here we're using
stereo, so we add two WAV files to a vector.
sound_files.push_back ("examples/sine_880_-12dB.wav");
/* 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)
- );
+ boost::shared_ptr<libdcp::SoundAsset> sound_asset (new libdcp::SoundAsset ("My Film DCP", "audio.mxf"));
+ sound_asset->set_edit_rate (24);
+ sound_asset->set_intrinsic_duration (48);
+ sound_asset->create (sound_files);
/* Now that we have the assets, we can create a Reel to put them in and add it to the CPL */
cpl->add_reel (
using namespace boost;
using namespace libdcp;
-Asset::Asset (boost::filesystem::path directory, string file_name, int edit_rate, int intrinsic_duration)
+Asset::Asset (boost::filesystem::path directory, string file_name)
: _directory (directory)
, _file_name (file_name)
, _uuid (make_uuid ())
- , _edit_rate (edit_rate)
+ , _edit_rate (0)
, _entry_point (0)
- , _intrinsic_duration (intrinsic_duration)
- , _duration (intrinsic_duration)
+ , _intrinsic_duration (0)
+ , _duration (0)
{
if (_file_name.empty ()) {
_file_name = _uuid + ".xml";
* @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 (boost::filesystem::path directory, std::string file_name = "", int edit_rate = 0, int intrinsic_duration = 0);
+ Asset (boost::filesystem::path directory, std::string file_name = "");
virtual ~Asset() {}
_intrinsic_duration = d;
}
+ void set_edit_rate (int r) {
+ _edit_rate = r;
+ }
+
virtual bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)>) const;
protected:
if (!(*i)->asset_list->main_stereoscopic_picture && p->edit_rate == p->frame_rate) {
- pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, p->id);
-
try {
- picture.reset (new MonoPictureAsset (
- asset.first,
- asset.second->chunks.front()->path
- )
- );
+ pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, p->id);
+ picture.reset (new MonoPictureAsset (asset.first, asset.second->chunks.front()->path));
+
+ picture->read ();
+ picture->set_edit_rate (_fps);
picture->set_entry_point (p->entry_point);
picture->set_duration (p->duration);
if (p->key_id.length() > 9) {
try {
pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, p->id);
- picture.reset (new StereoPictureAsset (
- asset.first,
- asset.second->chunks.front()->path,
- _fps,
- p->duration
- )
- );
+ picture.reset (new StereoPictureAsset (asset.first, asset.second->chunks.front()->path));
+ picture->read ();
+ picture->set_edit_rate (_fps);
picture->set_entry_point (p->entry_point);
picture->set_duration (p->duration);
if (p->key_id.length() > 9) {
try {
pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, (*i)->asset_list->main_sound->id);
- sound.reset (new SoundAsset (
- asset.first,
- asset.second->chunks.front()->path
- )
- );
-
+ sound.reset (new SoundAsset (asset.first, asset.second->chunks.front()->path));
shared_ptr<parse::MainSound> s = (*i)->asset_list->main_sound;
+ sound->read ();
sound->set_entry_point (s->entry_point);
sound->set_duration (s->duration);
if (s->key_id.length() > 9) {
pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, (*i)->asset_list->main_subtitle->id);
- subtitle.reset (new SubtitleAsset (
- asset.first,
- asset.second->chunks.front()->path
- )
- );
+ subtitle.reset (new SubtitleAsset (asset.first, asset.second->chunks.front()->path));
subtitle->set_entry_point ((*i)->asset_list->main_subtitle->entry_point);
subtitle->set_duration ((*i)->asset_list->main_subtitle->duration);
, _progress (0)
, _encryption_context (0)
, _decryption_context (0)
+ , _interop (false)
{
}
-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)
- , _decryption_context (0)
-{
-
-}
-
MXFAsset::~MXFAsset ()
{
delete _encryption_context;
#include <boost/signals2.hpp>
#include "asset.h"
#include "key.h"
+#include "metadata.h"
namespace ASDCP {
class AESEncContext;
*/
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 directory Directory where MXF file is.
- * @param file_name Name of MXF file.
- * @param progress Signal to use to inform of progress, or 0.
- * @param edit_rate Edit rate in frames per second (usually equal to the video frame rate).
- * @param intrinsic_duration Duration of the whole asset in frames.
- */
- MXFAsset (
- boost::filesystem::path directory,
- std::string file_name,
- boost::signals2::signal<void (float)>* progress,
- int edit_rate,
- int intrinsic_duration
- );
-
~MXFAsset ();
virtual bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
-
virtual void write_to_cpl (xmlpp::Element *, bool interop) const;
-
+ virtual std::string key_type () const = 0;
+
/** Fill in a ADSCP::WriteInfo struct.
* @param w struct to fill in.
* @param uuid uuid to use.
*/
void fill_writer_info (ASDCP::WriterInfo* w, std::string uuid, bool interop, MXFMetadata const & metadata);
+ void set_progress (boost::signals2::signal<void (float)>* progress) {
+ _progress = progress;
+ }
+
bool encrypted () const {
return !_key_id.empty ();
}
return _encryption_context;
}
- virtual std::string key_type () const = 0;
-
+ void set_metadata (MXFMetadata m) {
+ _metadata = m;
+ }
+
+ MXFMetadata metadata () const {
+ return _metadata;
+ }
+
+ void set_interop (bool i) {
+ _interop = i;
+ }
+
+ bool interop () const {
+ return _interop;
+ }
+
protected:
virtual std::string cpl_node_name () const = 0;
virtual std::pair<std::string, std::string> cpl_node_attribute (bool) const {
ASDCP::AESDecContext* _decryption_context;
std::string _key_id;
boost::optional<Key> _key;
+ MXFMetadata _metadata;
+ bool _interop;
};
}
using boost::lexical_cast;
using namespace libdcp;
-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 (boost::filesystem::path directory, string mxf_name)
: MXFAsset (directory, mxf_name)
{
}
-string
-MonoPictureAsset::cpl_node_name () const
-{
- return "MainPicture";
-}
-
-int
-MonoPictureAsset::edit_rate_factor () const
-{
- return 1;
-}
-
-string
-StereoPictureAsset::cpl_node_name () const
-{
- return "msp-cpl:MainStereoscopicPicture";
-}
-
-pair<string, string>
-StereoPictureAsset::cpl_node_attribute (bool interop) const
-{
- if (interop) {
- return make_pair ("xmlns:msp-cpl", "http://www.digicine.com/schemas/437-Y/2007/Main-Stereo-Picture-CPL");
- } else {
- return make_pair ("xmlns:msp-cpl", "http://www.smpte-ra.org/schemas/429-10/2008/Main-Stereo-Picture-CPL");
- }
-
- return make_pair ("", "");
-}
-
-int
-StereoPictureAsset::edit_rate_factor () const
-{
- return 2;
-}
-
void
PictureAsset::write_to_cpl (xmlpp::Element* node, bool interop) const
{
return true;
}
-
-MonoPictureAsset::MonoPictureAsset (
- boost::function<boost::filesystem::path (int)> get_path,
- boost::filesystem::path directory,
- string mxf_name,
- boost::signals2::signal<void (float)>* progress,
- int fps,
- int intrinsic_duration,
- Size size,
- bool interop,
- MXFMetadata const & metadata
- )
- : PictureAsset (directory, mxf_name, progress, fps, intrinsic_duration, size)
+MonoPictureAsset::MonoPictureAsset (boost::filesystem::path directory, string mxf_name)
+ : PictureAsset (directory, mxf_name)
{
- construct (get_path, interop, metadata);
-}
-MonoPictureAsset::MonoPictureAsset (
- vector<boost::filesystem::path> const & files,
- boost::filesystem::path directory,
- string mxf_name,
- boost::signals2::signal<void (float)>* progress,
- int fps,
- int intrinsic_duration,
- Size size,
- bool interop,
- MXFMetadata const & metadata
- )
- : PictureAsset (directory, mxf_name, progress, fps, intrinsic_duration, size)
-{
- construct (boost::bind (&MonoPictureAsset::path_from_list, this, _1, files), interop, metadata);
}
-MonoPictureAsset::MonoPictureAsset (boost::filesystem::path directory, string mxf_name, int fps, Size size)
- : PictureAsset (directory, mxf_name, 0, fps, 0, size)
+void
+MonoPictureAsset::create (vector<boost::filesystem::path> const & files)
{
-
-}
-
-MonoPictureAsset::MonoPictureAsset (boost::filesystem::path directory, string mxf_name)
- : PictureAsset (directory, mxf_name)
-{
- ASDCP::JP2K::MXFReader reader;
- if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string()));
- }
-
- ASDCP::JP2K::PictureDescriptor desc;
- if (ASDCP_FAILURE (reader.FillPictureDescriptor (desc))) {
- boost::throw_exception (DCPReadError ("could not read video MXF information"));
- }
-
- _size.width = desc.StoredWidth;
- _size.height = desc.StoredHeight;
- _edit_rate = desc.EditRate.Numerator;
- assert (desc.EditRate.Denominator == 1);
- _intrinsic_duration = desc.ContainerDuration;
+ create (boost::bind (&MonoPictureAsset::path_from_list, this, _1, files));
}
void
-MonoPictureAsset::construct (boost::function<boost::filesystem::path (int)> get_path, bool interop, MXFMetadata const & metadata)
+MonoPictureAsset::create (boost::function<boost::filesystem::path (int)> get_path)
{
ASDCP::JP2K::CodestreamParser j2k_parser;
ASDCP::JP2K::FrameBuffer frame_buffer (4 * Kumu::Megabyte);
picture_desc.EditRate = ASDCP::Rational (_edit_rate, 1);
ASDCP::WriterInfo writer_info;
- fill_writer_info (&writer_info, _uuid, interop, metadata);
+ fill_writer_info (&writer_info, _uuid, _interop, _metadata);
ASDCP::JP2K::MXFWriter mxf_writer;
if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, picture_desc, 16384, false))) {
}
}
+void
+MonoPictureAsset::read ()
+{
+ ASDCP::JP2K::MXFReader reader;
+ if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string()));
+ }
+
+ ASDCP::JP2K::PictureDescriptor desc;
+ if (ASDCP_FAILURE (reader.FillPictureDescriptor (desc))) {
+ boost::throw_exception (DCPReadError ("could not read video MXF information"));
+ }
+
+ _size.width = desc.StoredWidth;
+ _size.height = desc.StoredHeight;
+ _edit_rate = desc.EditRate.Numerator;
+ assert (desc.EditRate.Denominator == 1);
+ _intrinsic_duration = desc.ContainerDuration;
+}
+
boost::filesystem::path
MonoPictureAsset::path_from_list (int f, vector<boost::filesystem::path> const & files) const
{
return shared_ptr<const MonoPictureFrame> (new MonoPictureFrame (path().string(), n, _decryption_context));
}
-
bool
MonoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
{
}
-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))
+StereoPictureAsset::StereoPictureAsset (boost::filesystem::path directory, string mxf_name)
+ : PictureAsset (directory, mxf_name)
+{
+
+}
+
+void
+StereoPictureAsset::read ()
{
ASDCP::JP2K::MXFSReader reader;
if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
}
shared_ptr<PictureAssetWriter>
-MonoPictureAsset::start_write (bool overwrite, bool interop, MXFMetadata const & metadata)
+MonoPictureAsset::start_write (bool overwrite)
{
/* XXX: can't we use shared_ptr here? */
- return shared_ptr<MonoPictureAssetWriter> (new MonoPictureAssetWriter (this, overwrite, interop, metadata));
+ return shared_ptr<MonoPictureAssetWriter> (new MonoPictureAssetWriter (this, overwrite));
}
string
return "MDIK";
}
-StereoPictureAsset::StereoPictureAsset (boost::filesystem::path directory, string mxf_name, int fps, Size size)
- : PictureAsset (directory, mxf_name, 0, fps, 0, size)
+shared_ptr<PictureAssetWriter>
+StereoPictureAsset::start_write (bool overwrite)
{
+ return shared_ptr<StereoPictureAssetWriter> (new StereoPictureAssetWriter (this, overwrite));
+}
+string
+MonoPictureAsset::cpl_node_name () const
+{
+ return "MainPicture";
}
-shared_ptr<PictureAssetWriter>
-StereoPictureAsset::start_write (bool overwrite, bool interop, MXFMetadata const & metadata)
+int
+MonoPictureAsset::edit_rate_factor () const
+{
+ return 1;
+}
+
+string
+StereoPictureAsset::cpl_node_name () const
{
- return shared_ptr<StereoPictureAssetWriter> (new StereoPictureAssetWriter (this, overwrite, interop, metadata));
+ return "msp-cpl:MainStereoscopicPicture";
+}
+
+pair<string, string>
+StereoPictureAsset::cpl_node_attribute (bool interop) const
+{
+ if (interop) {
+ return make_pair ("xmlns:msp-cpl", "http://www.digicine.com/schemas/437-Y/2007/Main-Stereo-Picture-CPL");
+ } else {
+ return make_pair ("xmlns:msp-cpl", "http://www.smpte-ra.org/schemas/429-10/2008/Main-Stereo-Picture-CPL");
+ }
+
+ return make_pair ("", "");
+}
+
+int
+StereoPictureAsset::edit_rate_factor () const
+{
+ return 2;
}
*/
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 directory Directory where MXF file is.
- * @param mxf_name Name of MXF file.
- * @param progress Signal to use to inform of progres, or 0.
- * @param fps Video frames per second.
- * @param intrinsic_duration Total number of frames in the asset.
- * @param size Size of video frame images in pixels.
- */
- PictureAsset (
- boost::filesystem::path directory,
- std::string mxf_name,
- boost::signals2::signal<void (float)>* progress,
- int fps,
- int intrinsic_duration,
- Size
- );
-
/** Start a progressive write to this asset.
* @param overwrite true to overwrite an existing MXF file; in this mode, writing can be resumed to a partially-written MXF; false if the
* MXF file does not exist.
- * @param metadata MXF metadata to use.
*/
- virtual boost::shared_ptr<PictureAssetWriter> start_write (bool overwrite, bool interop, MXFMetadata const & metadata = MXFMetadata ()) = 0;
+ virtual boost::shared_ptr<PictureAssetWriter> start_write (bool overwrite) = 0;
+
+ virtual void read () = 0;
+ virtual void create (std::vector<boost::filesystem::path> const &) {}
+ virtual void create (boost::function<boost::filesystem::path (int)>) {}
bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
return _size;
}
+ void set_size (Size s) {
+ _size = s;
+ }
+
void write_to_cpl (xmlpp::Element *, bool) const;
protected:
class MonoPictureAsset : public PictureAsset
{
public:
- /** Construct a MonoPictureAsset, generating the MXF from the JPEG2000 files.
- * This may take some time; progress is indicated by emission of the Progress signal.
- *
- * @param files Pathnames of JPEG2000 files, in frame order.
- * @param directory Directory in which to create MXF file.
- * @param mxf_name Name of MXF file to create.
- * @param progress Signal to inform of progress.
- * @param fps Video frames per second.
- * @param intrinsic_duration Total number of frames in the asset.
- * @param size Size of images in pixels.
- */
- MonoPictureAsset (
- std::vector<boost::filesystem::path> const & files,
- boost::filesystem::path directory,
- std::string mxf_name,
- boost::signals2::signal<void (float)>* progress,
- int fps,
- int intrinsic_duration,
- Size size,
- bool interop,
- MXFMetadata const & metadata = MXFMetadata ()
- );
-
- /** Construct a MonoPictureAsset, generating the MXF from the JPEG2000 files.
- * This may take some time; progress is indicated by emission of the Progress signal.
- *
- * @param get_path Functor which returns a JPEG2000 file path for a given frame (frames counted from 0).
- * @param directory Directory in which to create MXF file.
- * @param mxf_name Name of MXF file to create.
- * @param progress Signal to inform of progress.
- * @param fps Video frames per second.
- * @param intrinsic_duration Total number of frames in the asset.
- * @param size Size of images in pixels.
- */
- MonoPictureAsset (
- boost::function<boost::filesystem::path (int)> get_path,
- boost::filesystem::path directory,
- std::string mxf_name,
- boost::signals2::signal<void (float)>* progress,
- int fps,
- int intrinsic_duration,
- Size size,
- bool interop,
- MXFMetadata const & metadata = MXFMetadata ()
- );
-
- /** Construct a MonoPictureAsset, reading the MXF from disk.
- * @param directory Directory that the MXF is in.
- * @param mxf_name The filename of the MXF within `directory'.
- */
MonoPictureAsset (boost::filesystem::path directory, std::string mxf_name);
- /** Construct a MonoPictureAsset for progressive writing using
- * start_write() and a MonoPictureAssetWriter.
- *
- * @param directory Directory to put the MXF in.
- * @param mxf_name Filename of the MXF within this directory.
- * @param fps Video frames per second.
- * @param size Size in pixels that the picture frames will be.
- */
- MonoPictureAsset (boost::filesystem::path directory, std::string mxf_name, int fps, Size size);
+ void read ();
+ void create (std::vector<boost::filesystem::path> const & files);
+ void create (boost::function<boost::filesystem::path (int)> get_path);
/** Start a progressive write to a MonoPictureAsset */
- boost::shared_ptr<PictureAssetWriter> start_write (bool, bool, MXFMetadata const & metadata = MXFMetadata ());
+ boost::shared_ptr<PictureAssetWriter> start_write (bool);
boost::shared_ptr<const MonoPictureFrame> get_frame (int n) const;
bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
class StereoPictureAsset : public PictureAsset
{
public:
- 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 directory Directory to put the MXF in.
- * @param mxf_name Filename of the MXF within this directory.
- * @param fps Video frames per second.
- * @param size Size in pixels that the picture frames will be.
- */
- StereoPictureAsset (boost::filesystem::path directory, std::string mxf_name, int fps, Size size);
+ StereoPictureAsset (boost::filesystem::path directory, std::string mxf_name);
+ void read ();
+
/** Start a progressive write to a StereoPictureAsset */
- boost::shared_ptr<PictureAssetWriter> start_write (bool, bool, MXFMetadata const & metadata = MXFMetadata ());
+ boost::shared_ptr<PictureAssetWriter> start_write (bool);
boost::shared_ptr<const StereoPictureFrame> get_frame (int n) const;
bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
}
-PictureAssetWriter::PictureAssetWriter (PictureAsset* asset, bool overwrite, bool interop, MXFMetadata const & metadata)
+PictureAssetWriter::PictureAssetWriter (PictureAsset* asset, bool overwrite)
: _asset (asset)
, _frames_written (0)
, _started (false)
, _finalized (false)
, _overwrite (overwrite)
- , _interop (interop)
- , _metadata (metadata)
{
}
/** @param a Asset to write to. `a' must not be deleted while
* this writer class still exists, or bad things will happen.
*/
-MonoPictureAssetWriter::MonoPictureAssetWriter (PictureAsset* asset, bool overwrite, bool interop, MXFMetadata const & metadata)
- : PictureAssetWriter (asset, overwrite, interop, metadata)
+MonoPictureAssetWriter::MonoPictureAssetWriter (PictureAsset* asset, bool overwrite)
+ : PictureAssetWriter (asset, overwrite)
, _state (new MonoPictureAssetWriter::ASDCPState)
{
_state->encryption_context = asset->encryption_context ();
}
-StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* asset, bool overwrite, bool interop, MXFMetadata const & metadata)
- : PictureAssetWriter (asset, overwrite, interop, metadata)
+StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* asset, bool overwrite)
+ : PictureAssetWriter (asset, overwrite)
, _state (new StereoPictureAssetWriter::ASDCPState)
, _next_eye (EYE_LEFT)
{
state->j2k_parser.FillPictureDescriptor (state->picture_descriptor);
state->picture_descriptor.EditRate = ASDCP::Rational (asset->edit_rate(), 1);
- asset->fill_writer_info (&state->writer_info, asset->uuid(), writer->_interop, writer->_metadata);
+ asset->fill_writer_info (&state->writer_info, asset->uuid(), writer->_asset->interop(), writer->_asset->metadata());
if (ASDCP_FAILURE (state->mxf_writer.OpenWrite (
asset->path().string().c_str(),
template <class P, class Q>
friend void start (PictureAssetWriter *, boost::shared_ptr<P>, Q *, uint8_t *, int);
- PictureAssetWriter (PictureAsset *, bool, bool, MXFMetadata const &);
+ PictureAssetWriter (PictureAsset *, bool);
PictureAsset* _asset;
/** true if finalize() has been called */
bool _finalized;
bool _overwrite;
- bool _interop;
- MXFMetadata _metadata;
};
/** A helper class for writing to MonoPictureAssets progressively (i.e. writing frame-by-frame,
private:
friend class MonoPictureAsset;
- MonoPictureAssetWriter (PictureAsset *, bool, bool, MXFMetadata const &);
+ MonoPictureAssetWriter (PictureAsset *, bool);
void start (uint8_t *, int);
/* do this with an opaque pointer so we don't have to include
private:
friend class StereoPictureAsset;
- StereoPictureAssetWriter (PictureAsset *, bool, bool, MXFMetadata const &);
+ StereoPictureAssetWriter (PictureAsset *, bool);
void start (uint8_t *, int);
/* do this with an opaque pointer so we don't have to include
using boost::lexical_cast;
using namespace libdcp;
-SoundAsset::SoundAsset (
- vector<boost::filesystem::path> const & files,
- boost::filesystem::path directory,
- string mxf_name,
- boost::signals2::signal<void (float)>* progress,
- int fps,
- int intrinsic_duration,
- bool interop,
- MXFMetadata const & metadata
- )
- : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration)
- , _channels (files.size ())
+SoundAsset::SoundAsset (boost::filesystem::path directory, string mxf_name)
+ : MXFAsset (directory, mxf_name)
+ , _channels (0)
, _sampling_rate (0)
{
- assert (_channels);
-
- construct (boost::bind (&SoundAsset::path_from_channel, this, _1, files), interop, metadata);
+
}
-SoundAsset::SoundAsset (
- boost::function<boost::filesystem::path (Channel)> get_path,
- boost::filesystem::path directory,
- string mxf_name,
- boost::signals2::signal<void (float)>* progress,
- int fps,
- int intrinsic_duration,
- int channels,
- bool interop,
- MXFMetadata const & metadata
- )
- : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration)
- , _channels (channels)
- , _sampling_rate (0)
+void
+SoundAsset::create (vector<boost::filesystem::path> const & files)
{
- assert (_channels);
-
- construct (get_path, interop, metadata);
+ create (boost::bind (&SoundAsset::path_from_channel, this, _1, files));
}
-SoundAsset::SoundAsset (boost::filesystem::path directory, string mxf_name)
- : MXFAsset (directory, mxf_name)
- , _channels (0)
+void
+SoundAsset::read ()
{
ASDCP::PCM::MXFReader reader;
if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
_intrinsic_duration = desc.ContainerDuration;
}
-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)
-{
-
-}
-
boost::filesystem::path
SoundAsset::path_from_channel (Channel channel, vector<boost::filesystem::path> const & files)
{
}
void
-SoundAsset::construct (boost::function<boost::filesystem::path (Channel)> get_path, bool interop, MXFMetadata const & metadata)
+SoundAsset::create (boost::function<boost::filesystem::path (Channel)> get_path)
{
ASDCP::Rational asdcp_edit_rate (_edit_rate, 1);
+ assert (_channels > 0);
ASDCP::PCM::WAVParser pcm_parser_channel[_channels];
if (pcm_parser_channel[0].OpenRead (get_path(LEFT).c_str(), asdcp_edit_rate)) {
boost::throw_exception (FileError ("could not open WAV file for reading", get_path(LEFT)));
frame_buffer.Size (ASDCP::PCM::CalcFrameBufferSize (audio_desc));
ASDCP::WriterInfo writer_info;
- MXFAsset::fill_writer_info (&writer_info, _uuid, interop, metadata);
+ MXFAsset::fill_writer_info (&writer_info, _uuid, _interop, _metadata);
ASDCP::PCM::MXFWriter mxf_writer;
if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, audio_desc))) {
}
shared_ptr<SoundAssetWriter>
-SoundAsset::start_write (bool interop, MXFMetadata const & metadata)
+SoundAsset::start_write ()
{
/* XXX: can't we use a shared_ptr here? */
- return shared_ptr<SoundAssetWriter> (new SoundAssetWriter (this, interop, metadata));
+ return shared_ptr<SoundAssetWriter> (new SoundAssetWriter (this));
}
struct SoundAssetWriter::ASDCPState
ASDCP::AESEncContext* encryption_context;
};
-SoundAssetWriter::SoundAssetWriter (SoundAsset* a, bool interop, MXFMetadata const & m)
+SoundAssetWriter::SoundAssetWriter (SoundAsset* a)
: _state (new SoundAssetWriter::ASDCPState)
, _asset (a)
, _finalized (false)
, _frames_written (0)
, _frame_buffer_offset (0)
- , _metadata (m)
{
_state->encryption_context = a->encryption_context ();
_state->frame_buffer.Size (ASDCP::PCM::CalcFrameBufferSize (_state->audio_desc));
memset (_state->frame_buffer.Data(), 0, _state->frame_buffer.Capacity());
- _asset->fill_writer_info (&_state->writer_info, _asset->uuid (), interop, _metadata);
+ _asset->fill_writer_info (&_state->writer_info, _asset->uuid (), _asset->interop(), _asset->metadata());
if (ASDCP_FAILURE (_state->mxf_writer.OpenWrite (_asset->path().string().c_str(), _state->writer_info, _state->audio_desc))) {
boost::throw_exception (FileError ("could not open audio MXF for writing", _asset->path().string()));
private:
friend class SoundAsset;
- SoundAssetWriter (SoundAsset *, bool interop, MXFMetadata const &);
+ SoundAssetWriter (SoundAsset *);
/* no copy construction */
SoundAssetWriter (SoundAssetWriter const &);
bool _finalized;
int _frames_written;
int _frame_buffer_offset;
- MXFMetadata _metadata;
};
/** @brief An asset made up of WAV files */
class SoundAsset : public MXFAsset
{
public:
- /** Construct a SoundAsset, generating the MXF from some WAV files.
- * This may take some time; progress is indicated by emission of the Progress signal.
- * @param files Pathnames of sound files, in the order Left, Right, Centre, Lfe (sub), Left surround, Right surround.
- * @param directory Directory in which to create MXF file.
- * @param mxf_name Name of MXF file to create.
- * @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 intrinsic_duration Length of the whole asset in frames.
- * Note that this is different to entry_point in that the asset will contain no data before start_frame.
- */
- SoundAsset (
- std::vector<boost::filesystem::path> const & files,
- boost::filesystem::path directory,
- std::string mxf_name,
- boost::signals2::signal<void (float)>* progress,
- int fps,
- int intrinsic_duration,
- bool interop,
- MXFMetadata const & metadata = MXFMetadata ()
- );
-
- /** Construct a SoundAsset, generating the MXF from some WAV files.
- * This may take some time; progress is indicated by emission of the Progress signal.
- * @param get_path Functor which returns a WAV file path for a given channel.
- * @param directory Directory in which to create MXF file.
- * @param mxf_name Name of MXF file to create.
- * @param progress Signal to inform of progress.
- * @param fps Frames per second.
- * @param intrinsic_duration Length of the whole asset in frames.
- * @param channels Number of audio channels.
- */
- SoundAsset (
- boost::function<boost::filesystem::path (Channel)> get_path,
- boost::filesystem::path directory,
- std::string mxf_name,
- boost::signals2::signal<void (float)>* progress,
- int fps,
- int intrinsic_duration,
- int channels,
- bool interop,
- MXFMetadata const & metadata = MXFMetadata ()
- );
-
- SoundAsset (
- boost::filesystem::path directory,
- std::string mxf_name
- );
-
- SoundAsset (
- boost::filesystem::path directory,
- std::string mxf_name,
- int fps,
- int channels,
- int sampling_rate
- );
-
- boost::shared_ptr<SoundAssetWriter> start_write (bool, MXFMetadata const & metadata = MXFMetadata ());
+ SoundAsset (boost::filesystem::path directory, std::string mxf_name);
+
+ void read ();
+ void create (std::vector<boost::filesystem::path> const & files);
+ void create (boost::function<boost::filesystem::path (Channel)> get_path);
+
+ boost::shared_ptr<SoundAssetWriter> start_write ();
bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
boost::shared_ptr<const SoundFrame> get_frame (int n) const;
+
+ void set_channels (int c) {
+ _channels = c;
+ }
int channels () const {
return _channels;
private:
std::string key_type () const;
- void construct (boost::function<boost::filesystem::path (Channel)> get_path, bool interop, MXFMetadata const &);
+ void construct (boost::function<boost::filesystem::path (Channel)> get_path);
boost::filesystem::path path_from_channel (Channel channel, std::vector<boost::filesystem::path> const & files);
std::string cpl_node_name () const;
libdcp::DCP d ("build/test/foo");
shared_ptr<libdcp::CPL> cpl (new libdcp::CPL ("build/test/foo", "A Test DCP", libdcp::FEATURE, 24, 24));
- shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset (
- j2c,
- "build/test/foo",
- "video.mxf",
- &d.Progress,
- 24,
- 24,
- libdcp::Size (32, 32),
- false,
- mxf_meta
- ));
+ shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset ("build/test/foo", "video.mxf"));
+ mp->set_progress (&d.Progress);
+ mp->set_edit_rate (24);
+ mp->set_intrinsic_duration (24);
+ mp->set_duration (24);
+ mp->set_size (libdcp::Size (32, 32));
+ mp->set_metadata (mxf_meta);
+ mp->create (j2c);
- shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset (
- wav,
- "build/test/foo",
- "audio.mxf",
- &(d.Progress),
- 24,
- 24,
- 2,
- false,
- mxf_meta
- ));
+ shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset ("build/test/foo", "audio.mxf"));
+ ms->set_progress (&d.Progress);
+ ms->set_edit_rate (24);
+ ms->set_intrinsic_duration (24);
+ ms->set_duration (24);
+ ms->set_channels (2);
+ ms->set_metadata (mxf_meta);
+ ms->create (wav);
cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
d.add_cpl (cpl);
#include "sound_asset.h"
#include "reel.h"
#include "test.h"
+#include "signer_chain.h"
using boost::shared_ptr;
*/
BOOST_AUTO_TEST_CASE (encryption)
{
+ boost::filesystem::remove_all ("build/test/signer");
+ boost::filesystem::create_directory ("build/test/signer");
+ libdcp::make_signer_chain ("build/test/signer");
+
Kumu::libdcp_test = true;
libdcp::MXFMetadata mxf_metadata;
);
shared_ptr<libdcp::CPL> cpl (new libdcp::CPL ("build/test/bar", "A Test DCP", libdcp::FEATURE, 24, 24));
-
- shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset (
- j2c,
- "build/test/bar",
- "video.mxf",
- &d.Progress,
- 24,
- 24,
- libdcp::Size (32, 32),
- false,
- mxf_metadata
- ));
libdcp::Key key;
-
+
+ shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset ("build/test/bar", "video.mxf"));
+ mp->set_progress (&d.Progress);
+ mp->set_edit_rate (24);
+ mp->set_intrinsic_duration (24);
+ mp->set_duration (24);
+ mp->set_size (libdcp::Size (32, 32));
+ mp->set_metadata (mxf_metadata);
mp->set_key (key);
-
- shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset (
- wav,
- "build/test/bar",
- "audio.mxf",
- &(d.Progress),
- 24,
- 24,
- 2,
- false,
- mxf_metadata
- ));
-
+ mp->create (j2c);
+
+ shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset ("build/test/bar", "audio.mxf"));
+ ms->set_progress (&d.Progress);
+ ms->set_edit_rate (24);
+ ms->set_intrinsic_duration (24);
+ mp->set_duration (24);
+ ms->set_channels (2);
+ ms->set_metadata (mxf_metadata);
ms->set_key (key);
+ ms->create (wav);
cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
d.add_cpl (cpl);
p.push_back ("frobozz");
/* Trying to create video/audio MXFs using a non-existant file should throw an exception */
- BOOST_CHECK_THROW (
- new libdcp::MonoPictureAsset (p, "build/test/fred", "video.mxf", &d.Progress, 24, 24, libdcp::Size (32, 32), false),
- libdcp::FileError
- );
+ libdcp::MonoPictureAsset pa ("build/test/fred", "video.mxf");
+ BOOST_CHECK_THROW (pa.create (p), libdcp::FileError);
- BOOST_CHECK_THROW (
- new libdcp::SoundAsset (p, "build/test/fred", "audio.mxf", &d.Progress, 24, 24, false),
- libdcp::FileError
- );
+ libdcp::SoundAsset sa ("build/test/fred", "audio.mxf");
+ sa.set_channels (1);
+ BOOST_CHECK_THROW (sa.create (p), libdcp::FileError);
}
boost::filesystem::remove_all ("build/test/baz");
boost::filesystem::create_directories ("build/test/baz");
- shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset ("build/test/baz", "video1.mxf", 24, libdcp::Size (32, 32)));
- shared_ptr<libdcp::PictureAssetWriter> writer = mp->start_write (false, false);
+ shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset ("build/test/baz", "video1.mxf"));
+ mp->set_edit_rate (24);
+ mp->set_size (libdcp::Size (32, 32));
+ shared_ptr<libdcp::PictureAssetWriter> writer = mp->start_write (false);
int written_size = 0;
for (int i = 0; i < 24; ++i) {
Kumu::ResetTestRNG ();
#endif
- mp.reset (new libdcp::MonoPictureAsset ("build/test/baz", "video2.mxf", 24, libdcp::Size (32, 32)));
- writer = mp->start_write (true, false);
+ mp.reset (new libdcp::MonoPictureAsset ("build/test/baz", "video2.mxf"));
+ mp->set_edit_rate (24);
+ mp->set_size (libdcp::Size (32, 32));
+ writer = mp->start_write (true);
writer->write (data, size);
#include "cpl.h"
#include "picture_frame.h"
#include "argb_frame.h"
+#include "signer_chain.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)
{
+ boost::filesystem::remove_all ("build/test/signer");
+ boost::filesystem::create_directory ("build/test/signer");
+ libdcp::make_signer_chain ("build/test/signer");
+
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"))));
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)
- );
+ shared_ptr<libdcp::MonoPictureAsset> asset_A (new libdcp::MonoPictureAsset (work_dir, "video.mxf"));
+ asset_A->set_edit_rate (24);
+ asset_A->set_intrinsic_duration (24);
+ asset_A->set_size (libdcp::Size (32, 32));
+ asset_A->create (j2c);
libdcp::Key key;
obj.uselib = 'BOOST_TEST OPENJPEG CXML XMLSEC1'
obj.use = 'libdcp'
obj.source = """
- test.cc
+ test.cc
certificates_test.cc
dcp_test.cc
encryption_test.cc
def configure(conf):
conf.load('compiler_cxx')
- conf.env.append_value('CXXFLAGS', ['-Wall', '-Wextra', '-O2', '-D_FILE_OFFSET_BITS=64'])
+ conf.env.append_value('CXXFLAGS', ['-Wall', '-Wextra', '-D_FILE_OFFSET_BITS=64'])
conf.env.append_value('CXXFLAGS', ['-DLIBDCP_VERSION="%s"' % VERSION])
conf.env.TARGET_WINDOWS = conf.options.target_windows