Various tweaks; work on read_dcp example.
authorCarl Hetherington <cth@carlh.net>
Mon, 27 Jan 2014 22:38:43 +0000 (22:38 +0000)
committerCarl Hetherington <cth@carlh.net>
Mon, 27 Jan 2014 22:38:43 +0000 (22:38 +0000)
25 files changed:
examples/read_dcp.cc
examples/wscript
src/content.cc
src/cpl.cc
src/cpl.h
src/dcp.cc
src/mono_picture_mxf.cc
src/mono_picture_mxf_writer.cc
src/mxf.cc
src/mxf.h
src/picture_mxf.cc
src/reel.cc
src/reel.h
src/reel_asset.cc
src/reel_asset.h
src/reel_mono_picture_asset.cc
src/reel_picture_asset.cc
src/reel_stereo_picture_asset.cc
src/sound_mxf.cc
src/sound_mxf_writer.cc
src/stereo_picture_mxf.cc
src/types.h
src/util.cc
src/util.h
wscript

index 43f5f0be4bc737d1f69d8c98aa5e08a323028958..f3c47a3cf5d72fb76626cb90c4804091bcf0b6f9 100644 (file)
 
 /* 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>
+#include <libdcp/picture_mxf.h>
 ... etc. ...
 */
 
 #include "dcp.h"
+#include "cpl.h"
+#include "reel.h"
+#include "reel_picture_asset.h"
+#include "mono_picture_frame.h"
+#include "mono_picture_mxf.h"
+#include "stereo_picture_mxf.h"
+#include "sound_mxf.h"
+#include "subtitle_content.h"
+#include "argb_frame.h"
+#include <Magick++.h>
 
 /** @file examples/read_dcp.cc
  *  @brief Shows how to read a DCP.
@@ -45,7 +54,37 @@ main ()
        }
 
        std::cout << "DCP has " << dcp.cpls().size() << " CPLs.\n";
-       std::cout << "DCP has " << dcp.assets().size() << " assets.\n";
+       std::list<boost::shared_ptr<dcp::Asset> > assets = dcp.assets ();
+       std::cout << "DCP has " << assets.size() << " assets.\n";
+       for (std::list<boost::shared_ptr<dcp::Asset> >::const_iterator i = assets.begin(); i != assets.end(); ++i) {
+               if (boost::dynamic_pointer_cast<dcp::MonoPictureMXF> (*i)) {
+                       std::cout << "2D picture\n";
+               } else if (boost::dynamic_pointer_cast<dcp::StereoPictureMXF> (*i)) {
+                       std::cout << "3D picture\n";
+               } else if (boost::dynamic_pointer_cast<dcp::SoundMXF> (*i)) {
+                       std::cout << "Sound\n";
+               } else if (boost::dynamic_pointer_cast<dcp::SubtitleContent> (*i)) {
+                       std::cout << "Subtitle\n";
+               } else if (boost::dynamic_pointer_cast<dcp::CPL> (*i)) {
+                       std::cout << "CPL\n";
+               }
+               std::cout << "\t" << (*i)->file().leaf().string() << "\n";
+       }
+
+       /* Take the first CPL */
+       boost::shared_ptr<dcp::CPL> cpl = dcp.cpls().front ();
+
+       /* Get the MXF of the picture asset in the first reel */
+       boost::shared_ptr<dcp::MonoPictureMXF> picture_mxf = boost::dynamic_pointer_cast<dcp::MonoPictureMXF> (cpl->reels().front()->main_picture()->mxf ());
+
+       /* Get the 1000th frame of it */
+       boost::shared_ptr<const dcp::MonoPictureFrame> picture_frame_j2k = picture_mxf->get_frame(999);
+
+       /* Get a ARGB copy of it */
+       boost::shared_ptr<dcp::ARGBFrame> picture_frame_rgb = picture_frame_j2k->argb_frame ();
+
+       Magick::Image image (picture_frame_rgb->size().width, picture_frame_rgb->size().height, "BGRA", Magick::CharPixel, picture_frame_rgb->data ());
+       image.write ("frame.png");
 
        return 0;
 }
index 7de1199d9abb91fef022d5c1b5eaa535bdcea96a..ce94bfa281db1847340e422cd7e5af8edfe214b0 100644 (file)
@@ -10,7 +10,7 @@ def build(bld):
     obj = bld(features = 'cxx cxxprogram')
     obj.name   = 'read_dcp'
     obj.use    = 'libdcp'
-    obj.uselib = 'OPENJPEG CXML'
+    obj.uselib = 'OPENJPEG CXML MAGICK'
     obj.source = 'read_dcp.cc'
     obj.target = 'read_dcp'
     obj.install_path = ''
index 85988a1ae4fbefa798d5fe276551fa1e894d5461..f038032370a9a58016a9d8cc071ef6fa3dddd8fb 100644 (file)
@@ -24,7 +24,6 @@
 #include "KM_util.h"
 #include <libxml++/nodes/element.h>
 #include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
 #include <boost/function.hpp>
 #include <iostream>
 
index d99e1cf7f2f8dd84f07db7c1edcfeee66c6957c6..96afc0887dadabf2aaaced479ec4493f171c5d3f 100644 (file)
@@ -54,18 +54,22 @@ 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)
+       : Asset (file)
+       , _content_kind (FEATURE)
 {
        cxml::Document f ("CompositionPlaylist");
        f.read_file (file);
 
        _id = f.string_child ("Id");
+       if (_id.length() > 9) {
+               _id = _id.substr (9);
+       }
        _annotation_text = f.optional_string_child ("AnnotationText").get_value_or ("");
        _issue_date = f.string_child ("IssueDate");
        _creator = f.optional_string_child ("Creator").get_value_or ("");
        _content_title_text = f.string_child ("ContentTitleText");
        _content_kind = content_kind_from_string (f.string_child ("ContentKind"));
-       shared_ptr<cxml::Node> content_version = f.node_child ("ContentVersion");
+       shared_ptr<cxml::Node> content_version = f.optional_node_child ("ContentVersion");
        if (content_version) {
                _content_version_id = content_version->optional_string_child ("Id").get_value_or ("");
                _content_version_label_text = content_version->string_child ("LabelText");
@@ -205,7 +209,7 @@ void
 CPL::add (KDM const & kdm)
 {
        for (list<shared_ptr<Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) {
-               (*i)->add_kdm (kdm);
+               (*i)->add (kdm);
        }
 }
 
@@ -220,3 +224,11 @@ CPL::set_mxf_keys (Key key)
                (*i)->set_mxf_keys (key);
        }
 }
+
+void
+CPL::resolve_refs (list<shared_ptr<Object> > objects)
+{
+       for (list<shared_ptr<Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) {
+               (*i)->resolve_refs (objects);
+       }
+}
index 35a8bb624d429b654f5c09ed8ab776d52a54556f..4c3f9bfa2f2578b13ea83a14c151231cc98075e9 100644 (file)
--- a/src/cpl.h
+++ b/src/cpl.h
@@ -94,6 +94,8 @@ public:
                XMLMetadata,
                boost::shared_ptr<const Signer>
                ) const;
+
+       void resolve_refs (std::list<boost::shared_ptr<Object> >);
        
 private:
        std::string _annotation_text;               ///< <AnnotationText>
index 6af33663781e982b2c5840a8d81d7439d2d0fc7f..1925ac0be4a77c29a1a830c7070bc13deedf5d87 100644 (file)
@@ -40,7 +40,6 @@
 #include <xmlsec/app.h>
 #include <libxml++/libxml++.h>
 #include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
 #include <boost/algorithm/string.hpp>
 #include <boost/lexical_cast.hpp>
 #include <sstream>
@@ -56,7 +55,6 @@ using std::make_pair;
 using std::map;
 using boost::shared_ptr;
 using boost::lexical_cast;
-using boost::dynamic_pointer_cast;
 using namespace dcp;
 
 DCP::DCP (boost::filesystem::path directory)
@@ -81,9 +79,9 @@ DCP::read ()
 
        cxml::Document asset_map ("AssetMap");
        asset_map.read_file (asset_map_file);
-       list<shared_ptr<cxml::Node> > assets = asset_map.node_child("AssetList")->node_children ("Asset");
+       list<shared_ptr<cxml::Node> > asset_nodes = asset_map.node_child("AssetList")->node_children ("Asset");
        map<string, boost::filesystem::path> paths;
-       for (list<shared_ptr<cxml::Node> >::const_iterator i = assets.begin(); i != assets.end(); ++i) {
+       for (list<shared_ptr<cxml::Node> >::const_iterator i = asset_nodes.begin(); i != asset_nodes.end(); ++i) {
                if ((*i)->node_child("ChunkList")->node_children("Chunk").size() != 1) {
                        boost::throw_exception (XMLError ("unsupported asset chunk count"));
                }
@@ -96,10 +94,11 @@ DCP::read ()
        /* Read all the assets from the asset map */
        
        for (map<string, boost::filesystem::path>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
-               if (boost::algorithm::ends_with (i->second.string(), ".xml")) {
+               boost::filesystem::path path = _directory / i->second;
+               if (boost::algorithm::ends_with (path.string(), ".xml")) {
                        xmlpp::DomParser* p = new xmlpp::DomParser;
                        try {
-                               p->parse_file (i->second.string());
+                               p->parse_file (path.string());
                        } catch (std::exception& e) {
                                delete p;
                                continue;
@@ -109,13 +108,13 @@ DCP::read ()
                        delete p;
                        
                        if (root == "CompositionPlaylist") {
-                               _assets.push_back (shared_ptr<CPL> (new CPL (i->second)));
+                               _assets.push_back (shared_ptr<CPL> (new CPL (path)));
                        } else if (root == "DCSubtitle") {
-                               _assets.push_back (shared_ptr<SubtitleContent> (new SubtitleContent (i->second)));
+                               _assets.push_back (shared_ptr<SubtitleContent> (new SubtitleContent (path)));
                        }
-               } else if (boost::algorithm::ends_with (i->second.string(), ".mxf")) {
+               } else if (boost::algorithm::ends_with (path.string(), ".mxf")) {
                        ASDCP::EssenceType_t type;
-                       if (ASDCP::EssenceType (i->second.string().c_str(), type) != ASDCP::RESULT_OK) {
+                       if (ASDCP::EssenceType (path.string().c_str(), type) != ASDCP::RESULT_OK) {
                                throw DCPReadError ("Could not find essence type");
                        }
                        switch (type) {
@@ -123,20 +122,25 @@ DCP::read ()
                                case ASDCP::ESS_MPEG2_VES:
                                        throw DCPReadError ("MPEG2 video essences are not supported");
                                case ASDCP::ESS_JPEG_2000:
-                                       _assets.push_back (shared_ptr<MonoPictureMXF> (new MonoPictureMXF (i->second)));
+                                       _assets.push_back (shared_ptr<MonoPictureMXF> (new MonoPictureMXF (path)));
                                        break;
                                case ASDCP::ESS_PCM_24b_48k:
                                case ASDCP::ESS_PCM_24b_96k:
-                                       _assets.push_back (shared_ptr<SoundMXF> (new SoundMXF (i->second)));
+                                       _assets.push_back (shared_ptr<SoundMXF> (new SoundMXF (path)));
                                        break;
                                case ASDCP::ESS_JPEG_2000_S:
-                                       _assets.push_back (shared_ptr<StereoPictureMXF> (new StereoPictureMXF (i->second)));
+                                       _assets.push_back (shared_ptr<StereoPictureMXF> (new StereoPictureMXF (path)));
                                        break;
                                default:
                                        throw DCPReadError ("Unknown MXF essence type");
                                }
                }
        }
+
+       list<shared_ptr<CPL> > cpl = cpls ();
+       for (list<shared_ptr<CPL> >::const_iterator i = cpl.begin(); i != cpl.end(); ++i) {
+               (*i)->resolve_refs (list_of_type<Asset, Object> (assets ()));
+       }
 }
 
 bool
@@ -226,29 +230,16 @@ DCP::write_pkl (Standard standard, string pkl_uuid, XMLMetadata metadata, shared
        pkl->add_child("Id")->add_child_text ("urn:uuid:" + pkl_uuid);
 
        /* XXX: this is a bit of a hack */
-       list<shared_ptr<Asset> >::const_iterator i = _assets.begin();
-       shared_ptr<CPL> first_cpl;
-       while (i != _assets.end()) {
-               first_cpl = dynamic_pointer_cast<CPL> (*i);
-               if (first_cpl) {
-                       break;
-               }
-       }
-
-       assert (first_cpl);
-       pkl->add_child("AnnotationText")->add_child_text (first_cpl->annotation_text ());
+       assert (cpls().size() > 0);
+       pkl->add_child("AnnotationText")->add_child_text (cpls().front()->annotation_text ());
        
        pkl->add_child("IssueDate")->add_child_text (metadata.issue_date);
        pkl->add_child("Issuer")->add_child_text (metadata.issuer);
        pkl->add_child("Creator")->add_child_text (metadata.creator);
 
        xmlpp::Element* asset_list = pkl->add_child("AssetList");
-
        for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) {
-               shared_ptr<Content> c = dynamic_pointer_cast<Content> (*i);
-               if (c) {
-                       c->write_to_pkl (asset_list);
-               }
+               (*i)->write_to_pkl (asset_list);
        }
 
        if (signer) {
@@ -343,27 +334,15 @@ DCP::write_xml (
        write_volindex (standard);
        write_assetmap (standard, pkl_uuid, boost::filesystem::file_size (pkl_path), metadata);
 
-       for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) {
-               shared_ptr<CPL> c = dynamic_pointer_cast<CPL> (*i);
-               if (c) {
-                       string const filename = c->id() + "_cpl.xml";
-                       c->write_xml (_directory / filename, standard, metadata, signer);
-               }
+       list<shared_ptr<CPL> > cpl = cpls ();
+       for (list<shared_ptr<CPL> >::const_iterator i = cpl.begin(); i != cpl.end(); ++i) {
+               string const filename = (*i)->id() + "_cpl.xml";
+               (*i)->write_xml (_directory / filename, standard, metadata, signer);
        }
 }
 
 list<shared_ptr<CPL> >
 DCP::cpls () const
 {
-       list<shared_ptr<CPL> > cpls;
-       for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) {
-               shared_ptr<CPL> c = dynamic_pointer_cast<CPL> (*i);
-               if (c) {
-                       cpls.push_back (c);
-               }
-       }
-
-       return cpls;
+       return list_of_type<Asset, CPL> (_assets);
 }
-
-       
index 9c16516d88f9c04c5c46c54e6c25659726d7f8b7..4af24008eb7d751e18bc91aad6a776776b9ee8c2 100644 (file)
 #include "KM_fileio.h"
 #include "exceptions.h"
 #include "mono_picture_frame.h"
+#include "compose.hpp"
 
 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)
@@ -46,6 +46,13 @@ MonoPictureMXF::MonoPictureMXF (boost::filesystem::path file)
        }
 
        read_picture_descriptor (desc);
+       
+       ASDCP::WriterInfo info;
+       if (ASDCP_FAILURE (reader.FillWriterInfo (info))) {
+               boost::throw_exception (DCPReadError ("could not read video MXF information"));
+       }
+
+       read_writer_info (info);
 }
 
 MonoPictureMXF::MonoPictureMXF (Fraction edit_rate)
@@ -100,7 +107,7 @@ MonoPictureMXF::equals (shared_ptr<const Content> other, EqualityOptions opt, bo
                        return false;
                }
                
-               note (PROGRESS, "Comparing video frame " + lexical_cast<string> (i) + " of " + lexical_cast<string> (_intrinsic_duration));
+               note (PROGRESS, String::compose ("Comparing video frame %1 of %2", i, _intrinsic_duration));
                shared_ptr<const MonoPictureFrame> frame_A = get_frame (i);
                shared_ptr<const MonoPictureFrame> frame_B = other_picture->get_frame (i);
                
index 96c054d7a5341033289834ec13380e11c527c916..d685cd69b67beac09a009fc440d0ad899b3e7883 100644 (file)
@@ -29,7 +29,6 @@ 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
index 1a19b817808ebbe4865a9fb3c501ba1c6904c539..200bc843b9d207c99078f368185734def45c9490 100644 (file)
@@ -31,7 +31,6 @@
 #include "kdm.h"
 #include <libxml++/nodes/element.h>
 #include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
 #include <iostream>
 
 using std::string;
@@ -147,3 +146,11 @@ MXF::set_key (Key key)
                throw MiscError ("could not set up CBC initialization vector");
        }
 }
+
+void
+MXF::read_writer_info (ASDCP::WriterInfo const & info)
+{
+       char buffer[64];
+       Kumu::bin2UUIDhex (info.AssetUUID, 16, buffer, 64);
+       _id = buffer;
+}
index f2c0fdf794cbf6952f0a434cb7bae77d8b822078..f7336fee56d660810328414516828f838452d402 100644 (file)
--- a/src/mxf.h
+++ b/src/mxf.h
@@ -98,6 +98,8 @@ public:
        }
 
 protected:
+       void read_writer_info (ASDCP::WriterInfo const &);
+       
        /** Signal to emit to report progress, or 0 */
        boost::signals2::signal<void (float)>* _progress;
        ASDCP::AESEncContext* _encryption_context;
index e59550472ca212497bdac2b5c97135b97466ab04..4a8e477b33e1e59234adb2e4ea083e78ae7e4709 100644 (file)
 #include "exceptions.h"
 #include "xyz_frame.h"
 #include "picture_mxf_writer.h"
+#include "compose.hpp"
 #include "AS_DCP.h"
 #include "KM_fileio.h"
 #include <libxml++/nodes/element.h>
 #include <openjpeg.h>
 #include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
 #include <list>
 #include <stdexcept>
 #include <iostream>
@@ -44,8 +44,6 @@ 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)
@@ -138,7 +136,7 @@ PictureMXF::frame_buffer_equals (
        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");
+                       note (ERROR, String::compose ("image sizes for frame %1 differ", frame));
                        return false;
                }
                
@@ -164,14 +162,12 @@ PictureMXF::frame_buffer_equals (
        
        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));
+       note (NOTE, String::compose ("mean difference %1, deviation %2", mean, 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)
+                       String::compose ("mean %1 out of range %2 in frame %3", mean, opt.max_mean_pixel_error, frame)
                        );
                
                return false;
@@ -180,9 +176,7 @@ PictureMXF::frame_buffer_equals (
        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)
+                       String::compose ("standard deviation %1 out of range %2 in frame %3", std_dev, opt.max_std_dev_pixel_error, frame)
                        );
                
                return false;
index 7503ae9c70719606d7b6a32163c4593c7f8d8181..723a2db408b425b474d9c499692131bacf1d66bf 100644 (file)
@@ -133,7 +133,7 @@ Reel::encrypted () const
 }
 
 void
-Reel::add_kdm (KDM const & kdm)
+Reel::add (KDM const & kdm)
 {
        list<KDMKey> keys = kdm.keys ();
        
@@ -172,3 +172,19 @@ Reel::add (shared_ptr<ReelAsset> asset)
                _main_subtitle = su;
        }
 }
+
+void
+Reel::resolve_refs (list<shared_ptr<Object> > objects)
+{
+       if (_main_picture) {
+               _main_picture->content().resolve (objects);
+       }
+
+       if (_main_sound) {
+               _main_sound->content().resolve (objects);
+       }
+
+       if (_main_subtitle) {
+               _main_subtitle->content().resolve (objects);
+       }
+}
index 30a0cc4e5678c8f66e7ed5108cd7dcaa1debf852..14def9c80593fc1f03f9218882b35ab55df42352 100644 (file)
@@ -39,6 +39,7 @@ class ReelAsset;
 class ReelPictureAsset;
 class ReelSoundAsset;
 class ReelSubtitleAsset;
+class Content;
 
 /** @brief A reel within a DCP; the part which actually refers to picture, sound and subtitle data */  
 class Reel : public Object
@@ -80,7 +81,9 @@ public:
        
        bool equals (boost::shared_ptr<const Reel> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> notes) const;
 
-       void add_kdm (KDM const &);
+       void add (KDM const &);
+
+       void resolve_refs (std::list<boost::shared_ptr<Object> >);
 
 private:
        boost::shared_ptr<ReelPictureAsset> _main_picture;
index 28b1937c24afec8fe51253d9860dbb52c870bfea..5fa59fc2f02364898da5ef4a9175cea0dc91fb5b 100644 (file)
@@ -71,8 +71,6 @@ ReelAsset::ReelAsset (boost::shared_ptr<const cxml::Node> node)
        if (_key_id.length() > 9) {
                _key_id = _key_id.substr (9);
        }
-       
-       node->done ();
 }
 
 void
index 25c13354c0170aa1c5faa603a741c5af8cfbac1d..b5e0537c4172f55c0638297dc05492c9e382e7c6 100644 (file)
@@ -63,7 +63,7 @@ public:
        }
 
        /** @return a Ref to our actual content */
-       Ref<Content> content () const {
+       Ref<Content>& content () {
                return _content;
        }
 
index c0b604a133e05eae93beeed288531c14edf26e61..1a5d256db23aacfbda29b2bf04bc986743f6d98c 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "reel_mono_picture_asset.h"
 #include "mono_picture_mxf.h"
+#include <libcxml/cxml.h>
 
 using std::string;
 using boost::shared_ptr;
@@ -38,7 +39,7 @@ ReelMonoPictureAsset::ReelMonoPictureAsset (boost::shared_ptr<MonoPictureMXF> mx
 ReelMonoPictureAsset::ReelMonoPictureAsset (boost::shared_ptr<const cxml::Node> node)
        : ReelPictureAsset (node)
 {
-
+       node->done ();
 }
 
 string
index 758ed85eedfcb0a4f5a7a204a58bb8a1cbbec651..673eb133fda7bd0c77944507be70cc54830a69a2 100644 (file)
@@ -27,7 +27,6 @@ using std::bad_cast;
 using std::string;
 using std::stringstream;
 using boost::shared_ptr;
-using boost::lexical_cast;
 using namespace dcp;
 
 ReelPictureAsset::ReelPictureAsset ()
index 20e332793f22b44e95440599ade734ec43d73917..a9cdab713267d24d1d7fdfb0a744706afeffee1f 100644 (file)
@@ -18,6 +18,7 @@
 */
 
 #include "reel_stereo_picture_asset.h"
+#include <libcxml/cxml.h>
 
 using std::string;
 using std::pair;
@@ -28,7 +29,7 @@ using namespace dcp;
 ReelStereoPictureAsset::ReelStereoPictureAsset (boost::shared_ptr<const cxml::Node> node)
        : ReelPictureAsset (node)
 {
-
+       node->done ();
 }
 
 string
index ebcf12c60609587cf29e7a93e9c6c63f23028489..f6613867373cd7de219fd48716d32f21b783a0bc 100644 (file)
 #include "exceptions.h"
 #include "sound_frame.h"
 #include "sound_mxf_writer.h"
+#include "compose.hpp"
 #include "KM_fileio.h"
 #include "AS_DCP.h"
 #include <libxml++/nodes/element.h>
 #include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
 #include <iostream>
 #include <stdexcept>
 
@@ -40,7 +40,6 @@ 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)
@@ -64,6 +63,14 @@ SoundMXF::SoundMXF (boost::filesystem::path file)
        _edit_rate = Fraction (desc.EditRate.Numerator, desc.EditRate.Denominator);
 
        _intrinsic_duration = desc.ContainerDuration;
+
+       ASDCP::WriterInfo info;
+       if (ASDCP_FAILURE (reader.FillWriterInfo (info))) {
+               boost::throw_exception (DCPReadError ("could not read audio MXF information"));
+       }
+
+       read_writer_info (info);
+
 }
 
 SoundMXF::SoundMXF (Fraction edit_rate, int sampling_rate, int channels)
@@ -132,7 +139,7 @@ SoundMXF::equals (shared_ptr<const Content> other, EqualityOptions opt, boost::f
                }
                
                if (buffer_A.Size() != buffer_B.Size()) {
-                       note (ERROR, "sizes of audio data for frame " + lexical_cast<string>(i) + " differ");
+                       note (ERROR, String::compose ("sizes of audio data for frame %1 differ", i));
                        return false;
                }
                
@@ -140,7 +147,7 @@ SoundMXF::equals (shared_ptr<const Content> other, EqualityOptions opt, boost::f
                        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));
+                                       note (ERROR, String::compose ("PCM data difference of %1", d));
                                        return false;
                                }
                        }
index 5dcd6791af7f4c322f3543e958092d5cf374072e..51ba7e404a918b6f1dc4ac2d968d457b82ed87db 100644 (file)
@@ -22,9 +22,7 @@
 #include "exceptions.h"
 #include "compose.hpp"
 #include "AS_DCP.h"
-#include <boost/lexical_cast.hpp>
 
-using boost::lexical_cast;
 using namespace dcp;
 
 struct SoundMXFWriter::ASDCPState
index 6bcd75c89ad38e485d2341f06d7d6d476d528210..0188e4e7876cb60fba975255a1043753150e6184 100644 (file)
@@ -45,6 +45,13 @@ StereoPictureMXF::StereoPictureMXF (boost::filesystem::path file)
        }
 
        read_picture_descriptor (desc);
+
+       ASDCP::WriterInfo info;
+       if (ASDCP_FAILURE (reader.FillWriterInfo (info))) {
+               boost::throw_exception (DCPReadError ("could not read video MXF information"));
+       }
+
+       read_writer_info (info);
 }
 
 StereoPictureMXF::StereoPictureMXF (Fraction edit_rate)
index d34a9039be7f2fa724033314119c5d189281aaaa..0a3860a8c5683f528a5d9296cad277f3527edddd 100644 (file)
@@ -24,8 +24,8 @@
 #ifndef LIBDCP_TYPES_H
 #define LIBDCP_TYPES_H
 
-#include <string>
 #include <boost/shared_ptr.hpp>
+#include <string>
 
 namespace dcp
 {
index e53556e421b73ca8916a86bae70e7d08506a4c19..e26e66be421760a9b5ad1d04818b75dc62dccba8 100644 (file)
@@ -28,6 +28,7 @@
 #include "certificates.h"
 #include "gamma_lut.h"
 #include "xyz_frame.h"
+#include "compose.hpp"
 #include "KM_util.h"
 #include "KM_fileio.h"
 #include "AS_DCP.h"
@@ -39,7 +40,6 @@
 #include <libxml++/document.h>
 #include <openssl/sha.h>
 #include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
 #include <stdexcept>
 #include <sstream>
 #include <iostream>
@@ -55,7 +55,6 @@ using std::list;
 using std::setw;
 using std::setfill;
 using boost::shared_ptr;
-using boost::lexical_cast;
 using namespace dcp;
 
 /** Create a UUID.
@@ -211,7 +210,7 @@ dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce)
        if (!image) {
                opj_destroy_decompress (decoder);
                opj_cio_close (cio);
-               boost::throw_exception (DCPReadError ("could not decode JPEG2000 codestream of " + lexical_cast<string> (size) + " bytes."));
+               boost::throw_exception (DCPReadError (String::compose ("could not decode JPEG2000 codestream of %1 bytes.", size)));
        }
 
        opj_destroy_decompress (decoder);
index e26c73326000b46a1aca11e7f2ab29906b84887a..e79c0a0bf1a13e8f16d7682bb6d3d0d7049e7ddb 100644 (file)
@@ -86,6 +86,21 @@ extern std::string tm_to_string (struct tm *);
 extern std::string utc_offset_to_string (int);
 extern std::string ptime_to_string (boost::posix_time::ptime);
 extern FILE * fopen_boost (boost::filesystem::path, std::string);
+
+template <class F, class T>
+std::list<boost::shared_ptr<T> >
+list_of_type (std::list<boost::shared_ptr<F> > const & from)
+{
+       std::list<boost::shared_ptr<T> > out;
+       for (typename std::list<boost::shared_ptr<F> >::const_iterator i = from.begin(); i != from.end(); ++i) {
+               boost::shared_ptr<T> check = boost::dynamic_pointer_cast<T> (*i);
+               if (check) {
+                       out.push_back (check);
+               }
+       }
+
+       return out;
+}
        
 }
 
diff --git a/wscript b/wscript
index 1004ad545f928bed5e97ed21aa1bbb79f1aa0e20..baebc72eeec0b3659fc04f69332d564e94d526d2 100644 (file)
--- a/wscript
+++ b/wscript
@@ -34,6 +34,7 @@ def configure(conf):
     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]
+    conf.check_cfg(package='', path='Magick++-config', args='--cppflags --cxxflags --libs', uselib_store='MAGICK', mandatory=False)
 
     if conf.options.static:
         conf.check_cc(fragment="""