#include "dcp.h"
#include "cpl.h"
-#include "mono_picture_asset.h"
-#include "sound_asset.h"
+#include "mono_picture_mxf.h"
+#include "mono_picture_mxf_writer.h"
+#include "sound_mxf.h"
#include "reel.h"
-/* This method returns the filename of the JPEG2000 file to use for a given frame.
- In this example, we are using the same file for each frame, so we don't bother
- looking at the frame parameter, but it will called with frame=0, frame=1, ...
-*/
-std::string
-video_frame (int /* frame */)
-{
- return "examples/help.j2c";
-}
-
int
main ()
{
- /* Make a DCP object. "My Film DCP" is the directory name for the DCP */
- libdcp::DCP dcp ("My Film DCP");
+ /* Create a directory to put the DCP in */
+ boost::filesystem::create_directory ("DCP");
- /* Now make a CPL object.
-
- "My Film" is the title that will be shown on the projector / TMS when the DCP is ingested.
- FEATURE is the type that the projector will list the DCP as.
- 24 is the frame rate, and the DCP will be 48 frames long (ie 2 seconds at 24 fps).
- */
- boost::shared_ptr<libdcp::CPL> cpl (new libdcp::CPL ("My Film DCP", "My Film", libdcp::FEATURE, 24, 48));
-
- /* 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.
- First, create the object.
+ /* Make a picture MXF. This is a file which combines JPEG2000 files together to make
+ up the video of the DCP. First, create the object, specifying a frame rate of 24 frames
+ per second.
*/
- boost::shared_ptr<libdcp::MonoPictureAsset> picture_asset (
- new libdcp::MonoPictureAsset ("My Film DCP", "video.mxf")
- );
+ boost::shared_ptr<dcp::MonoPictureMXF> picture_mxf (new dcp::MonoPictureMXF (24));
- /* 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".
- */
+ /* Start off a write to it */
+ boost::shared_ptr<dcp::MonoPictureMXFWriter> picture_writer = picture_mxf->start_write ("DCP/picture.mxf", false);
- picture_asset->create (video_frame);
+ /* Write 24 frames of the same JPEG2000 file */
+ dcp::File picture ("examples/help.j2c");
+ for (int i = 0; i < 24; ++i) {
+ picture_writer->write (picture.data(), picture.size());
+ }
- /* 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.
+ /* And finish off */
+ picture_writer->finalize ();
- We could add more files here to use more channels; the file order is:
- Left
- Right
- Centre
- LFE (sub)
- Left surround
- Right surround
+ /* Now create a sound MXF. As before, create an object and a writer.
+ When creating the object we specify the sampling rate (48kHz) and the number of channels (2).
*/
- 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");
-
- /* Now we can create the sound asset using these files */
- 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 (
- boost::shared_ptr<libdcp::Reel> (
- new libdcp::Reel (picture_asset, sound_asset, boost::shared_ptr<libdcp::SubtitleAsset> ())
- )
- );
-
- /* Finally, we call this to write the XML description files to the DCP. After this, the DCP
- is ready to ingest and play.
+ boost::shared_ptr<dcp::SoundMXF> sound_mxf (new dcp::SoundMXF (48000, 2));
+ boost::shared_ptr<dcp::SoundMXFWriter> sound_writer = sound_mxf->start_write ("DCP/sound.mxf", false);
+
+ /* Write some sine waves */
+ float* audio[2];
+ audio[0] = new float[48000];
+ audio[1] = new float[48000];
+ for (int i = 0; i < 48000; ++i) {
+ audio[0][i] = sin (2 * M_PI * i * 440 / 48000) * 0.25;
+ audio[1][i] = sin (2 * M_PI * i * 880 / 48000) * 0.25;
+ }
+ sound_writer->write (audio, 48000);
+
+ /* And tidy up */
+ delete[] audio[0];
+ delete[] audio[1];
+ sound_writer->finalize ();
+
+ /* Now create a reel */
+ shared_ptr<dcp::Reel> reel (new dcp::Reel ());
+
+ /* Add picture and sound to it. The zeros are the `entry points', i.e. the first
+ (video) frame from the MXFs that the reel should play.
*/
- libdcp::XMLMetadata metadata;
- dcp.write_xml (false, metadata);
-
+ reel->add (picture, 0);
+ reel->add (sound, 0);
+
+ /* Make a CPL with this reel */
+ shared_ptr<dcp::CPL> cpl (new dcp::CPL ("My film", dcp::FEATURE));
+ cpl->add (reel);
+
+ /* Write the DCP */
+ list<shared_ptr<dcp::Asset> > assets;
+ asset.push_back (cpl);
+ asset.push_back (picture);
+ asset.push_back (sound);
+ dcp::write ("DCP", assets);
+
return 0;
}
#include "argb_frame.h"
-using namespace libdcp;
+using namespace dcp;
/** Construct an empty ARGBFrame of a given size and with
* undefined contents.
#include <stdint.h>
#include "util.h"
-namespace libdcp
+namespace dcp
{
/** @class ARGBFrame
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014 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
*/
-/** @file src/asset.cc
- * @brief Parent class for assets of DCPs.
- */
-
-#include <iostream>
-#include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/function.hpp>
-#include <libxml++/nodes/element.h>
-#include "AS_DCP.h"
-#include "KM_util.h"
#include "asset.h"
-#include "util.h"
-#include "metadata.h"
-
-using namespace std;
-using namespace boost;
-using namespace libdcp;
-
-Asset::Asset (boost::filesystem::path directory, boost::filesystem::path file_name)
- : _directory (directory)
- , _file_name (file_name)
- , _uuid (make_uuid ())
- , _edit_rate (0)
- , _entry_point (0)
- , _intrinsic_duration (0)
- , _duration (0)
-{
- if (_file_name.empty ()) {
- _file_name = _uuid + ".xml";
- }
-}
-
-void
-Asset::write_to_pkl (xmlpp::Node* node) const
-{
- xmlpp::Node* asset = node->add_child ("Asset");
- asset->add_child("Id")->add_child_text ("urn:uuid:" + _uuid);
- asset->add_child("AnnotationText")->add_child_text (_file_name.string ());
- asset->add_child("Hash")->add_child_text (digest ());
- asset->add_child("Size")->add_child_text (lexical_cast<string> (filesystem::file_size(path())));
- asset->add_child("Type")->add_child_text ("application/mxf");
-}
-
-void
-Asset::write_to_assetmap (xmlpp::Node* node) const
-{
- xmlpp::Node* asset = node->add_child ("Asset");
- asset->add_child("Id")->add_child_text ("urn:uuid:" + _uuid);
- xmlpp::Node* chunk_list = asset->add_child ("ChunkList");
- xmlpp::Node* chunk = chunk_list->add_child ("Chunk");
- chunk->add_child("Path")->add_child_text (_file_name.string ());
- chunk->add_child("VolumeIndex")->add_child_text ("1");
- chunk->add_child("Offset")->add_child_text ("0");
- chunk->add_child("Length")->add_child_text (lexical_cast<string> (filesystem::file_size(path())));
-}
-filesystem::path
-Asset::path () const
-{
- filesystem::path p;
- p /= _directory;
- p /= _file_name;
- return p;
-}
+using std::string;
+using namespace dcp;
-string
-Asset::digest () const
+Asset::Asset ()
{
- if (_digest.empty ()) {
- _digest = make_digest (path().string(), 0);
- }
- return _digest;
}
-void
-Asset::compute_digest (boost::function<void (float)> progress)
+Asset::Asset (string id)
+ : Object (id)
{
- if (!_digest.empty ()) {
- return;
- }
-
- _digest = make_digest (path().string(), &progress);
-}
-
-bool
-Asset::equals (shared_ptr<const Asset> other, EqualityOptions, boost::function<void (NoteType, string)> note) const
-{
- if (_edit_rate != other->_edit_rate) {
- note (ERROR, "asset edit rates differ");
- return false;
- }
-
- if (_intrinsic_duration != other->_intrinsic_duration) {
- note (ERROR, "asset intrinsic durations differ");
- }
-
- if (_duration != other->_duration) {
- note (ERROR, "asset durations differ");
- }
- return true;
}
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014 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
*/
-/** @file src/asset.h
- * @brief Parent class for assets of DCPs.
- */
-
#ifndef LIBDCP_ASSET_H
#define LIBDCP_ASSET_H
-#include <string>
-#include <list>
-#include <boost/filesystem.hpp>
-#include <boost/function.hpp>
-#include <libxml++/libxml++.h>
-#include "types.h"
-
-namespace ASDCP {
- class WriterInfo;
-}
-
-namespace xmlpp {
- class Element;
-}
+#include "object.h"
-namespace libdcp
-{
+namespace dcp {
-/** @brief Parent class for assets of DCPs
- *
- * These are collections of pictures or sound.
+/** @class Asset
+ * @brief Parent class for DCP assets, i.e. picture/sound/subtitles, CPLs and PKLs.
*/
-class Asset
+
+class Asset : public Object
{
public:
- /** Construct an Asset.
- * @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, boost::filesystem::path file_name = "");
-
- virtual ~Asset() {}
-
- /** Write details of the asset to a CPL AssetList node.
- * @param p Parent element.
- */
- virtual void write_to_cpl (xmlpp::Element* p) const = 0;
-
- /** Write details of the asset to a PKL AssetList node.
- * @param p Parent node.
- */
- void write_to_pkl (xmlpp::Node *) const;
-
- /** Write details of the asset to a ASSETMAP stream.
- * @param s Stream.
- */
- void write_to_assetmap (xmlpp::Node *) const;
-
- /** Compute the digest for this asset. Calling this is optional: if
- * it is not called, the digest will be computed when required. However,
- * calling this method allows the caller to see the progress of the
- * computation, which can be long for large assets.
- * @param Called with progress between 0 and 1.
- */
- void compute_digest (boost::function<void (float)> progress);
-
- std::string uuid () const {
- return _uuid;
- }
-
- boost::filesystem::path path () const;
-
- void set_directory (boost::filesystem::path d) {
- _directory = d;
- }
-
- void set_file_name (boost::filesystem::path f) {
- _file_name = f;
- }
-
- int entry_point () const {
- return _entry_point;
- }
-
- int duration () const {
- return _duration;
- }
-
- int intrinsic_duration () const {
- return _intrinsic_duration;
- }
-
- int edit_rate () const {
- return _edit_rate;
- }
-
- void set_entry_point (int e) {
- _entry_point = e;
- }
-
- void set_duration (int d) {
- _duration = d;
- }
-
- void set_intrinsic_duration (int d) {
- _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:
-
- std::string digest () const;
-
- /** Directory that our MXF or XML file is in */
- boost::filesystem::path _directory;
- /** Name of our MXF or XML file */
- boost::filesystem::path _file_name;
- /** Our UUID */
- std::string _uuid;
- /** The edit rate; this is normally equal to the number of video frames per second */
- int _edit_rate;
- /** Start point to present in frames */
- int _entry_point;
- /** Total length in frames */
- int _intrinsic_duration;
- /** Length to present in frames */
- int _duration;
+ Asset ();
+ Asset (std::string id);
-private:
- /** Digest of our MXF or XML file */
- mutable std::string _digest;
};
}
using std::stringstream;
using std::vector;
using boost::shared_ptr;
-using namespace libdcp;
+using namespace dcp;
/** @param c X509 certificate, which this object will take ownership of */
Certificate::Certificate (X509* c)
class Element;
}
-namespace libdcp {
+namespace dcp {
class Certificate
{
EasyDCP player, I think.
*/
-double const libdcp::colour_matrix::xyz_to_rgb[3][3] = {
+double const dcp::colour_matrix::xyz_to_rgb[3][3] = {
{ 3.24096989631653, -1.5373831987381, -0.498610764741898 },
{ -0.96924364566803, 1.87596750259399, 0.0415550582110882 },
{ 0.0556300804018974, -0.203976958990097, 1.05697154998779 }
};
-double const libdcp::colour_matrix::srgb_to_xyz[3][3] = {
+double const dcp::colour_matrix::srgb_to_xyz[3][3] = {
{0.4124564, 0.3575761, 0.1804375},
{0.2126729, 0.7151522, 0.0721750},
{0.0193339, 0.1191920, 0.9503041}
};
-double const libdcp::colour_matrix::rec709_to_xyz[3][3] = {
+double const dcp::colour_matrix::rec709_to_xyz[3][3] = {
{ 0.412390799265959, 0.357584339383878, 0.180480788401834 },
{ 0.21263900587151, 0.715168678767756, 0.0721923153607337 },
{ 0.0193308187155918, 0.119194779794626, 0.950532152249661 }
*/
-namespace libdcp {
+namespace dcp {
namespace colour_matrix {
--- /dev/null
+/*
+ Copyright (C) 2012 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/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/function.hpp>
+#include <libxml++/nodes/element.h>
+#include "AS_DCP.h"
+#include "KM_util.h"
+#include "content.h"
+#include "util.h"
+#include "metadata.h"
+
+using namespace std;
+using namespace boost;
+using namespace dcp;
+
+Content::Content (boost::filesystem::path file)
+ : _file (file)
+ , _edit_rate (0)
+ , _intrinsic_duration (0)
+{
+
+}
+
+Content::Content (int edit_rate)
+ : _edit_rate (edit_rate)
+ , _intrinsic_duration (0)
+{
+
+}
+
+void
+Content::write_to_pkl (xmlpp::Node* node) const
+{
+ xmlpp::Node* asset = node->add_child ("Asset");
+ asset->add_child("Id")->add_child_text ("urn:uuid:" + _id);
+ asset->add_child("AnnotationText")->add_child_text (_id);
+//XXX asset->add_child("Hash")->add_child_text (digest ());
+ asset->add_child("Size")->add_child_text (lexical_cast<string> (filesystem::file_size (_file)));
+ asset->add_child("Type")->add_child_text ("application/mxf");
+}
+
+void
+Content::write_to_assetmap (xmlpp::Node* node) const
+{
+ xmlpp::Node* asset = node->add_child ("Asset");
+ asset->add_child("Id")->add_child_text ("urn:uuid:" + _id);
+ xmlpp::Node* chunk_list = asset->add_child ("ChunkList");
+ xmlpp::Node* chunk = chunk_list->add_child ("Chunk");
+ chunk->add_child("Path")->add_child_text (_file.string ());
+ chunk->add_child("VolumeIndex")->add_child_text ("1");
+ chunk->add_child("Offset")->add_child_text ("0");
+ chunk->add_child("Length")->add_child_text (lexical_cast<string> (filesystem::file_size (_file)));
+}
+
+bool
+Content::equals (shared_ptr<const Content> other, EqualityOptions, boost::function<void (NoteType, string)> note) const
+{
+ // if (_edit_rate != other->_edit_rate) {
+ // note (ERROR, "asset edit rates differ");
+ // return false;
+ // }
+
+ // if (_intrinsic_duration != other->_intrinsic_duration) {
+ // note (ERROR, "asset intrinsic durations differ");
+ // }
+
+ // if (_duration != other->_duration) {
+ // note (ERROR, "asset durations differ");
+ // }
+
+ // return true;
+}
--- /dev/null
+/*
+ Copyright (C) 2012 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.
+
+*/
+
+#ifndef LIBDCP_CONTENT_H
+#define LIBDCP_CONTENT_H
+
+#include <string>
+#include <list>
+#include <boost/filesystem.hpp>
+#include <boost/function.hpp>
+#include <libxml++/libxml++.h>
+#include "types.h"
+#include "asset.h"
+
+namespace ASDCP {
+ class WriterInfo;
+}
+
+namespace xmlpp {
+ class Element;
+}
+
+namespace dcp
+{
+
+/** @class Content
+ * @brief An asset that represents a piece of content, i.e. picture, sound or subtitle.
+ *
+ * Such a piece of content will be contained in a file (either MXF or XML) within a DCP.
+ */
+class Content : public Asset
+{
+public:
+ Content (boost::filesystem::path file);
+ Content (int edit_rate);
+
+ virtual ~Content () {}
+
+ /** Write details of the asset to a PKL AssetList node.
+ * @param p Parent node.
+ */
+ void write_to_pkl (xmlpp::Node *) const;
+
+ /** Write details of the asset to a ASSETMAP stream.
+ * @param s Stream.
+ */
+ void write_to_assetmap (xmlpp::Node *) const;
+
+ boost::filesystem::path file () const {
+ return _file;
+ }
+
+ void set_file (boost::filesystem::path file) {
+ _file = file;
+ }
+
+ int edit_rate () const {
+ return _edit_rate;
+ }
+
+ void set_edit_rate (int r) {
+ _edit_rate = r;
+ }
+
+ void set_entry_point (int64_t p) {
+ _entry_point = p;
+ }
+
+ int64_t intrinsic_duration () const {
+ return _intrinsic_duration;
+ }
+
+ void set_intrinsic_duration (int64_t d) {
+ _intrinsic_duration = d;
+ }
+
+ int64_t duration () const {
+ return _duration;
+ }
+
+ void set_duration (int64_t d) {
+ _duration = d;
+ }
+
+ virtual bool equals (boost::shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, std::string)>) const;
+
+protected:
+ boost::filesystem::path _file;
+ /** The edit rate; this is normally equal to the number of video frames per second */
+ int _edit_rate;
+ int64_t _entry_point;
+ int64_t _intrinsic_duration;
+ int64_t _duration;
+};
+
+}
+
+#endif
#include "cpl.h"
#include "parse/cpl.h"
#include "util.h"
-#include "mono_picture_asset.h"
-#include "stereo_picture_asset.h"
-#include "sound_asset.h"
+#include "mono_picture_mxf.h"
+#include "stereo_picture_mxf.h"
+#include "sound_mxf.h"
#include "subtitle_asset.h"
#include "parse/asset_map.h"
#include "reel.h"
using boost::shared_ptr;
using boost::lexical_cast;
using boost::optional;
-using namespace libdcp;
+using namespace dcp;
CPL::CPL (boost::filesystem::path directory, string name, ContentKind content_kind, int length, int frames_per_second)
: _directory (directory)
, _length (length)
, _fps (frames_per_second)
{
- _id = make_uuid ();
+
}
/** Construct a CPL object from a XML file.
_fps = p->edit_rate.numerator;
_length += p->duration;
- shared_ptr<PictureAsset> picture;
- shared_ptr<SoundAsset> sound;
+ shared_ptr<PictureMXF> picture;
+ shared_ptr<SoundMXF> sound;
shared_ptr<SubtitleAsset> subtitle;
/* Some rather twisted logic to decide if we are 3D or not;
try {
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.reset (new MonoPictureMXF (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);
+// 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) {
/* Trim urn:uuid: */
- picture->set_key_id (p->key_id.substr (9));
+// picture->set_key_id (p->key_id.substr (9));
}
} catch (MXFFileError) {
if (require_mxfs) {
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));
+// picture.reset (new StereoPictureMXF (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);
+// 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) {
/* Trim urn:uuid: */
- picture->set_key_id (p->key_id.substr (9));
+// picture->set_key_id (p->key_id.substr (9));
}
} catch (MXFFileError) {
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));
- shared_ptr<parse::MainSound> s = (*i)->asset_list->main_sound;
+// sound.reset (new SoundMXF (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) {
+// sound->read ();
+// sound->set_entry_point (s->entry_point);
+// sound->set_duration (s->duration);
+// if (s->key_id.length() > 9) {
/* Trim urn:uuid: */
- sound->set_key_id (s->key_id.substr (9));
- }
+// sound->set_key_id (s->key_id.substr (9));
+// }
} catch (MXFFileError) {
if (require_mxfs) {
throw;
if ((*i)->asset_list->main_subtitle) {
- pair<string, shared_ptr<const parse::AssetMapAsset> > asset = asset_from_id (asset_maps, (*i)->asset_list->main_subtitle->id);
+// 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);
+// subtitle->set_entry_point ((*i)->asset_list->main_subtitle->entry_point);
+// subtitle->set_duration ((*i)->asset_list->main_subtitle->duration);
}
- _reels.push_back (shared_ptr<Reel> (new Reel (picture, sound, subtitle)));
+// _reels.push_back (shared_ptr<Reel> (new Reel (picture, sound, subtitle)));
}
}
asset->add_child("Type")->add_child_text ("text/xml");
}
-list<shared_ptr<const Asset> >
+list<shared_ptr<const Content> >
CPL::assets () const
{
- list<shared_ptr<const Asset> > a;
+ list<shared_ptr<const Content> > a;
for (list<shared_ptr<Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) {
if ((*i)->main_picture ()) {
a.push_back ((*i)->main_picture ());
#include "types.h"
#include "certificates.h"
#include "key.h"
+#include "asset.h"
-namespace libdcp {
+namespace dcp {
namespace parse {
class AssetMap;
class AssetMapAsset;
}
-class Asset;
+class Content;
class Reel;
class XMLMetadata;
class MXFMetadata;
class Signer;
class KDM;
-/** @brief A CPL within a DCP */
-class CPL
+/** @class CPL
+ * @brief A Composition Playlist.
+ */
+class CPL : public Asset
{
public:
CPL (boost::filesystem::path directory, std::string name, ContentKind content_kind, int length, int frames_per_second);
return _fps;
}
- std::list<boost::shared_ptr<const Asset> > assets () const;
+ std::list<boost::shared_ptr<const Content> > assets () const;
bool encrypted () const;
void set_mxf_keys (Key);
- std::string id () const {
- return _id;
- }
-
bool equals (CPL const & other, EqualityOptions options, boost::function<void (NoteType, std::string)> note) const;
void write_xml (bool, XMLMetadata const &, boost::shared_ptr<const Signer>) const;
/** reels */
std::list<boost::shared_ptr<Reel> > _reels;
- /** our UUID */
- std::string _id;
/** a SHA1 digest of our XML */
mutable std::string _digest;
};
#include <xmlsec/xmldsig.h>
#include <xmlsec/app.h>
#include "dcp.h"
-#include "asset.h"
-#include "sound_asset.h"
-#include "picture_asset.h"
+#include "sound_mxf.h"
+#include "picture_mxf.h"
#include "subtitle_asset.h"
#include "util.h"
#include "metadata.h"
using std::make_pair;
using boost::shared_ptr;
using boost::lexical_cast;
-using namespace libdcp;
+using namespace dcp;
DCP::DCP (boost::filesystem::path directory)
: _directory (directory)
pkl->add_child("Creator")->add_child_text (metadata.creator);
xmlpp::Element* asset_list = pkl->add_child("AssetList");
- list<shared_ptr<const Asset> > a = assets ();
- for (list<shared_ptr<const Asset> >::const_iterator i = a.begin(); i != a.end(); ++i) {
+ list<shared_ptr<const Content> > a = assets ();
+ for (list<shared_ptr<const Content> >::const_iterator i = a.begin(); i != a.end(); ++i) {
(*i)->write_to_pkl (asset_list);
}
(*i)->write_to_assetmap (asset_list);
}
- list<shared_ptr<const Asset> > a = assets ();
- for (list<shared_ptr<const Asset> >::const_iterator i = a.begin(); i != a.end(); ++i) {
+ list<shared_ptr<const Content> > a = assets ();
+ for (list<shared_ptr<const Content> >::const_iterator i = a.begin(); i != a.end(); ++i) {
(*i)->write_to_assetmap (asset_list);
}
boost::filesystem::path p = _directory;
p /= "ASSETMAP";
if (boost::filesystem::exists (p)) {
- asset_map.reset (new libdcp::parse::AssetMap (p.string ()));
+ asset_map.reset (new dcp::parse::AssetMap (p.string ()));
} else {
p = _directory;
p /= "ASSETMAP.xml";
if (boost::filesystem::exists (p)) {
- asset_map.reset (new libdcp::parse::AssetMap (p.string ()));
+ asset_map.reset (new dcp::parse::AssetMap (p.string ()));
} else {
boost::throw_exception (DCPReadError ("could not find AssetMap file"));
}
boost::throw_exception (FileError ("could not load AssetMap file", _files.asset_map, e.number ()));
}
- for (list<shared_ptr<libdcp::parse::AssetMapAsset> >::const_iterator i = asset_map->assets.begin(); i != asset_map->assets.end(); ++i) {
+ for (list<shared_ptr<dcp::parse::AssetMapAsset> >::const_iterator i = asset_map->assets.begin(); i != asset_map->assets.end(); ++i) {
if ((*i)->chunks.size() != 1) {
boost::throw_exception (XMLError ("unsupported asset chunk count"));
}
class AssetComparator
{
public:
- bool operator() (shared_ptr<const Asset> a, shared_ptr<const Asset> b) {
- return a->uuid() < b->uuid();
+ bool operator() (shared_ptr<const Content> a, shared_ptr<const Content> b) {
+ return a->id() < b->id();
}
};
-list<shared_ptr<const Asset> >
+list<shared_ptr<const Content> >
DCP::assets () const
{
- list<shared_ptr<const Asset> > a;
+ list<shared_ptr<const Content> > a;
for (list<shared_ptr<CPL> >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) {
- list<shared_ptr<const Asset> > t = (*i)->assets ();
+ list<shared_ptr<const Content> > t = (*i)->assets ();
a.merge (t);
}
}
/** @brief Namespace for everything in libdcp */
-namespace libdcp
+namespace dcp
{
-class Asset;
+class Content;
class PictureAsset;
class SoundAsset;
class SubtitleAsset;
* supplemental.add_assets_from (original_version);
* supplemental.read ();
*/
- void add_assets_from (libdcp::DCP const &);
+ void add_assets_from (DCP const &);
bool encrypted () const;
void write_assetmap (std::string pkl_uuid, int pkl_length, bool, XMLMetadata const &) const;
/** @return Assets in all the CPLs in this DCP */
- std::list<boost::shared_ptr<const Asset> > assets () const;
+ std::list<boost::shared_ptr<const Content> > assets () const;
struct Files {
std::list<std::string> cpls;
using namespace std;
using namespace boost;
-using namespace libdcp;
+using namespace dcp;
Time::Time (int frame, int frames_per_second)
: h (0)
}
bool
-libdcp::operator== (Time const & a, Time const & b)
+dcp::operator== (Time const & a, Time const & b)
{
return (a.h == b.h && a.m == b.m && a.s == b.s && a.t == b.t);
}
bool
-libdcp::operator!= (Time const & a, Time const & b)
+dcp::operator!= (Time const & a, Time const & b)
{
return !(a == b);
}
bool
-libdcp::operator<= (Time const & a, Time const & b)
+dcp::operator<= (Time const & a, Time const & b)
{
if (a.h != b.h) {
return a.h <= b.h;
}
bool
-libdcp::operator< (Time const & a, Time const & b)
+dcp::operator< (Time const & a, Time const & b)
{
if (a.h != b.h) {
return a.h < b.h;
}
bool
-libdcp::operator> (Time const & a, Time const & b)
+dcp::operator> (Time const & a, Time const & b)
{
if (a.h != b.h) {
return a.h > b.h;
}
ostream &
-libdcp::operator<< (ostream& s, Time const & t)
+dcp::operator<< (ostream& s, Time const & t)
{
s << t.h << ":" << t.m << ":" << t.s << "." << t.t;
return s;
}
-libdcp::Time
-libdcp::operator+ (Time a, Time const & b)
+dcp::Time
+dcp::operator+ (Time a, Time const & b)
{
Time r;
return r;
}
-libdcp::Time
-libdcp::operator- (Time a, Time const & b)
+dcp::Time
+dcp::operator- (Time a, Time const & b)
{
Time r;
}
float
-libdcp::operator/ (Time a, Time const & b)
+dcp::operator/ (Time a, Time const & b)
{
int64_t const at = a.h * 3600 * 250 + a.m * 60 * 250 + a.s * 250 + a.t;
int64_t const bt = b.h * 3600 * 250 + b.m * 60 * 250 + b.s * 250 + b.t;
#include <iostream>
#include <stdint.h>
-namespace libdcp {
+namespace dcp {
/** @class Time
* @brief A representation of time within a DCP.
#include "compose.hpp"
using std::string;
-using namespace libdcp;
+using namespace dcp;
FileError::FileError (std::string const & message, boost::filesystem::path filename, int number)
: _message (String::compose ("%1 (error %2) (%3)", message, filename.string(), number))
* @brief Exceptions thrown by libdcp.
*/
-namespace libdcp
+namespace dcp
{
/** @brief An exception related to a file */
#include "gamma_lut.h"
#include "lut_cache.h"
-using namespace libdcp;
+using namespace dcp;
LUTCache<GammaLUT> GammaLUT::cache;
#include "lut.h"
#include "lut_cache.h"
-namespace libdcp {
+namespace dcp {
class GammaLUT : public LUT
{
#include "image.h"
using boost::shared_ptr;
-using namespace libdcp;
+using namespace dcp;
Image::Image (Size s)
: _size (s)
#include "util.h"
-namespace libdcp {
+namespace dcp {
class Image
{
#include "exceptions.h"
#include "signer.h"
#include "cpl.h"
-#include "mxf_asset.h"
+#include "mxf.h"
#include "xml/kdm_smpte.h"
using std::list;
using std::setfill;
using std::cout;
using boost::shared_ptr;
-using namespace libdcp;
+using namespace dcp;
KDM::KDM (boost::filesystem::path kdm, boost::filesystem::path private_key)
: _xml_kdm (new xml::DCinemaSecurityMessage (kdm))
*/
apu.authorized_device_info.device_list.push_back ("2jmj7l5rSw0yVb/vlWAYkK/YBwk=");
- list<shared_ptr<const Asset> > assets = cpl->assets ();
- for (list<shared_ptr<const Asset> >::iterator i = assets.begin(); i != assets.end(); ++i) {
+ list<shared_ptr<const Content> > assets = cpl->assets ();
+ for (list<shared_ptr<const Content> >::iterator i = assets.begin(); i != assets.end(); ++i) {
/* XXX: non-MXF assets? */
- shared_ptr<const MXFAsset> mxf = boost::dynamic_pointer_cast<const MXFAsset> (*i);
+ shared_ptr<const MXF> mxf = boost::dynamic_pointer_cast<const MXF> (*i);
if (mxf) {
apu.key_id_list.push_back (xml::TypedKeyId (mxf->key_type(), "urn:uuid:" + mxf->key_id()));
}
/* AuthenticatedPrivate */
- for (list<shared_ptr<const Asset> >::iterator i = assets.begin(); i != assets.end(); ++i) {
+ for (list<shared_ptr<const Content> >::iterator i = assets.begin(); i != assets.end(); ++i) {
/* XXX: non-MXF assets? */
- shared_ptr<const MXFAsset> mxf = boost::dynamic_pointer_cast<const MXFAsset> (*i);
+ shared_ptr<const MXF> mxf = boost::dynamic_pointer_cast<const MXF> (*i);
if (mxf) {
KDMKey kkey (
signer, cpl->id (), mxf->key_type (), mxf->key_id (),
}
bool
-libdcp::operator== (libdcp::KDMKey const & a, libdcp::KDMKey const & b)
+dcp::operator== (dcp::KDMKey const & a, dcp::KDMKey const & b)
{
if (memcmp (a._signer_thumbprint, b._signer_thumbprint, 20) != 0) {
return false;
class kdm_key_test;
-namespace libdcp {
+namespace dcp {
namespace xml {
class DCinemaSecurityMessage;
using std::stringstream;
using std::setw;
using std::setfill;
-using namespace libdcp;
+using namespace dcp;
Key::Key ()
: _value (new uint8_t[ASDCP::KeyLen])
}
bool
-libdcp::operator== (Key const & a, Key const & b)
+dcp::operator== (Key const & a, Key const & b)
{
return memcmp (a.value(), b.value(), ASDCP::KeyLen) == 0;
}
bool
-libdcp::operator!= (Key const & a, Key const & b)
+dcp::operator!= (Key const & a, Key const & b)
{
return !(a == b);
}
#include <stdint.h>
-namespace libdcp {
+namespace dcp {
/** @class Key
* @brief A key for encrypting MXFs.
#include <cmath>
#include <boost/utility.hpp>
-namespace libdcp {
+namespace dcp {
class LUT : boost::noncopyable
{
#include "util.h"
using namespace std;
-using namespace libdcp;
+using namespace dcp;
MXFMetadata::MXFMetadata ()
: company_name ("libdcp")
class utc_offset_to_string_test;
-namespace libdcp
+namespace dcp
{
class MXFMetadata
+++ /dev/null
-/*
- Copyright (C) 2012-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 "mono_picture_asset.h"
-#include "mono_picture_asset_writer.h"
-#include "AS_DCP.h"
-#include "KM_fileio.h"
-#include "exceptions.h"
-#include "mono_picture_frame.h"
-
-using std::string;
-using std::vector;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using boost::lexical_cast;
-using namespace libdcp;
-
-MonoPictureAsset::MonoPictureAsset (boost::filesystem::path directory, boost::filesystem::path mxf_name)
- : PictureAsset (directory, mxf_name)
-{
-
-}
-
-void
-MonoPictureAsset::create (vector<boost::filesystem::path> const & files)
-{
- create (boost::bind (&MonoPictureAsset::path_from_list, this, _1, files));
-}
-
-void
-MonoPictureAsset::create (boost::function<boost::filesystem::path (int)> get_path)
-{
- ASDCP::JP2K::CodestreamParser j2k_parser;
- ASDCP::JP2K::FrameBuffer frame_buffer (4 * Kumu::Megabyte);
- Kumu::Result_t r = j2k_parser.OpenReadFrame (get_path(0).string().c_str(), frame_buffer);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (FileError ("could not open JPEG2000 file for reading", get_path(0), r));
- }
-
- ASDCP::JP2K::PictureDescriptor picture_desc;
- j2k_parser.FillPictureDescriptor (picture_desc);
- picture_desc.EditRate = ASDCP::Rational (_edit_rate, 1);
-
- ASDCP::WriterInfo writer_info;
- fill_writer_info (&writer_info);
-
- ASDCP::JP2K::MXFWriter mxf_writer;
- r = mxf_writer.OpenWrite (path().string().c_str(), writer_info, picture_desc, 16384, false);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for writing", path().string(), r));
- }
-
- for (int i = 0; i < _intrinsic_duration; ++i) {
-
- boost::filesystem::path const path = get_path (i);
-
- Kumu::Result_t r = j2k_parser.OpenReadFrame (path.string().c_str(), frame_buffer);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (FileError ("could not open JPEG2000 file for reading", path, r));
- }
-
- r = mxf_writer.WriteFrame (frame_buffer, _encryption_context, 0);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("error in writing video MXF", this->path().string(), r));
- }
-
- if (_progress) {
- (*_progress) (0.5 * float (i) / _intrinsic_duration);
- }
- }
-
- r = mxf_writer.Finalize();
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("error in finalising video MXF", path().string(), r));
- }
-}
-
-void
-MonoPictureAsset::read ()
-{
- ASDCP::JP2K::MXFReader reader;
- Kumu::Result_t r = reader.OpenRead (path().string().c_str());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r));
- }
-
- 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 files[f];
-}
-
-shared_ptr<const MonoPictureFrame>
-MonoPictureAsset::get_frame (int n) const
-{
- return shared_ptr<const MonoPictureFrame> (new MonoPictureFrame (path(), n, _decryption_context));
-}
-
-bool
-MonoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
-{
- if (!MXFAsset::equals (other, opt, note)) {
- return false;
- }
-
- ASDCP::JP2K::MXFReader reader_A;
- Kumu::Result_t r = reader_A.OpenRead (path().string().c_str());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r));
- }
-
- ASDCP::JP2K::MXFReader reader_B;
- r = reader_B.OpenRead (other->path().string().c_str());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r));
- }
-
- ASDCP::JP2K::PictureDescriptor desc_A;
- if (ASDCP_FAILURE (reader_A.FillPictureDescriptor (desc_A))) {
- boost::throw_exception (DCPReadError ("could not read video MXF information"));
- }
- ASDCP::JP2K::PictureDescriptor desc_B;
- if (ASDCP_FAILURE (reader_B.FillPictureDescriptor (desc_B))) {
- boost::throw_exception (DCPReadError ("could not read video MXF information"));
- }
-
- if (!descriptor_equals (desc_A, desc_B, note)) {
- return false;
- }
-
- shared_ptr<const MonoPictureAsset> other_picture = dynamic_pointer_cast<const MonoPictureAsset> (other);
- assert (other_picture);
-
- for (int i = 0; i < _intrinsic_duration; ++i) {
- if (i >= other_picture->intrinsic_duration()) {
- return false;
- }
-
- note (PROGRESS, "Comparing video frame " + lexical_cast<string> (i) + " of " + lexical_cast<string> (_intrinsic_duration));
- shared_ptr<const MonoPictureFrame> frame_A = get_frame (i);
- shared_ptr<const MonoPictureFrame> frame_B = other_picture->get_frame (i);
-
- if (!frame_buffer_equals (
- i, opt, note,
- frame_A->j2k_data(), frame_A->j2k_size(),
- frame_B->j2k_data(), frame_B->j2k_size()
- )) {
- return false;
- }
- }
-
- return true;
-}
-
-shared_ptr<PictureAssetWriter>
-MonoPictureAsset::start_write (bool overwrite)
-{
- /* XXX: can't we use shared_ptr here? */
- return shared_ptr<MonoPictureAssetWriter> (new MonoPictureAssetWriter (this, overwrite));
-}
-
-string
-MonoPictureAsset::cpl_node_name () const
-{
- return "MainPicture";
-}
-
-int
-MonoPictureAsset::edit_rate_factor () const
-{
- return 1;
-}
+++ /dev/null
-/*
- Copyright (C) 2012-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.
-
-*/
-
-#ifndef LIBDCP_MONO_PICTURE_ASSET_H
-#define LIBDCP_MONO_PICTURE_ASSET_H
-
-#include "picture_asset.h"
-
-namespace libdcp {
-
-/** A 2D (monoscopic) picture asset */
-class MonoPictureAsset : public PictureAsset
-{
-public:
- MonoPictureAsset (boost::filesystem::path directory, boost::filesystem::path mxf_name);
-
- void read ();
-
- /** The following parameters must be set up (if required) before calling this:
- * Interop mode (set_interop)
- * Edit rate (set_edit_rate)
- * MXF Metadata (set_metadata)
- */
- void create (std::vector<boost::filesystem::path> const & files);
-
- /** The following parameters must be set up (if required) before calling this:
- * Interop mode (set_interop)
- * Edit rate (set_edit_rate)
- * MXF Metadata (set_metadata)
- */
- void create (boost::function<boost::filesystem::path (int)> get_path);
-
- /** Start a progressive write to a MonoPictureAsset */
- 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;
-
-private:
- 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;
-};
-
-}
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2012-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 "AS_DCP.h"
-#include "KM_fileio.h"
-#include "mono_picture_asset_writer.h"
-#include "exceptions.h"
-#include "picture_asset.h"
-
-#include "picture_asset_writer_common.cc"
-
-using std::istream;
-using std::ostream;
-using std::string;
-using boost::shared_ptr;
-using boost::lexical_cast;
-using namespace libdcp;
-
-struct MonoPictureAssetWriter::ASDCPState : public ASDCPStateBase
-{
- ASDCP::JP2K::MXFWriter mxf_writer;
-};
-
-/** @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)
- : PictureAssetWriter (asset, overwrite)
- , _state (new MonoPictureAssetWriter::ASDCPState)
-{
- _state->encryption_context = asset->encryption_context ();
-}
-
-void
-MonoPictureAssetWriter::start (uint8_t* data, int size)
-{
- libdcp::start (this, _state, _asset, data, size);
-}
-
-FrameInfo
-MonoPictureAssetWriter::write (uint8_t* data, int size)
-{
- assert (!_finalized);
-
- if (!_started) {
- start (data, size);
- }
-
- if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) {
- boost::throw_exception (MiscError ("could not parse J2K frame"));
- }
-
- uint64_t const before_offset = _state->mxf_writer.Tell ();
-
- string hash;
- ASDCP::Result_t const r = _state->mxf_writer.WriteFrame (_state->frame_buffer, _state->encryption_context, 0, &hash);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string(), r));
- }
-
- ++_frames_written;
- return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
-}
-
-void
-MonoPictureAssetWriter::fake_write (int size)
-{
- assert (_started);
- assert (!_finalized);
-
- Kumu::Result_t r = _state->mxf_writer.FakeWriteFrame (size);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string(), r));
- }
-
- ++_frames_written;
-}
-
-void
-MonoPictureAssetWriter::finalize ()
-{
- assert (!_finalized);
-
- Kumu::Result_t r = _state->mxf_writer.Finalize();
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("error in finalizing video MXF", _asset->path().string(), r));
- }
-
- _finalized = true;
- _asset->set_intrinsic_duration (_frames_written);
- _asset->set_duration (_frames_written);
-}
-
+++ /dev/null
-/*
- Copyright (C) 2012-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 <stdint.h>
-#include <string>
-#include <fstream>
-#include <boost/shared_ptr.hpp>
-#include <boost/utility.hpp>
-#include "picture_asset_writer.h"
-
-namespace libdcp {
-
-/** A helper class for writing to MonoPictureAssets progressively (i.e. writing frame-by-frame,
- * rather than giving libdcp all the frames in one go).
- *
- * Objects of this class can only be created with MonoPictureAsset::start_write().
- *
- * Frames can be written to the MonoPictureAsset by calling write() with a JPEG2000 image
- * (a verbatim .j2c file). finalize() must be called after the last frame has been written.
- * The action of finalize() can't be done in MonoPictureAssetWriter's destructor as it may
- * throw an exception.
- */
-class MonoPictureAssetWriter : public PictureAssetWriter
-{
-public:
- FrameInfo write (uint8_t *, int);
- void fake_write (int size);
- void finalize ();
-
-private:
- friend class MonoPictureAsset;
-
- MonoPictureAssetWriter (PictureAsset *, bool);
- void start (uint8_t *, int);
-
- /* do this with an opaque pointer so we don't have to include
- ASDCP headers
- */
-
- struct ASDCPState;
- boost::shared_ptr<ASDCPState> _state;
-};
-
-}
using std::string;
using boost::shared_ptr;
-using namespace libdcp;
+using namespace dcp;
/** Make a picture frame from a 2D (monoscopic) asset.
* @param mxf_path Path to the asset's MXF file.
class AESDecContext;
}
-namespace libdcp {
+namespace dcp {
class ARGBFrame;
--- /dev/null
+/*
+ Copyright (C) 2012-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 "mono_picture_mxf.h"
+#include "mono_picture_mxf_writer.h"
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "exceptions.h"
+#include "mono_picture_frame.h"
+
+using std::string;
+using std::vector;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using boost::lexical_cast;
+using namespace dcp;
+
+MonoPictureMXF::MonoPictureMXF (boost::filesystem::path file)
+ : PictureMXF (file)
+{
+ ASDCP::JP2K::MXFReader reader;
+ Kumu::Result_t r = reader.OpenRead (file.string().c_str());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", file.string(), r));
+ }
+
+ 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;
+}
+
+MonoPictureMXF::MonoPictureMXF (int edit_rate)
+ : PictureMXF (edit_rate)
+{
+
+}
+
+shared_ptr<const MonoPictureFrame>
+MonoPictureMXF::get_frame (int n) const
+{
+ return shared_ptr<const MonoPictureFrame> (new MonoPictureFrame (_file, n, _decryption_context));
+}
+
+bool
+MonoPictureMXF::equals (shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
+{
+ if (!MXF::equals (other, opt, note)) {
+ return false;
+ }
+
+ ASDCP::JP2K::MXFReader reader_A;
+ Kumu::Result_t r = reader_A.OpenRead (_file.string().c_str());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", _file.string(), r));
+ }
+
+ ASDCP::JP2K::MXFReader reader_B;
+ r = reader_B.OpenRead (other->file().string().c_str());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", other->file().string(), r));
+ }
+
+ ASDCP::JP2K::PictureDescriptor desc_A;
+ if (ASDCP_FAILURE (reader_A.FillPictureDescriptor (desc_A))) {
+ boost::throw_exception (DCPReadError ("could not read video MXF information"));
+ }
+ ASDCP::JP2K::PictureDescriptor desc_B;
+ if (ASDCP_FAILURE (reader_B.FillPictureDescriptor (desc_B))) {
+ boost::throw_exception (DCPReadError ("could not read video MXF information"));
+ }
+
+ if (!descriptor_equals (desc_A, desc_B, note)) {
+ return false;
+ }
+
+ shared_ptr<const MonoPictureMXF> other_picture = dynamic_pointer_cast<const MonoPictureMXF> (other);
+ assert (other_picture);
+
+ for (int i = 0; i < _intrinsic_duration; ++i) {
+ if (i >= other_picture->intrinsic_duration()) {
+ return false;
+ }
+
+ note (PROGRESS, "Comparing video frame " + lexical_cast<string> (i) + " of " + lexical_cast<string> (_intrinsic_duration));
+ shared_ptr<const MonoPictureFrame> frame_A = get_frame (i);
+ shared_ptr<const MonoPictureFrame> frame_B = other_picture->get_frame (i);
+
+ if (!frame_buffer_equals (
+ i, opt, note,
+ frame_A->j2k_data(), frame_A->j2k_size(),
+ frame_B->j2k_data(), frame_B->j2k_size()
+ )) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+shared_ptr<PictureMXFWriter>
+MonoPictureMXF::start_write (boost::filesystem::path file, bool overwrite)
+{
+ /* XXX: can't we use shared_ptr here? */
+ return shared_ptr<MonoPictureMXFWriter> (new MonoPictureMXFWriter (this, file, overwrite));
+}
+
+string
+MonoPictureMXF::cpl_node_name () const
+{
+ return "MainPicture";
+}
+
+int
+MonoPictureMXF::edit_rate_factor () const
+{
+ return 1;
+}
--- /dev/null
+/*
+ Copyright (C) 2012-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.
+
+*/
+
+#ifndef LIBDCP_MONO_PICTURE_MXF_H
+#define LIBDCP_MONO_PICTURE_MXF_H
+
+#include "picture_mxf.h"
+
+namespace dcp {
+
+/** @class MonoPictureMXF
+ * @brief A 2D (monoscopic) picture MXF.
+ */
+class MonoPictureMXF : public PictureMXF
+{
+public:
+ /** Create a MonoPictureMXF by reading a file.
+ * @param file MXF file to read.
+ */
+ MonoPictureMXF (boost::filesystem::path file);
+
+ /** Create a MonoPictureMXF with a given edit rate.
+ * @param edit_rate Edit rate (i.e. frame rate) in frames per second.
+ */
+ MonoPictureMXF (int edit_rate);
+
+ /** Start a progressive write to a MonoPictureMXF */
+ boost::shared_ptr<PictureMXFWriter> start_write (boost::filesystem::path, bool);
+
+ boost::shared_ptr<const MonoPictureFrame> get_frame (int n) const;
+ bool equals (boost::shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
+
+private:
+ std::string cpl_node_name () const;
+ int edit_rate_factor () const;
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2012-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 "AS_DCP.h"
+#include "KM_fileio.h"
+#include "mono_picture_mxf_writer.h"
+#include "exceptions.h"
+#include "picture_mxf.h"
+
+#include "picture_mxf_writer_common.cc"
+
+using std::istream;
+using std::ostream;
+using std::string;
+using boost::shared_ptr;
+using boost::lexical_cast;
+using namespace dcp;
+
+struct MonoPictureMXFWriter::ASDCPState : public ASDCPStateBase
+{
+ ASDCP::JP2K::MXFWriter mxf_writer;
+};
+
+/** @param a Asset to write to. `a' must not be deleted while
+ * this writer class still exists, or bad things will happen.
+ */
+MonoPictureMXFWriter::MonoPictureMXFWriter (PictureMXF* asset, boost::filesystem::path file, bool overwrite)
+ : PictureMXFWriter (asset, file, overwrite)
+ , _state (new MonoPictureMXFWriter::ASDCPState)
+{
+ _state->encryption_context = asset->encryption_context ();
+}
+
+void
+MonoPictureMXFWriter::start (uint8_t* data, int size)
+{
+ dcp::start (this, _state, _mxf, data, size);
+}
+
+FrameInfo
+MonoPictureMXFWriter::write (uint8_t* data, int size)
+{
+ assert (!_finalized);
+
+ if (!_started) {
+ start (data, size);
+ }
+
+ if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) {
+ boost::throw_exception (MiscError ("could not parse J2K frame"));
+ }
+
+ uint64_t const before_offset = _state->mxf_writer.Tell ();
+
+ string hash;
+ ASDCP::Result_t const r = _state->mxf_writer.WriteFrame (_state->frame_buffer, _state->encryption_context, 0, &hash);
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("error in writing video MXF", _file.string(), r));
+ }
+
+ ++_frames_written;
+ return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
+}
+
+void
+MonoPictureMXFWriter::fake_write (int size)
+{
+ assert (_started);
+ assert (!_finalized);
+
+ Kumu::Result_t r = _state->mxf_writer.FakeWriteFrame (size);
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("error in writing video MXF", _mxf->file().string(), r));
+ }
+
+ ++_frames_written;
+}
+
+void
+MonoPictureMXFWriter::finalize ()
+{
+ assert (!_finalized);
+
+ Kumu::Result_t r = _state->mxf_writer.Finalize();
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("error in finalizing video MXF", _mxf->file().string(), r));
+ }
+
+ _finalized = true;
+ _mxf->set_intrinsic_duration (_frames_written);
+ _mxf->set_duration (_frames_written);
+}
+
--- /dev/null
+/*
+ Copyright (C) 2012-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 <stdint.h>
+#include <string>
+#include <fstream>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include "picture_mxf_writer.h"
+
+namespace dcp {
+
+/** A helper class for writing to MonoPictureMXFs.
+ *
+ * Objects of this class can only be created with MonoPictureMXF::start_write().
+ *
+ * Frames can be written to the MonoPictureAsset by calling write() with a JPEG2000 image
+ * (a verbatim .j2c file). finalize() must be called after the last frame has been written.
+ * The action of finalize() can't be done in MonoPictureAssetWriter's destructor as it may
+ * throw an exception.
+ */
+class MonoPictureMXFWriter : public PictureMXFWriter
+{
+public:
+ FrameInfo write (uint8_t *, int);
+ void fake_write (int size);
+ void finalize ();
+
+private:
+ friend class MonoPictureMXF;
+
+ MonoPictureMXFWriter (PictureMXF *, boost::filesystem::path file, bool);
+ void start (uint8_t *, int);
+
+ /* do this with an opaque pointer so we don't have to include
+ ASDCP headers
+ */
+
+ struct ASDCPState;
+ boost::shared_ptr<ASDCPState> _state;
+};
+
+}
--- /dev/null
+/*
+ Copyright (C) 2012 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.
+
+*/
+
+/** @file src/asset.cc
+ * @brief Parent class for assets of DCPs made up of MXF files.
+ */
+
+#include <iostream>
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include <libxml++/nodes/element.h>
+#include "AS_DCP.h"
+#include "KM_prng.h"
+#include "KM_util.h"
+#include "mxf.h"
+#include "util.h"
+#include "metadata.h"
+#include "exceptions.h"
+#include "kdm.h"
+
+using std::string;
+using std::list;
+using std::pair;
+using boost::shared_ptr;
+using boost::lexical_cast;
+using boost::dynamic_pointer_cast;
+using namespace dcp;
+
+MXF::MXF (boost::filesystem::path file)
+ : Content (file)
+ , _progress (0)
+ , _encryption_context (0)
+ , _decryption_context (0)
+ , _interop (false)
+{
+
+}
+
+MXF::~MXF ()
+{
+ delete _encryption_context;
+ delete _decryption_context;
+}
+
+void
+MXF::fill_writer_info (ASDCP::WriterInfo* writer_info)
+{
+ writer_info->ProductVersion = _metadata.product_version;
+ writer_info->CompanyName = _metadata.company_name;
+ writer_info->ProductName = _metadata.product_name.c_str();
+
+ if (_interop) {
+ writer_info->LabelSetType = ASDCP::LS_MXF_INTEROP;
+ } else {
+ writer_info->LabelSetType = ASDCP::LS_MXF_SMPTE;
+ }
+ unsigned int c;
+ Kumu::hex2bin (_id.c_str(), writer_info->AssetUUID, Kumu::UUID_Length, &c);
+ assert (c == Kumu::UUID_Length);
+
+ if (_key) {
+ Kumu::GenRandomUUID (writer_info->ContextID);
+ writer_info->EncryptedEssence = true;
+
+ unsigned int c;
+ Kumu::hex2bin (_key_id.c_str(), writer_info->CryptographicKeyID, Kumu::UUID_Length, &c);
+ assert (c == Kumu::UUID_Length);
+ }
+}
+
+bool
+MXF::equals (shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
+{
+ if (!Content::equals (other, opt, note)) {
+ return false;
+ }
+
+ shared_ptr<const MXF> other_mxf = dynamic_pointer_cast<const MXF> (other);
+ if (!other_mxf) {
+ note (ERROR, "comparing an MXF asset with a non-MXF asset");
+ return false;
+ }
+
+ if (_file != other_mxf->file ()) {
+ note (ERROR, "MXF names differ");
+ if (!opt.mxf_names_can_differ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void
+MXF::write_to_cpl (xmlpp::Element* node) const
+{
+ pair<string, string> const attr = cpl_node_attribute ();
+ xmlpp::Element* a = node->add_child (cpl_node_name ());
+ if (!attr.first.empty ()) {
+ a->set_attribute (attr.first, attr.second);
+ }
+ a->add_child ("Id")->add_child_text ("urn:uuid:" + _id);
+ a->add_child ("AnnotationText")->add_child_text (_file.string ());
+ a->add_child ("EditRate")->add_child_text (lexical_cast<string> (_edit_rate) + " 1");
+ a->add_child ("IntrinsicDuration")->add_child_text (lexical_cast<string> (_intrinsic_duration));
+ a->add_child ("EntryPoint")->add_child_text (lexical_cast<string> (_entry_point));
+ a->add_child ("Duration")->add_child_text (lexical_cast<string> (_duration));
+ if (!_key_id.empty ()) {
+ a->add_child("KeyId")->add_child_text ("urn:uuid:" + _key_id);
+ }
+}
+
+void
+MXF::set_key (Key key)
+{
+ _key = key;
+
+ if (_key_id.empty ()) {
+ /* No key ID so far; we now need one */
+ _key_id = make_uuid ();
+ }
+
+ _decryption_context = new ASDCP::AESDecContext;
+ if (ASDCP_FAILURE (_decryption_context->InitKey (_key->value ()))) {
+ throw MiscError ("could not set up decryption context");
+ }
+
+ _encryption_context = new ASDCP::AESEncContext;
+ if (ASDCP_FAILURE (_encryption_context->InitKey (_key->value ()))) {
+ throw MiscError ("could not set up encryption context");
+ }
+
+ uint8_t cbc_buffer[ASDCP::CBC_BLOCK_SIZE];
+
+ Kumu::FortunaRNG rng;
+ if (ASDCP_FAILURE (_encryption_context->SetIVec (rng.FillRandom (cbc_buffer, ASDCP::CBC_BLOCK_SIZE)))) {
+ throw MiscError ("could not set up CBC initialization vector");
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 2012 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.
+
+*/
+
+#ifndef LIBDCP_MXF_ASSET_H
+#define LIBDCP_MXF_ASSET_H
+
+#include <boost/signals2.hpp>
+#include "content.h"
+#include "key.h"
+#include "metadata.h"
+
+namespace ASDCP {
+ class AESEncContext;
+ class AESDecContext;
+}
+
+namespace dcp
+{
+
+class MXFMetadata;
+
+/** @class MXF
+ * @brief Parent class for classes which represent MXF files.
+ */
+class MXF : public Content
+{
+public:
+ MXF (boost::filesystem::path file);
+ MXF (int edit_rate);
+
+ ~MXF ();
+
+ virtual bool equals (boost::shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
+ virtual void write_to_cpl (xmlpp::Element *) const;
+ virtual std::string key_type () const = 0;
+
+ /** Fill in a ADSCP::WriteInfo struct.
+ * @param w struct to fill in.
+ */
+ void fill_writer_info (ASDCP::WriterInfo* w);
+
+ void set_progress (boost::signals2::signal<void (float)>* progress) {
+ _progress = progress;
+ }
+
+ bool encrypted () const {
+ return !_key_id.empty ();
+ }
+
+ void set_key_id (std::string i) {
+ _key_id = i;
+ }
+
+ std::string key_id () const {
+ return _key_id;
+ }
+
+ void set_key (Key);
+
+ boost::optional<Key> key () const {
+ return _key;
+ }
+
+ ASDCP::AESEncContext* encryption_context () const {
+ return _encryption_context;
+ }
+
+ void set_metadata (MXFMetadata m) {
+ _metadata = m;
+ }
+
+ MXFMetadata metadata () const {
+ return _metadata;
+ }
+
+ /** Set whether or not the asset should be written in Interop mode.
+ * @param i true to use interop.
+ */
+ 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 () const {
+ return std::make_pair ("", "");
+ }
+
+ /** Signal to emit to report progress, or 0 */
+ boost::signals2::signal<void (float)>* _progress;
+ ASDCP::AESEncContext* _encryption_context;
+ ASDCP::AESDecContext* _decryption_context;
+ std::string _key_id;
+ boost::optional<Key> _key;
+ MXFMetadata _metadata;
+ bool _interop;
+};
+
+}
+
+#endif
+++ /dev/null
-/*
- Copyright (C) 2012 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.
-
-*/
-
-/** @file src/asset.cc
- * @brief Parent class for assets of DCPs made up of MXF files.
- */
-
-#include <iostream>
-#include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
-#include <libxml++/nodes/element.h>
-#include "AS_DCP.h"
-#include "KM_prng.h"
-#include "KM_util.h"
-#include "mxf_asset.h"
-#include "util.h"
-#include "metadata.h"
-#include "exceptions.h"
-#include "kdm.h"
-
-using std::string;
-using std::list;
-using std::pair;
-using boost::shared_ptr;
-using boost::lexical_cast;
-using boost::dynamic_pointer_cast;
-using namespace libdcp;
-
-MXFAsset::MXFAsset (boost::filesystem::path directory, boost::filesystem::path file_name)
- : Asset (directory, file_name)
- , _progress (0)
- , _encryption_context (0)
- , _decryption_context (0)
- , _interop (false)
-{
-
-}
-
-MXFAsset::~MXFAsset ()
-{
- delete _encryption_context;
- delete _decryption_context;
-}
-
-void
-MXFAsset::fill_writer_info (ASDCP::WriterInfo* writer_info)
-{
- writer_info->ProductVersion = _metadata.product_version;
- writer_info->CompanyName = _metadata.company_name;
- writer_info->ProductName = _metadata.product_name.c_str();
-
- if (_interop) {
- writer_info->LabelSetType = ASDCP::LS_MXF_INTEROP;
- } else {
- writer_info->LabelSetType = ASDCP::LS_MXF_SMPTE;
- }
- unsigned int c;
- Kumu::hex2bin (_uuid.c_str(), writer_info->AssetUUID, Kumu::UUID_Length, &c);
- assert (c == Kumu::UUID_Length);
-
- if (_key) {
- Kumu::GenRandomUUID (writer_info->ContextID);
- writer_info->EncryptedEssence = true;
-
- unsigned int c;
- Kumu::hex2bin (_key_id.c_str(), writer_info->CryptographicKeyID, Kumu::UUID_Length, &c);
- assert (c == Kumu::UUID_Length);
- }
-}
-
-bool
-MXFAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
-{
- if (!Asset::equals (other, opt, note)) {
- return false;
- }
-
- shared_ptr<const MXFAsset> other_mxf = dynamic_pointer_cast<const MXFAsset> (other);
- if (!other_mxf) {
- note (ERROR, "comparing an MXF asset with a non-MXF asset");
- return false;
- }
-
- if (_file_name != other_mxf->_file_name) {
- note (ERROR, "MXF names differ");
- if (!opt.mxf_names_can_differ) {
- return false;
- }
- }
-
- return true;
-}
-
-void
-MXFAsset::write_to_cpl (xmlpp::Element* node) const
-{
- pair<string, string> const attr = cpl_node_attribute ();
- xmlpp::Element* a = node->add_child (cpl_node_name ());
- if (!attr.first.empty ()) {
- a->set_attribute (attr.first, attr.second);
- }
- a->add_child ("Id")->add_child_text ("urn:uuid:" + _uuid);
- a->add_child ("AnnotationText")->add_child_text (_file_name.string ());
- a->add_child ("EditRate")->add_child_text (lexical_cast<string> (_edit_rate) + " 1");
- a->add_child ("IntrinsicDuration")->add_child_text (lexical_cast<string> (_intrinsic_duration));
- a->add_child ("EntryPoint")->add_child_text (lexical_cast<string> (_entry_point));
- a->add_child ("Duration")->add_child_text (lexical_cast<string> (_duration));
- if (!_key_id.empty ()) {
- a->add_child("KeyId")->add_child_text ("urn:uuid:" + _key_id);
- }
-}
-
-void
-MXFAsset::set_key (Key key)
-{
- _key = key;
-
- if (_key_id.empty ()) {
- /* No key ID so far; we now need one */
- _key_id = make_uuid ();
- }
-
- _decryption_context = new ASDCP::AESDecContext;
- if (ASDCP_FAILURE (_decryption_context->InitKey (_key->value ()))) {
- throw MiscError ("could not set up decryption context");
- }
-
- _encryption_context = new ASDCP::AESEncContext;
- if (ASDCP_FAILURE (_encryption_context->InitKey (_key->value ()))) {
- throw MiscError ("could not set up encryption context");
- }
-
- uint8_t cbc_buffer[ASDCP::CBC_BLOCK_SIZE];
-
- Kumu::FortunaRNG rng;
- if (ASDCP_FAILURE (_encryption_context->SetIVec (rng.FillRandom (cbc_buffer, ASDCP::CBC_BLOCK_SIZE)))) {
- throw MiscError ("could not set up CBC initialization vector");
- }
-}
+++ /dev/null
-/*
- Copyright (C) 2012 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.
-
-*/
-
-#ifndef LIBDCP_MXF_ASSET_H
-#define LIBDCP_MXF_ASSET_H
-
-#include <boost/signals2.hpp>
-#include "asset.h"
-#include "key.h"
-#include "metadata.h"
-
-namespace ASDCP {
- class AESEncContext;
- class AESDecContext;
-}
-
-namespace libdcp
-{
-
-class MXFMetadata;
-
-/** @brief Parent class for assets which have MXF files */
-class MXFAsset : public Asset
-{
-public:
- /** 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.
- */
- MXFAsset (boost::filesystem::path directory, boost::filesystem::path file_name);
-
- ~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 *) const;
- virtual std::string key_type () const = 0;
-
- /** Fill in a ADSCP::WriteInfo struct.
- * @param w struct to fill in.
- */
- void fill_writer_info (ASDCP::WriterInfo* w);
-
- void set_progress (boost::signals2::signal<void (float)>* progress) {
- _progress = progress;
- }
-
- bool encrypted () const {
- return !_key_id.empty ();
- }
-
- void set_key_id (std::string i) {
- _key_id = i;
- }
-
- std::string key_id () const {
- return _key_id;
- }
-
- void set_key (Key);
-
- boost::optional<Key> key () const {
- return _key;
- }
-
- ASDCP::AESEncContext* encryption_context () const {
- return _encryption_context;
- }
-
- void set_metadata (MXFMetadata m) {
- _metadata = m;
- }
-
- MXFMetadata metadata () const {
- return _metadata;
- }
-
- /** Set whether or not the asset should be written in Interop mode.
- * @param i true to use interop.
- */
- 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 () const {
- return std::make_pair ("", "");
- }
-
- /** Signal to emit to report progress, or 0 */
- boost::signals2::signal<void (float)>* _progress;
- ASDCP::AESEncContext* _encryption_context;
- ASDCP::AESDecContext* _decryption_context;
- std::string _key_id;
- boost::optional<Key> _key;
- MXFMetadata _metadata;
- bool _interop;
-};
-
-}
-
-#endif
--- /dev/null
+/*
+ Copyright (C) 2014 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 "object.h"
+#include "util.h"
+
+using std::string;
+using namespace dcp;
+
+Object::Object ()
+ : _id (make_uuid ())
+{
+
+}
+
+Object::Object (string id)
+ : _id (id)
+{
+
+}
--- /dev/null
+/*
+ Copyright (C) 2014 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.
+
+*/
+
+#ifndef LIBDCP_OBJECT_H
+#define LIBDCP_OBJECT_H
+
+#include <string>
+
+namespace dcp {
+
+/** Some part of a DCP that has a UUID */
+class Object
+{
+public:
+ Object ();
+ Object (std::string id);
+ virtual ~Object () {}
+
+ std::string id () const {
+ return _id;
+ }
+
+protected:
+ std::string _id;
+};
+
+}
+
+#endif
using std::string;
using std::list;
using boost::shared_ptr;
-using namespace libdcp::parse;
+using namespace dcp::parse;
AssetMap::AssetMap (string file)
{
#include <boost/shared_ptr.hpp>
#include <libcxml/cxml.h>
-namespace libdcp {
+namespace dcp {
namespace parse {
using std::string;
using std::bad_cast;
using boost::shared_ptr;
-using namespace libdcp::parse;
+using namespace dcp::parse;
CPL::CPL (string file)
{
#include <libcxml/cxml.h>
#include "../types.h"
-namespace libdcp {
+namespace dcp {
namespace parse {
using namespace std;
using namespace boost;
-using namespace libdcp::parse;
+using namespace dcp::parse;
PKL::PKL (string file)
{
#include <boost/shared_ptr.hpp>
#include "../xml.h"
-namespace libdcp {
+namespace dcp {
namespace parse {
using boost::shared_ptr;
using boost::optional;
using boost::lexical_cast;
-using namespace libdcp;
-using namespace libdcp::parse;
+using namespace dcp;
+using namespace dcp::parse;
Font::Font (shared_ptr<const cxml::Node> node)
{
#include "../dcp_time.h"
#include "../types.h"
-namespace libdcp
+namespace dcp
{
namespace parse
+++ /dev/null
-/*
- Copyright (C) 2012 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.
-
-*/
-
-/** @file src/picture_asset.cc
- * @brief An asset made up of JPEG2000 files
- */
-
-#include <list>
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-#include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
-#include <openjpeg.h>
-#include <libxml++/nodes/element.h>
-#include "AS_DCP.h"
-#include "KM_fileio.h"
-#include "picture_asset.h"
-#include "util.h"
-#include "exceptions.h"
-#include "xyz_frame.h"
-#include "picture_asset_writer.h"
-
-using std::string;
-using std::ostream;
-using std::list;
-using std::vector;
-using std::max;
-using std::stringstream;
-using std::pair;
-using std::make_pair;
-using std::istream;
-using std::cout;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using boost::lexical_cast;
-using namespace libdcp;
-
-PictureAsset::PictureAsset (boost::filesystem::path directory, boost::filesystem::path mxf_name)
- : MXFAsset (directory, mxf_name)
-{
-
-}
-
-void
-PictureAsset::write_to_cpl (xmlpp::Element* node) const
-{
- MXFAsset::write_to_cpl (node);
-
- xmlpp::Node::NodeList c = node->get_children ();
- xmlpp::Node::NodeList::iterator i = c.begin();
- while (i != c.end() && (*i)->get_name() != cpl_node_name ()) {
- ++i;
- }
-
- assert (i != c.end ());
-
- (*i)->add_child ("FrameRate")->add_child_text (lexical_cast<string> (_edit_rate * edit_rate_factor ()) + " 1");
- if (_interop) {
- stringstream s;
- s << std::fixed << std::setprecision (2) << (float (_size.width) / _size.height);
- (*i)->add_child ("ScreenAspectRatio")->add_child_text (s.str ());
- } else {
- (*i)->add_child ("ScreenAspectRatio")->add_child_text (lexical_cast<string> (_size.width) + " " + lexical_cast<string> (_size.height));
- }
-}
-
-bool
-PictureAsset::descriptor_equals (
- ASDCP::JP2K::PictureDescriptor const & a, ASDCP::JP2K::PictureDescriptor const & b, boost::function<void (NoteType, string)> note
- ) const
-{
- if (
- a.EditRate != b.EditRate ||
- a.SampleRate != b.SampleRate ||
- a.StoredWidth != b.StoredWidth ||
- a.StoredHeight != b.StoredHeight ||
- a.AspectRatio != b.AspectRatio ||
- a.Rsize != b.Rsize ||
- a.Xsize != b.Xsize ||
- a.Ysize != b.Ysize ||
- a.XOsize != b.XOsize ||
- a.YOsize != b.YOsize ||
- a.XTsize != b.XTsize ||
- a.YTsize != b.YTsize ||
- a.XTOsize != b.XTOsize ||
- a.YTOsize != b.YTOsize ||
- a.Csize != b.Csize
-// a.CodingStyleDefault != b.CodingStyleDefault ||
-// a.QuantizationDefault != b.QuantizationDefault
- ) {
-
- note (ERROR, "video MXF picture descriptors differ");
- return false;
- }
-
- if (a.ContainerDuration != b.ContainerDuration) {
- note (ERROR, "video container durations differ");
- }
-
-// for (unsigned int j = 0; j < ASDCP::JP2K::MaxComponents; ++j) {
-// if (a.ImageComponents[j] != b.ImageComponents[j]) {
-// notes.pack_start ("video MXF picture descriptors differ");
-// }
-// }
-
- return true;
-}
-
-bool
-PictureAsset::frame_buffer_equals (
- int frame, EqualityOptions opt, boost::function<void (NoteType, string)> note,
- uint8_t const * data_A, unsigned int size_A, uint8_t const * data_B, unsigned int size_B
- ) const
-{
- if (size_A == size_B && memcmp (data_A, data_B, size_A) == 0) {
- note (NOTE, "J2K identical");
- /* Easy result; the J2K data is identical */
- return true;
- }
-
- /* Decompress the images to bitmaps */
- shared_ptr<XYZFrame> image_A = decompress_j2k (const_cast<uint8_t*> (data_A), size_A, 0);
- shared_ptr<XYZFrame> image_B = decompress_j2k (const_cast<uint8_t*> (data_B), size_B, 0);
-
- /* Compare them */
-
- vector<int> abs_diffs (image_A->size().width * image_A->size().height * 3);
- int d = 0;
- int max_diff = 0;
-
- for (int c = 0; c < 3; ++c) {
-
- if (image_A->size() != image_B->size()) {
- note (ERROR, "image sizes for frame " + lexical_cast<string>(frame) + " differ");
- return false;
- }
-
- int const pixels = image_A->size().width * image_A->size().height;
- for (int j = 0; j < pixels; ++j) {
- int const t = abs (image_A->data(c)[j] - image_B->data(c)[j]);
- abs_diffs[d++] = t;
- max_diff = max (max_diff, t);
- }
- }
-
- uint64_t total = 0;
- for (vector<int>::iterator j = abs_diffs.begin(); j != abs_diffs.end(); ++j) {
- total += *j;
- }
-
- double const mean = double (total) / abs_diffs.size ();
-
- uint64_t total_squared_deviation = 0;
- for (vector<int>::iterator j = abs_diffs.begin(); j != abs_diffs.end(); ++j) {
- total_squared_deviation += pow (*j - mean, 2);
- }
-
- double const std_dev = sqrt (double (total_squared_deviation) / abs_diffs.size());
-
- note (NOTE, "mean difference " + lexical_cast<string> (mean) + ", deviation " + lexical_cast<string> (std_dev));
-
- if (mean > opt.max_mean_pixel_error) {
- note (
- ERROR,
- "mean " + lexical_cast<string>(mean) +
- " out of range " + lexical_cast<string>(opt.max_mean_pixel_error) +
- " in frame " + lexical_cast<string>(frame)
- );
-
- return false;
- }
-
- if (std_dev > opt.max_std_dev_pixel_error) {
- note (
- ERROR,
- "standard deviation " + lexical_cast<string>(std_dev) +
- " out of range " + lexical_cast<string>(opt.max_std_dev_pixel_error) +
- " in frame " + lexical_cast<string>(frame)
- );
-
- return false;
- }
-
- return true;
-}
-
-string
-PictureAsset::key_type () const
-{
- return "MDIK";
-}
-
-
-
+++ /dev/null
-/*
- Copyright (C) 2012 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.
-
-*/
-
-#ifndef LIBDCP_PICTURE_ASSET_H
-#define LIBDCP_PICTURE_ASSET_H
-
-/** @file src/picture_asset.h
- * @brief An asset made up of JPEG2000 data
- */
-
-#include <openjpeg.h>
-#include "mxf_asset.h"
-#include "util.h"
-#include "metadata.h"
-
-namespace ASDCP {
- namespace JP2K {
- class PictureDescriptor;
- }
-}
-
-namespace libdcp
-{
-
-class MonoPictureFrame;
-class StereoPictureFrame;
-class PictureAssetWriter;
-
-/** @brief An asset made up of JPEG2000 data */
-class PictureAsset : public MXFAsset
-{
-public:
- /** Construct a PictureAsset.
- *
- * @param directory Directory where MXF file is.
- * @param mxf_name Name of MXF file.
- */
- PictureAsset (boost::filesystem::path directory, boost::filesystem::path mxf_name);
-
- /** Start a progressive write to this asset.
- * The following parameters must be set up (if required) before calling this:
- * Interop mode (set_interop)
- * Edit rate (set_edit_rate)
- * MXF Metadata (set_metadata)
- *
- * @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.
- */
- 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)>) {}
-
- Size size () const {
- return _size;
- }
-
- void set_size (Size s) {
- _size = s;
- }
-
- void write_to_cpl (xmlpp::Element *) const;
-
-protected:
-
- bool frame_buffer_equals (
- int frame, EqualityOptions opt, boost::function<void (NoteType, std::string)> note,
- uint8_t const * data_A, unsigned int size_A, uint8_t const * data_B, unsigned int size_B
- ) const;
-
- bool descriptor_equals (
- ASDCP::JP2K::PictureDescriptor const & a, ASDCP::JP2K::PictureDescriptor const & b, boost::function<void (NoteType, std::string)>
- ) const;
-
- /** picture size in pixels */
- Size _size;
-
-private:
- std::string key_type () const;
- virtual int edit_rate_factor () const = 0;
-};
-
-
-}
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2012-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 <inttypes.h>
-#include <stdint.h>
-#include "AS_DCP.h"
-#include "KM_fileio.h"
-#include "picture_asset_writer.h"
-#include "exceptions.h"
-#include "picture_asset.h"
-
-using std::istream;
-using std::ostream;
-using std::string;
-using boost::shared_ptr;
-using namespace libdcp;
-
-FrameInfo::FrameInfo (istream& s)
- : offset (0)
- , size (0)
-{
- s >> offset >> size;
-
- if (!s.good ()) {
- /* Make sure we zero these if something bad happened, otherwise
- the caller might try to alloc lots of RAM.
- */
- offset = size = 0;
- }
-
- s >> hash;
-}
-
-FrameInfo::FrameInfo (FILE* f)
-{
-#ifdef LIBDCP_WINDOWS
- fscanf (f, "%I64u", &offset);
- fscanf (f, "%I64u", &size);
-#else
- fscanf (f, "%" SCNu64, &offset);
- fscanf (f, "%" SCNu64, &size);
-#endif
-
- if (ferror (f)) {
- offset = size = 0;
- }
-
- char hash_buffer[128];
- fscanf (f, "%s", hash_buffer);
- hash = hash_buffer;
-}
-
-void
-FrameInfo::write (ostream& s) const
-{
- s << offset << " " << size << " " << hash;
-}
-
-void
-FrameInfo::write (FILE* f) const
-{
-#ifdef LIBDCP_WINDOWS
- fprintf (f, "%I64u %I64u %s", offset, size, hash.c_str ());
-#else
- fprintf (f, "%" PRIu64 " %" PRIu64 " %s", offset, size, hash.c_str ());
-#endif
-}
-
-
-PictureAssetWriter::PictureAssetWriter (PictureAsset* asset, bool overwrite)
- : _asset (asset)
- , _frames_written (0)
- , _started (false)
- , _finalized (false)
- , _overwrite (overwrite)
-{
-
-}
+++ /dev/null
-/*
- Copyright (C) 2012-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 <stdint.h>
-#include <string>
-#include <fstream>
-#include <boost/shared_ptr.hpp>
-#include <boost/utility.hpp>
-#include "metadata.h"
-#include "types.h"
-
-namespace libdcp {
-
-class PictureAsset;
-
-/** Information about a single frame (either a monoscopic frame or a left *or* right eye stereoscopic frame) */
-struct FrameInfo
-{
- FrameInfo (uint64_t o, uint64_t s, std::string h)
- : offset (o)
- , size (s)
- , hash (h)
- {}
-
- FrameInfo (std::istream& s);
- FrameInfo (FILE *);
-
- void write (std::ostream& s) const;
- void write (FILE *) const;
-
- uint64_t offset;
- uint64_t size;
- std::string hash;
-};
-
-class PictureAssetWriter : public boost::noncopyable
-{
-public:
- virtual ~PictureAssetWriter () {}
- virtual FrameInfo write (uint8_t *, int) = 0;
- virtual void finalize () = 0;
- virtual void fake_write (int) = 0;
-
-protected:
- template <class P, class Q>
- friend void start (PictureAssetWriter *, boost::shared_ptr<P>, Q *, uint8_t *, int);
-
- PictureAssetWriter (PictureAsset *, bool);
-
- PictureAsset* _asset;
-
- /** Number of picture frames written to the asset so far. For stereo assets
- * this will be incremented for each eye (i.e. there will be twice the number
- * of frames as in a mono asset).
- */
- int _frames_written;
- bool _started;
- /** true if finalize() has been called */
- bool _finalized;
- bool _overwrite;
-};
-
-}
+++ /dev/null
-/*
- Copyright (C) 2012-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.
-
-*/
-
-using boost::shared_ptr;
-
-struct ASDCPStateBase
-{
- ASDCPStateBase ()
- : frame_buffer (4 * Kumu::Megabyte)
- {}
-
- ASDCP::JP2K::CodestreamParser j2k_parser;
- ASDCP::JP2K::FrameBuffer frame_buffer;
- ASDCP::WriterInfo writer_info;
- ASDCP::JP2K::PictureDescriptor picture_descriptor;
- ASDCP::AESEncContext* encryption_context;
-};
-
-template <class P, class Q>
-void libdcp::start (PictureAssetWriter* writer, shared_ptr<P> state, Q* asset, uint8_t* data, int size)
-{
- if (ASDCP_FAILURE (state->j2k_parser.OpenReadFrame (data, size, state->frame_buffer))) {
- boost::throw_exception (MiscError ("could not parse J2K frame"));
- }
-
- state->j2k_parser.FillPictureDescriptor (state->picture_descriptor);
- state->picture_descriptor.EditRate = ASDCP::Rational (asset->edit_rate(), 1);
-
- asset->fill_writer_info (&state->writer_info);
-
- Kumu::Result_t r = state->mxf_writer.OpenWrite (
- asset->path().string().c_str(),
- state->writer_info,
- state->picture_descriptor,
- 16384,
- writer->_overwrite
- );
-
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for writing", asset->path().string(), r));
- }
-
- writer->_started = true;
-}
--- /dev/null
+/*
+ Copyright (C) 2012 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.
+
+*/
+
+/** @file src/picture_asset.cc
+ * @brief An asset made up of JPEG2000 files
+ */
+
+#include <list>
+#include <stdexcept>
+#include <iostream>
+#include <sstream>
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include <openjpeg.h>
+#include <libxml++/nodes/element.h>
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "picture_mxf.h"
+#include "util.h"
+#include "exceptions.h"
+#include "xyz_frame.h"
+#include "picture_mxf_writer.h"
+
+using std::string;
+using std::ostream;
+using std::list;
+using std::vector;
+using std::max;
+using std::stringstream;
+using std::pair;
+using std::make_pair;
+using std::istream;
+using std::cout;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using boost::lexical_cast;
+using namespace dcp;
+
+PictureMXF::PictureMXF (boost::filesystem::path file)
+ : MXF (file)
+{
+
+}
+
+PictureMXF::PictureMXF (int edit_rate)
+ : MXF (edit_rate)
+{
+
+}
+
+void
+PictureMXF::write_to_cpl (xmlpp::Element* node) const
+{
+ MXF::write_to_cpl (node);
+
+ xmlpp::Node::NodeList c = node->get_children ();
+ xmlpp::Node::NodeList::iterator i = c.begin();
+ while (i != c.end() && (*i)->get_name() != cpl_node_name ()) {
+ ++i;
+ }
+
+ assert (i != c.end ());
+
+ (*i)->add_child ("FrameRate")->add_child_text (lexical_cast<string> (_edit_rate * edit_rate_factor ()) + " 1");
+ if (_interop) {
+ stringstream s;
+ s << std::fixed << std::setprecision (2) << (float (_size.width) / _size.height);
+ (*i)->add_child ("ScreenAspectRatio")->add_child_text (s.str ());
+ } else {
+ (*i)->add_child ("ScreenAspectRatio")->add_child_text (lexical_cast<string> (_size.width) + " " + lexical_cast<string> (_size.height));
+ }
+}
+
+bool
+PictureMXF::descriptor_equals (
+ ASDCP::JP2K::PictureDescriptor const & a, ASDCP::JP2K::PictureDescriptor const & b, boost::function<void (NoteType, string)> note
+ ) const
+{
+ if (
+ a.EditRate != b.EditRate ||
+ a.SampleRate != b.SampleRate ||
+ a.StoredWidth != b.StoredWidth ||
+ a.StoredHeight != b.StoredHeight ||
+ a.AspectRatio != b.AspectRatio ||
+ a.Rsize != b.Rsize ||
+ a.Xsize != b.Xsize ||
+ a.Ysize != b.Ysize ||
+ a.XOsize != b.XOsize ||
+ a.YOsize != b.YOsize ||
+ a.XTsize != b.XTsize ||
+ a.YTsize != b.YTsize ||
+ a.XTOsize != b.XTOsize ||
+ a.YTOsize != b.YTOsize ||
+ a.Csize != b.Csize
+// a.CodingStyleDefault != b.CodingStyleDefault ||
+// a.QuantizationDefault != b.QuantizationDefault
+ ) {
+
+ note (ERROR, "video MXF picture descriptors differ");
+ return false;
+ }
+
+ if (a.ContainerDuration != b.ContainerDuration) {
+ note (ERROR, "video container durations differ");
+ }
+
+// for (unsigned int j = 0; j < ASDCP::JP2K::MaxComponents; ++j) {
+// if (a.ImageComponents[j] != b.ImageComponents[j]) {
+// notes.pack_start ("video MXF picture descriptors differ");
+// }
+// }
+
+ return true;
+}
+
+bool
+PictureMXF::frame_buffer_equals (
+ int frame, EqualityOptions opt, boost::function<void (NoteType, string)> note,
+ uint8_t const * data_A, unsigned int size_A, uint8_t const * data_B, unsigned int size_B
+ ) const
+{
+ if (size_A == size_B && memcmp (data_A, data_B, size_A) == 0) {
+ note (NOTE, "J2K identical");
+ /* Easy result; the J2K data is identical */
+ return true;
+ }
+
+ /* Decompress the images to bitmaps */
+ shared_ptr<XYZFrame> image_A = decompress_j2k (const_cast<uint8_t*> (data_A), size_A, 0);
+ shared_ptr<XYZFrame> image_B = decompress_j2k (const_cast<uint8_t*> (data_B), size_B, 0);
+
+ /* Compare them */
+
+ vector<int> abs_diffs (image_A->size().width * image_A->size().height * 3);
+ int d = 0;
+ int max_diff = 0;
+
+ for (int c = 0; c < 3; ++c) {
+
+ if (image_A->size() != image_B->size()) {
+ note (ERROR, "image sizes for frame " + lexical_cast<string>(frame) + " differ");
+ return false;
+ }
+
+ int const pixels = image_A->size().width * image_A->size().height;
+ for (int j = 0; j < pixels; ++j) {
+ int const t = abs (image_A->data(c)[j] - image_B->data(c)[j]);
+ abs_diffs[d++] = t;
+ max_diff = max (max_diff, t);
+ }
+ }
+
+ uint64_t total = 0;
+ for (vector<int>::iterator j = abs_diffs.begin(); j != abs_diffs.end(); ++j) {
+ total += *j;
+ }
+
+ double const mean = double (total) / abs_diffs.size ();
+
+ uint64_t total_squared_deviation = 0;
+ for (vector<int>::iterator j = abs_diffs.begin(); j != abs_diffs.end(); ++j) {
+ total_squared_deviation += pow (*j - mean, 2);
+ }
+
+ double const std_dev = sqrt (double (total_squared_deviation) / abs_diffs.size());
+
+ note (NOTE, "mean difference " + lexical_cast<string> (mean) + ", deviation " + lexical_cast<string> (std_dev));
+
+ if (mean > opt.max_mean_pixel_error) {
+ note (
+ ERROR,
+ "mean " + lexical_cast<string>(mean) +
+ " out of range " + lexical_cast<string>(opt.max_mean_pixel_error) +
+ " in frame " + lexical_cast<string>(frame)
+ );
+
+ return false;
+ }
+
+ if (std_dev > opt.max_std_dev_pixel_error) {
+ note (
+ ERROR,
+ "standard deviation " + lexical_cast<string>(std_dev) +
+ " out of range " + lexical_cast<string>(opt.max_std_dev_pixel_error) +
+ " in frame " + lexical_cast<string>(frame)
+ );
+
+ return false;
+ }
+
+ return true;
+}
+
+string
+PictureMXF::key_type () const
+{
+ return "MDIK";
+}
+
+
+
--- /dev/null
+/*
+ Copyright (C) 2012 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.
+
+*/
+
+#ifndef LIBDCP_PICTURE_MXF_H
+#define LIBDCP_PICTURE_MXF_H
+
+/** @file src/picture_asset.h
+ * @brief An asset made up of JPEG2000 data
+ */
+
+#include <openjpeg.h>
+#include "mxf.h"
+#include "util.h"
+#include "metadata.h"
+
+namespace ASDCP {
+ namespace JP2K {
+ class PictureDescriptor;
+ }
+}
+
+namespace dcp
+{
+
+class MonoPictureFrame;
+class StereoPictureFrame;
+class PictureMXFWriter;
+
+/** @brief An asset made up of JPEG2000 data */
+class PictureMXF : public MXF
+{
+public:
+ PictureMXF (boost::filesystem::path file);
+ PictureMXF (int edit_rate);
+
+ virtual boost::shared_ptr<PictureMXFWriter> start_write (boost::filesystem::path file, bool overwrite) = 0;
+
+ Size size () const {
+ return _size;
+ }
+
+ void set_size (Size s) {
+ _size = s;
+ }
+
+ void write_to_cpl (xmlpp::Element *) const;
+
+protected:
+
+ bool frame_buffer_equals (
+ int frame, EqualityOptions opt, boost::function<void (NoteType, std::string)> note,
+ uint8_t const * data_A, unsigned int size_A, uint8_t const * data_B, unsigned int size_B
+ ) const;
+
+ bool descriptor_equals (
+ ASDCP::JP2K::PictureDescriptor const & a, ASDCP::JP2K::PictureDescriptor const & b, boost::function<void (NoteType, std::string)>
+ ) const;
+
+ /** picture size in pixels */
+ Size _size;
+
+private:
+ std::string key_type () const;
+ virtual int edit_rate_factor () const = 0;
+};
+
+
+}
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2012-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 <inttypes.h>
+#include <stdint.h>
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "picture_mxf_writer.h"
+#include "exceptions.h"
+#include "picture_mxf.h"
+
+using std::istream;
+using std::ostream;
+using std::string;
+using boost::shared_ptr;
+using namespace dcp;
+
+FrameInfo::FrameInfo (istream& s)
+ : offset (0)
+ , size (0)
+{
+ s >> offset >> size;
+
+ if (!s.good ()) {
+ /* Make sure we zero these if something bad happened, otherwise
+ the caller might try to alloc lots of RAM.
+ */
+ offset = size = 0;
+ }
+
+ s >> hash;
+}
+
+FrameInfo::FrameInfo (FILE* f)
+{
+#ifdef LIBDCP_WINDOWS
+ fscanf (f, "%I64u", &offset);
+ fscanf (f, "%I64u", &size);
+#else
+ fscanf (f, "%" SCNu64, &offset);
+ fscanf (f, "%" SCNu64, &size);
+#endif
+
+ if (ferror (f)) {
+ offset = size = 0;
+ }
+
+ char hash_buffer[128];
+ fscanf (f, "%s", hash_buffer);
+ hash = hash_buffer;
+}
+
+void
+FrameInfo::write (ostream& s) const
+{
+ s << offset << " " << size << " " << hash;
+}
+
+void
+FrameInfo::write (FILE* f) const
+{
+#ifdef LIBDCP_WINDOWS
+ fprintf (f, "%I64u %I64u %s", offset, size, hash.c_str ());
+#else
+ fprintf (f, "%" PRIu64 " %" PRIu64 " %s", offset, size, hash.c_str ());
+#endif
+}
+
+
+PictureMXFWriter::PictureMXFWriter (PictureMXF* mxf, boost::filesystem::path file, bool overwrite)
+ : _mxf (mxf)
+ , _file (file)
+ , _frames_written (0)
+ , _started (false)
+ , _finalized (false)
+ , _overwrite (overwrite)
+{
+
+}
--- /dev/null
+/*
+ Copyright (C) 2012-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 <stdint.h>
+#include <string>
+#include <fstream>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include "metadata.h"
+#include "types.h"
+
+namespace dcp {
+
+class PictureMXF;
+
+/** Information about a single frame (either a monoscopic frame or a left *or* right eye stereoscopic frame) */
+struct FrameInfo
+{
+ FrameInfo (uint64_t o, uint64_t s, std::string h)
+ : offset (o)
+ , size (s)
+ , hash (h)
+ {}
+
+ FrameInfo (std::istream& s);
+ FrameInfo (FILE *);
+
+ void write (std::ostream& s) const;
+ void write (FILE *) const;
+
+ uint64_t offset;
+ uint64_t size;
+ std::string hash;
+};
+
+class PictureMXFWriter : public boost::noncopyable
+{
+public:
+ virtual ~PictureMXFWriter () {}
+ virtual FrameInfo write (uint8_t *, int) = 0;
+ virtual void finalize () = 0;
+ virtual void fake_write (int) = 0;
+
+protected:
+ template <class P, class Q>
+ friend void start (PictureMXFWriter *, boost::shared_ptr<P>, Q *, uint8_t *, int);
+
+ PictureMXFWriter (PictureMXF *, boost::filesystem::path, bool);
+
+ PictureMXF* _mxf;
+
+ boost::filesystem::path _file;
+ /** Number of picture frames written to the asset so far. For stereo assets
+ * this will be incremented for each eye (i.e. there will be twice the number
+ * of frames as in a mono asset).
+ */
+ int _frames_written;
+ bool _started;
+ /** true if finalize() has been called */
+ bool _finalized;
+ bool _overwrite;
+};
+
+}
--- /dev/null
+/*
+ Copyright (C) 2012-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.
+
+*/
+
+using boost::shared_ptr;
+
+struct ASDCPStateBase
+{
+ ASDCPStateBase ()
+ : frame_buffer (4 * Kumu::Megabyte)
+ {}
+
+ ASDCP::JP2K::CodestreamParser j2k_parser;
+ ASDCP::JP2K::FrameBuffer frame_buffer;
+ ASDCP::WriterInfo writer_info;
+ ASDCP::JP2K::PictureDescriptor picture_descriptor;
+ ASDCP::AESEncContext* encryption_context;
+};
+
+template <class P, class Q>
+void dcp::start (PictureMXFWriter* writer, shared_ptr<P> state, Q* mxf, uint8_t* data, int size)
+{
+ mxf->set_file (writer->_file);
+
+ if (ASDCP_FAILURE (state->j2k_parser.OpenReadFrame (data, size, state->frame_buffer))) {
+ boost::throw_exception (MiscError ("could not parse J2K frame"));
+ }
+
+ state->j2k_parser.FillPictureDescriptor (state->picture_descriptor);
+ state->picture_descriptor.EditRate = ASDCP::Rational (mxf->edit_rate(), 1);
+
+ mxf->fill_writer_info (&state->writer_info);
+
+ Kumu::Result_t r = state->mxf_writer.OpenWrite (
+ mxf->file().string().c_str(),
+ state->writer_info,
+ state->picture_descriptor,
+ 16384,
+ writer->_overwrite
+ );
+
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for writing", mxf->file().string(), r));
+ }
+
+ writer->_started = true;
+}
#include "rec709_linearised_gamma_lut.h"
-using namespace libdcp;
+using namespace dcp;
LUTCache<Rec709LinearisedGammaLUT> Rec709LinearisedGammaLUT::cache;
#include "lut.h"
#include "lut_cache.h"
-namespace libdcp {
+namespace dcp {
class Rec709LinearisedGammaLUT : public LUT
{
#include <libxml++/nodes/element.h>
#include "reel.h"
#include "util.h"
-#include "picture_asset.h"
-#include "mono_picture_asset.h"
-#include "stereo_picture_asset.h"
-#include "sound_asset.h"
+#include "picture_mxf.h"
+#include "mono_picture_mxf.h"
+#include "stereo_picture_mxf.h"
+#include "sound_mxf.h"
#include "subtitle_asset.h"
#include "kdm.h"
using std::cout;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
-using namespace libdcp;
+using namespace dcp;
void
Reel::write_to_cpl (xmlpp::Element* node) const
reel->add_child("Id")->add_child_text ("urn:uuid:" + make_uuid());
xmlpp::Element* asset_list = reel->add_child ("AssetList");
- if (_main_picture && dynamic_pointer_cast<MonoPictureAsset> (_main_picture)) {
+ if (_main_picture && dynamic_pointer_cast<MonoPictureMXF> (_main_picture)) {
/* Mono pictures come before other stuff... */
_main_picture->write_to_cpl (asset_list);
}
_main_subtitle->write_to_cpl (asset_list);
}
- if (_main_picture && dynamic_pointer_cast<StereoPictureAsset> (_main_picture)) {
+ if (_main_picture && dynamic_pointer_cast<StereoPictureMXF> (_main_picture)) {
/* ... but stereo pictures must come after */
_main_picture->write_to_cpl (asset_list);
}
class Node;
}
-namespace libdcp {
+namespace dcp {
-class PictureAsset;
-class SoundAsset;
+class PictureMXF;
+class SoundMXF;
class SubtitleAsset;
class KDM;
{
public:
Reel (
- boost::shared_ptr<PictureAsset> picture,
- boost::shared_ptr<SoundAsset> sound,
+ boost::shared_ptr<PictureMXF> picture,
+ boost::shared_ptr<SoundMXF> sound,
boost::shared_ptr<SubtitleAsset> subtitle
)
: _main_picture (picture)
, _main_subtitle (subtitle)
{}
- boost::shared_ptr<const PictureAsset> main_picture () const {
+ boost::shared_ptr<const PictureMXF> main_picture () const {
return _main_picture;
}
- boost::shared_ptr<const SoundAsset> main_sound () const {
+ boost::shared_ptr<const SoundMXF> main_sound () const {
return _main_sound;
}
bool encrypted () const;
- void set_mxf_keys (libdcp::Key);
+ void set_mxf_keys (dcp::Key);
bool equals (boost::shared_ptr<const Reel> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> notes) const;
void add_kdm (KDM const &);
private:
- boost::shared_ptr<PictureAsset> _main_picture;
- boost::shared_ptr<SoundAsset> _main_sound;
+ boost::shared_ptr<PictureMXF> _main_picture;
+ boost::shared_ptr<SoundMXF> _main_sound;
boost::shared_ptr<SubtitleAsset> _main_subtitle;
};
using std::min;
using std::max;
using boost::shared_ptr;
-using namespace libdcp;
+using namespace dcp;
#define DCI_COEFFICIENT (48.0 / 52.37)
* @return RGB image.
*/
shared_ptr<ARGBFrame>
-libdcp::xyz_to_rgb (shared_ptr<const XYZFrame> xyz_frame, shared_ptr<const LUT> lut_in, shared_ptr<const LUT> lut_out)
+dcp::xyz_to_rgb (shared_ptr<const XYZFrame> xyz_frame, shared_ptr<const LUT> lut_in, shared_ptr<const LUT> lut_out)
{
int const max_colour = pow (2, lut_out->bit_depth()) - 1;
return argb_frame;
}
-shared_ptr<libdcp::XYZFrame>
-libdcp::rgb_to_xyz (shared_ptr<const Image> rgb, shared_ptr<const LUT> lut_in, shared_ptr<const LUT> lut_out, double const colour_matrix[3][3])
+shared_ptr<dcp::XYZFrame>
+dcp::rgb_to_xyz (shared_ptr<const Image> rgb, shared_ptr<const LUT> lut_in, shared_ptr<const LUT> lut_out, double const colour_matrix[3][3])
{
assert (lut_in->bit_depth() == 12);
assert (lut_out->bit_depth() == 16);
#include <boost/shared_ptr.hpp>
-namespace libdcp {
+namespace dcp {
class ARGBFrame;
class XYZFrame;
using std::list;
using std::cout;
using boost::shared_ptr;
-using namespace libdcp;
+using namespace dcp;
/** @param signer_key Filename of private key to sign with */
void
class Node;
}
-namespace libdcp {
+namespace dcp {
class Signer
{
if (code) {
stringstream s;
s << "error " << code << " in " << cmd << " within " << boost::filesystem::current_path();
- throw libdcp::MiscError (s.str());
+ throw dcp::MiscError (s.str());
}
}
string pub;
ifstream f (public_name.string().c_str ());
if (!f.good ()) {
- throw libdcp::MiscError ("public key not found");
+ throw dcp::MiscError ("public key not found");
}
bool read = false;
/* Decode the base64 of the public key */
unsigned char buffer[512];
- int const N = libdcp::base64_decode (pub, buffer, 1024);
+ int const N = dcp::base64_decode (pub, buffer, 1024);
/* Hash it with SHA1 (without the first 24 bytes, for reasons that are not entirely clear) */
SHA_CTX context;
if (!SHA1_Init (&context)) {
- throw libdcp::MiscError ("could not init SHA1 context");
+ throw dcp::MiscError ("could not init SHA1 context");
}
if (!SHA1_Update (&context, buffer + 24, N - 24)) {
- throw libdcp::MiscError ("could not update SHA1 digest");
+ throw dcp::MiscError ("could not update SHA1 digest");
}
unsigned char digest[SHA_DIGEST_LENGTH];
if (!SHA1_Final (digest, &context)) {
- throw libdcp::MiscError ("could not finish SHA1 digest");
+ throw dcp::MiscError ("could not finish SHA1 digest");
}
char digest_base64[64];
}
void
-libdcp::make_signer_chain (boost::filesystem::path directory, boost::filesystem::path openssl)
+dcp::make_signer_chain (boost::filesystem::path directory, boost::filesystem::path openssl)
{
boost::filesystem::path const cwd = boost::filesystem::current_path ();
#include <boost/filesystem.hpp>
-namespace libdcp {
+namespace dcp {
/** Create a chain of certificates for signing things.
* @param directory Directory to write files to.
+++ /dev/null
-/*
- Copyright (C) 2012 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.
-
-*/
-
-/** @file src/sound_asset.cc
- * @brief An asset made up of WAV files
- */
-
-#include <iostream>
-#include <stdexcept>
-#include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
-#include <libxml++/nodes/element.h>
-#include "KM_fileio.h"
-#include "AS_DCP.h"
-#include "sound_asset.h"
-#include "util.h"
-#include "exceptions.h"
-#include "sound_frame.h"
-
-using std::string;
-using std::stringstream;
-using std::ostream;
-using std::vector;
-using std::list;
-using boost::shared_ptr;
-using boost::lexical_cast;
-using namespace libdcp;
-
-SoundAsset::SoundAsset (boost::filesystem::path directory, boost::filesystem::path mxf_name)
- : MXFAsset (directory, mxf_name)
- , _channels (0)
- , _sampling_rate (0)
-{
-
-}
-
-void
-SoundAsset::create (vector<boost::filesystem::path> const & files)
-{
- create (boost::bind (&SoundAsset::path_from_channel, this, _1, files));
-}
-
-void
-SoundAsset::read ()
-{
- ASDCP::PCM::MXFReader reader;
- Kumu::Result_t r = reader.OpenRead (path().string().c_str());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r));
- }
-
- ASDCP::PCM::AudioDescriptor desc;
- if (ASDCP_FAILURE (reader.FillAudioDescriptor (desc))) {
- boost::throw_exception (DCPReadError ("could not read audio MXF information"));
- }
-
- _sampling_rate = desc.AudioSamplingRate.Numerator / desc.AudioSamplingRate.Denominator;
- _channels = desc.ChannelCount;
- _edit_rate = desc.EditRate.Numerator;
- assert (desc.EditRate.Denominator == 1);
- _intrinsic_duration = desc.ContainerDuration;
-}
-
-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 ());
- return files[c];
-}
-
-void
-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];
- for (int i = 0; i < _channels; ++i) {
- pcm_parser_channel[i] = new ASDCP::PCM::WAVParser ();
- }
-
- Kumu::Result_t r = pcm_parser_channel[0]->OpenRead (get_path(LEFT).string().c_str(), asdcp_edit_rate);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (FileError ("could not open WAV file for reading", get_path(LEFT), r));
- }
-
- ASDCP::PCM::AudioDescriptor audio_desc;
- pcm_parser_channel[0]->FillAudioDescriptor (audio_desc);
- audio_desc.ChannelCount = 0;
- audio_desc.BlockAlign = 0;
- audio_desc.EditRate = asdcp_edit_rate;
- audio_desc.AvgBps = audio_desc.AvgBps * _channels;
-
- Channel channels[] = {
- LEFT,
- RIGHT,
- CENTRE,
- LFE,
- LS,
- RS,
- /* XXX: not quite sure what these should be yet */
- CHANNEL_7,
- CHANNEL_8
- };
-
- assert (int(_channels) <= int(sizeof(channels) / sizeof(Channel)));
-
- ASDCP::PCM::FrameBuffer* frame_buffer_channel[_channels];
- ASDCP::PCM::AudioDescriptor* audio_desc_channel[_channels];
- for (int i = 0; i < _channels; ++i) {
- frame_buffer_channel[i] = new ASDCP::PCM::FrameBuffer ();
- audio_desc_channel[i] = new ASDCP::PCM::AudioDescriptor ();
- }
-
- for (int i = 0; i < _channels; ++i) {
-
- boost::filesystem::path const path = get_path (channels[i]);
-
- Kumu::Result_t r = pcm_parser_channel[i]->OpenRead (path.string().c_str(), asdcp_edit_rate);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (FileError ("could not open WAV file for reading", path, r));
- }
-
- pcm_parser_channel[i]->FillAudioDescriptor (*audio_desc_channel[i]);
- frame_buffer_channel[i]->Capacity (ASDCP::PCM::CalcFrameBufferSize (*audio_desc_channel[i]));
-
- audio_desc.ChannelCount += audio_desc_channel[i]->ChannelCount;
- audio_desc.BlockAlign += audio_desc_channel[i]->BlockAlign;
- }
-
- ASDCP::PCM::FrameBuffer frame_buffer;
- frame_buffer.Capacity (ASDCP::PCM::CalcFrameBufferSize (audio_desc));
- frame_buffer.Size (ASDCP::PCM::CalcFrameBufferSize (audio_desc));
-
- ASDCP::WriterInfo writer_info;
- MXFAsset::fill_writer_info (&writer_info);
-
- ASDCP::PCM::MXFWriter mxf_writer;
- r = mxf_writer.OpenWrite (path().string().c_str(), writer_info, audio_desc);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (FileError ("could not open audio MXF for writing", path().string(), r));
- }
-
- for (int i = 0; i < _intrinsic_duration; ++i) {
-
- for (int j = 0; j < _channels; ++j) {
- memset (frame_buffer_channel[j]->Data(), 0, frame_buffer_channel[j]->Capacity());
- if (ASDCP_FAILURE (pcm_parser_channel[j]->ReadFrame (*frame_buffer_channel[j]))) {
- boost::throw_exception (MiscError ("could not read audio frame"));
- }
- }
-
- byte_t *data_s = frame_buffer.Data();
- byte_t *data_e = data_s + frame_buffer.Capacity();
- byte_t sample_size = ASDCP::PCM::CalcSampleSize (*audio_desc_channel[0]);
- int offset = 0;
-
- while (data_s < data_e) {
- for (int j = 0; j < _channels; ++j) {
- byte_t* frame = frame_buffer_channel[j]->Data() + offset;
- memcpy (data_s, frame, sample_size);
- data_s += sample_size;
- }
- offset += sample_size;
- }
-
- if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, _encryption_context, 0))) {
- boost::throw_exception (MiscError ("could not write audio MXF frame"));
- }
-
- if (_progress) {
- (*_progress) (0.5 * float (i) / _intrinsic_duration);
- }
- }
-
- bool const failed = ASDCP_FAILURE (mxf_writer.Finalize());
-
- for (int i = 0; i < _channels; ++i) {
- delete pcm_parser_channel[i];
- delete frame_buffer_channel[i];
- delete audio_desc_channel[i];
- }
-
- if (failed) {
- boost::throw_exception (MiscError ("could not finalise audio MXF"));
- }
-}
-
-string
-SoundAsset::cpl_node_name () const
-{
- return "MainSound";
-}
-
-bool
-SoundAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
-{
- if (!MXFAsset::equals (other, opt, note)) {
- return false;
- }
-
- ASDCP::PCM::MXFReader reader_A;
- Kumu::Result_t r = reader_A.OpenRead (path().string().c_str());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r));
- }
-
- ASDCP::PCM::MXFReader reader_B;
- r = reader_B.OpenRead (other->path().string().c_str());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r));
- }
-
- ASDCP::PCM::AudioDescriptor desc_A;
- if (ASDCP_FAILURE (reader_A.FillAudioDescriptor (desc_A))) {
- boost::throw_exception (DCPReadError ("could not read audio MXF information"));
- }
- ASDCP::PCM::AudioDescriptor desc_B;
- if (ASDCP_FAILURE (reader_B.FillAudioDescriptor (desc_B))) {
- boost::throw_exception (DCPReadError ("could not read audio MXF information"));
- }
-
- if (
- desc_A.EditRate != desc_B.EditRate ||
- desc_A.AudioSamplingRate != desc_B.AudioSamplingRate ||
- desc_A.Locked != desc_B.Locked ||
- desc_A.ChannelCount != desc_B.ChannelCount ||
- desc_A.QuantizationBits != desc_B.QuantizationBits ||
- desc_A.BlockAlign != desc_B.BlockAlign ||
- desc_A.AvgBps != desc_B.AvgBps ||
- desc_A.LinkedTrackID != desc_B.LinkedTrackID ||
- desc_A.ContainerDuration != desc_B.ContainerDuration
-// desc_A.ChannelFormat != desc_B.ChannelFormat ||
- ) {
-
- note (ERROR, "audio MXF picture descriptors differ");
- return false;
- }
-
- ASDCP::PCM::FrameBuffer buffer_A (1 * Kumu::Megabyte);
- ASDCP::PCM::FrameBuffer buffer_B (1 * Kumu::Megabyte);
-
- for (int i = 0; i < _intrinsic_duration; ++i) {
- if (ASDCP_FAILURE (reader_A.ReadFrame (i, buffer_A))) {
- boost::throw_exception (DCPReadError ("could not read audio frame"));
- }
-
- if (ASDCP_FAILURE (reader_B.ReadFrame (i, buffer_B))) {
- boost::throw_exception (DCPReadError ("could not read audio frame"));
- }
-
- if (buffer_A.Size() != buffer_B.Size()) {
- note (ERROR, "sizes of audio data for frame " + lexical_cast<string>(i) + " differ");
- return false;
- }
-
- if (memcmp (buffer_A.RoData(), buffer_B.RoData(), buffer_A.Size()) != 0) {
- for (uint32_t i = 0; i < buffer_A.Size(); ++i) {
- int const d = abs (buffer_A.RoData()[i] - buffer_B.RoData()[i]);
- if (d > opt.max_audio_sample_error) {
- note (ERROR, "PCM data difference of " + lexical_cast<string> (d));
- return false;
- }
- }
- }
- }
-
- return true;
-}
-
-shared_ptr<const SoundFrame>
-SoundAsset::get_frame (int n) const
-{
- /* XXX: should add on entry point here? */
- return shared_ptr<const SoundFrame> (new SoundFrame (path().string(), n, _decryption_context));
-}
-
-shared_ptr<SoundAssetWriter>
-SoundAsset::start_write ()
-{
- /* XXX: can't we use a shared_ptr here? */
- return shared_ptr<SoundAssetWriter> (new SoundAssetWriter (this));
-}
-
-struct SoundAssetWriter::ASDCPState
-{
- ASDCP::PCM::MXFWriter mxf_writer;
- ASDCP::PCM::FrameBuffer frame_buffer;
- ASDCP::WriterInfo writer_info;
- ASDCP::PCM::AudioDescriptor audio_desc;
- ASDCP::AESEncContext* encryption_context;
-};
-
-SoundAssetWriter::SoundAssetWriter (SoundAsset* a)
- : _state (new SoundAssetWriter::ASDCPState)
- , _asset (a)
- , _finalized (false)
- , _frames_written (0)
- , _frame_buffer_offset (0)
-{
- _state->encryption_context = a->encryption_context ();
-
- /* Derived from ASDCP::Wav::SimpleWaveHeader::FillADesc */
- _state->audio_desc.EditRate = ASDCP::Rational (_asset->edit_rate(), 1);
- _state->audio_desc.AudioSamplingRate = ASDCP::Rational (_asset->sampling_rate(), 1);
- _state->audio_desc.Locked = 0;
- _state->audio_desc.ChannelCount = _asset->channels ();
- _state->audio_desc.QuantizationBits = 24;
- _state->audio_desc.BlockAlign = 3 * _asset->channels();
- _state->audio_desc.AvgBps = _asset->sampling_rate() * _state->audio_desc.BlockAlign;
- _state->audio_desc.LinkedTrackID = 0;
- _state->audio_desc.ChannelFormat = ASDCP::PCM::CF_NONE;
-
- _state->frame_buffer.Capacity (ASDCP::PCM::CalcFrameBufferSize (_state->audio_desc));
- _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);
-
- Kumu::Result_t r = _state->mxf_writer.OpenWrite (_asset->path().string().c_str(), _state->writer_info, _state->audio_desc);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (FileError ("could not open audio MXF for writing", _asset->path().string(), r));
- }
-}
-
-void
-SoundAssetWriter::write (float const * const * data, int frames)
-{
- for (int i = 0; i < frames; ++i) {
-
- byte_t* out = _state->frame_buffer.Data() + _frame_buffer_offset;
-
- /* Write one sample per channel */
- for (int j = 0; j < _asset->channels(); ++j) {
- int32_t const s = data[j][i] * (1 << 23);
- *out++ = (s & 0xff);
- *out++ = (s & 0xff00) >> 8;
- *out++ = (s & 0xff0000) >> 16;
- }
- _frame_buffer_offset += 3 * _asset->channels();
-
- assert (_frame_buffer_offset <= int (_state->frame_buffer.Capacity()));
-
- /* Finish the MXF frame if required */
- if (_frame_buffer_offset == int (_state->frame_buffer.Capacity())) {
- write_current_frame ();
- _frame_buffer_offset = 0;
- memset (_state->frame_buffer.Data(), 0, _state->frame_buffer.Capacity());
- }
- }
-}
-
-void
-SoundAssetWriter::write_current_frame ()
-{
- ASDCP::Result_t const r = _state->mxf_writer.WriteFrame (_state->frame_buffer, _state->encryption_context, 0);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MiscError ("could not write audio MXF frame (" + lexical_cast<string> (int (r)) + ")"));
- }
-
- ++_frames_written;
-}
-
-void
-SoundAssetWriter::finalize ()
-{
- if (_frame_buffer_offset > 0) {
- write_current_frame ();
- }
-
- if (ASDCP_FAILURE (_state->mxf_writer.Finalize())) {
- boost::throw_exception (MiscError ("could not finalise audio MXF"));
- }
-
- _finalized = true;
- _asset->set_intrinsic_duration (_frames_written);
- _asset->set_duration (_frames_written);
-}
-
-string
-SoundAsset::key_type () const
-{
- return "MDAK";
-}
+++ /dev/null
-/*
- Copyright (C) 2012 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.
-
-*/
-
-#ifndef LIBDCP_SOUND_ASSET_H
-#define LIBDCP_SOUND_ASSET_H
-
-/** @file src/sound_asset.h
- * @brief An asset made up of PCM audio data files
- */
-
-#include "mxf_asset.h"
-#include "types.h"
-#include "metadata.h"
-
-namespace libdcp
-{
-
-class SoundFrame;
-class SoundAsset;
-
-class SoundAssetWriter
-{
-public:
- void write (float const * const *, int);
- void finalize ();
-
-private:
- friend class SoundAsset;
-
- SoundAssetWriter (SoundAsset *);
-
- /* no copy construction */
- SoundAssetWriter (SoundAssetWriter const &);
- SoundAssetWriter& operator= (SoundAssetWriter const &);
-
- void write_current_frame ();
-
- /* do this with an opaque pointer so we don't have to include
- ASDCP headers
- */
-
- struct ASDCPState;
- boost::shared_ptr<ASDCPState> _state;
-
- SoundAsset* _asset;
- bool _finalized;
- int _frames_written;
- int _frame_buffer_offset;
-};
-
-/** @brief An asset made up of WAV files */
-class SoundAsset : public MXFAsset
-{
-public:
- SoundAsset (boost::filesystem::path directory, boost::filesystem::path mxf_name);
-
- void read ();
-
- /** The following parameters must be set up (if required) before calling this:
- * Interop mode (set_interop)
- * Edit rate (set_edit_rate)
- * MXF Metadata (set_metadata)
- * Channels (set_channels)
- * Intrinsic duration (set_intrinsic_duration)
- */
- void create (std::vector<boost::filesystem::path> const & files);
-
- /** The following parameters must be set up (if required) before calling this:
- * Interop mode (set_interop)
- * Edit rate (set_edit_rate)
- * MXF Metadata (set_metadata)
- * Channels (set_channels)
- * Intrinsic duration (set_intrinsic_duration)
- */
- 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;
- }
-
- void set_sampling_rate (int s) {
- _sampling_rate = s;
- }
-
- int sampling_rate () const {
- return _sampling_rate;
- }
-
-private:
- std::string key_type () 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;
-
- /** Number of channels in the asset */
- int _channels;
- int _sampling_rate;
-};
-
-}
-
-#endif
#include "exceptions.h"
using namespace std;
-using namespace libdcp;
+using namespace dcp;
SoundFrame::SoundFrame (string mxf_path, int n, ASDCP::AESDecContext* c)
{
class AESDecContext;
}
-namespace libdcp {
+namespace dcp {
class SoundFrame
{
--- /dev/null
+/*
+ Copyright (C) 2012 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.
+
+*/
+
+/** @file src/sound_asset.cc
+ * @brief An asset made up of WAV files
+ */
+
+#include <iostream>
+#include <stdexcept>
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include <libxml++/nodes/element.h>
+#include "KM_fileio.h"
+#include "AS_DCP.h"
+#include "sound_mxf.h"
+#include "util.h"
+#include "exceptions.h"
+#include "sound_frame.h"
+
+using std::string;
+using std::stringstream;
+using std::ostream;
+using std::vector;
+using std::list;
+using boost::shared_ptr;
+using boost::lexical_cast;
+using namespace dcp;
+
+SoundMXF::SoundMXF (boost::filesystem::path file)
+ : MXF (file)
+ , _channels (0)
+ , _sampling_rate (0)
+{
+ ASDCP::PCM::MXFReader reader;
+ Kumu::Result_t r = reader.OpenRead (file.string().c_str());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", file.string(), r));
+ }
+
+ ASDCP::PCM::AudioDescriptor desc;
+ if (ASDCP_FAILURE (reader.FillAudioDescriptor (desc))) {
+ boost::throw_exception (DCPReadError ("could not read audio MXF information"));
+ }
+
+ _sampling_rate = desc.AudioSamplingRate.Numerator / desc.AudioSamplingRate.Denominator;
+ _channels = desc.ChannelCount;
+ _edit_rate = desc.EditRate.Numerator;
+ assert (desc.EditRate.Denominator == 1);
+ _intrinsic_duration = desc.ContainerDuration;
+}
+
+string
+SoundMXF::cpl_node_name () const
+{
+ return "MainSound";
+}
+
+bool
+SoundMXF::equals (shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
+{
+ if (!MXF::equals (other, opt, note)) {
+ return false;
+ }
+
+ ASDCP::PCM::MXFReader reader_A;
+ Kumu::Result_t r = reader_A.OpenRead (file().string().c_str());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", file().string(), r));
+ }
+
+ ASDCP::PCM::MXFReader reader_B;
+ r = reader_B.OpenRead (other->file().string().c_str());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", file().string(), r));
+ }
+
+ ASDCP::PCM::AudioDescriptor desc_A;
+ if (ASDCP_FAILURE (reader_A.FillAudioDescriptor (desc_A))) {
+ boost::throw_exception (DCPReadError ("could not read audio MXF information"));
+ }
+ ASDCP::PCM::AudioDescriptor desc_B;
+ if (ASDCP_FAILURE (reader_B.FillAudioDescriptor (desc_B))) {
+ boost::throw_exception (DCPReadError ("could not read audio MXF information"));
+ }
+
+ if (
+ desc_A.EditRate != desc_B.EditRate ||
+ desc_A.AudioSamplingRate != desc_B.AudioSamplingRate ||
+ desc_A.Locked != desc_B.Locked ||
+ desc_A.ChannelCount != desc_B.ChannelCount ||
+ desc_A.QuantizationBits != desc_B.QuantizationBits ||
+ desc_A.BlockAlign != desc_B.BlockAlign ||
+ desc_A.AvgBps != desc_B.AvgBps ||
+ desc_A.LinkedTrackID != desc_B.LinkedTrackID ||
+ desc_A.ContainerDuration != desc_B.ContainerDuration
+// desc_A.ChannelFormat != desc_B.ChannelFormat ||
+ ) {
+
+ note (ERROR, "audio MXF picture descriptors differ");
+ return false;
+ }
+
+ ASDCP::PCM::FrameBuffer buffer_A (1 * Kumu::Megabyte);
+ ASDCP::PCM::FrameBuffer buffer_B (1 * Kumu::Megabyte);
+
+ for (int i = 0; i < _intrinsic_duration; ++i) {
+ if (ASDCP_FAILURE (reader_A.ReadFrame (i, buffer_A))) {
+ boost::throw_exception (DCPReadError ("could not read audio frame"));
+ }
+
+ if (ASDCP_FAILURE (reader_B.ReadFrame (i, buffer_B))) {
+ boost::throw_exception (DCPReadError ("could not read audio frame"));
+ }
+
+ if (buffer_A.Size() != buffer_B.Size()) {
+ note (ERROR, "sizes of audio data for frame " + lexical_cast<string>(i) + " differ");
+ return false;
+ }
+
+ if (memcmp (buffer_A.RoData(), buffer_B.RoData(), buffer_A.Size()) != 0) {
+ for (uint32_t i = 0; i < buffer_A.Size(); ++i) {
+ int const d = abs (buffer_A.RoData()[i] - buffer_B.RoData()[i]);
+ if (d > opt.max_audio_sample_error) {
+ note (ERROR, "PCM data difference of " + lexical_cast<string> (d));
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+shared_ptr<const SoundFrame>
+SoundMXF::get_frame (int n) const
+{
+ /* XXX: should add on entry point here? */
+ return shared_ptr<const SoundFrame> (new SoundFrame (file().string(), n, _decryption_context));
+}
+
+shared_ptr<SoundMXFWriter>
+SoundMXF::start_write ()
+{
+ /* XXX: can't we use a shared_ptr here? */
+ return shared_ptr<SoundMXFWriter> (new SoundMXFWriter (this));
+}
+
+struct SoundMXFWriter::ASDCPState
+{
+ ASDCP::PCM::MXFWriter mxf_writer;
+ ASDCP::PCM::FrameBuffer frame_buffer;
+ ASDCP::WriterInfo writer_info;
+ ASDCP::PCM::AudioDescriptor audio_desc;
+ ASDCP::AESEncContext* encryption_context;
+};
+
+SoundMXFWriter::SoundMXFWriter (SoundMXF* a)
+ : _state (new SoundMXFWriter::ASDCPState)
+ , _asset (a)
+ , _finalized (false)
+ , _frames_written (0)
+ , _frame_buffer_offset (0)
+{
+ _state->encryption_context = a->encryption_context ();
+
+ /* Derived from ASDCP::Wav::SimpleWaveHeader::FillADesc */
+ _state->audio_desc.EditRate = ASDCP::Rational (_asset->edit_rate(), 1);
+ _state->audio_desc.AudioSamplingRate = ASDCP::Rational (_asset->sampling_rate(), 1);
+ _state->audio_desc.Locked = 0;
+ _state->audio_desc.ChannelCount = _asset->channels ();
+ _state->audio_desc.QuantizationBits = 24;
+ _state->audio_desc.BlockAlign = 3 * _asset->channels();
+ _state->audio_desc.AvgBps = _asset->sampling_rate() * _state->audio_desc.BlockAlign;
+ _state->audio_desc.LinkedTrackID = 0;
+ _state->audio_desc.ChannelFormat = ASDCP::PCM::CF_NONE;
+
+ _state->frame_buffer.Capacity (ASDCP::PCM::CalcFrameBufferSize (_state->audio_desc));
+ _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);
+
+ Kumu::Result_t r = _state->mxf_writer.OpenWrite (_asset->file().string().c_str(), _state->writer_info, _state->audio_desc);
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (FileError ("could not open audio MXF for writing", _asset->file().string(), r));
+ }
+}
+
+void
+SoundMXFWriter::write (float const * const * data, int frames)
+{
+ for (int i = 0; i < frames; ++i) {
+
+ byte_t* out = _state->frame_buffer.Data() + _frame_buffer_offset;
+
+ /* Write one sample per channel */
+ for (int j = 0; j < _asset->channels(); ++j) {
+ int32_t const s = data[j][i] * (1 << 23);
+ *out++ = (s & 0xff);
+ *out++ = (s & 0xff00) >> 8;
+ *out++ = (s & 0xff0000) >> 16;
+ }
+ _frame_buffer_offset += 3 * _asset->channels();
+
+ assert (_frame_buffer_offset <= int (_state->frame_buffer.Capacity()));
+
+ /* Finish the MXF frame if required */
+ if (_frame_buffer_offset == int (_state->frame_buffer.Capacity())) {
+ write_current_frame ();
+ _frame_buffer_offset = 0;
+ memset (_state->frame_buffer.Data(), 0, _state->frame_buffer.Capacity());
+ }
+ }
+}
+
+void
+SoundMXFWriter::write_current_frame ()
+{
+ ASDCP::Result_t const r = _state->mxf_writer.WriteFrame (_state->frame_buffer, _state->encryption_context, 0);
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MiscError ("could not write audio MXF frame (" + lexical_cast<string> (int (r)) + ")"));
+ }
+
+ ++_frames_written;
+}
+
+void
+SoundMXFWriter::finalize ()
+{
+ if (_frame_buffer_offset > 0) {
+ write_current_frame ();
+ }
+
+ if (ASDCP_FAILURE (_state->mxf_writer.Finalize())) {
+ boost::throw_exception (MiscError ("could not finalise audio MXF"));
+ }
+
+ _finalized = true;
+ _asset->set_intrinsic_duration (_frames_written);
+ _asset->set_duration (_frames_written);
+}
+
+string
+SoundMXF::key_type () const
+{
+ return "MDAK";
+}
--- /dev/null
+/*
+ Copyright (C) 2012 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.
+
+*/
+
+#ifndef LIBDCP_SOUND_ASSET_H
+#define LIBDCP_SOUND_ASSET_H
+
+/** @file src/sound_asset.h
+ * @brief An asset made up of PCM audio data files
+ */
+
+#include "mxf.h"
+#include "types.h"
+#include "metadata.h"
+
+namespace dcp
+{
+
+class SoundFrame;
+class SoundMXF;
+
+class SoundMXFWriter
+{
+public:
+ void write (float const * const *, int);
+ void finalize ();
+
+private:
+ friend class SoundMXF;
+
+ SoundMXFWriter (SoundMXF *);
+
+ /* no copy construction */
+ SoundMXFWriter (SoundMXFWriter const &);
+ SoundMXFWriter& operator= (SoundMXFWriter const &);
+
+ void write_current_frame ();
+
+ /* do this with an opaque pointer so we don't have to include
+ ASDCP headers
+ */
+
+ struct ASDCPState;
+ boost::shared_ptr<ASDCPState> _state;
+
+ SoundMXF* _asset;
+ bool _finalized;
+ int _frames_written;
+ int _frame_buffer_offset;
+};
+
+/** @brief An asset made up of WAV files */
+class SoundMXF : public MXF
+{
+public:
+ SoundMXF (boost::filesystem::path file);
+
+ boost::shared_ptr<SoundMXFWriter> start_write ();
+
+ bool equals (boost::shared_ptr<const Content> 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;
+ }
+
+ void set_sampling_rate (int s) {
+ _sampling_rate = s;
+ }
+
+ int sampling_rate () const {
+ return _sampling_rate;
+ }
+
+private:
+ std::string key_type () const;
+ std::string cpl_node_name () const;
+
+ /** Number of channels in the asset */
+ int _channels;
+ int _sampling_rate;
+};
+
+}
+
+#endif
#include "srgb_linearised_gamma_lut.h"
-using namespace libdcp;
+using namespace dcp;
LUTCache<SRGBLinearisedGammaLUT> SRGBLinearisedGammaLUT::cache;
#include "lut.h"
#include "lut_cache.h"
-namespace libdcp {
+namespace dcp {
class SRGBLinearisedGammaLUT : public LUT
{
+++ /dev/null
-/*
- Copyright (C) 2012-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 "AS_DCP.h"
-#include "stereo_picture_asset.h"
-#include "stereo_picture_frame.h"
-#include "exceptions.h"
-#include "stereo_picture_asset_writer.h"
-
-using std::string;
-using std::pair;
-using std::make_pair;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using namespace libdcp;
-
-bool
-StereoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
-{
- if (!MXFAsset::equals (other, opt, note)) {
- return false;
- }
-
- ASDCP::JP2K::MXFSReader reader_A;
- Kumu::Result_t r = reader_A.OpenRead (path().string().c_str());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r));
- }
-
- ASDCP::JP2K::MXFSReader reader_B;
- r = reader_B.OpenRead (other->path().string().c_str());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r));
- }
-
- ASDCP::JP2K::PictureDescriptor desc_A;
- if (ASDCP_FAILURE (reader_A.FillPictureDescriptor (desc_A))) {
- boost::throw_exception (DCPReadError ("could not read video MXF information"));
- }
- ASDCP::JP2K::PictureDescriptor desc_B;
- if (ASDCP_FAILURE (reader_B.FillPictureDescriptor (desc_B))) {
- boost::throw_exception (DCPReadError ("could not read video MXF information"));
- }
-
- if (!descriptor_equals (desc_A, desc_B, note)) {
- return false;
- }
-
- shared_ptr<const StereoPictureAsset> other_picture = dynamic_pointer_cast<const StereoPictureAsset> (other);
- assert (other_picture);
-
- for (int i = 0; i < _intrinsic_duration; ++i) {
- shared_ptr<const StereoPictureFrame> frame_A = get_frame (i);
- shared_ptr<const StereoPictureFrame> frame_B = other_picture->get_frame (i);
-
- if (!frame_buffer_equals (
- i, opt, note,
- frame_A->left_j2k_data(), frame_A->left_j2k_size(),
- frame_B->left_j2k_data(), frame_B->left_j2k_size()
- )) {
- return false;
- }
-
- if (!frame_buffer_equals (
- i, opt, note,
- frame_A->right_j2k_data(), frame_A->right_j2k_size(),
- frame_B->right_j2k_data(), frame_B->right_j2k_size()
- )) {
- return false;
- }
- }
-
- return true;
-}
-
-StereoPictureAsset::StereoPictureAsset (boost::filesystem::path directory, boost::filesystem::path mxf_name)
- : PictureAsset (directory, mxf_name)
-{
-
-}
-
-void
-StereoPictureAsset::read ()
-{
- ASDCP::JP2K::MXFSReader reader;
- Kumu::Result_t r = reader.OpenRead (path().string().c_str());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r));
- }
-
- 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;
-}
-
-shared_ptr<const StereoPictureFrame>
-StereoPictureAsset::get_frame (int n) const
-{
- return shared_ptr<const StereoPictureFrame> (new StereoPictureFrame (path().string(), n));
-}
-
-shared_ptr<PictureAssetWriter>
-StereoPictureAsset::start_write (bool overwrite)
-{
- return shared_ptr<StereoPictureAssetWriter> (new StereoPictureAssetWriter (this, overwrite));
-}
-
-string
-StereoPictureAsset::cpl_node_name () const
-{
- return "msp-cpl:MainStereoscopicPicture";
-}
-
-pair<string, string>
-StereoPictureAsset::cpl_node_attribute () 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;
-}
+++ /dev/null
-/*
- Copyright (C) 2012-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.
-
-*/
-
-#ifndef LIBDCP_STEREO_PICTURE_ASSET_H
-#define LIBDCP_STEREO_PICTURE_ASSET_H
-
-#include "picture_asset.h"
-
-namespace libdcp {
-
-/** A 3D (stereoscopic) picture asset */
-class StereoPictureAsset : public PictureAsset
-{
-public:
- StereoPictureAsset (boost::filesystem::path directory, boost::filesystem::path mxf_name);
-
- void read ();
-
- /** Start a progressive write to a StereoPictureAsset */
- 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;
-
-private:
- std::string cpl_node_name () const;
- std::pair<std::string, std::string> cpl_node_attribute () const;
- int edit_rate_factor () const;
-};
-
-}
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2012-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 "AS_DCP.h"
-#include "KM_fileio.h"
-#include "stereo_picture_asset_writer.h"
-#include "exceptions.h"
-#include "picture_asset.h"
-
-#include "picture_asset_writer_common.cc"
-
-using std::istream;
-using std::ostream;
-using std::string;
-using boost::shared_ptr;
-using namespace libdcp;
-
-struct StereoPictureAssetWriter::ASDCPState : public ASDCPStateBase
-{
- ASDCP::JP2K::MXFSWriter mxf_writer;
-};
-
-StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* asset, bool overwrite)
- : PictureAssetWriter (asset, overwrite)
- , _state (new StereoPictureAssetWriter::ASDCPState)
- , _next_eye (EYE_LEFT)
-{
- _state->encryption_context = asset->encryption_context ();
-}
-
-void
-StereoPictureAssetWriter::start (uint8_t* data, int size)
-{
- libdcp::start (this, _state, _asset, data, size);
-}
-
-/** Write a frame for one eye. Frames must be written left, then right, then left etc.
- * @param data JPEG2000 data.
- * @param size Size of data.
- */
-FrameInfo
-StereoPictureAssetWriter::write (uint8_t* data, int size)
-{
- assert (!_finalized);
-
- if (!_started) {
- start (data, size);
- }
-
- if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) {
- boost::throw_exception (MiscError ("could not parse J2K frame"));
- }
-
- uint64_t const before_offset = _state->mxf_writer.Tell ();
-
- string hash;
- Kumu::Result_t r = _state->mxf_writer.WriteFrame (
- _state->frame_buffer,
- _next_eye == EYE_LEFT ? ASDCP::JP2K::SP_LEFT : ASDCP::JP2K::SP_RIGHT,
- _state->encryption_context,
- 0,
- &hash
- );
-
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string(), r));
- }
-
- _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
-
- ++_frames_written;
- return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
-}
-
-void
-StereoPictureAssetWriter::fake_write (int size)
-{
- assert (_started);
- assert (!_finalized);
-
- Kumu::Result_t r = _state->mxf_writer.FakeWriteFrame (size, _next_eye == EYE_LEFT ? ASDCP::JP2K::SP_LEFT : ASDCP::JP2K::SP_RIGHT);
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string(), r));
- }
-
- _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
- ++_frames_written;
-}
-
-void
-StereoPictureAssetWriter::finalize ()
-{
- assert (!_finalized);
-
- Kumu::Result_t r = _state->mxf_writer.Finalize();
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("error in finalizing video MXF", _asset->path().string(), r));
- }
-
- _finalized = true;
- _asset->set_intrinsic_duration (_frames_written / 2);
- _asset->set_duration (_frames_written / 2);
-}
+++ /dev/null
-/*
- Copyright (C) 2012-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 <stdint.h>
-#include <string>
-#include <fstream>
-#include <boost/shared_ptr.hpp>
-#include <boost/utility.hpp>
-#include "picture_asset_writer.h"
-
-namespace libdcp {
-
-/** A helper class for writing to StereoPictureAssets progressively (i.e. writing frame-by-frame,
- * rather than giving libdcp all the frames in one go).
- *
- * Objects of this class can only be created with StereoPictureAsset::start_write().
- *
- * Frames can be written to the MonoPictureAsset by calling write() with a JPEG2000 image
- * (a verbatim .j2c file). finalize() must be called after the last frame has been written.
- * The action of finalize() can't be done in MonoPictureAssetWriter's destructor as it may
- * throw an exception.
- */
-class StereoPictureAssetWriter : public PictureAssetWriter
-{
-public:
- FrameInfo write (uint8_t *, int);
- void fake_write (int size);
- void finalize ();
-
-private:
- friend class StereoPictureAsset;
-
- StereoPictureAssetWriter (PictureAsset *, bool);
- void start (uint8_t *, int);
-
- /* do this with an opaque pointer so we don't have to include
- ASDCP headers
- */
-
- struct ASDCPState;
- boost::shared_ptr<ASDCPState> _state;
-
- libdcp::Eye _next_eye;
-};
-
-}
using std::string;
using boost::shared_ptr;
-using namespace libdcp;
+using namespace dcp;
/** Make a picture frame from a 3D (stereoscopic) asset.
* @param mxf_path Path to the asset's MXF file.
delete _buffer;
}
-/** @param reduce a factor by which to reduce the resolution
+/** @param eye Eye to return (EYE_LEFT or EYE_RIGHT).
+ * @param reduce a factor by which to reduce the resolution
* of the image, expressed as a power of two (pass 0 for no
* reduction).
*
- * @param eye Eye to return (EYE_LEFT or EYE_RIGHT).
- *
* @return An ARGB representation of one of the eyes (left or right)
* of this frame. This is ARGB in the Cairo sense, so that each
* pixel takes up 4 bytes; the first byte is blue, second green,
class AESDecContext;
}
-namespace libdcp {
+namespace dcp {
class ARGBFrame;
--- /dev/null
+/*
+ Copyright (C) 2012-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 "AS_DCP.h"
+#include "stereo_picture_mxf.h"
+#include "stereo_picture_frame.h"
+#include "exceptions.h"
+#include "stereo_picture_mxf_writer.h"
+
+using std::string;
+using std::pair;
+using std::make_pair;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using namespace dcp;
+
+bool
+StereoPictureMXF::equals (shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
+{
+ if (!MXF::equals (other, opt, note)) {
+ return false;
+ }
+
+ ASDCP::JP2K::MXFSReader reader_A;
+ Kumu::Result_t r = reader_A.OpenRead (file().string().c_str());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", file().string(), r));
+ }
+
+ ASDCP::JP2K::MXFSReader reader_B;
+ r = reader_B.OpenRead (other->file().string().c_str());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", file().string(), r));
+ }
+
+ ASDCP::JP2K::PictureDescriptor desc_A;
+ if (ASDCP_FAILURE (reader_A.FillPictureDescriptor (desc_A))) {
+ boost::throw_exception (DCPReadError ("could not read video MXF information"));
+ }
+ ASDCP::JP2K::PictureDescriptor desc_B;
+ if (ASDCP_FAILURE (reader_B.FillPictureDescriptor (desc_B))) {
+ boost::throw_exception (DCPReadError ("could not read video MXF information"));
+ }
+
+ if (!descriptor_equals (desc_A, desc_B, note)) {
+ return false;
+ }
+
+ shared_ptr<const StereoPictureMXF> other_picture = dynamic_pointer_cast<const StereoPictureMXF> (other);
+ assert (other_picture);
+
+ for (int i = 0; i < _intrinsic_duration; ++i) {
+ shared_ptr<const StereoPictureFrame> frame_A = get_frame (i);
+ shared_ptr<const StereoPictureFrame> frame_B = other_picture->get_frame (i);
+
+ if (!frame_buffer_equals (
+ i, opt, note,
+ frame_A->left_j2k_data(), frame_A->left_j2k_size(),
+ frame_B->left_j2k_data(), frame_B->left_j2k_size()
+ )) {
+ return false;
+ }
+
+ if (!frame_buffer_equals (
+ i, opt, note,
+ frame_A->right_j2k_data(), frame_A->right_j2k_size(),
+ frame_B->right_j2k_data(), frame_B->right_j2k_size()
+ )) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+StereoPictureMXF::StereoPictureMXF (boost::filesystem::path file)
+ : PictureMXF (file)
+{
+ ASDCP::JP2K::MXFSReader reader;
+ Kumu::Result_t r = reader.OpenRead (file.string().c_str());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", file.string(), r));
+ }
+
+ 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;
+}
+
+shared_ptr<const StereoPictureFrame>
+StereoPictureMXF::get_frame (int n) const
+{
+ return shared_ptr<const StereoPictureFrame> (new StereoPictureFrame (file().string(), n));
+}
+
+shared_ptr<PictureMXFWriter>
+StereoPictureMXF::start_write (boost::filesystem::path file, bool overwrite)
+{
+ return shared_ptr<StereoPictureMXFWriter> (new StereoPictureMXFWriter (this, file, overwrite));
+}
+
+string
+StereoPictureMXF::cpl_node_name () const
+{
+ return "msp-cpl:MainStereoscopicPicture";
+}
+
+pair<string, string>
+StereoPictureMXF::cpl_node_attribute () 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
+StereoPictureMXF::edit_rate_factor () const
+{
+ return 2;
+}
--- /dev/null
+/*
+ Copyright (C) 2012-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.
+
+*/
+
+#ifndef LIBDCP_STEREO_PICTURE_MXF_H
+#define LIBDCP_STEREO_PICTURE_MXF_H
+
+#include "picture_mxf.h"
+
+namespace dcp {
+
+/** A 3D (stereoscopic) picture asset */
+class StereoPictureMXF : public PictureMXF
+{
+public:
+ StereoPictureMXF (boost::filesystem::path file);
+
+ /** Start a progressive write to a StereoPictureMXF */
+ boost::shared_ptr<PictureMXFWriter> start_write (boost::filesystem::path file, bool);
+
+ boost::shared_ptr<const StereoPictureFrame> get_frame (int n) const;
+ bool equals (boost::shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
+
+private:
+ std::string cpl_node_name () const;
+ std::pair<std::string, std::string> cpl_node_attribute () const;
+ int edit_rate_factor () const;
+};
+
+}
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2012-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 "AS_DCP.h"
+#include "KM_fileio.h"
+#include "stereo_picture_mxf_writer.h"
+#include "exceptions.h"
+#include "picture_mxf.h"
+
+#include "picture_mxf_writer_common.cc"
+
+using std::istream;
+using std::ostream;
+using std::string;
+using boost::shared_ptr;
+using namespace dcp;
+
+struct StereoPictureMXFWriter::ASDCPState : public ASDCPStateBase
+{
+ ASDCP::JP2K::MXFSWriter mxf_writer;
+};
+
+StereoPictureMXFWriter::StereoPictureMXFWriter (PictureMXF* mxf, boost::filesystem::path file, bool overwrite)
+ : PictureMXFWriter (mxf, file, overwrite)
+ , _state (new StereoPictureMXFWriter::ASDCPState)
+ , _next_eye (EYE_LEFT)
+{
+ _state->encryption_context = mxf->encryption_context ();
+}
+
+void
+StereoPictureMXFWriter::start (uint8_t* data, int size)
+{
+ dcp::start (this, _state, _mxf, data, size);
+}
+
+/** Write a frame for one eye. Frames must be written left, then right, then left etc.
+ * @param data JPEG2000 data.
+ * @param size Size of data.
+ */
+FrameInfo
+StereoPictureMXFWriter::write (uint8_t* data, int size)
+{
+ assert (!_finalized);
+
+ if (!_started) {
+ start (data, size);
+ }
+
+ if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) {
+ boost::throw_exception (MiscError ("could not parse J2K frame"));
+ }
+
+ uint64_t const before_offset = _state->mxf_writer.Tell ();
+
+ string hash;
+ Kumu::Result_t r = _state->mxf_writer.WriteFrame (
+ _state->frame_buffer,
+ _next_eye == EYE_LEFT ? ASDCP::JP2K::SP_LEFT : ASDCP::JP2K::SP_RIGHT,
+ _state->encryption_context,
+ 0,
+ &hash
+ );
+
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("error in writing video MXF", _mxf->file().string(), r));
+ }
+
+ _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
+
+ ++_frames_written;
+ return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
+}
+
+void
+StereoPictureMXFWriter::fake_write (int size)
+{
+ assert (_started);
+ assert (!_finalized);
+
+ Kumu::Result_t r = _state->mxf_writer.FakeWriteFrame (size, _next_eye == EYE_LEFT ? ASDCP::JP2K::SP_LEFT : ASDCP::JP2K::SP_RIGHT);
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("error in writing video MXF", _mxf->file().string(), r));
+ }
+
+ _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
+ ++_frames_written;
+}
+
+void
+StereoPictureMXFWriter::finalize ()
+{
+ assert (!_finalized);
+
+ Kumu::Result_t r = _state->mxf_writer.Finalize();
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("error in finalizing video MXF", _mxf->file().string(), r));
+ }
+
+ _finalized = true;
+ _mxf->set_intrinsic_duration (_frames_written / 2);
+ _mxf->set_duration (_frames_written / 2);
+}
--- /dev/null
+/*
+ Copyright (C) 2012-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 <stdint.h>
+#include <string>
+#include <fstream>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include "picture_mxf_writer.h"
+
+namespace dcp {
+
+/** A helper class for writing to StereoPictureAssets progressively (i.e. writing frame-by-frame,
+ * rather than giving libdcp all the frames in one go).
+ *
+ * Objects of this class can only be created with StereoPictureAsset::start_write().
+ *
+ * Frames can be written to the MonoPictureAsset by calling write() with a JPEG2000 image
+ * (a verbatim .j2c file). finalize() must be called after the last frame has been written.
+ * The action of finalize() can't be done in MonoPictureAssetWriter's destructor as it may
+ * throw an exception.
+ */
+class StereoPictureMXFWriter : public PictureMXFWriter
+{
+public:
+ FrameInfo write (uint8_t *, int);
+ void fake_write (int size);
+ void finalize ();
+
+private:
+ friend class StereoPictureMXF;
+
+ StereoPictureMXFWriter (PictureMXF *, boost::filesystem::path file, bool);
+ void start (uint8_t *, int);
+
+ /* do this with an opaque pointer so we don't have to include
+ ASDCP headers
+ */
+
+ struct ASDCPState;
+ boost::shared_ptr<ASDCPState> _state;
+
+ dcp::Eye _next_eye;
+};
+
+}
using boost::shared_ptr;
using boost::lexical_cast;
using boost::optional;
-using namespace libdcp;
+using namespace dcp;
-SubtitleAsset::SubtitleAsset (string directory, string xml_file)
- : Asset (directory, xml_file)
+SubtitleAsset::SubtitleAsset (boost::filesystem::path file)
+ : Content (file)
, _need_sort (false)
-{
- read_xml (path().string());
-}
-
-SubtitleAsset::SubtitleAsset (string directory, string movie_title, string language)
- : Asset (directory)
- , _movie_title (movie_title)
- , _reel_number ("1")
- , _language (language)
- , _need_sort (false)
-{
-
-}
-
-void
-SubtitleAsset::read_xml (string xml_file)
{
shared_ptr<cxml::Document> xml (new cxml::Document ("DCSubtitle"));
- xml->read_file (xml_file);
+ xml->read_file (file);
- _uuid = xml->string_child ("SubtitleID");
+ _id = xml->string_child ("SubtitleID");
_movie_title = xml->string_child ("MovieTitle");
_reel_number = xml->string_child ("ReelNumber");
_language = xml->string_child ("Language");
xml->ignore_child ("LoadFont");
- list<shared_ptr<libdcp::parse::Font> > font_nodes = type_children<libdcp::parse::Font> (xml, "Font");
- _load_font_nodes = type_children<libdcp::parse::LoadFont> (xml, "LoadFont");
+ list<shared_ptr<dcp::parse::Font> > font_nodes = type_children<dcp::parse::Font> (xml, "Font");
+ _load_font_nodes = type_children<dcp::parse::LoadFont> (xml, "LoadFont");
/* Now make Subtitle objects to represent the raw XML nodes
in a sane way.
examine_font_nodes (xml, font_nodes, parse_state);
}
+SubtitleAsset::SubtitleAsset (string directory, string movie_title, string language)
+ : Content (directory)
+ , _movie_title (movie_title)
+ , _reel_number ("1")
+ , _language (language)
+ , _need_sort (false)
+{
+
+}
+
void
SubtitleAsset::examine_font_nodes (
shared_ptr<const cxml::Node> xml,
- list<shared_ptr<libdcp::parse::Font> > const & font_nodes,
+ list<shared_ptr<dcp::parse::Font> > const & font_nodes,
ParseState& parse_state
)
{
- for (list<shared_ptr<libdcp::parse::Font> >::const_iterator i = font_nodes.begin(); i != font_nodes.end(); ++i) {
+ for (list<shared_ptr<dcp::parse::Font> >::const_iterator i = font_nodes.begin(); i != font_nodes.end(); ++i) {
parse_state.font_nodes.push_back (*i);
maybe_add_subtitle ((*i)->text, parse_state);
- for (list<shared_ptr<libdcp::parse::Subtitle> >::iterator j = (*i)->subtitle_nodes.begin(); j != (*i)->subtitle_nodes.end(); ++j) {
+ for (list<shared_ptr<dcp::parse::Subtitle> >::iterator j = (*i)->subtitle_nodes.begin(); j != (*i)->subtitle_nodes.end(); ++j) {
parse_state.subtitle_nodes.push_back (*j);
examine_text_nodes (xml, (*j)->text_nodes, parse_state);
examine_font_nodes (xml, (*j)->font_nodes, parse_state);
void
SubtitleAsset::examine_text_nodes (
shared_ptr<const cxml::Node> xml,
- list<shared_ptr<libdcp::parse::Text> > const & text_nodes,
+ list<shared_ptr<dcp::parse::Text> > const & text_nodes,
ParseState& parse_state
)
{
- for (list<shared_ptr<libdcp::parse::Text> >::const_iterator i = text_nodes.begin(); i != text_nodes.end(); ++i) {
+ for (list<shared_ptr<dcp::parse::Text> >::const_iterator i = text_nodes.begin(); i != text_nodes.end(); ++i) {
parse_state.text_nodes.push_back (*i);
maybe_add_subtitle ((*i)->text, parse_state);
examine_font_nodes (xml, (*i)->font_nodes, parse_state);
assert (!parse_state.text_nodes.empty ());
assert (!parse_state.subtitle_nodes.empty ());
- libdcp::parse::Font effective_font (parse_state.font_nodes);
- libdcp::parse::Text effective_text (*parse_state.text_nodes.back ());
- libdcp::parse::Subtitle effective_subtitle (*parse_state.subtitle_nodes.back ());
+ dcp::parse::Font effective_font (parse_state.font_nodes);
+ dcp::parse::Text effective_text (*parse_state.text_nodes.back ());
+ dcp::parse::Subtitle effective_subtitle (*parse_state.subtitle_nodes.back ());
_subtitles.push_back (
shared_ptr<Subtitle> (
std::string
SubtitleAsset::font_id_to_name (string id) const
{
- list<shared_ptr<libdcp::parse::LoadFont> >::const_iterator i = _load_font_nodes.begin();
+ list<shared_ptr<dcp::parse::LoadFont> >::const_iterator i = _load_font_nodes.begin();
while (i != _load_font_nodes.end() && (*i)->id != id) {
++i;
}
}
bool
-libdcp::operator== (Subtitle const & a, Subtitle const & b)
+dcp::operator== (Subtitle const & a, Subtitle const & b)
{
return (
a.font() == b.font() &&
}
ostream&
-libdcp::operator<< (ostream& s, Subtitle const & sub)
+dcp::operator<< (ostream& s, Subtitle const & sub)
{
s << "\n`" << sub.text() << "' from " << sub.in() << " to " << sub.out() << ";\n"
<< "fade up " << sub.fade_up_time() << ", fade down " << sub.fade_down_time() << ";\n"
/* XXX: should EditRate, Duration and IntrinsicDuration be in here? */
xmlpp::Node* ms = node->add_child ("MainSubtitle");
- ms->add_child("Id")->add_child_text("urn:uuid:" + _uuid);
- ms->add_child("AnnotationText")->add_child_text (_file_name.string ());
+ ms->add_child("Id")->add_child_text("urn:uuid:" + _id);
+ ms->add_child("AnnotationText")->add_child_text (_file.string ());
/* XXX */
ms->add_child("EntryPoint")->add_child_text ("0");
}
void
SubtitleAsset::write_xml () const
{
- FILE* f = fopen_boost (path (), "r");
+ FILE* f = fopen_boost (file (), "r");
Glib::ustring const s = xml_as_string ();
fwrite (s.c_str(), 1, s.length(), f);
fclose (f);
xmlpp::Element* root = doc.create_root_node ("DCSubtitle");
root->set_attribute ("Version", "1.0");
- root->add_child("SubtitleID")->add_child_text (_uuid);
+ root->add_child("SubtitleID")->add_child_text (_id);
root->add_child("MovieTitle")->add_child_text (_movie_title);
root->add_child("ReelNumber")->add_child_text (lexical_cast<string> (_reel_number));
root->add_child("Language")->add_child_text (_language);
#define LIBDCP_SUBTITLE_ASSET_H
#include <libcxml/cxml.h>
-#include "asset.h"
+#include "content.h"
#include "dcp_time.h"
-namespace libdcp
+namespace dcp
{
namespace parse
bool operator== (Subtitle const & a, Subtitle const & b);
std::ostream& operator<< (std::ostream& s, Subtitle const & sub);
-class SubtitleAsset : public Asset
+class SubtitleAsset : public Content
{
public:
- SubtitleAsset (std::string directory, std::string xml_file);
+ SubtitleAsset (boost::filesystem::path file);
SubtitleAsset (std::string directory, std::string movie_title, std::string language);
void write_to_cpl (xmlpp::Element *) const;
- virtual bool equals (boost::shared_ptr<const Asset>, EqualityOptions, boost::function<void (NoteType, std::string)> note) const {
+ virtual bool equals (boost::shared_ptr<const Content>, EqualityOptions, boost::function<void (NoteType, std::string)> note) const {
/* XXX */
note (ERROR, "subtitle assets not compared yet");
return true;
void add (boost::shared_ptr<Subtitle>);
- void read_xml (std::string);
void write_xml () const;
Glib::ustring xml_as_string () const;
#include "exceptions.h"
using namespace std;
-using namespace libdcp;
+using namespace dcp;
using namespace boost;
Fraction::Fraction (string s)
}
bool
-libdcp::operator== (Fraction const & a, Fraction const & b)
+dcp::operator== (Fraction const & a, Fraction const & b)
{
return (a.numerator == b.numerator && a.denominator == b.denominator);
}
bool
-libdcp::operator!= (Fraction const & a, Fraction const & b)
+dcp::operator!= (Fraction const & a, Fraction const & b)
{
return (a.numerator != b.numerator || a.denominator != b.denominator);
}
* @param b Second color to compare.
*/
bool
-libdcp::operator== (Color const & a, Color const & b)
+dcp::operator== (Color const & a, Color const & b)
{
return (a.r == b.r && a.g == b.g && a.b == b.b);
}
* @param b Second color to compare.
*/
bool
-libdcp::operator!= (Color const & a, Color const & b)
+dcp::operator!= (Color const & a, Color const & b)
{
return !(a == b);
}
ostream &
-libdcp::operator<< (ostream& s, Color const & c)
+dcp::operator<< (ostream& s, Color const & c)
{
s << "(" << c.r << ", " << c.g << ", " << c.b << ")";
return s;
}
string
-libdcp::effect_to_string (Effect e)
+dcp::effect_to_string (Effect e)
{
switch (e) {
case NONE:
}
Effect
-libdcp::string_to_effect (string s)
+dcp::string_to_effect (string s)
{
if (s == "none") {
return NONE;
}
string
-libdcp::valign_to_string (VAlign v)
+dcp::valign_to_string (VAlign v)
{
switch (v) {
case TOP:
}
VAlign
-libdcp::string_to_valign (string s)
+dcp::string_to_valign (string s)
{
if (s == "top") {
return TOP;
#include <string>
#include <boost/shared_ptr.hpp>
-namespace libdcp
+namespace dcp
{
namespace parse {
using std::setfill;
using boost::shared_ptr;
using boost::lexical_cast;
-using namespace libdcp;
+using namespace dcp;
/** Create a UUID.
* @return UUID.
*/
string
-libdcp::make_uuid ()
+dcp::make_uuid ()
{
char buffer[64];
Kumu::UUID id;
* @return Digest.
*/
string
-libdcp::make_digest (string filename, boost::function<void (float)>* progress)
+dcp::make_digest (string filename, boost::function<void (float)>* progress)
{
Kumu::FileReader reader;
Kumu::Result_t r = reader.OpenRead (filename.c_str ());
* @return string.
*/
string
-libdcp::content_kind_to_string (ContentKind kind)
+dcp::content_kind_to_string (ContentKind kind)
{
switch (kind) {
case FEATURE:
* @param type Content kind string.
* @return libdcp ContentKind.
*/
-libdcp::ContentKind
-libdcp::content_kind_from_string (string type)
+dcp::ContentKind
+dcp::content_kind_from_string (string type)
{
transform (type.begin(), type.end(), type.begin(), ::tolower);
* This is useful for scaling 4K DCP images down to 2K.
* @return XYZ image.
*/
-shared_ptr<libdcp::XYZFrame>
-libdcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
+shared_ptr<dcp::XYZFrame>
+dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
{
opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K);
opj_dparameters_t parameters;
* @return true if the string contains only space, newline or tab characters, or is empty.
*/
bool
-libdcp::empty_or_white_space (string s)
+dcp::empty_or_white_space (string s)
{
for (size_t i = 0; i < s.length(); ++i) {
if (s[i] != ' ' && s[i] != '\n' && s[i] != '\t') {
}
void
-libdcp::init ()
+dcp::init ()
{
if (xmlSecInit() < 0) {
throw MiscError ("could not initialise xmlsec");
}
}
-bool libdcp::operator== (libdcp::Size const & a, libdcp::Size const & b)
+bool dcp::operator== (dcp::Size const & a, dcp::Size const & b)
{
return (a.width == b.width && a.height == b.height);
}
-bool libdcp::operator!= (libdcp::Size const & a, libdcp::Size const & b)
+bool dcp::operator!= (dcp::Size const & a, dcp::Size const & b)
{
return !(a == b);
}
* this and the command-line base64 for some inputs. Not sure why.
*/
int
-libdcp::base64_decode (string const & in, unsigned char* out, int out_length)
+dcp::base64_decode (string const & in, unsigned char* out, int out_length)
{
BIO* b64 = BIO_new (BIO_f_base64 ());
}
string
-libdcp::tm_to_string (struct tm* tm)
+dcp::tm_to_string (struct tm* tm)
{
char buffer[64];
strftime (buffer, 64, "%Y-%m-%dT%H:%M:%S", tm);
* @return string of the form e.g. -01:00.
*/
string
-libdcp::utc_offset_to_string (int b)
+dcp::utc_offset_to_string (int b)
{
bool const negative = (b < 0);
b = negative ? -b : b;
}
string
-libdcp::ptime_to_string (boost::posix_time::ptime t)
+dcp::ptime_to_string (boost::posix_time::ptime t)
{
struct tm t_tm = boost::posix_time::to_tm (t);
return tm_to_string (&t_tm);
with this wrapper.
*/
FILE *
-libdcp::fopen_boost (boost::filesystem::path p, string t)
+dcp::fopen_boost (boost::filesystem::path p, string t)
{
#ifdef LIBDCP_WINDOWS
wstring w (t.begin(), t.end());
class Element;
}
-namespace libdcp {
+namespace dcp {
class ARGBFrame;
class CertificateChain;
-namespace libdcp {
+namespace dcp {
extern char const * version;
extern char const * git_commit;
asset.cc
certificates.cc
colour_matrix.cc
+ content.cc
cpl.cc
dcp.cc
dcp_time.cc
kdm.cc
key.cc
metadata.cc
- mono_picture_asset.cc
- mono_picture_asset_writer.cc
+ mono_picture_mxf.cc
+ mono_picture_mxf_writer.cc
mono_picture_frame.cc
- mxf_asset.cc
- picture_asset.cc
- picture_asset_writer.cc
+ mxf.cc
+ object.cc
+ picture_mxf.cc
+ picture_mxf_writer.cc
rec709_linearised_gamma_lut.cc
reel.cc
rgb_xyz.cc
signer.cc
signer_chain.cc
- sound_asset.cc
+ sound_mxf.cc
sound_frame.cc
srgb_linearised_gamma_lut.cc
- stereo_picture_asset.cc
- stereo_picture_asset_writer.cc
+ stereo_picture_mxf.cc
+ stereo_picture_mxf_writer.cc
stereo_picture_frame.cc
subtitle_asset.cc
types.cc
lut.h
lut_cache.h
metadata.h
- mono_picture_asset.h
+ mono_picture_mxf.h
mono_picture_frame.h
- mxf_asset.h
- picture_asset.h
- picture_asset_writer.h
+ mxf.h
+ object.h
+ picture_mxf.h
+ picture_mxf_writer.h
rgb_xyz.h
rec709_linearised_gamma_lut.h
reel.h
argb_frame.h
signer.h
signer_chain.h
- sound_asset.h
+ sound_mxf.h
sound_frame.h
srgb_linearised_gamma_lut.h
- stereo_picture_asset.h
+ stereo_picture_mxf.h
stereo_picture_frame.h
subtitle_asset.h
types.h
#include <libcxml/cxml.h>
#include "exceptions.h"
-namespace libdcp
+namespace dcp
{
template <class T>
#include <libcxml/cxml.h>
#include "../exceptions.h"
-namespace libdcp {
+namespace dcp {
namespace xml {
class Writer
#include <stdexcept>
#include "xyz_frame.h"
-using namespace libdcp;
+using namespace dcp;
/** Construct an XYZFrame, taking ownership of the opj_image_t */
XYZFrame::XYZFrame (opj_image_t* image)
return _opj_image->comps[c].data;
}
-libdcp::Size
+dcp::Size
XYZFrame::size () const
{
/* XXX: this may not be right; x0 and y0 can presumably be non-zero */
- return libdcp::Size (_opj_image->x1, _opj_image->y1);
+ return dcp::Size (_opj_image->x1, _opj_image->y1);
}
#include <openjpeg.h>
#include "util.h"
-namespace libdcp {
+namespace dcp {
class XYZFrame
{
~XYZFrame ();
int* data (int) const;
- libdcp::Size size () const;
+ dcp::Size size () const;
opj_image_t* opj_image () const {
return _opj_image;
BOOST_AUTO_TEST_CASE (certificates)
{
- libdcp::CertificateChain c;
+ dcp::CertificateChain c;
- c.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
- c.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
- c.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
+ c.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
+ c.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
+ c.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
- list<shared_ptr<libdcp::Certificate> > leaf_to_root = c.leaf_to_root ();
+ list<shared_ptr<dcp::Certificate> > leaf_to_root = c.leaf_to_root ();
- list<shared_ptr<libdcp::Certificate> >::iterator i = leaf_to_root.begin ();
+ list<shared_ptr<dcp::Certificate> >::iterator i = leaf_to_root.begin ();
/* Leaf */
BOOST_CHECK_EQUAL (*i, c.leaf ());
);
/* Check that reconstruction from a string works */
- libdcp::Certificate test (c.root()->certificate (true));
+ dcp::Certificate test (c.root()->certificate (true));
BOOST_CHECK_EQUAL (test.certificate(), c.root()->certificate());
}
#include "util.h"
-/* Check that libdcp::Color works */
+/* Check that dcp::Color works */
BOOST_AUTO_TEST_CASE (color)
{
- libdcp::Color c ("FFFF0000");
+ dcp::Color c ("FFFF0000");
BOOST_CHECK_EQUAL (c.r, 255);
BOOST_CHECK_EQUAL (c.g, 0);
BOOST_CHECK_EQUAL (c.b, 0);
BOOST_CHECK_EQUAL (c.to_argb_string(), "FFFF0000");
- c = libdcp::Color ("FF00FF00");
+ c = dcp::Color ("FF00FF00");
BOOST_CHECK_EQUAL (c.r, 0);
BOOST_CHECK_EQUAL (c.g, 255);
BOOST_CHECK_EQUAL (c.b, 0);
BOOST_CHECK_EQUAL (c.to_argb_string(), "FF00FF00");
- c = libdcp::Color ("FF0000FF");
+ c = dcp::Color ("FF0000FF");
BOOST_CHECK_EQUAL (c.r, 0);
BOOST_CHECK_EQUAL (c.g, 0);
#include <boost/test/unit_test.hpp>
#include <libcxml/cxml.h>
#include "cpl.h"
-#include "mono_picture_asset.h"
+#include "mono_picture_mxf.h"
using boost::shared_ptr;
*/
BOOST_AUTO_TEST_CASE (cpl_sar)
{
- shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset ("build/test/foo", "video.mxf"));
+ shared_ptr<dcp::MonoPictureMXF> mp (new dcp::MonoPictureMXF ("build/test/foo/video.mxf"));
mp->set_interop (true);
{
- mp->set_size (libdcp::Size (1998, 1080));
+ mp->set_size (dcp::Size (1998, 1080));
xmlpp::Document doc;
xmlpp::Element* el = doc.create_root_node ("Test");
mp->write_to_cpl (el);
}
{
- mp->set_size (libdcp::Size (2048, 858));
+ mp->set_size (dcp::Size (2048, 858));
xmlpp::Document doc;
xmlpp::Element* el = doc.create_root_node ("Test");
mp->write_to_cpl (el);
Kumu::libdcp_test = true;
/* Some known metadata */
- libdcp::XMLMetadata xml_meta;
+ dcp::XMLMetadata xml_meta;
xml_meta.issuer = "OpenDCP 0.0.25";
xml_meta.creator = "OpenDCP 0.0.25";
xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
- libdcp::MXFMetadata mxf_meta;
+ dcp::MXFMetadata mxf_meta;
mxf_meta.company_name = "OpenDCP";
mxf_meta.product_name = "OpenDCP";
mxf_meta.product_version = "0.0.25";
/* We're making build/test/foo */
boost::filesystem::remove_all ("build/test/foo");
boost::filesystem::create_directories ("build/test/foo");
- libdcp::DCP d ("build/test/foo");
- shared_ptr<libdcp::CPL> cpl (new libdcp::CPL ("build/test/foo", "A Test DCP", libdcp::FEATURE, 24, 24));
+ dcp::DCP d ("build/test/foo");
+ shared_ptr<dcp::CPL> cpl (new dcp::CPL ("build/test/foo", "A Test DCP", dcp::FEATURE, 24, 24));
- shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset ("build/test/foo", "video.mxf"));
+ shared_ptr<dcp::MonoPictureAsset> mp (new dcp::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_size (dcp::Size (32, 32));
mp->set_metadata (mxf_meta);
mp->create (j2c);
- shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset ("build/test/foo", "audio.mxf"));
+ shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset ("build/test/foo", "audio.mxf"));
ms->set_progress (&d.Progress);
ms->set_edit_rate (24);
ms->set_intrinsic_duration (24);
ms->set_metadata (mxf_meta);
ms->create (wav);
- cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
+ cpl->add_reel (shared_ptr<dcp::Reel> (new dcp::Reel (mp, ms, shared_ptr<dcp::SubtitleAsset> ())));
d.add_cpl (cpl);
d.write_xml (false, xml_meta);
#include <boost/test/unit_test.hpp>
#include "dcp_time.h"
-/** Check that libdcp::Time works */
+/** Check that dcp::Time works */
BOOST_AUTO_TEST_CASE (dcp_time)
{
- libdcp::Time t (977143, 24);
+ dcp::Time t (977143, 24);
BOOST_CHECK_EQUAL (t.t, 73);
BOOST_CHECK_EQUAL (t.s, 34);
BOOST_CHECK_EQUAL (t.to_string(), "11:18:34:73");
BOOST_CHECK_EQUAL (t.to_ticks(), 10178573);
- libdcp::Time a (3, 2, 3, 4);
- libdcp::Time b (2, 3, 4, 5);
+ dcp::Time a (3, 2, 3, 4);
+ dcp::Time b (2, 3, 4, 5);
- libdcp::Time r = a - b;
+ dcp::Time r = a - b;
BOOST_CHECK_EQUAL (r.h, 0);
BOOST_CHECK_EQUAL (r.m, 58);
BOOST_CHECK_EQUAL (r.s, 58);
BOOST_CHECK_EQUAL (r.to_string(), "0:58:58:249");
BOOST_CHECK_EQUAL (r.to_ticks(), 884749);
- a = libdcp::Time (1, 58, 56, 240);
- b = libdcp::Time (1, 7, 12, 120);
+ a = dcp::Time (1, 58, 56, 240);
+ b = dcp::Time (1, 7, 12, 120);
r = a + b;
BOOST_CHECK_EQUAL (r.h, 3);
BOOST_CHECK_EQUAL (r.m, 6);
BOOST_CHECK_EQUAL (r.to_string(), "3:6:9:110");
BOOST_CHECK_EQUAL (r.to_ticks(), 2792360);
- a = libdcp::Time (24, 12, 6, 3);
- b = libdcp::Time (16, 8, 4, 2);
+ a = dcp::Time (24, 12, 6, 3);
+ b = dcp::Time (16, 8, 4, 2);
BOOST_CHECK_CLOSE (a / b, 1.5, 1e-5);
- BOOST_CHECK_EQUAL (libdcp::Time (4128391203LL).to_ticks(), 4128391203LL);
- BOOST_CHECK_EQUAL (libdcp::Time (60000).to_ticks(), 60000);
+ BOOST_CHECK_EQUAL (dcp::Time (4128391203LL).to_ticks(), 4128391203LL);
+ BOOST_CHECK_EQUAL (dcp::Time (60000).to_ticks(), 60000);
}
#include "mono_picture_frame.h"
#include "cpl.h"
#include "argb_frame.h"
-#include "mono_picture_asset.h"
+#include "mono_picture_mxf.h"
#include "reel.h"
#include "test.h"
using boost::dynamic_pointer_cast;
using boost::shared_ptr;
-static shared_ptr<const libdcp::ARGBFrame>
-get_frame (libdcp::DCP const & dcp)
+static shared_ptr<const dcp::ARGBFrame>
+get_frame (dcp::DCP const & dcp)
{
- shared_ptr<const libdcp::Reel> reel = dcp.cpls().front()->reels().front ();
- shared_ptr<const libdcp::PictureAsset> picture = reel->main_picture ();
+ shared_ptr<const dcp::Reel> reel = dcp.cpls().front()->reels().front ();
+ shared_ptr<const dcp::PictureMXF> picture = reel->main_picture ();
BOOST_CHECK (picture);
- shared_ptr<const libdcp::MonoPictureAsset> mono_picture = dynamic_pointer_cast<const libdcp::MonoPictureAsset> (picture);
- shared_ptr<const libdcp::MonoPictureFrame> j2k_frame = mono_picture->get_frame (0);
+ shared_ptr<const dcp::MonoPictureMXF> mono_picture = dynamic_pointer_cast<const dcp::MonoPictureMXF> (picture);
+ shared_ptr<const dcp::MonoPictureFrame> j2k_frame = mono_picture->get_frame (0);
return j2k_frame->argb_frame ();
}
{
boost::filesystem::path plaintext_path = test_corpus;
plaintext_path /= "TONEPLATES-SMPTE-PLAINTEXT_TST_F_XX-XX_ITL-TD_51-XX_2K_WOE_20111001_WOE_OV";
- libdcp::DCP plaintext (plaintext_path.string ());
+ dcp::DCP plaintext (plaintext_path.string ());
plaintext.read ();
BOOST_CHECK_EQUAL (plaintext.encrypted (), false);
boost::filesystem::path encrypted_path = test_corpus;
encrypted_path /= "TONEPLATES-SMPTE-ENCRYPTED_TST_F_XX-XX_ITL-TD_51-XX_2K_WOE_20111001_WOE_OV";
- libdcp::DCP encrypted (encrypted_path.string ());
+ dcp::DCP encrypted (encrypted_path.string ());
encrypted.read ();
BOOST_CHECK_EQUAL (encrypted.encrypted (), true);
- libdcp::KDM kdm (
+ dcp::KDM kdm (
"test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml",
"test/data/private.key"
);
encrypted.add_kdm (kdm);
- shared_ptr<const libdcp::ARGBFrame> plaintext_frame = get_frame (plaintext);
- shared_ptr<const libdcp::ARGBFrame> encrypted_frame = get_frame (encrypted);
+ shared_ptr<const dcp::ARGBFrame> plaintext_frame = get_frame (plaintext);
+ shared_ptr<const dcp::ARGBFrame> encrypted_frame = get_frame (encrypted);
/* Check that plaintext and encrypted are the same */
BOOST_CHECK_EQUAL (plaintext_frame->stride(), encrypted_frame->stride());
/** Load in a KDM that didn't work at first */
BOOST_AUTO_TEST_CASE (failing_kdm_test)
{
- libdcp::KDM kdm (
+ dcp::KDM kdm (
"test/data/target.pem.crt.de5d4eba-e683-41ca-bdda-aa4ad96af3f4.kdm.xml",
"test/data/private.key"
);
{
boost::filesystem::remove_all ("build/test/signer");
boost::filesystem::create_directory ("build/test/signer");
- libdcp::make_signer_chain ("build/test/signer", "openssl");
+ dcp::make_signer_chain ("build/test/signer", "openssl");
Kumu::libdcp_test = true;
- libdcp::MXFMetadata mxf_metadata;
+ dcp::MXFMetadata mxf_metadata;
mxf_metadata.company_name = "OpenDCP";
mxf_metadata.product_name = "OpenDCP";
mxf_metadata.product_version = "0.0.25";
- libdcp::XMLMetadata xml_metadata;
+ dcp::XMLMetadata xml_metadata;
xml_metadata.issuer = "OpenDCP 0.0.25";
xml_metadata.creator = "OpenDCP 0.0.25";
xml_metadata.issue_date = "2012-07-17T04:45:18+00:00";
boost::filesystem::remove_all ("build/test/DCP/bar");
boost::filesystem::create_directories ("build/test/DCP/bar");
- libdcp::DCP d ("build/test/DCP/bar");
+ dcp::DCP d ("build/test/DCP/bar");
- 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"))));
+ dcp::CertificateChain chain;
+ chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("build/test/signer/ca.self-signed.pem"))));
+ chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("build/test/signer/intermediate.signed.pem"))));
+ chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("build/test/signer/leaf.signed.pem"))));
- shared_ptr<libdcp::Signer> signer (
- new libdcp::Signer (
+ shared_ptr<dcp::Signer> signer (
+ new dcp::Signer (
chain,
"build/test/signer/leaf.key"
)
);
- shared_ptr<libdcp::CPL> cpl (new libdcp::CPL ("build/test/DCP/bar", "A Test DCP", libdcp::FEATURE, 24, 24));
+ shared_ptr<dcp::CPL> cpl (new dcp::CPL ("build/test/DCP/bar", "A Test DCP", dcp::FEATURE, 24, 24));
- libdcp::Key key;
+ dcp::Key key;
- shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset ("build/test/DCP/bar", "video.mxf"));
+ shared_ptr<dcp::MonoPictureAsset> mp (new dcp::MonoPictureAsset ("build/test/DCP/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_size (dcp::Size (32, 32));
mp->set_metadata (mxf_metadata);
mp->set_key (key);
mp->create (j2c);
- shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset ("build/test/DCP/bar", "audio.mxf"));
+ shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset ("build/test/DCP/bar", "audio.mxf"));
ms->set_progress (&d.Progress);
ms->set_edit_rate (24);
ms->set_intrinsic_duration (24);
ms->set_key (key);
ms->create (wav);
- cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
+ cpl->add_reel (shared_ptr<dcp::Reel> (new dcp::Reel (mp, ms, shared_ptr<dcp::SubtitleAsset> ())));
d.add_cpl (cpl);
d.write_xml (false, xml_metadata, signer);
- libdcp::KDM kdm (
+ dcp::KDM kdm (
cpl,
signer,
signer->certificates().leaf(),
+++ /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 <boost/test/unit_test.hpp>
-#include "dcp.h"
-#include "mono_picture_asset.h"
-#include "sound_asset.h"
-#include "util.h"
-#include "exceptions.h"
-
-using std::vector;
-using std::string;
-
-/* Check that an exception is thrown when trying to create MXFs from non-existant sources */
-BOOST_AUTO_TEST_CASE (error_test)
-{
- /* Create an empty DCP */
- libdcp::DCP d ("build/test/fred");
-
- /* Random filename that does not exist */
- vector<boost::filesystem::path> p;
- p.push_back ("frobozz");
-
- /* Trying to create video/audio MXFs using a non-existant file should throw an exception */
- libdcp::MonoPictureAsset pa ("build/test/fred", "video.mxf");
- BOOST_CHECK_THROW (pa.create (p), libdcp::FileError);
-
- libdcp::SoundAsset sa ("build/test/fred", "audio.mxf");
- sa.set_channels (1);
- BOOST_CHECK_THROW (sa.create (p), libdcp::FileError);
-}
#include <fstream>
#include <boost/test/unit_test.hpp>
-#include "picture_asset_writer.h"
+#include "picture_mxf.h"
+#include "picture_mxf_writer.h"
using namespace std;
/* Test writing and reading of frame_info_test with fstream and stdio */
BOOST_AUTO_TEST_CASE (frame_info_test)
{
- libdcp::FrameInfo a (8589934592LL, 17179869184LL, "thisisahash");
+ dcp::FrameInfo a (8589934592LL, 17179869184LL, "thisisahash");
ofstream o1 ("build/test/frame_info1");
a.write (o1);
BOOST_CHECK_EQUAL (s1, s2);
ifstream l1 ("build/test/frame_info1");
- libdcp::FrameInfo b1 (l1);
+ dcp::FrameInfo b1 (l1);
FILE* l2 = fopen ("build/test/frame_info2", "r");
BOOST_CHECK (l2);
- libdcp::FrameInfo b2 (l2);
+ dcp::FrameInfo b2 (l2);
BOOST_CHECK_EQUAL (b1.offset, b2.offset);
BOOST_CHECK_EQUAL (b1.size, b2.size);
{
uint8_t foo[138];
memset (foo, 0, 138);
- libdcp::KDMKey kkey (foo, 138);
+ dcp::KDMKey kkey (foo, 138);
uint8_t* raw = new uint8_t[16];
uint8_t* p = raw;
BOOST_AUTO_TEST_CASE (kdm_test)
{
- libdcp::KDM kdm (
+ dcp::KDM kdm (
"test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml",
"test/data/private.key"
);
- list<libdcp::KDMKey> keys = kdm.keys ();
+ list<dcp::KDMKey> keys = kdm.keys ();
BOOST_CHECK_EQUAL (keys.size(), 2);
/* Check that we can read in a KDM and then write it back out again the same */
BOOST_AUTO_TEST_CASE (kdm_passthrough_test)
{
- libdcp::xml::DCinemaSecurityMessage kdm (
+ dcp::xml::DCinemaSecurityMessage kdm (
"test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml"
);
*/
BOOST_AUTO_TEST_CASE (lut_test)
{
- libdcp::SRGBLinearisedGammaLUT lut_in_srgb (12, 2.4);
+ dcp::SRGBLinearisedGammaLUT lut_in_srgb (12, 2.4);
for (int i = 0; i < 4096; ++i) {
/* Hmm; 1% isn't exactly great... */
BOOST_CHECK_CLOSE (opendcp::lut_in[0][i], lut_in_srgb.lut()[i], 1);
}
- libdcp::Rec709LinearisedGammaLUT lut_in_rec709 (12, 1 / 0.45);
+ dcp::Rec709LinearisedGammaLUT lut_in_rec709 (12, 1 / 0.45);
for (int i = 0; i < 4096; ++i) {
/* Hmm; 1% isn't exactly great... */
BOOST_CHECK_CLOSE (opendcp::lut_in[1][i], lut_in_rec709.lut()[i], 1);
}
- libdcp::GammaLUT lut_out (16, 1 / 2.6);
+ dcp::GammaLUT lut_out (16, 1 / 2.6);
for (int i = 0; i < 65536; ++i) {
BOOST_CHECK_CLOSE (opendcp::lut_out[0][i], lut_out.lut()[i] * 4096, 1);
}
/* Read DCP that is in git and make sure that basic stuff is read in correctly */
BOOST_AUTO_TEST_CASE (read_dcp)
{
- libdcp::DCP d ("test/ref/DCP/foo");
+ dcp::DCP d ("test/ref/DCP/foo");
d.read ();
- list<shared_ptr<libdcp::CPL> > cpls = d.cpls ();
+ list<shared_ptr<dcp::CPL> > cpls = d.cpls ();
BOOST_CHECK_EQUAL (cpls.size(), 1);
BOOST_CHECK_EQUAL (cpls.front()->name(), "A Test DCP");
- BOOST_CHECK_EQUAL (cpls.front()->content_kind(), libdcp::FEATURE);
+ BOOST_CHECK_EQUAL (cpls.front()->content_kind(), dcp::FEATURE);
BOOST_CHECK_EQUAL (cpls.front()->frames_per_second(), 24);
BOOST_CHECK_EQUAL (cpls.front()->length(), 24);
}
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
-#include "mono_picture_asset_writer.h"
-#include "mono_picture_asset.h"
+#include "mono_picture_mxf_writer.h"
+#include "mono_picture_mxf.h"
#include "KM_util.h"
using std::string;
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"));
- mp->set_edit_rate (24);
- mp->set_size (libdcp::Size (32, 32));
- shared_ptr<libdcp::PictureAssetWriter> writer = mp->start_write (false);
+ shared_ptr<dcp::MonoPictureMXF> mp (new dcp::MonoPictureMXF (24));
+ mp->set_size (dcp::Size (32, 32));
+ shared_ptr<dcp::PictureMXFWriter> writer = mp->start_write ("build/test/baz/video1.mxf", false);
int written_size = 0;
for (int i = 0; i < 24; ++i) {
- libdcp::FrameInfo info = writer->write (data, size);
+ dcp::FrameInfo info = writer->write (data, size);
written_size = info.size;
}
Kumu::ResetTestRNG ();
#endif
- 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);
+ mp.reset (new dcp::MonoPictureMXF (24));
+ mp->set_size (dcp::Size (32, 32));
+ writer = mp->start_write ("build/test/baz/video2.mxf", true);
writer->write (data, size);
using std::cerr;
using std::list;
using boost::shared_ptr;
-using namespace libdcp;
+using namespace dcp;
int
main (int argc, char* argv[])
#include "certificates.h"
#include "kdm.h"
#include "signer.h"
-#include "mono_picture_asset.h"
-#include "sound_asset.h"
+#include "mono_picture_mxf.h"
+#include "sound_mxf.h"
#include "reel.h"
#include "test.h"
#include "cpl.h"
{
boost::filesystem::remove_all ("build/test/signer");
boost::filesystem::create_directory ("build/test/signer");
- libdcp::make_signer_chain ("build/test/signer", "openssl");
+ dcp::make_signer_chain ("build/test/signer", "openssl");
- 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"))));
+ dcp::CertificateChain chain;
+ chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("build/test/signer/ca.self-signed.pem"))));
+ chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("build/test/signer/intermediate.signed.pem"))));
+ chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("build/test/signer/leaf.signed.pem"))));
- shared_ptr<libdcp::Signer> signer (
- new libdcp::Signer (
+ shared_ptr<dcp::Signer> signer (
+ new dcp::Signer (
chain,
"test/data/signer.key"
)
boost::filesystem::path work_dir = "build/test/round_trip_test";
boost::filesystem::create_directory (work_dir);
- shared_ptr<libdcp::MonoPictureAsset> asset_A (new libdcp::MonoPictureAsset (work_dir, "video.mxf"));
+ shared_ptr<dcp::MonoPictureMXF> asset_A (new dcp::MonoPictureMXF (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);
+ shared_ptr<PictureMXFWriter> writer;
+ boost::filesystem::path mxf = work_dir + "video.mxf";
+ writer->start_write (mxf, false);
+ TestFile j2c ("test/data/32x32_red_square.j2c");
+ for (int i = 0; i < 24; ++i) {
+ writer->write (j2c.data (), j2c.size ());
+ }
+ writer->finalize ();
- libdcp::Key key;
+ dcp::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> ())));
+ shared_ptr<dcp::CPL> cpl (new dcp::CPL (work_dir, "A Test DCP", dcp::FEATURE, 24, 24));
+ cpl->add_reel (shared_ptr<dcp::Reel> (new dcp::Reel (asset_A, shared_ptr<dcp::SoundMXF> (), shared_ptr<dcp::SubtitleAsset> ())));
/* A KDM using our certificate chain's leaf key pair */
- libdcp::KDM kdm_A (
+ dcp::KDM kdm_A (
cpl,
signer,
signer->certificates().leaf(),
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");
+ dcp::KDM kdm_B (kdm_file, "build/test/signer/leaf.key");
/* Check that the decrypted KDMKeys are the same as the ones we started with */
BOOST_CHECK_EQUAL (kdm_A.keys().size(), kdm_B.keys().size());
- list<libdcp::KDMKey> keys_A = kdm_A.keys ();
- list<libdcp::KDMKey> keys_B = kdm_B.keys ();
- list<libdcp::KDMKey>::const_iterator i = keys_A.begin();
- list<libdcp::KDMKey>::const_iterator j = keys_B.begin();
+ list<dcp::KDMKey> keys_A = kdm_A.keys ();
+ list<dcp::KDMKey> keys_B = kdm_B.keys ();
+ list<dcp::KDMKey>::const_iterator i = keys_A.begin();
+ list<dcp::KDMKey>::const_iterator j = keys_B.begin();
while (i != keys_A.end ()) {
BOOST_CHECK (*i == *j);
++i;
}
/* Reload the picture MXF */
- shared_ptr<libdcp::MonoPictureAsset> asset_B (
- new libdcp::MonoPictureAsset (work_dir, "video.mxf")
+ shared_ptr<dcp::MonoPictureMXF> asset_B (
+ new dcp::MonoPictureMXF (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 ();
+ shared_ptr<dcp::ARGBFrame> frame_A = asset_A->get_frame(0)->argb_frame ();
+ shared_ptr<dcp::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);
exit (EXIT_FAILURE);
}
- libdcp::SubtitleAsset s ("foo", "bar", "baz");
- s.read_xml (argv[1]);
+ dcp::SubtitleAsset s (argv[1]);
cout << s.xml_as_string ();
return 0;
}
/* Load a subtitle asset from XML and check that it is read correctly */
BOOST_AUTO_TEST_CASE (subtitles1)
{
- libdcp::SubtitleAsset subs ("test/data", "subs1.xml");
+ dcp::SubtitleAsset subs ("test/data/subs1.xml");
BOOST_CHECK_EQUAL (subs.language(), "French");
- list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_at (libdcp::Time (0, 0, 6, 1));
+ list<shared_ptr<dcp::Subtitle> > s = subs.subtitles_at (dcp::Time (0, 0, 6, 1));
BOOST_CHECK_EQUAL (s.size(), 1);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
39,
- libdcp::Time (0, 0, 5, 198),
- libdcp::Time (0, 0, 7, 115),
+ dcp::Time (0, 0, 5, 198),
+ dcp::Time (0, 0, 7, 115),
15,
- libdcp::BOTTOM,
+ dcp::BOTTOM,
"My jacket was Idi Amin's",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 1),
- libdcp::Time (0, 0, 0, 1)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 1),
+ dcp::Time (0, 0, 0, 1)
));
- s = subs.subtitles_at (libdcp::Time (0, 0, 7, 190));
+ s = subs.subtitles_at (dcp::Time (0, 0, 7, 190));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
39,
- libdcp::Time (0, 0, 7, 177),
- libdcp::Time (0, 0, 11, 31),
+ dcp::Time (0, 0, 7, 177),
+ dcp::Time (0, 0, 11, 31),
21,
- libdcp::BOTTOM,
+ dcp::BOTTOM,
"My corset was H.M. The Queen's",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 1),
- libdcp::Time (0, 0, 0, 1)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 1),
+ dcp::Time (0, 0, 0, 1)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
39,
- libdcp::Time (0, 0, 7, 177),
- libdcp::Time (0, 0, 11, 31),
+ dcp::Time (0, 0, 7, 177),
+ dcp::Time (0, 0, 11, 31),
15,
- libdcp::BOTTOM,
+ dcp::BOTTOM,
"My large wonderbra",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 1),
- libdcp::Time (0, 0, 0, 1)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 1),
+ dcp::Time (0, 0, 0, 1)
));
- s = subs.subtitles_at (libdcp::Time (0, 0, 11, 95));
+ s = subs.subtitles_at (dcp::Time (0, 0, 11, 95));
BOOST_CHECK_EQUAL (s.size(), 1);
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
39,
- libdcp::Time (0, 0, 11, 94),
- libdcp::Time (0, 0, 13, 63),
+ dcp::Time (0, 0, 11, 94),
+ dcp::Time (0, 0, 13, 63),
15,
- libdcp::BOTTOM,
+ dcp::BOTTOM,
"Once belonged to the Shah",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 1),
- libdcp::Time (0, 0, 0, 1)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 1),
+ dcp::Time (0, 0, 0, 1)
));
- s = subs.subtitles_at (libdcp::Time (0, 0, 14, 42));
+ s = subs.subtitles_at (dcp::Time (0, 0, 14, 42));
BOOST_CHECK_EQUAL (s.size(), 1);
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
39,
- libdcp::Time (0, 0, 13, 104),
- libdcp::Time (0, 0, 15, 177),
+ dcp::Time (0, 0, 13, 104),
+ dcp::Time (0, 0, 15, 177),
15,
- libdcp::BOTTOM,
+ dcp::BOTTOM,
"And these are Roy Hattersley's jeans",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 1),
- libdcp::Time (0, 0, 0, 1)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 1),
+ dcp::Time (0, 0, 0, 1)
));
}
/** And similarly for another one */
BOOST_AUTO_TEST_CASE (subtitles2)
{
- libdcp::SubtitleAsset subs ("test/data", "subs2.xml");
+ dcp::SubtitleAsset subs ("test/data/subs2.xml");
- list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_at (libdcp::Time (0, 0, 42, 100));
+ list<shared_ptr<dcp::Subtitle> > s = subs.subtitles_at (dcp::Time (0, 0, 42, 100));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 0, 41, 62),
- libdcp::Time (0, 0, 43, 52),
+ dcp::Time (0, 0, 41, 62),
+ dcp::Time (0, 0, 43, 52),
89,
- libdcp::TOP,
+ dcp::TOP,
"At afternoon tea with John Peel",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 0, 41, 62),
- libdcp::Time (0, 0, 43, 52),
+ dcp::Time (0, 0, 41, 62),
+ dcp::Time (0, 0, 43, 52),
95,
- libdcp::TOP,
+ dcp::TOP,
"I enquired if his accent was real",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- s = subs.subtitles_at (libdcp::Time (0, 0, 50, 50));
+ s = subs.subtitles_at (dcp::Time (0, 0, 50, 50));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 0, 50, 42),
- libdcp::Time (0, 0, 52, 21),
+ dcp::Time (0, 0, 50, 42),
+ dcp::Time (0, 0, 52, 21),
89,
- libdcp::TOP,
+ dcp::TOP,
"He said \"out of the house",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 0, 50, 42),
- libdcp::Time (0, 0, 52, 21),
+ dcp::Time (0, 0, 50, 42),
+ dcp::Time (0, 0, 52, 21),
95,
- libdcp::TOP,
+ dcp::TOP,
"I'm incredibly scouse",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- s = subs.subtitles_at (libdcp::Time (0, 1, 2, 300));
+ s = subs.subtitles_at (dcp::Time (0, 1, 2, 300));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 2, 208),
- libdcp::Time (0, 1, 4, 10),
+ dcp::Time (0, 1, 2, 208),
+ dcp::Time (0, 1, 4, 10),
89,
- libdcp::TOP,
+ dcp::TOP,
"At home it depends how I feel.\"",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 2, 208),
- libdcp::Time (0, 1, 4, 10),
+ dcp::Time (0, 1, 2, 208),
+ dcp::Time (0, 1, 4, 10),
95,
- libdcp::TOP,
+ dcp::TOP,
"I spent a long weekend in Brighton",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- s = subs.subtitles_at (libdcp::Time (0, 1, 15, 50));
+ s = subs.subtitles_at (dcp::Time (0, 1, 15, 50));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 15, 42),
- libdcp::Time (0, 1, 16, 42),
+ dcp::Time (0, 1, 15, 42),
+ dcp::Time (0, 1, 16, 42),
89,
- libdcp::TOP,
+ dcp::TOP,
"With the legendary Miss Enid Blyton",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 15, 42),
- libdcp::Time (0, 1, 16, 42),
+ dcp::Time (0, 1, 15, 42),
+ dcp::Time (0, 1, 16, 42),
95,
- libdcp::TOP,
+ dcp::TOP,
"She said \"you be Noddy",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- s = subs.subtitles_at (libdcp::Time (0, 1, 27, 200));
+ s = subs.subtitles_at (dcp::Time (0, 1, 27, 200));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 27, 115),
- libdcp::Time (0, 1, 28, 208),
+ dcp::Time (0, 1, 27, 115),
+ dcp::Time (0, 1, 28, 208),
89,
- libdcp::TOP,
+ dcp::TOP,
"That curious creature the Sphinx",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 27, 115),
- libdcp::Time (0, 1, 28, 208),
+ dcp::Time (0, 1, 27, 115),
+ dcp::Time (0, 1, 28, 208),
95,
- libdcp::TOP,
+ dcp::TOP,
"Is smarter than anyone thinks",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- s = subs.subtitles_at (libdcp::Time (0, 1, 42, 300));
+ s = subs.subtitles_at (dcp::Time (0, 1, 42, 300));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 42, 229),
- libdcp::Time (0, 1, 45, 62),
+ dcp::Time (0, 1, 42, 229),
+ dcp::Time (0, 1, 45, 62),
89,
- libdcp::TOP,
+ dcp::TOP,
"It sits there and smirks",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 42, 229),
- libdcp::Time (0, 1, 45, 62),
+ dcp::Time (0, 1, 42, 229),
+ dcp::Time (0, 1, 45, 62),
95,
- libdcp::TOP,
+ dcp::TOP,
"And you don't think it works",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- s = subs.subtitles_at (libdcp::Time (0, 1, 45, 200));
+ s = subs.subtitles_at (dcp::Time (0, 1, 45, 200));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 45, 146),
- libdcp::Time (0, 1, 47, 94),
+ dcp::Time (0, 1, 45, 146),
+ dcp::Time (0, 1, 47, 94),
89,
- libdcp::TOP,
+ dcp::TOP,
"Then when you're not looking, it winks.",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 45, 146),
- libdcp::Time (0, 1, 47, 94),
+ dcp::Time (0, 1, 45, 146),
+ dcp::Time (0, 1, 47, 94),
95,
- libdcp::TOP,
+ dcp::TOP,
"When it snows you will find Sister Sledge",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- s = subs.subtitles_at (libdcp::Time (0, 1, 47, 249));
+ s = subs.subtitles_at (dcp::Time (0, 1, 47, 249));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 47, 146),
- libdcp::Time (0, 1, 48, 167),
+ dcp::Time (0, 1, 47, 146),
+ dcp::Time (0, 1, 48, 167),
89,
- libdcp::TOP,
+ dcp::TOP,
"Out mooning, at night, on the ledge",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
false,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 1, 47, 146),
- libdcp::Time (0, 1, 48, 167),
+ dcp::Time (0, 1, 47, 146),
+ dcp::Time (0, 1, 48, 167),
95,
- libdcp::TOP,
+ dcp::TOP,
"One storey down",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- s = subs.subtitles_at (libdcp::Time (0, 2, 6, 210));
+ s = subs.subtitles_at (dcp::Time (0, 2, 6, 210));
BOOST_CHECK_EQUAL (s.size(), 2);
- BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.front().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 2, 5, 208),
- libdcp::Time (0, 2, 7, 31),
+ dcp::Time (0, 2, 5, 208),
+ dcp::Time (0, 2, 7, 31),
89,
- libdcp::TOP,
+ dcp::TOP,
"HELLO",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
- BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
+ BOOST_CHECK_EQUAL (*(s.back().get()), dcp::Subtitle (
"Arial",
true,
- libdcp::Color (255, 255, 255),
+ dcp::Color (255, 255, 255),
42,
- libdcp::Time (0, 2, 5, 208),
- libdcp::Time (0, 2, 7, 31),
+ dcp::Time (0, 2, 5, 208),
+ dcp::Time (0, 2, 7, 31),
95,
- libdcp::TOP,
+ dcp::TOP,
"WORLD",
- libdcp::BORDER,
- libdcp::Color (0, 0, 0),
- libdcp::Time (0, 0, 0, 0),
- libdcp::Time (0, 0, 0, 0)
+ dcp::BORDER,
+ dcp::Color (0, 0, 0),
+ dcp::Time (0, 0, 0, 0),
+ dcp::Time (0, 0, 0, 0)
));
#define BOOST_TEST_MODULE libdcp_test
#include <boost/test/unit_test.hpp>
#include "util.h"
+#include "test.h"
using std::string;
{
TestConfig()
{
- libdcp::init ();
+ dcp::init ();
}
};
}
boost::filesystem::path
-wav (libdcp::Channel)
+wav (dcp::Channel)
{
return "test/data/1s_24-bit_48k_silence.wav";
}
string test_corpus = "../libdcp-test";
+TestFile::TestFile (boost::filesystem::path file)
+{
+ _size = boost::filesystem::file_size (file);
+ _data = new uint8_t[_size];
+ FILE* f = dcp::fopen_boost (file, "r");
+ assert (f);
+ fread (_data, 1, _size, f);
+ fclose (f);
+}
+
+TestFile::~TestFile ()
+{
+ delete[] _data;
+}
*/
-extern boost::filesystem::path j2c (int);
-extern boost::filesystem::path wav (libdcp::Channel);
extern std::string test_corpus;
+
+class TestFile
+{
+public:
+ TestFile (boost::filesystem::path file);
+ ~TestFile ();
+
+ uint8_t* data () const {
+ return _data;
+ }
+
+ int64_t size () const {
+ return _size;
+ }
+
+private:
+ uint8_t* _data;
+ int64_t _size;
+};
#include "metadata.h"
#include "util.h"
-/** Test libdcp::utc_offset_to_string */
+/** Test dcp::utc_offset_to_string */
BOOST_AUTO_TEST_CASE (utc_offset_to_string_test)
{
- BOOST_CHECK_EQUAL (libdcp::utc_offset_to_string (30), "+00:30");
- BOOST_CHECK_EQUAL (libdcp::utc_offset_to_string (60), "+01:00");
- BOOST_CHECK_EQUAL (libdcp::utc_offset_to_string (61), "+01:01");
- BOOST_CHECK_EQUAL (libdcp::utc_offset_to_string (7 * 60), "+07:00");
- BOOST_CHECK_EQUAL (libdcp::utc_offset_to_string (-11 * 60), "-11:00");
+ BOOST_CHECK_EQUAL (dcp::utc_offset_to_string (30), "+00:30");
+ BOOST_CHECK_EQUAL (dcp::utc_offset_to_string (60), "+01:00");
+ BOOST_CHECK_EQUAL (dcp::utc_offset_to_string (61), "+01:01");
+ BOOST_CHECK_EQUAL (dcp::utc_offset_to_string (7 * 60), "+07:00");
+ BOOST_CHECK_EQUAL (dcp::utc_offset_to_string (-11 * 60), "-11:00");
}
}
unsigned char decoded[N];
- int const r = libdcp::base64_decode (s, decoded, N);
+ int const r = dcp::base64_decode (s, decoded, N);
BOOST_CHECK_EQUAL (r, N);
for (int i = 0; i < N; ++i) {
BOOST_AUTO_TEST_CASE (content_kind_test)
{
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("feature"), libdcp::FEATURE);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("Feature"), libdcp::FEATURE);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("FeaturE"), libdcp::FEATURE);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("Short"), libdcp::SHORT);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("trailer"), libdcp::TRAILER);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("test"), libdcp::TEST);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("transitional"), libdcp::TRANSITIONAL);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("rating"), libdcp::RATING);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("teaser"), libdcp::TEASER);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("policy"), libdcp::POLICY);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("psa"), libdcp::PUBLIC_SERVICE_ANNOUNCEMENT);
- BOOST_CHECK_EQUAL (libdcp::content_kind_from_string ("advertisement"), libdcp::ADVERTISEMENT);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("feature"), dcp::FEATURE);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("Feature"), dcp::FEATURE);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("FeaturE"), dcp::FEATURE);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("Short"), dcp::SHORT);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("trailer"), dcp::TRAILER);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("test"), dcp::TEST);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("transitional"), dcp::TRANSITIONAL);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("rating"), dcp::RATING);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("teaser"), dcp::TEASER);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("policy"), dcp::POLICY);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("psa"), dcp::PUBLIC_SERVICE_ANNOUNCEMENT);
+ BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("advertisement"), dcp::ADVERTISEMENT);
}
else:
boost_lib_suffix = ''
- conf.check_cxx(fragment = """
- #define BOOST_TEST_MODULE Config test\n
- #include <boost/test/unit_test.hpp>\n
- int main() {}
- """,
- msg = 'Checking for boost unit testing library',
- lib = 'boost_unit_test_framework%s' % boost_lib_suffix,
- uselib_store = 'BOOST_TEST')
+ conf.check_cxx(fragment="""
+ #define BOOST_TEST_MODULE Config test\n
+ #include <boost/test/unit_test.hpp>\n
+ int main() {}
+ """,
+ msg='Checking for boost unit testing library',
+ lib='boost_unit_test_framework%s' % boost_lib_suffix,
+ uselib_store='BOOST_TEST')
conf.env.prepend_value('LINKFLAGS', '-Lsrc')
def build(bld):
- obj = bld(features = 'cxx cxxprogram')
+ obj = bld(features='cxx cxxprogram')
obj.name = 'tests'
obj.uselib = 'BOOST_TEST OPENJPEG CXML XMLSEC1'
obj.use = 'libdcp'
+# dcp_test.cc
+# encryption_test.cc
obj.source = """
certificates_test.cc
color_test.cc
cpl_sar.cc
- dcp_test.cc
dcp_time_test.cc
decryption_test.cc
- encryption_test.cc
- error_test.cc
frame_info_test.cc
kdm_key_test.cc
kdm_test.cc
obj.target = 'tests'
obj.install_path = ''
- obj = bld(features = 'cxx cxxprogram')
+ obj = bld(features='cxx cxxprogram')
obj.name = 'subs_in_out'
obj.uselib = 'BOOST_TEST OPENJPEG CXML'
obj.use = 'libdcp'
obj.target = 'subs_in_out'
obj.install_path = ''
- obj = bld(features = 'cxx cxxprogram')
+ obj = bld(features='cxx cxxprogram')
obj.name = 'rewrite_subs'
obj.uselib = 'BOOST_TEST OPENJPEG CXML'
obj.use = 'libdcp'
using namespace std;
using namespace boost;
-using namespace libdcp;
+using namespace dcp;
static bool verbose = false;
#include "dcp.h"
#include "exceptions.h"
#include "reel.h"
-#include "sound_asset.h"
-#include "picture_asset.h"
+#include "sound_mxf.h"
+#include "picture_mxf.h"
#include "subtitle_asset.h"
#include "cpl.h"
using std::cout;
using std::list;
using boost::shared_ptr;
-using namespace libdcp;
+using namespace dcp;
static void
help (string n)
import os
APPNAME = 'libdcp'
-VERSION = '0.93pre'
+VERSION = '1.00.0devel'
def options(opt):
opt.load('compiler_cxx')
- opt.add_option('--target-windows', action='store_true', default = False, help = 'set up to do a cross-compile to Windows')
- opt.add_option('--osx', action='store_true', default = False, help = 'set up to build on OS X')
- opt.add_option('--enable-debug', action='store_true', default = False, help = 'build with debugging information and without optimisation')
- opt.add_option('--static', action='store_true', default = False, help = 'build libdcp and in-tree dependencies statically, and link statically to openjpeg and cxml')
+ opt.add_option('--target-windows', action='store_true', default=False, help='set up to do a cross-compile to Windows')
+ opt.add_option('--target-osx', action='store_true', default=False, help='set up to build on OS X')
+ opt.add_option('--enable-debug', action='store_true', default=False, help='build with debugging information and without optimisation')
+ opt.add_option('--static', action='store_true', default=False, help='build libdcp and in-tree dependencies statically, and link statically to openjpeg and cxml')
def configure(conf):
conf.load('compiler_cxx')
conf.env.append_value('CXXFLAGS', ['-DLIBDCP_VERSION="%s"' % VERSION])
conf.env.TARGET_WINDOWS = conf.options.target_windows
- conf.env.STATIC = conf.options.static
- conf.env.OSX = conf.options.osx
+ conf.env.TARGET_OSX = conf.options.target_osx
conf.env.ENABLE_DEBUG = conf.options.enable_debug
+ conf.env.STATIC = conf.options.static
if conf.options.target_windows:
conf.env.append_value('CXXFLAGS', '-DLIBDCP_WINDOWS')
else:
conf.env.append_value('CXXFLAGS', '-DLIBDCP_POSIX')
- if not conf.options.osx:
+ if not conf.options.target_osx:
conf.env.append_value('CXXFLAGS', ['-Wno-unused-result'])
- conf.check_cfg(package = 'openssl', args = '--cflags --libs', uselib_store = 'OPENSSL', mandatory = True)
- conf.check_cfg(package = 'libxml++-2.6', args = '--cflags --libs', uselib_store = 'LIBXML++', mandatory = True)
- conf.check_cfg(package = 'xmlsec1', args = '--cflags --libs', uselib_store = 'XMLSEC1', mandatory = True)
+ conf.check_cfg(package='openssl', args='--cflags --libs', uselib_store='OPENSSL', mandatory=True)
+ conf.check_cfg(package='libxml++-2.6', args='--cflags --libs', uselib_store='LIBXML++', mandatory=True)
+ conf.check_cfg(package='xmlsec1', args='--cflags --libs', uselib_store='XMLSEC1', mandatory=True)
# Remove erroneous escaping of quotes from xmlsec1 defines
conf.env.DEFINES_XMLSEC1 = [f.replace('\\', '') for f in conf.env.DEFINES_XMLSEC1]
if conf.options.static:
- conf.check_cc(fragment = """
- #include <stdio.h>\n
- #include <openjpeg.h>\n
- int main () {\n
- void* p = (void *) opj_image_create;\n
- return 0;\n
- }
- """,
- msg = 'Checking for library openjpeg', stlib = 'openjpeg', uselib_store = 'OPENJPEG', mandatory = True)
+ conf.check_cc(fragment="""
+ #include <stdio.h>\n
+ #include <openjpeg.h>\n
+ int main () {\n
+ void* p = (void *) opj_image_create;\n
+ return 0;\n
+ }
+ """,
+ msg='Checking for library openjpeg', stlib='openjpeg', uselib_store='OPENJPEG', mandatory=True)
conf.env.HAVE_CXML = 1
conf.env.STLIB_CXML = ['cxml']
# Windows builds are any more reliable
conf.env.append_value('CXXFLAGS', '-O2')
- conf.check_cxx(fragment = """
- #include <boost/version.hpp>\n
- #if BOOST_VERSION < 104500\n
- #error boost too old\n
- #endif\n
- int main(void) { return 0; }\n
- """,
- mandatory = True,
- msg = 'Checking for boost library >= 1.45',
- okmsg = 'yes',
- errmsg = 'too old\nPlease install boost version 1.45 or higher.')
-
- conf.check_cxx(fragment = """
- #include <boost/filesystem.hpp>\n
- int main() { boost::filesystem::copy_file ("a", "b"); }\n
- """,
- msg = 'Checking for boost filesystem library',
- libpath = '/usr/local/lib',
- lib = ['boost_filesystem%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix],
- uselib_store = 'BOOST_FILESYSTEM')
-
- conf.check_cxx(fragment = """
- #include <boost/signals2.hpp>\n
- int main() { boost::signals2::signal<void (int)> x; }\n
- """,
- msg = 'Checking for boost signals2 library',
- uselib_store = 'BOOST_SIGNALS2')
-
- conf.check_cxx(fragment = """
- #include <boost/date_time.hpp>\n
- int main() { boost::gregorian::day_clock::local_day(); }\n
- """,
- msg = 'Checking for boost datetime library',
- libpath = '/usr/local/lib',
- lib = ['boost_date_time%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix],
- uselib_store = 'BOOST_DATETIME')
+ conf.check_cxx(fragment="""
+ #include <boost/version.hpp>\n
+ #if BOOST_VERSION < 104500\n
+ #error boost too old\n
+ #endif\n
+ int main(void) { return 0; }\n
+ """,
+ mandatory=True,
+ msg='Checking for boost library >= 1.45',
+ okmsg='yes',
+ errmsg='too old\nPlease install boost version 1.45 or higher.')
+
+ conf.check_cxx(fragment="""
+ #include <boost/filesystem.hpp>\n
+ int main() { boost::filesystem::copy_file ("a", "b"); }\n
+ """,
+ msg='Checking for boost filesystem library',
+ libpath='/usr/local/lib',
+ lib=['boost_filesystem%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix],
+ uselib_store='BOOST_FILESYSTEM')
+
+ conf.check_cxx(fragment="""
+ #include <boost/signals2.hpp>\n
+ int main() { boost::signals2::signal<void (int)> x; }\n
+ """,
+ msg='Checking for boost signals2 library',
+ uselib_store='BOOST_SIGNALS2')
+
+ conf.check_cxx(fragment="""
+ #include <boost/date_time.hpp>\n
+ int main() { boost::gregorian::day_clock::local_day(); }\n
+ """,
+ msg='Checking for boost datetime library',
+ libpath='/usr/local/lib',
+ lib=['boost_date_time%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix],
+ uselib_store='BOOST_DATETIME')
conf.recurse('test')
conf.recurse('asdcplib')
else:
boost_lib_suffix = ''
- bld(source = 'libdcp.pc.in',
- version = VERSION,
- includedir = '%s/include' % bld.env.PREFIX,
- libs = "-L${libdir} -ldcp -lasdcp-libdcp -lkumu-libdcp -lboost_system%s" % boost_lib_suffix,
- install_path = '${LIBDIR}/pkgconfig')
+ bld(source='libdcp.pc.in',
+ version=VERSION,
+ includedir='%s/include' % bld.env.PREFIX,
+ libs="-L${libdir} -ldcp -lasdcp-libdcp -lkumu-libdcp -lboost_system%s" % boost_lib_suffix,
+ install_path='${LIBDIR}/pkgconfig')
bld.recurse('src')
bld.recurse('tools')
try:
text = '#include "version.h"\n'
- text += 'char const * libdcp::git_commit = \"%s\";\n' % commit
- text += 'char const * libdcp::version = \"%s\";\n' % version
+ text += 'char const * dcp::git_commit = \"%s\";\n' % commit
+ text += 'char const * dcp::version = \"%s\";\n' % version
if bld.env.ENABLE_DEBUG:
debug_string = 'true'
else: