diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-01-27 14:41:33 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-01-27 14:41:33 +0000 |
| commit | 8c2f3517e868078b551bb01d975f2956cb692fbf (patch) | |
| tree | 81bf98f00b9a267a73494c1939c6e9473559c85e | |
| parent | e5d368553b47a566a83d4edce0a8f166db9509e6 (diff) | |
Various tinkerings.
47 files changed, 370 insertions, 145 deletions
@@ -351,12 +351,12 @@ LOOKUP_CACHE_SIZE = 0 # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES -EXTRACT_ALL = YES +EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. -EXTRACT_PRIVATE = NO +EXTRACT_PRIVATE = YES # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. @@ -1716,7 +1716,7 @@ DOT_NUM_THREADS = 0 # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. -DOT_FONTNAME = FreeSans.ttf +DOT_FONTNAME = # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. diff --git a/doc/mainpage.txt b/doc/mainpage.txt index b4cb21d5..84c3c585 100644 --- a/doc/mainpage.txt +++ b/doc/mainpage.txt @@ -2,11 +2,13 @@ @mainpage libdcp -libdcp is a library to create Digital Cinema Packages (DCPs) from JPEG2000 and WAV files, and also to -read and process existing DCPs. +libdcp is a library to create Digital Cinema Packages (DCPs) from +video, audio and subtitle data, and also to read and process existing +DCPs. -Most of the hard work is done by a (slightly patched) version of asdcplib (http://www.cinecert.com/asdcplib/) -which is included in the source distribution for libdcp. +Most of the hard work is done by a (slightly patched) version of +asdcplib (http://www.cinecert.com/asdcplib/) which is included in the +source distribution for libdcp. libdcp is distributed under the GNU GPL. diff --git a/examples/make_dcp.cc b/examples/make_dcp.cc index e3e83f8d..d86cd30a 100644 --- a/examples/make_dcp.cc +++ b/examples/make_dcp.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-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 @@ -18,7 +18,7 @@ */ /** @file examples/make_dcp.cc - * @brief Shows how to make a DCP from some JPEG2000 and WAV files. + * @brief Shows how to make a DCP from some JPEG2000 and audio data. */ #include <vector> diff --git a/examples/read_dcp.cc b/examples/read_dcp.cc new file mode 100644 index 00000000..43f5f0be --- /dev/null +++ b/examples/read_dcp.cc @@ -0,0 +1,51 @@ +/* + Copyright (C) 2012-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. + +*/ + +/* If you are using an installed libdcp, these #includes would need to be changed to +#include <libdcp/dcp.h> +#include <libdcp/cpl.h> +#include <libdcp/mono_picture_asset.h> +... etc. ... +*/ + +#include "dcp.h" + +/** @file examples/read_dcp.cc + * @brief Shows how to read a DCP. + */ + +int +main () +{ + /* Create a DCP, specifying where our existing data is */ + dcp::DCP dcp ("/home/carl/diagonal.com/APPASSIONATA_TLR_F_UK-DEFR_CH_51_2K_LOK_20121115_DGL_OV"); + /* Read the DCP to find out about it */ + dcp.read (); + + if (dcp.encrypted ()) { + std::cout << "DCP is encrypted.\n"; + } else { + std::cout << "DCP is not encrypted.\n"; + } + + std::cout << "DCP has " << dcp.cpls().size() << " CPLs.\n"; + std::cout << "DCP has " << dcp.assets().size() << " assets.\n"; + + return 0; +} diff --git a/examples/wscript b/examples/wscript index 05cca98f..7de1199d 100644 --- a/examples/wscript +++ b/examples/wscript @@ -1,8 +1,16 @@ def build(bld): obj = bld(features = 'cxx cxxprogram') - obj.name = 'examples' + obj.name = 'make_dcp' obj.use = 'libdcp' obj.uselib = 'OPENJPEG CXML' obj.source = 'make_dcp.cc' obj.target = 'make_dcp' obj.install_path = '' + + obj = bld(features = 'cxx cxxprogram') + obj.name = 'read_dcp' + obj.use = 'libdcp' + obj.uselib = 'OPENJPEG CXML' + obj.source = 'read_dcp.cc' + obj.target = 'read_dcp' + obj.install_path = '' diff --git a/run/examples/read_dcp b/run/examples/read_dcp new file mode 100755 index 00000000..92f25b21 --- /dev/null +++ b/run/examples/read_dcp @@ -0,0 +1,12 @@ +#!/bin/bash + +export LD_LIBRARY_PATH=build/src +if [ "$1" == "--debug" ]; then + shift + gdb --args build/examples/read_dcp "$@" +elif [ "$1" == "--valgrind" ]; then + shift + valgrind --tool="memcheck" --leak-check=full --show-reachable=yes build/examples/read_dcp "$@" +else + build/examples/read_dcp "$@" +fi diff --git a/src/asset.cc b/src/asset.cc index 74e32cf0..43db41e3 100644 --- a/src/asset.cc +++ b/src/asset.cc @@ -37,6 +37,10 @@ Asset::Asset () } +/** Create an Asset from a given file. The ID will + * be extracted from the file. + * @param file File name. + */ Asset::Asset (boost::filesystem::path file) : _file (file) { @@ -55,6 +59,8 @@ Asset::Asset (string id) void Asset::write_to_pkl (xmlpp::Node* node) const { + assert (!_file.empty ()); + 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); @@ -66,6 +72,8 @@ Asset::write_to_pkl (xmlpp::Node* node) const void Asset::write_to_assetmap (xmlpp::Node* node) const { + assert (!_file.empty ()); + 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"); @@ -79,6 +87,8 @@ Asset::write_to_assetmap (xmlpp::Node* node) const string Asset::hash () const { + assert (!_file.empty ()); + if (!_hash.empty ()) { _hash = make_digest (_file, 0); } diff --git a/src/asset.h b/src/asset.h index abaa63be..f9ec949f 100644 --- a/src/asset.h +++ b/src/asset.h @@ -38,7 +38,7 @@ namespace dcp { /** @class Asset * @brief Parent class for DCP assets, i.e. picture/sound/subtitles and CPLs. * - * Note that this class is not used for ReelAssets; they are just for the metadata + * Note that this class is not used for ReelAssets; those are just for the metadata * that gets put into <Reel>s. */ class Asset : public Object @@ -49,28 +49,40 @@ public: Asset (std::string id); virtual std::string pkl_type () const = 0; - virtual bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const; - + virtual bool equals ( + boost::shared_ptr<const Asset> other, + EqualityOptions opt, + boost::function<void (NoteType, std::string)> note + ) const; + + /** Write details of the asset to a ASSETMAP. + * @param node Parent node. + */ + void write_to_assetmap (xmlpp::Node* node) const; + /** Write details of the asset to a PKL AssetList node. * @param node Parent node. */ void write_to_pkl (xmlpp::Node* node) const; - void write_to_assetmap (xmlpp::Node* node) const; boost::filesystem::path file () const { return _file; } - void set_file (boost::filesystem::path file) { + void set_file (boost::filesystem::path file) const { _file = file; + _hash.clear (); } + /** @return the hash of this asset's file. It will be + * computed by this call if necessary. + */ std::string hash () const; protected: - friend class MXFWriter; - - boost::filesystem::path _file; + /** The disk file that represents this asset, if one exists */ + mutable boost::filesystem::path _file; + /** Hash of _file, or empty if the hash has not yet been computed */ mutable std::string _hash; }; diff --git a/src/content.h b/src/content.h index 57aaa14c..e7445d47 100644 --- a/src/content.h +++ b/src/content.h @@ -53,9 +53,14 @@ class Content : public Asset public: Content (boost::filesystem::path file); Content (Fraction edit_rate); - virtual ~Content () {} + bool equals ( + boost::shared_ptr<const Content> other, + EqualityOptions opt, + boost::function<void (NoteType, std::string)> + ) const; + Fraction edit_rate () const { return _edit_rate; } @@ -64,8 +69,6 @@ public: return _intrinsic_duration; } - virtual bool equals (boost::shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, std::string)>) const; - protected: friend class MXFWriter; @@ -48,7 +48,6 @@ using namespace dcp; CPL::CPL (string annotation_text, ContentKind content_kind) : _annotation_text (annotation_text) , _content_kind (content_kind) - , _length (0) { } @@ -56,7 +55,6 @@ CPL::CPL (string annotation_text, ContentKind content_kind) /** Construct a CPL object from a XML file */ CPL::CPL (boost::filesystem::path file) : _content_kind (FEATURE) - , _length (0) { cxml::Document f ("CompositionPlaylist"); f.read_file (file); @@ -87,7 +85,7 @@ CPL::CPL (boost::filesystem::path file) * @param reel Reel to add. */ void -CPL::add (shared_ptr<Reel> reel) +CPL::add (boost::shared_ptr<Reel> reel) { _reels.push_back (reel); } @@ -134,8 +132,7 @@ CPL::write_xml (boost::filesystem::path file, Standard standard, XMLMetadata met /* This must not be the _formatted version otherwise signature digests will be wrong */ doc.write_to_file (file.string (), "UTF-8"); - _digest = make_digest (file.string (), 0); - _length = boost::filesystem::file_size (file.string ()); + set_file (file); } list<shared_ptr<const Content> > @@ -156,19 +153,6 @@ CPL::assets () const return a; } - -void -CPL::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 (_id + "_cpl.xml"); - 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> (_length)); -} bool CPL::equals (CPL const & other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const @@ -225,6 +209,10 @@ CPL::add (KDM const & kdm) } } +/** Set a private key for every MXF referenced by this CPL. This will allow the data + * to be decrypted or encrypted. + * @param key Key to use. + */ void CPL::set_mxf_keys (Key key) { @@ -54,8 +54,15 @@ public: return "text/xml"; } - void add (boost::shared_ptr<Reel> reel); + bool equals ( + CPL const & other, + EqualityOptions options, + boost::function<void (NoteType, std::string)> note + ) const; + void add (boost::shared_ptr<Reel> reel); + void add (KDM const &); + std::string annotation_text () const { return _annotation_text; } @@ -81,29 +88,22 @@ public: void set_mxf_keys (Key); - bool equals (CPL const & other, EqualityOptions options, boost::function<void (NoteType, std::string)> note) const; - - void write_xml (boost::filesystem::path file, Standard standard, XMLMetadata, boost::shared_ptr<const Signer>) const; - void write_to_assetmap (xmlpp::Node *) const; - - void add (KDM const &); + void write_xml ( + boost::filesystem::path file, + Standard standard, + XMLMetadata, + boost::shared_ptr<const Signer> + ) const; private: - - std::string _annotation_text; - std::string _issue_date; - std::string _creator; - std::string _content_title_text; - ContentKind _content_kind; - std::string _content_version_id; - std::string _content_version_label_text; - /** reels */ + std::string _annotation_text; ///< <AnnotationText> + std::string _issue_date; ///< <IssueDate> + std::string _creator; ///< <Creator> + std::string _content_title_text; ///< <ContentTitleText> + ContentKind _content_kind; ///< <ContentKind> + std::string _content_version_id; ///< <Id> in <ContentVersion> + std::string _content_version_label_text; ///< <LabelText> in <ContentVersion> std::list<boost::shared_ptr<Reel> > _reels; - - /** a SHA1 digest of our XML */ - mutable std::string _digest; - /** length in bytes of the XML that we last wrote to disk */ - mutable int64_t _length; }; } @@ -162,7 +162,7 @@ DCP::equals (DCP const & other, EqualityOptions opt, boost::function<void (NoteT } void -DCP::add (shared_ptr<Asset> asset) +DCP::add (boost::shared_ptr<Asset> asset) { _assets.push_back (asset); } @@ -82,6 +82,11 @@ public: std::list<boost::shared_ptr<CPL> > cpls () const; + /** @return All this DCP's assets (note that CPLs are assets) */ + std::list<boost::shared_ptr<Asset> > assets () const { + return _assets; + } + bool encrypted () const; void add (KDM const &); @@ -102,7 +107,12 @@ private: /** Write the PKL file. * @param pkl_uuid UUID to use. */ - boost::filesystem::path write_pkl (Standard standard, std::string pkl_uuid, XMLMetadata metadata, boost::shared_ptr<const Signer> signer) const; + boost::filesystem::path write_pkl ( + Standard standard, + std::string pkl_uuid, + XMLMetadata metadata, + boost::shared_ptr<const Signer> signer + ) const; void write_volindex (Standard standard) const; diff --git a/src/font.cc b/src/font.cc index 5a568a63..52996a73 100644 --- a/src/font.cc +++ b/src/font.cc @@ -28,7 +28,7 @@ using boost::shared_ptr; using boost::optional; using namespace dcp; -Font::Font (shared_ptr<const cxml::Node> node) +Font::Font (boost::shared_ptr<const cxml::Node> node) { text = node->content (); @@ -52,7 +52,7 @@ Font::Font (shared_ptr<const cxml::Node> node) text_nodes = type_children<Text> (node, "Text"); } -Font::Font (list<shared_ptr<Font> > const & font_nodes) +Font::Font (std::list<boost::shared_ptr<Font> > const & font_nodes) : size (0) , italic (false) , color ("FFFFFFFF") diff --git a/src/image.cc b/src/image.cc index f12ceea2..15ff24dc 100644 --- a/src/image.cc +++ b/src/image.cc @@ -34,7 +34,7 @@ Image::Image (Image const & other) } -Image::Image (shared_ptr<const Image> other) +Image::Image (boost::shared_ptr<const Image> other) : _size (other->_size) { @@ -91,7 +91,9 @@ KDM::KDM (boost::filesystem::path kdm, boost::filesystem::path private_key) } KDM::KDM ( - shared_ptr<const CPL> cpl, shared_ptr<const Signer> signer, shared_ptr<const Certificate> recipient_cert, + boost::shared_ptr<const CPL> cpl, + boost::shared_ptr<const Signer> signer, + boost::shared_ptr<const Certificate> recipient_cert, boost::posix_time::ptime not_valid_before, boost::posix_time::ptime not_valid_after, string annotation_text, string issue_date ) @@ -206,7 +208,13 @@ KDM::as_xml () const } KDMKey::KDMKey ( - shared_ptr<const Signer> signer, string cpl_id, string key_type, string key_id, boost::posix_time::ptime from, boost::posix_time::ptime until, Key key + boost::shared_ptr<const Signer> signer, + string cpl_id, + string key_type, + string key_id, + boost::posix_time::ptime from, + boost::posix_time::ptime until, + Key key ) : _cpl_id (cpl_id) , _key_type (key_type) @@ -279,7 +287,7 @@ KDMKey::operator= (KDMKey const & other) } string -KDMKey::encrypted_base64 (shared_ptr<const Certificate> recipient_cert) const +KDMKey::encrypted_base64 (boost::shared_ptr<const Certificate> recipient_cert) const { assert (_key_type.length() == 4); assert (_not_valid_before.length() == 25); @@ -30,7 +30,7 @@ namespace dcp { /** @class Key - * @brief A key for encrypting MXFs. + * @brief A key for decrypting/encrypting MXFs. */ class Key { diff --git a/src/load_font.cc b/src/load_font.cc index a337856c..707f4a0b 100644 --- a/src/load_font.cc +++ b/src/load_font.cc @@ -23,7 +23,7 @@ using boost::shared_ptr; using namespace dcp; -LoadFont::LoadFont (shared_ptr<const cxml::Node> node) +LoadFont::LoadFont (boost::shared_ptr<const cxml::Node> node) { id = node->string_attribute ("Id"); uri = node->string_attribute ("URI"); diff --git a/src/mono_picture_mxf.cc b/src/mono_picture_mxf.cc index 699cfc23..9c16516d 100644 --- a/src/mono_picture_mxf.cc +++ b/src/mono_picture_mxf.cc @@ -128,9 +128,3 @@ MonoPictureMXF::cpl_node_name () const { return "MainPicture"; } - -int -MonoPictureMXF::edit_rate_factor () const -{ - return 1; -} diff --git a/src/mono_picture_mxf.h b/src/mono_picture_mxf.h index c742ae37..c02a63c1 100644 --- a/src/mono_picture_mxf.h +++ b/src/mono_picture_mxf.h @@ -45,12 +45,16 @@ public: /** Start a progressive write to a MonoPictureMXF */ boost::shared_ptr<PictureMXFWriter> start_write (boost::filesystem::path, Standard standard, bool); + bool equals ( + boost::shared_ptr<const Content> other, + EqualityOptions opt, + boost::function<void (NoteType, std::string)> note + ) const; + 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; }; } @@ -115,6 +115,11 @@ MXF::equals (shared_ptr<const Content> other, EqualityOptions opt, boost::functi return true; } +/** Set the (private) key that will be used to encrypt or decrypt this MXF's content. + * This is the top-secret key that is distributed (itself encrypted) to cinemas + * via Key Delivery Messages (KDMs). + * @param key Key to use. + */ void MXF::set_key (Key key) { @@ -43,16 +43,20 @@ class MXF : public Content public: MXF (Fraction edit_rate); MXF (boost::filesystem::path file); - ~MXF (); - virtual bool equals (boost::shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const; virtual std::string key_type () const = 0; - + std::string pkl_type () const { return "application/x-smpte-mxf"; } + bool equals ( + boost::shared_ptr<const Content> other, + EqualityOptions opt, + boost::function<void (NoteType, std::string)> note + ) const; + /** Fill in a ADSCP::WriteInfo struct. * @param w struct to fill in. * @param standard INTEROP or SMPTE. diff --git a/src/mxf_writer.cc b/src/mxf_writer.cc index c5fca159..374e6590 100644 --- a/src/mxf_writer.cc +++ b/src/mxf_writer.cc @@ -17,19 +17,26 @@ */ +/** @file src/mxf_writer.h + * @brief MXFWriter class. + */ + #include "mxf_writer.h" #include "mxf.h" using namespace dcp; +/** Create an MXFWriter. + * @param mxf MXF that we are writing. + * @param file File to write to. + */ MXFWriter::MXFWriter (MXF* mxf, boost::filesystem::path file) : _mxf (mxf) , _file (file) , _frames_written (0) , _finalized (false) { - mxf->_file = file; - mxf->_hash.clear (); + mxf->set_file (file); } MXFWriter::~MXFWriter () diff --git a/src/mxf_writer.h b/src/mxf_writer.h index 19632131..b4e20f33 100644 --- a/src/mxf_writer.h +++ b/src/mxf_writer.h @@ -17,6 +17,10 @@ */ +/** @file src/mxf_writer.h + * @brief MXFWriter class. + */ + #ifndef LIBDCP_MXF_WRITER_H #define LIBDCP_MXF_WRITER_H @@ -26,6 +30,12 @@ namespace dcp { class MXF; +/** @class MXFWriter + * @brief Parent class for classes which can write MXF files. + * + * The MXFWriter lasts for the duration of the write and is then discarded. + * They can only be created by calling start_write() on an MXF object. + */ class MXFWriter : public boost::noncopyable { public: @@ -35,9 +45,15 @@ public: protected: MXFWriter (MXF* mxf, boost::filesystem::path file); + /** MXF that we are writing */ MXF* _mxf; + /** File that we are writing to */ boost::filesystem::path _file; + /** Number of `frames' written so far; the definition of a frame + * varies depending on the subclass. + */ int64_t _frames_written; + /** true if finalize() has been called on this object */ bool _finalized; }; diff --git a/src/picture_mxf.h b/src/picture_mxf.h index 4653196d..e8040a4e 100644 --- a/src/picture_mxf.h +++ b/src/picture_mxf.h @@ -20,14 +20,14 @@ #ifndef LIBDCP_PICTURE_MXF_H #define LIBDCP_PICTURE_MXF_H -/** @file src/picture_asset.h - * @brief An asset made up of JPEG2000 data +/** @file src/picture_mxf.h + * @brief PictureMXF class. */ -#include <openjpeg.h> #include "mxf.h" #include "util.h" #include "metadata.h" +#include <openjpeg.h> namespace ASDCP { namespace JP2K { @@ -42,16 +42,20 @@ class MonoPictureFrame; class StereoPictureFrame; class PictureMXFWriter; -/** @brief An asset made up of JPEG2000 data */ +/** @class PictureMXF + * @brief An asset made up of JPEG2000 data. + */ class PictureMXF : public MXF { public: PictureMXF (boost::filesystem::path file); PictureMXF (Fraction edit_rate); - virtual boost::shared_ptr<PictureMXFWriter> start_write (boost::filesystem::path file, Standard standard, bool overwrite) = 0; - - void write_to_pkl (xmlpp::Node* node) const; + virtual boost::shared_ptr<PictureMXFWriter> start_write ( + boost::filesystem::path file, + Standard standard, + bool overwrite + ) = 0; Size size () const { return _size; @@ -65,10 +69,6 @@ public: return _screen_aspect_ratio; } - Fraction edit_rate () const { - return _edit_rate; - } - protected: bool frame_buffer_equals ( @@ -77,7 +77,9 @@ protected: ) const; bool descriptor_equals ( - ASDCP::JP2K::PictureDescriptor const & a, ASDCP::JP2K::PictureDescriptor const & b, boost::function<void (NoteType, std::string)> + ASDCP::JP2K::PictureDescriptor const & a, + ASDCP::JP2K::PictureDescriptor const & b, + boost::function<void (NoteType, std::string)> ) const; void read_picture_descriptor (ASDCP::JP2K::PictureDescriptor const &); @@ -89,7 +91,6 @@ protected: private: std::string key_type () const; - virtual int edit_rate_factor () const = 0; }; diff --git a/src/reel.cc b/src/reel.cc index 8326c197..7503ae9c 100644 --- a/src/reel.cc +++ b/src/reel.cc @@ -38,7 +38,7 @@ using boost::shared_ptr; using boost::dynamic_pointer_cast; using namespace dcp; -Reel::Reel (shared_ptr<const cxml::Node> node) +Reel::Reel (boost::shared_ptr<const cxml::Node> node) : Object (node->string_child ("Id")) { shared_ptr<cxml::Node> asset_list = node->node_child ("AssetList"); @@ -40,7 +40,7 @@ class ReelPictureAsset; class ReelSoundAsset; class ReelSubtitleAsset; -/** @brief A reel within a DCP; the part which actually contains picture, sound and subtitle data */ +/** @brief A reel within a DCP; the part which actually refers to picture, sound and subtitle data */ class Reel : public Object { public: diff --git a/src/reel_asset.cc b/src/reel_asset.cc index 8e03b5c4..28b1937c 100644 --- a/src/reel_asset.cc +++ b/src/reel_asset.cc @@ -40,7 +40,7 @@ ReelAsset::ReelAsset () } -ReelAsset::ReelAsset (shared_ptr<Content> content, int64_t entry_point) +ReelAsset::ReelAsset (boost::shared_ptr<Content> content, int64_t entry_point) : Object (content->id ()) , _content (content) , _edit_rate (content->edit_rate ()) @@ -52,7 +52,7 @@ ReelAsset::ReelAsset (shared_ptr<Content> content, int64_t entry_point) } -ReelAsset::ReelAsset (shared_ptr<const cxml::Node> node) +ReelAsset::ReelAsset (boost::shared_ptr<const cxml::Node> node) : Object (node->string_child ("Id")) , _content (_id) , _annotation_text (node->optional_string_child ("AnnotationText").get_value_or ("")) diff --git a/src/reel_asset.h b/src/reel_asset.h index 5207166a..25c13354 100644 --- a/src/reel_asset.h +++ b/src/reel_asset.h @@ -37,6 +37,13 @@ namespace dcp { class Content; +/** @class ReelAsset + * @brief An entry in a <Reel> which refers to a use of a piece of content. + * + * This class encapsulates the XML that exists in a <Reel> to say + * that a piece of content is used in this reel. It does not + * describe the content itself (but links to a Content object which does). + */ class ReelAsset : public Object { public: @@ -44,37 +51,61 @@ public: ReelAsset (boost::shared_ptr<Content> content, int64_t entry_point); ReelAsset (boost::shared_ptr<const cxml::Node>); + virtual void write_to_cpl (xmlpp::Node* node, Standard standard) const; + + virtual bool equals ( + boost::shared_ptr<const ReelAsset>, + EqualityOptions, + boost::function<void (NoteType, std::string)>) + const { + + return false; + } + + /** @return a Ref to our actual content */ Ref<Content> content () const { return _content; } + /** @return true if a KeyId is specified for this asset, implying + * that its content is encrypted. + */ bool encrypted () const { return !_key_id.empty (); } + /** @return Key ID to describe the key that encrypts this asset's; + * content. + */ std::string key_id () const { return _key_id; } - virtual void write_to_cpl (xmlpp::Node* node, Standard standard) const; - virtual bool equals (boost::shared_ptr<const ReelAsset>, EqualityOptions, boost::function<void (NoteType, std::string)>) const { - return false; - } - protected: + /** @return the node name that this asset uses in the CPL's <Reel> node + * e.g. MainPicture, MainSound etc. + */ virtual std::string cpl_node_name () const = 0; + + /** @return Any attribute that should be used on the asset's node in the + * CPL. + */ virtual std::pair<std::string, std::string> cpl_node_attribute () const; + /** Reference to the content (MXF or XML file) that this reel entry + * applies to. + */ Ref<Content> _content; private: - std::string _annotation_text; - Fraction _edit_rate; - int64_t _intrinsic_duration; - int64_t _entry_point; - int64_t _duration; - std::string _hash; - std::string _key_id; + + std::string _annotation_text; ///< The <AnnotationText> from the reel's entry for this asset + Fraction _edit_rate; ///< The <EditRate> from the reel's entry for this asset + int64_t _intrinsic_duration; ///< The <IntrinsicDuration> from the reel's entry for this asset + int64_t _entry_point; ///< The <EntryPoint> from the reel's entry for this asset + int64_t _duration; ///< The <Duration> from the reel's entry for this asset + std::string _hash; ///< The <Hash> from the reel's entry for this asset + std::string _key_id; ///< The <KeyId> from the reel's entry for this asset, or empty if there isn't one }; } diff --git a/src/reel_mono_picture_asset.cc b/src/reel_mono_picture_asset.cc index 892c9f4e..c0b604a1 100644 --- a/src/reel_mono_picture_asset.cc +++ b/src/reel_mono_picture_asset.cc @@ -29,13 +29,13 @@ ReelMonoPictureAsset::ReelMonoPictureAsset () } -ReelMonoPictureAsset::ReelMonoPictureAsset (shared_ptr<MonoPictureMXF> mxf, int64_t entry_point) +ReelMonoPictureAsset::ReelMonoPictureAsset (boost::shared_ptr<MonoPictureMXF> mxf, int64_t entry_point) : ReelPictureAsset (mxf, entry_point) { } -ReelMonoPictureAsset::ReelMonoPictureAsset (shared_ptr<const cxml::Node> node) +ReelMonoPictureAsset::ReelMonoPictureAsset (boost::shared_ptr<const cxml::Node> node) : ReelPictureAsset (node) { diff --git a/src/reel_picture_asset.cc b/src/reel_picture_asset.cc index 9fdc3b9e..758ed85e 100644 --- a/src/reel_picture_asset.cc +++ b/src/reel_picture_asset.cc @@ -37,7 +37,7 @@ ReelPictureAsset::ReelPictureAsset () } -ReelPictureAsset::ReelPictureAsset (shared_ptr<PictureMXF> content, int64_t entry_point) +ReelPictureAsset::ReelPictureAsset (boost::shared_ptr<PictureMXF> content, int64_t entry_point) : ReelAsset (content, entry_point) , _frame_rate (content->frame_rate ()) , _screen_aspect_ratio (content->screen_aspect_ratio ()) @@ -45,7 +45,7 @@ ReelPictureAsset::ReelPictureAsset (shared_ptr<PictureMXF> content, int64_t entr } -ReelPictureAsset::ReelPictureAsset (shared_ptr<const cxml::Node> node) +ReelPictureAsset::ReelPictureAsset (boost::shared_ptr<const cxml::Node> node) : ReelAsset (node) { _frame_rate = Fraction (node->string_child ("FrameRate")); diff --git a/src/reel_picture_asset.h b/src/reel_picture_asset.h index c6eb2c73..b433ff88 100644 --- a/src/reel_picture_asset.h +++ b/src/reel_picture_asset.h @@ -32,6 +32,8 @@ public: ReelPictureAsset (boost::shared_ptr<PictureMXF> content, int64_t entry_point); ReelPictureAsset (boost::shared_ptr<const cxml::Node>); + virtual void write_to_cpl (xmlpp::Node* node, Standard standard) const; + boost::shared_ptr<PictureMXF> mxf () { return boost::dynamic_pointer_cast<PictureMXF> (_content.object ()); } @@ -40,8 +42,6 @@ public: _screen_aspect_ratio = a; } - virtual void write_to_cpl (xmlpp::Node* node, Standard standard) const; - private: Fraction _frame_rate; Fraction _screen_aspect_ratio; diff --git a/src/reel_sound_asset.cc b/src/reel_sound_asset.cc index 6ef473fe..b3bc049f 100644 --- a/src/reel_sound_asset.cc +++ b/src/reel_sound_asset.cc @@ -24,13 +24,13 @@ using std::string; using boost::shared_ptr; using namespace dcp; -ReelSoundAsset::ReelSoundAsset (shared_ptr<Content> content, int64_t entry_point) +ReelSoundAsset::ReelSoundAsset (boost::shared_ptr<Content> content, int64_t entry_point) : ReelAsset (content, entry_point) { } -ReelSoundAsset::ReelSoundAsset (shared_ptr<const cxml::Node> node) +ReelSoundAsset::ReelSoundAsset (boost::shared_ptr<const cxml::Node> node) : ReelAsset (node) { node->ignore_child ("Language"); diff --git a/src/reel_stereo_picture_asset.cc b/src/reel_stereo_picture_asset.cc index 2715eb34..20e33279 100644 --- a/src/reel_stereo_picture_asset.cc +++ b/src/reel_stereo_picture_asset.cc @@ -25,7 +25,7 @@ using std::make_pair; using boost::shared_ptr; using namespace dcp; -ReelStereoPictureAsset::ReelStereoPictureAsset (shared_ptr<const cxml::Node> node) +ReelStereoPictureAsset::ReelStereoPictureAsset (boost::shared_ptr<const cxml::Node> node) : ReelPictureAsset (node) { diff --git a/src/reel_subtitle_asset.cc b/src/reel_subtitle_asset.cc index 326e343c..b2e46f93 100644 --- a/src/reel_subtitle_asset.cc +++ b/src/reel_subtitle_asset.cc @@ -24,13 +24,13 @@ using std::string; using boost::shared_ptr; using namespace dcp; -ReelSubtitleAsset::ReelSubtitleAsset (shared_ptr<SubtitleContent> content, int64_t entry_point) +ReelSubtitleAsset::ReelSubtitleAsset (boost::shared_ptr<SubtitleContent> content, int64_t entry_point) : ReelAsset (content, entry_point) { } -ReelSubtitleAsset::ReelSubtitleAsset (shared_ptr<const cxml::Node> node) +ReelSubtitleAsset::ReelSubtitleAsset (boost::shared_ptr<const cxml::Node> node) : ReelAsset (node) { node->ignore_child ("Language"); @@ -17,6 +17,10 @@ */ +/** @file src/ref.h + * @brief Ref class. + */ + #ifndef LIBDCP_REF_H #define LIBDCP_REF_H @@ -27,24 +31,41 @@ namespace dcp { +/** @class Ref + * @brief A reference to an object which is identified by a universally-unique identifier (UUID). + * + * This class is a `pointer' to a thing. It will always know the + * UUID of the thing, and it may have a shared_ptr to the C++ object + * which represents the thing. + * + * If the Ref does not have a shared_ptr it may be given one by + * calling resolve() with a list of objects. The shared_ptr will be + * set up using any object on the list which has a matching ID. + */ template<class T> class Ref { public: + /** Initialise a Ref with an ID but no shared_ptr */ Ref (std::string id) : _id (id) {} + /** Initialise a Ref with a shared_ptr to an object */ Ref (boost::shared_ptr<T> object) : _id (object->id ()) , _object (object) {} + /** Set the ID of this Ref */ void set_id (std::string id) { _id = id; } + /** Look through a list of objects and copy a shared_ptr to any object + * which matches the ID of this one. + */ void resolve (std::list<boost::shared_ptr<Object> > objects) { typename std::list<boost::shared_ptr<Object> >::iterator i = objects.begin(); @@ -57,10 +78,14 @@ public: } } + /** @return the ID of the thing that we are pointing to */ std::string id () const { return _id; } + /** @return a shared_ptr to the thing; an UnresolvedRefError is thrown + * if the shared_ptr is not known. + */ boost::shared_ptr<T> object () const { if (!_object) { throw UnresolvedRefError (_id); @@ -69,6 +94,9 @@ public: return _object; } + /** operator-> to access the shared_ptr; an UnresolvedRefError is thrown + * if the shared_ptr is not known. + */ T * operator->() const { if (!_object) { throw UnresolvedRefError (_id); @@ -77,13 +105,14 @@ public: return _object.get (); } + /** @return true if a shared_ptr is known for this Ref */ bool resolved () const { return _object; } private: - std::string _id; - boost::shared_ptr<T> _object; + std::string _id; ///< ID; will always be known + boost::shared_ptr<T> _object; ///< shared_ptr to the thing, may be null. }; } diff --git a/src/rgb_xyz.cc b/src/rgb_xyz.cc index 6fc28e3d..9cf12e4c 100644 --- a/src/rgb_xyz.cc +++ b/src/rgb_xyz.cc @@ -33,10 +33,16 @@ using namespace dcp; /** Convert an openjpeg XYZ image to RGB. * @param xyz_frame Frame in XYZ. + * @param lut_in Input Gamma LUT to use. + * @param lut_out Output Gamma LUT to use. * @return RGB image. */ shared_ptr<ARGBFrame> -dcp::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 ( + boost::shared_ptr<const XYZFrame> xyz_frame, + boost::shared_ptr<const LUT> lut_in, + boost::shared_ptr<const LUT> lut_out + ) { int const max_colour = pow (2, lut_out->bit_depth()) - 1; @@ -100,7 +106,12 @@ dcp::xyz_to_rgb (shared_ptr<const XYZFrame> xyz_frame, shared_ptr<const LUT> lut } 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]) +dcp::rgb_to_xyz ( + boost::shared_ptr<const Image> rgb, + boost::shared_ptr<const LUT> lut_in, + boost::shared_ptr<const LUT> lut_out, + double const colour_matrix[3][3] + ) { assert (lut_in->bit_depth() == 12); assert (lut_out->bit_depth() == 16); diff --git a/src/sound_mxf.cc b/src/sound_mxf.cc index 5ce72b1d..ebcf12c6 100644 --- a/src/sound_mxf.cc +++ b/src/sound_mxf.cc @@ -17,8 +17,8 @@ */ -/** @file src/sound_asset.cc - * @brief An asset made up of WAV files +/** @file src/sound_mxf.cc + * @brief SoundMXF class. */ #include "sound_mxf.h" diff --git a/src/sound_mxf.h b/src/sound_mxf.h index 098680ac..04ec8aeb 100644 --- a/src/sound_mxf.h +++ b/src/sound_mxf.h @@ -38,7 +38,11 @@ public: boost::shared_ptr<SoundMXFWriter> start_write (boost::filesystem::path file, Standard standard); - bool equals (boost::shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const; + 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; diff --git a/src/stereo_picture_mxf.cc b/src/stereo_picture_mxf.cc index 59f16c93..6bcd75c8 100644 --- a/src/stereo_picture_mxf.cc +++ b/src/stereo_picture_mxf.cc @@ -66,12 +66,6 @@ StereoPictureMXF::start_write (boost::filesystem::path file, Standard standard, return shared_ptr<StereoPictureMXFWriter> (new StereoPictureMXFWriter (this, file, standard, overwrite)); } -int -StereoPictureMXF::edit_rate_factor () const -{ - return 2; -} - bool StereoPictureMXF::equals (shared_ptr<const Content> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const { diff --git a/src/stereo_picture_mxf.h b/src/stereo_picture_mxf.h index f4a4771a..dc4605c7 100644 --- a/src/stereo_picture_mxf.h +++ b/src/stereo_picture_mxf.h @@ -34,11 +34,13 @@ public: /** Start a progressive write to a StereoPictureMXF */ boost::shared_ptr<PictureMXFWriter> start_write (boost::filesystem::path file, Standard, bool); + bool equals ( + boost::shared_ptr<const Content> other, + EqualityOptions opt, + boost::function<void (NoteType, std::string)> note + ) const; + 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: - int edit_rate_factor () const; }; } diff --git a/src/subtitle.cc b/src/subtitle.cc index dc7a6b22..8c40254a 100644 --- a/src/subtitle.cc +++ b/src/subtitle.cc @@ -28,7 +28,7 @@ using boost::shared_ptr; using boost::lexical_cast; using namespace dcp; -Subtitle::Subtitle (shared_ptr<const cxml::Node> node) +Subtitle::Subtitle (boost::shared_ptr<const cxml::Node> node) { in = Time (node->string_attribute ("TimeIn")); out = Time (node->string_attribute ("TimeOut")); diff --git a/src/subtitle_content.h b/src/subtitle_content.h index b8db0c2c..476f8fe4 100644 --- a/src/subtitle_content.h +++ b/src/subtitle_content.h @@ -46,7 +46,11 @@ public: return "text/xml"; } - virtual bool equals (boost::shared_ptr<const Content>, EqualityOptions, boost::function<void (NoteType, std::string)> note) const { + bool equals ( + boost::shared_ptr<const Content>, + EqualityOptions, + boost::function<void (NoteType, std::string)> note + ) const { /* XXX */ note (ERROR, "subtitle content not compared yet"); return true; diff --git a/src/text.cc b/src/text.cc index c70e4333..888cab29 100644 --- a/src/text.cc +++ b/src/text.cc @@ -35,7 +35,7 @@ using namespace dcp; * in this object's member variables. * @param node Node to read. */ -Text::Text (shared_ptr<const cxml::Node> node) +Text::Text (boost::shared_ptr<const cxml::Node> node) : v_align (CENTER) { text = node->content (); @@ -44,7 +44,7 @@ public: : v_position (0) , v_align (TOP) {} - + Text (boost::shared_ptr<const cxml::Node> node); float v_position; diff --git a/src/types.cc b/src/types.cc index 106fb44c..0ecf7a16 100644 --- a/src/types.cc +++ b/src/types.cc @@ -29,6 +29,9 @@ using namespace std; using namespace dcp; using namespace boost; +/** Construct a Fraction from a string of the form <numerator> <denominator> + * e.g. "1 3". + */ Fraction::Fraction (string s) { vector<string> b; @@ -52,6 +55,7 @@ dcp::operator!= (Fraction const & a, Fraction const & b) return (a.numerator != b.numerator || a.denominator != b.denominator); } +/** Construct a Color, initialising it to black. */ Color::Color () : r (0) , g (0) @@ -60,6 +64,9 @@ Color::Color () } +/** Construct a Color from R, G and B. The values run between + * 0 and 255. + */ Color::Color (int r_, int g_, int b_) : r (r_) , g (g_) diff --git a/src/types.h b/src/types.h index 1397dfdc..d34a9039 100644 --- a/src/types.h +++ b/src/types.h @@ -85,12 +85,20 @@ enum Eye EYE_LEFT, EYE_RIGHT }; - + +/** @class Fraction + * @brief A fraction (i.e. a thing with an integer numerator and an integer denominator). + */ class Fraction { public: + /** Construct a fraction of 0/0 */ Fraction () : numerator (0), denominator (0) {} Fraction (std::string s); + /** Construct a fraction with a specified numerator and denominator. + * @param n Numerator. + * @param d Denominator. + */ Fraction (int n, int d) : numerator (n), denominator (d) {} int numerator; |
