Various fixes.
authorCarl Hetherington <cth@carlh.net>
Tue, 28 Jan 2014 16:00:16 +0000 (16:00 +0000)
committerCarl Hetherington <cth@carlh.net>
Tue, 28 Jan 2014 16:00:16 +0000 (16:00 +0000)
src/asset.cc
src/asset.h
src/dcp.cc
src/mono_picture_mxf_writer.cc
src/picture_mxf.h
src/picture_mxf_writer_common.cc
src/stereo_picture_mxf_writer.cc
src/util.cc
src/util.h
test/dcp_test.cc
test/util_test.cc

index 43db41e30cbb669f3b4b98c34eebdea5c9974648..738fb0193d1636fd45f83e00766629bfd5b75204 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "asset.h"
 #include "util.h"
+#include "exceptions.h"
+#include "compose.hpp"
 #include <libxml++/libxml++.h>
 #include <boost/lexical_cast.hpp>
 
@@ -70,7 +72,7 @@ Asset::write_to_pkl (xmlpp::Node* node) const
 }
 
 void
-Asset::write_to_assetmap (xmlpp::Node* node) const
+Asset::write_to_assetmap (xmlpp::Node* node, boost::filesystem::path root) const
 {
        assert (!_file.empty ());
 
@@ -78,7 +80,11 @@ Asset::write_to_assetmap (xmlpp::Node* node) const
        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 ());
+       boost::optional<boost::filesystem::path> path = relative_to_root (root, _file);
+       if (!path) {
+               throw MiscError (String::compose ("Asset %1 is not within the directory %2", _file, root));
+       }
+       chunk->add_child("Path")->add_child_text (path.get().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> (boost::filesystem::file_size (_file)));
@@ -89,7 +95,7 @@ Asset::hash () const
 {
        assert (!_file.empty ());
                
-       if (!_hash.empty ()) {
+       if (_hash.empty ()) {
                _hash = make_digest (_file, 0);
        }
 
@@ -106,3 +112,11 @@ Asset::equals (boost::shared_ptr<const Asset> other, EqualityOptions, function<v
 
        return true;
 }
+
+void
+Asset::set_file (boost::filesystem::path file) const
+{
+       _file = boost::filesystem::absolute (file);
+       _hash.clear ();
+}
+       
index f9ec949f662c4b48d5e5d5fe0e05c921e71290b0..bd172428cc78249b28363a9cd8a598a91404036d 100644 (file)
@@ -58,7 +58,7 @@ public:
        /** Write details of the asset to a ASSETMAP.
         *  @param node Parent node.
         */
-       void write_to_assetmap (xmlpp::Node* node) const;
+       void write_to_assetmap (xmlpp::Node* node, boost::filesystem::path root) const;
 
        /** Write details of the asset to a PKL AssetList node.
         *  @param node Parent node.
@@ -69,10 +69,7 @@ public:
                return _file;
        }
 
-       void set_file (boost::filesystem::path file) const {
-               _file = file;
-               _hash.clear ();
-       }
+       void set_file (boost::filesystem::path file) const;
 
        /** @return the hash of this asset's file.  It will be
         *  computed by this call if necessary.
index e4a5678c922600ac79823dd8a1a4ad290dd6f7c8..2588c6548f15c5e096d315a1c0d1b1eaeaa7939a 100644 (file)
@@ -61,6 +61,7 @@ DCP::DCP (boost::filesystem::path directory)
        : _directory (directory)
 {
        boost::filesystem::create_directories (directory);
+       _directory = boost::filesystem::canonical (_directory);
 }
 
 void
@@ -314,7 +315,7 @@ DCP::write_assetmap (Standard standard, string pkl_uuid, int pkl_length, XMLMeta
        chunk->add_child("Length")->add_child_text (lexical_cast<string> (pkl_length));
        
        for (list<shared_ptr<Asset> >::const_iterator i = _assets.begin(); i != _assets.end(); ++i) {
-               (*i)->write_to_assetmap (asset_list);
+               (*i)->write_to_assetmap (asset_list, _directory);
        }
 
        /* This must not be the _formatted version otherwise signature digests will be wrong */
index d685cd69b67beac09a009fc440d0ad899b3e7883..b32a79f5d07ddf0d8c6fbaae3355ec2d5a1bca17 100644 (file)
@@ -50,6 +50,7 @@ void
 MonoPictureMXFWriter::start (uint8_t* data, int size)
 {
        dcp::start (this, _state, _standard, _picture_mxf, data, size);
+       _picture_mxf->set_frame_rate (_picture_mxf->edit_rate());
 }
 
 FrameInfo
index e8040a4efd92a2434a536f94bc9c64d82cc4cb16..38a1819e6589f7c55208ce0f2e9c189106a1dbb1 100644 (file)
@@ -61,15 +61,27 @@ public:
                return _size;
        }
 
+       void set_size (Size s) {
+               _size = s;
+       }
+
        Fraction frame_rate () const {
                return _frame_rate;
        }
 
+       void set_frame_rate (Fraction r) {
+               _frame_rate = r;
+       }
+
        Fraction screen_aspect_ratio () const {
                return _screen_aspect_ratio;
        }
 
-protected:     
+       void set_screen_aspect_ratio (Fraction r) {
+               _screen_aspect_ratio = r;
+       }
+
+protected:
 
        bool frame_buffer_equals (
                int frame, EqualityOptions opt, boost::function<void (NoteType, std::string)> note,
index d2073f77fa6f56f840151de0ee74900bfaafee35..d8d1589b491a1c91d1f9e4c5a9af02e391eb4594 100644 (file)
@@ -43,6 +43,9 @@ void dcp::start (PictureMXFWriter* writer, shared_ptr<P> state, Standard standar
 
        state->j2k_parser.FillPictureDescriptor (state->picture_descriptor);
        state->picture_descriptor.EditRate = ASDCP::Rational (mxf->edit_rate().numerator, mxf->edit_rate().denominator);
+
+       mxf->set_size (Size (state->picture_descriptor.StoredWidth, state->picture_descriptor.StoredHeight));
+       mxf->set_screen_aspect_ratio (Fraction (state->picture_descriptor.AspectRatio.Numerator, state->picture_descriptor.AspectRatio.Denominator));
        
        mxf->fill_writer_info (&state->writer_info, standard);
        
index d7344894ee84f2aed942c85fa3879339ce63bfac..4f98c60e3d70ef95e0b1c53dc1223758141bd065 100644 (file)
@@ -48,6 +48,7 @@ void
 StereoPictureMXFWriter::start (uint8_t* data, int size)
 {
        dcp::start (this, _state, _standard, _picture_mxf, data, size);
+       _picture_mxf->set_frame_rate (Fraction (_picture_mxf->edit_rate().numerator * 2, _picture_mxf->edit_rate().denominator));
 }
 
 /** Write a frame for one eye.  Frames must be written left, then right, then left etc.
index e26e66be421760a9b5ad1d04818b75dc62dccba8..4be026d28f0c35d9c0c0d3123a36bc752bf16162 100644 (file)
@@ -384,3 +384,26 @@ dcp::fopen_boost (boost::filesystem::path p, string t)
         return fopen (p.c_str(), t.c_str ());
 #endif
 }
+
+boost::optional<boost::filesystem::path>
+dcp::relative_to_root (boost::filesystem::path root, boost::filesystem::path file)
+{
+       boost::filesystem::path::const_iterator i = root.begin ();
+       boost::filesystem::path::const_iterator j = file.begin ();
+
+       while (i != root.end() && j != file.end() && *i == *j) {
+               ++i;
+               ++j;
+       }
+
+       if (i != root.end ()) {
+               return boost::optional<boost::filesystem::path> ();
+       }
+
+       boost::filesystem::path rel;
+       while (j != file.end ()) {
+               rel /= *j++;
+       }
+
+       return rel;
+}
index e79c0a0bf1a13e8f16d7682bb6d3d0d7049e7ddb..8db838ebc7c2adbfc6269f47be87bd193ad18bc4 100644 (file)
@@ -29,6 +29,7 @@
 #include <boost/function.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/filesystem.hpp>
+#include <boost/optional.hpp>
 #include <openjpeg.h>
 #include <string>
 #include <stdint.h>
@@ -81,7 +82,7 @@ extern void add_signature_value (xmlpp::Element* parent, CertificateChain const
 extern void add_signer (xmlpp::Element* parent, CertificateChain const & certificates, std::string const & ns);
 
 extern int base64_decode (std::string const & in, unsigned char* out, int out_length);
-
+extern boost::optional<boost::filesystem::path> relative_to_root (boost::filesystem::path root, boost::filesystem::path file);
 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);
index 38c9a3fdb45ce9a375968f5ebd4c71cfc8efef25..af5a79f51f760a455848736806f15224fbd7adfa 100644 (file)
@@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE (dcp_test)
        shared_ptr<dcp::MonoPictureMXF> mp (new dcp::MonoPictureMXF (dcp::Fraction (24, 1)));
        mp->set_progress (&d.Progress);
        mp->set_metadata (mxf_meta);
-       shared_ptr<dcp::PictureMXFWriter> picture_writer = mp->start_write ("build/test/DCP/bar/video.mxf", dcp::SMPTE, false);
+       shared_ptr<dcp::PictureMXFWriter> picture_writer = mp->start_write ("build/test/foo/video.mxf", dcp::SMPTE, false);
        dcp::File j2c ("test/data/32x32_red_square.j2c");
        for (int i = 0; i < 24; ++i) {
                picture_writer->write (j2c.data (), j2c.size ());
@@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE (dcp_test)
        shared_ptr<dcp::SoundMXF> ms (new dcp::SoundMXF (dcp::Fraction (24, 1), 48000, 1));
        ms->set_progress (&d.Progress);
        ms->set_metadata (mxf_meta);
-       shared_ptr<dcp::SoundMXFWriter> sound_writer = ms->start_write ("build/test/DCP/bar/audio.mxf", dcp::SMPTE);
+       shared_ptr<dcp::SoundMXFWriter> sound_writer = ms->start_write ("build/test/foo/audio.mxf", dcp::SMPTE);
 
        SF_INFO info;
        info.format = 0;
@@ -100,6 +100,8 @@ BOOST_AUTO_TEST_CASE (dcp_test)
                          ));
                  
        d.add (cpl);
+       d.add (mp);
+       d.add (ms);
 
        d.write_xml (dcp::SMPTE, xml_meta);
 
index 74a3e9200f3949e27e8123202185514bc2a420cd..15f22f57db5806099825661115d4b19c8af2ea92 100644 (file)
@@ -70,3 +70,46 @@ BOOST_AUTO_TEST_CASE (content_kind_test)
        BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("psa"), dcp::PUBLIC_SERVICE_ANNOUNCEMENT);
        BOOST_CHECK_EQUAL (dcp::content_kind_from_string ("advertisement"), dcp::ADVERTISEMENT);
 }
+
+BOOST_AUTO_TEST_CASE (relative_to_root_test)
+{
+       {
+               boost::filesystem::path root = "a";
+               root /= "b";
+               
+               boost::filesystem::path file = "a";
+               file /= "b";
+               file /= "c";
+               
+               boost::optional<boost::filesystem::path> rel = dcp::relative_to_root (root, file);
+               BOOST_CHECK (rel);
+               BOOST_CHECK_EQUAL (rel.get(), boost::filesystem::path ("c"));
+       }
+
+       {
+               boost::filesystem::path root = "a";
+               root /= "b";
+               root /= "c";
+               
+               boost::filesystem::path file = "a";
+               file /= "b";
+               
+               boost::optional<boost::filesystem::path> rel = dcp::relative_to_root (root, file);
+               BOOST_CHECK (!rel);
+       }
+
+       {
+               boost::filesystem::path root = "a";
+               
+               boost::filesystem::path file = "a";
+               file /= "b";
+               file /= "c";
+               
+               boost::optional<boost::filesystem::path> rel = dcp::relative_to_root (root, file);
+               BOOST_CHECK (rel);
+
+               boost::filesystem::path check = "b";
+               check /= "c";
+               BOOST_CHECK_EQUAL (rel.get(), check);
+       }
+}