MXF -> Asset in lots of places.
authorCarl Hetherington <cth@carlh.net>
Thu, 4 Jun 2015 23:05:32 +0000 (00:05 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 5 Jun 2015 13:36:27 +0000 (14:36 +0100)
73 files changed:
examples/make_dcp.cc
examples/read_dcp.cc
src/asset_writer.cc [new file with mode: 0644]
src/asset_writer.h [new file with mode: 0644]
src/dcp.cc
src/decrypted_kdm.h
src/key.h
src/mono_picture_asset.cc [new file with mode: 0644]
src/mono_picture_asset.h [new file with mode: 0644]
src/mono_picture_asset_writer.cc [new file with mode: 0644]
src/mono_picture_asset_writer.h [new file with mode: 0644]
src/mono_picture_frame.cc
src/mono_picture_frame.h
src/mono_picture_mxf.cc [deleted file]
src/mono_picture_mxf.h [deleted file]
src/mono_picture_mxf_writer.cc [deleted file]
src/mono_picture_mxf_writer.h [deleted file]
src/mxf.h
src/mxf_writer.cc [deleted file]
src/mxf_writer.h [deleted file]
src/picture_asset.cc [new file with mode: 0644]
src/picture_asset.h [new file with mode: 0644]
src/picture_asset_writer.cc [new file with mode: 0644]
src/picture_asset_writer.h [new file with mode: 0644]
src/picture_asset_writer_common.cc [new file with mode: 0644]
src/picture_mxf.cc [deleted file]
src/picture_mxf.h [deleted file]
src/picture_mxf_writer.cc [deleted file]
src/picture_mxf_writer.h [deleted file]
src/picture_mxf_writer_common.cc [deleted file]
src/reel.cc
src/reel_asset.cc
src/reel_asset.h
src/reel_mono_picture_asset.cc
src/reel_mono_picture_asset.h
src/reel_mxf_asset.h
src/reel_picture_asset.cc
src/reel_picture_asset.h
src/reel_sound_asset.cc
src/reel_sound_asset.h
src/reel_stereo_picture_asset.cc
src/reel_stereo_picture_asset.h
src/reel_subtitle_asset.h
src/sound_asset.cc [new file with mode: 0644]
src/sound_asset.h [new file with mode: 0644]
src/sound_asset_writer.cc [new file with mode: 0644]
src/sound_asset_writer.h [new file with mode: 0644]
src/sound_frame.cc
src/sound_frame.h
src/sound_mxf.cc [deleted file]
src/sound_mxf.h [deleted file]
src/sound_mxf_writer.cc [deleted file]
src/sound_mxf_writer.h [deleted file]
src/stereo_picture_asset.cc [new file with mode: 0644]
src/stereo_picture_asset.h [new file with mode: 0644]
src/stereo_picture_asset_writer.cc [new file with mode: 0644]
src/stereo_picture_asset_writer.h [new file with mode: 0644]
src/stereo_picture_frame.cc
src/stereo_picture_frame.h
src/stereo_picture_mxf.cc [deleted file]
src/stereo_picture_mxf.h [deleted file]
src/stereo_picture_mxf_writer.cc [deleted file]
src/stereo_picture_mxf_writer.h [deleted file]
src/types.h
src/wscript
test/cpl_sar_test.cc
test/dcp_test.cc
test/decryption_test.cc
test/encryption_test.cc
test/recovery_test.cc
test/round_trip_test.cc
tools/dcpdiff.cc
tools/dcpinfo.cc

index d83391712fa5ab9ef40a6cc63305eef91ea99b7a..7b15e5e0808fbfb774480021f4e94a80146fe7ae 100644 (file)
 
 #include "dcp.h"
 #include "cpl.h"
-#include "mono_picture_mxf.h"
-#include "mono_picture_mxf_writer.h"
-#include "sound_mxf.h"
-#include "sound_mxf_writer.h"
+#include "mono_picture_asset.h"
+#include "mono_picture_asset_writer.h"
+#include "sound_asset.h"
+#include "sound_asset_writer.h"
 #include "reel.h"
 #include "file.h"
 #include "reel_mono_picture_asset.h"
@@ -49,15 +49,15 @@ main ()
        /* Create a directory to put the DCP in */
        boost::filesystem::create_directory ("DCP");
        
-       /* Make a picture MXF.  This is a file which combines JPEG2000 files together to make
+       /* Make a picture asset.  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<dcp::MonoPictureMXF> picture_mxf (new dcp::MonoPictureMXF (dcp::Fraction (24, 1)));
+       boost::shared_ptr<dcp::MonoPictureAsset> picture_asset (new dcp::MonoPictureAsset (dcp::Fraction (24, 1)));
 
        /* Start off a write to it */
-       boost::shared_ptr<dcp::PictureMXFWriter> picture_writer = picture_mxf->start_write ("DCP/picture.mxf", dcp::SMPTE, false);
+       boost::shared_ptr<dcp::PictureAssetWriter> picture_writer = picture_asset->start_write ("DCP/picture.mxf", dcp::SMPTE, false);
 
        /* Write 24 frames of the same JPEG2000 file */
        dcp::File picture ("examples/help.j2c");
@@ -71,8 +71,8 @@ main ()
        /* 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).
        */
-       boost::shared_ptr<dcp::SoundMXF> sound_mxf (new dcp::SoundMXF (dcp::Fraction (24, 1), 48000, 2));
-       boost::shared_ptr<dcp::SoundMXFWriter> sound_writer = sound_mxf->start_write ("DCP/sound.mxf", dcp::SMPTE);
+       boost::shared_ptr<dcp::SoundAsset> sound_asset (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 2));
+       boost::shared_ptr<dcp::SoundAssetWriter> sound_writer = sound_asset->start_write ("DCP/sound.mxf", dcp::SMPTE);
 
        /* Write some sine waves */
        float* audio[2];
@@ -93,10 +93,10 @@ main ()
        boost::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.
+          (video) frame from the assets that the reel should play.
        */
-       reel->add (boost::shared_ptr<dcp::ReelPictureAsset> (new dcp::ReelMonoPictureAsset (picture_mxf, 0)));
-       reel->add (boost::shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (sound_mxf, 0)));
+       reel->add (boost::shared_ptr<dcp::ReelPictureAsset> (new dcp::ReelMonoPictureAsset (picture_asset, 0)));
+       reel->add (boost::shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (sound_asset, 0)));
 
        /* Make a CPL with this reel */
        boost::shared_ptr<dcp::CPL> cpl (new dcp::CPL ("My film", dcp::FEATURE));
@@ -105,8 +105,8 @@ main ()
        /* Write the DCP */
        dcp::DCP dcp ("DCP");
        dcp.add (cpl);
-       dcp.add (picture_mxf);
-       dcp.add (sound_mxf);
+       dcp.add (picture_asset);
+       dcp.add (sound_asset);
        dcp.write_xml (dcp::SMPTE);
        
        return 0;
index 068fc09be6d26c400d81caba4f38663be316873b..c7efd77b8c709b262bcd08e447aabe08a6b33e66 100644 (file)
@@ -19,7 +19,7 @@
 
 /* If you are using an installed libdcp, these #includes would need to be changed to
 #include <dcp/dcp.h>
-#include <dcp/picture_mxf.h>
+#include <dcp/picture_asset.h>
 ... etc. ...
 */
 
@@ -28,9 +28,9 @@
 #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 "mono_picture_asset.h"
+#include "stereo_picture_asset.h"
+#include "sound_asset.h"
 #include "subtitle_asset.h"
 #include "xyz_image.h"
 #include "colour_conversion.h"
@@ -60,11 +60,11 @@ main ()
        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)) {
+               if (boost::dynamic_pointer_cast<dcp::MonoPictureAsset> (*i)) {
                        std::cout << "2D picture\n";
-               } else if (boost::dynamic_pointer_cast<dcp::StereoPictureMXF> (*i)) {
+               } else if (boost::dynamic_pointer_cast<dcp::StereoPictureAsset> (*i)) {
                        std::cout << "3D picture\n";
-               } else if (boost::dynamic_pointer_cast<dcp::SoundMXF> (*i)) {
+               } else if (boost::dynamic_pointer_cast<dcp::SoundAsset> (*i)) {
                        std::cout << "Sound\n";
                } else if (boost::dynamic_pointer_cast<dcp::SubtitleAsset> (*i)) {
                        std::cout << "Subtitle\n";
@@ -77,11 +77,13 @@ main ()
        /* 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 picture asset in the first reel */
+       boost::shared_ptr<dcp::MonoPictureAsset> picture_asset = boost::dynamic_pointer_cast<dcp::MonoPictureAsset> (
+               cpl->reels().front()->main_picture()->asset()
+               );
 
        /* Get the 1000th frame of it */
-       boost::shared_ptr<const dcp::MonoPictureFrame> picture_frame_j2k = picture_mxf->get_frame(999);
+       boost::shared_ptr<const dcp::MonoPictureFrame> picture_frame_j2k = picture_asset->get_frame(999);
 
        /* Get the frame as an XYZ image */
        boost::shared_ptr<const dcp::XYZImage> picture_image_xyz = picture_frame_j2k->xyz_image ();
diff --git a/src/asset_writer.cc b/src/asset_writer.cc
new file mode 100644 (file)
index 0000000..eb55fea
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+    Copyright (C) 2012-2015 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_writer.h
+ *  @brief AssetWriter class.
+ */
+
+#include "asset_writer.h"
+#include "mxf.h"
+#include "dcp_assert.h"
+#include "AS_DCP.h"
+#include "KM_prng.h"
+
+using namespace dcp;
+
+/** Create an AssetWriter.
+ *  @param mxf MXF that we are writing.
+ *  @param file File to write to.
+ */
+AssetWriter::AssetWriter (MXF* mxf, boost::filesystem::path file)
+       : _mxf (mxf)
+       , _file (file)
+       , _frames_written (0)
+       , _finalized (false)
+       , _encryption_context (0)
+{
+       if (mxf->key ()) {
+               _encryption_context = new ASDCP::AESEncContext;
+               if (ASDCP_FAILURE (_encryption_context->InitKey (mxf->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");
+               }
+       }
+}
+
+AssetWriter::~AssetWriter ()
+{
+       delete _encryption_context;
+}
+
+void
+AssetWriter::finalize ()
+{
+       DCP_ASSERT (!_finalized);
+       _finalized = true;
+}
diff --git a/src/asset_writer.h b/src/asset_writer.h
new file mode 100644 (file)
index 0000000..31d2f7a
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+    Copyright (C) 2012-2015 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_writer.h
+ *  @brief AssetWriter class.
+ */
+
+#ifndef LIBDCP_ASSET_WRITER_H
+#define LIBDCP_ASSET_WRITER_H
+
+#include <boost/filesystem.hpp>
+
+namespace ASDCP {
+       class AESEncContext;
+}
+
+namespace dcp {
+
+class MXF;
+
+/** @class AssetWriter
+ *  @brief Parent class for classes which can write MXF-based assets.
+ *
+ *  The AssetWriter lasts for the duration of the write and is then discarded.
+ *  They can only be created by calling start_write() on an appropriate Asset object.
+ */
+class AssetWriter : public boost::noncopyable
+{
+public:
+       virtual ~AssetWriter ();
+       virtual void finalize ();
+
+protected:
+       AssetWriter (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;
+       ASDCP::AESEncContext* _encryption_context;
+};
+
+}
+
+#endif
index e1b632c6f239976e16fee5f3e50512bb762f0db3..abeafdfbd9053eda7a3ff505d2507bdfb97fc608 100644 (file)
 
 #include "raw_convert.h"
 #include "dcp.h"
-#include "sound_mxf.h"
-#include "picture_mxf.h"
+#include "sound_asset.h"
+#include "picture_asset.h"
 #include "interop_subtitle_asset.h"
 #include "smpte_subtitle_asset.h"
-#include "mono_picture_mxf.h"
-#include "stereo_picture_mxf.h"
+#include "mono_picture_asset.h"
+#include "stereo_picture_asset.h"
 #include "util.h"
 #include "metadata.h"
 #include "exceptions.h"
@@ -149,14 +149,14 @@ DCP::read (bool keep_going, ReadErrors* errors)
                                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 (path)));
+                                       _assets.push_back (shared_ptr<MonoPictureAsset> (new MonoPictureAsset (path)));
                                        break;
                                case ASDCP::ESS_PCM_24b_48k:
                                case ASDCP::ESS_PCM_24b_96k:
-                                       _assets.push_back (shared_ptr<SoundMXF> (new SoundMXF (path)));
+                                       _assets.push_back (shared_ptr<SoundAsset> (new SoundAsset (path)));
                                        break;
                                case ASDCP::ESS_JPEG_2000_S:
-                                       _assets.push_back (shared_ptr<StereoPictureMXF> (new StereoPictureMXF (path)));
+                                       _assets.push_back (shared_ptr<StereoPictureAsset> (new StereoPictureAsset (path)));
                                        break;
                                case ASDCP::ESS_TIMED_TEXT:
                                        _assets.push_back (shared_ptr<SMPTESubtitleAsset> (new SMPTESubtitleAsset (path)));
index 91b2f7d3d25a2ebe8d116cdf1ede49e4b6f38170..5ea67861250827608fc255f4a35733e1fc69aa5f 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2015 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
@@ -45,7 +45,7 @@ class CPL;
  *  has been created (by some other means) ready for encryption later.
  *
  *  A DecryptedKDM object can be created either from an EncryptedKDM and private key file,
- *  or from the details of the MXFs that the KDM should protect.
+ *  or from the details of the assets that the KDM should protect.
  */
 class DecryptedKDM
 {
@@ -57,7 +57,7 @@ public:
 
        /** Construct a DecryptedKDM.
         *  @param cpl CPL that the keys are for.
-        *  @param key Key that was used to encrypt the MXFs.
+        *  @param key Key that was used to encrypt the assets.
         *  @param not_valid_before Start time for the KDM.
         *  @param not_valid_after End time for the KDM.
         */
@@ -79,7 +79,7 @@ public:
         */
        EncryptedKDM encrypt (boost::shared_ptr<const Signer> signer, Certificate recipient, Formulation formulation) const;
 
-       /** @return This KDM's (decrypted) keys, which could be used to decrypt MXFs. */
+       /** @return This KDM's (decrypted) keys, which could be used to decrypt assets. */
        std::list<DecryptedKDMKey> keys () const {
                return _keys;
        }
index 248a2a958193c40c0d92690f381478121f62bf86..9d16c8a15667a719df5e4f80b2eda059b6e62e5e 100644 (file)
--- a/src/key.h
+++ b/src/key.h
@@ -30,7 +30,7 @@
 namespace dcp {
 
 /** @class Key
- *  @brief A key for decrypting/encrypting MXFs.
+ *  @brief A key for decrypting/encrypting assets.
  */
 class Key
 {
diff --git a/src/mono_picture_asset.cc b/src/mono_picture_asset.cc
new file mode 100644 (file)
index 0000000..19210ce
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+    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.
+
+*/
+
+#include "mono_picture_asset.h"
+#include "mono_picture_asset_writer.h"
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "exceptions.h"
+#include "dcp_assert.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 namespace dcp;
+
+MonoPictureAsset::MonoPictureAsset (boost::filesystem::path file)
+       : PictureAsset (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"));
+       }
+
+       read_picture_descriptor (desc);
+       
+       ASDCP::WriterInfo info;
+       if (ASDCP_FAILURE (reader.FillWriterInfo (info))) {
+               boost::throw_exception (DCPReadError ("could not read video MXF information"));
+       }
+
+       _id = read_writer_info (info);
+}
+
+MonoPictureAsset::MonoPictureAsset (Fraction edit_rate)
+       : PictureAsset (edit_rate)
+{
+       
+}
+
+shared_ptr<const MonoPictureFrame>
+MonoPictureAsset::get_frame (int n) const
+{
+       return shared_ptr<const MonoPictureFrame> (new MonoPictureFrame (_file, n, _decryption_context));
+}
+
+bool
+MonoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, NoteHandler note) const
+{
+       if (!dynamic_pointer_cast<const MonoPictureAsset> (other)) {
+               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 MonoPictureAsset> other_picture = dynamic_pointer_cast<const MonoPictureAsset> (other);
+       DCP_ASSERT (other_picture);
+
+       for (int i = 0; i < _intrinsic_duration; ++i) {
+               if (i >= other_picture->intrinsic_duration()) {
+                       return false;
+               }
+               
+               note (DCP_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);
+               
+               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 (boost::filesystem::path file, Standard standard, bool overwrite)
+{
+       /* XXX: can't we use shared_ptr here? */
+       return shared_ptr<MonoPictureAssetWriter> (new MonoPictureAssetWriter (this, file, standard, overwrite));
+}
+
+string
+MonoPictureAsset::cpl_node_name () const
+{
+       return "MainPicture";
+}
diff --git a/src/mono_picture_asset.h b/src/mono_picture_asset.h
new file mode 100644 (file)
index 0000000..fc1e4f9
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+    Copyright (C) 2012-2015 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 dcp {
+
+class MonoPictureAssetWriter;  
+
+/** @class MonoPictureAsset
+ *  @brief A 2D (monoscopic) picture asset.
+ */
+class MonoPictureAsset : public PictureAsset
+{
+public:
+       /** Create a MonoPictureAsset by reading a file.
+        *  @param file Asset file to read.
+        */
+       MonoPictureAsset (boost::filesystem::path file);
+
+       /** Create a MonoPictureAsset with a given edit rate.
+        *  @param edit_rate Edit rate (i.e. frame rate) in frames per second.
+        */
+       MonoPictureAsset (Fraction edit_rate);
+
+       /** Start a progressive write to a MonoPictureAsset */
+       boost::shared_ptr<PictureAssetWriter> start_write (boost::filesystem::path, Standard standard, bool);
+
+       bool equals (
+               boost::shared_ptr<const Asset> other,
+               EqualityOptions opt,
+               NoteHandler note
+               ) const;
+       
+       boost::shared_ptr<const MonoPictureFrame> get_frame (int n) const;
+
+private:
+       std::string cpl_node_name () const;
+};
+
+}      
+
+#endif
diff --git a/src/mono_picture_asset_writer.cc b/src/mono_picture_asset_writer.cc
new file mode 100644 (file)
index 0000000..0f09f8f
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+    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.
+
+*/
+
+/** @file  src/mono_picture_asset_writer.cc
+ *  @brief MonoPictureAssetWriter class
+ */
+
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "mono_picture_asset_writer.h"
+#include "exceptions.h"
+#include "picture_asset.h"
+#include "dcp_assert.h"
+
+#include "picture_asset_writer_common.cc"
+
+using std::istream;
+using std::ostream;
+using std::string;
+using boost::shared_ptr;
+using namespace dcp;
+
+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, boost::filesystem::path file, Standard standard, bool overwrite)
+       : PictureAssetWriter (asset, file, standard, overwrite)
+       , _state (new MonoPictureAssetWriter::ASDCPState)
+{
+
+}
+
+void
+MonoPictureAssetWriter::start (uint8_t* data, int size)
+{
+       dcp::start (this, _state, _standard, _picture_asset, data, size);
+       _picture_asset->set_frame_rate (_picture_asset->edit_rate());
+}
+
+FrameInfo
+MonoPictureAssetWriter::write (uint8_t* data, int size)
+{
+       DCP_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, _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
+MonoPictureAssetWriter::fake_write (int size)
+{
+       DCP_ASSERT (_started);
+       DCP_ASSERT (!_finalized);
+
+       Kumu::Result_t r = _state->mxf_writer.FakeWriteFrame (size);
+       if (ASDCP_FAILURE (r)) {
+               boost::throw_exception (MXFFileError ("error in writing video MXF", _file.string(), r));
+       }
+
+       ++_frames_written;
+}
+
+void
+MonoPictureAssetWriter::finalize ()
+{
+       Kumu::Result_t r = _state->mxf_writer.Finalize();
+       if (ASDCP_FAILURE (r)) {
+               boost::throw_exception (MXFFileError ("error in finalizing video MXF", _file.string(), r));
+       }
+
+       _picture_asset->_intrinsic_duration = _frames_written;
+       PictureAssetWriter::finalize ();
+}
+
diff --git a/src/mono_picture_asset_writer.h b/src/mono_picture_asset_writer.h
new file mode 100644 (file)
index 0000000..6478c9b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+    Copyright (C) 2012-2015 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/mono_picture_asset_writer.h
+ *  @brief MonoPictureAssetWriter class
+ */
+
+#ifndef LIBDCP_MONO_PICTURE_ASSET_WRITER_H
+#define LIBDCP_MONO_PICTURE_ASSET_WRITER_H
+
+#include "picture_asset_writer.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <stdint.h>
+#include <string>
+#include <fstream>
+
+namespace dcp {
+
+/** @class MonoPictureAssetWriter
+ *  @brief A helper class for writing to MonoPictureAssets
+ *
+ *  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 *, boost::filesystem::path file, Standard standard, 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;
+};
+
+}
+
+#endif
index 689a8b21f6c199b6ce6d7fb39cacd94c43161607..1237fd904754e53fdec6a371baca33d82e8cb6d1 100644 (file)
@@ -56,16 +56,16 @@ MonoPictureFrame::MonoPictureFrame (boost::filesystem::path path)
 }
 
 /** Make a picture frame from a 2D (monoscopic) asset.
- *  @param mxf_path Path to the asset's MXF file.
+ *  @param path Path to the asset's MXF file.
  *  @param n Frame within the asset, not taking EntryPoint into account.
  *  @param c Context for decryption, or 0.
  */
-MonoPictureFrame::MonoPictureFrame (boost::filesystem::path mxf_path, int n, ASDCP::AESDecContext* c)
+MonoPictureFrame::MonoPictureFrame (boost::filesystem::path path, int n, ASDCP::AESDecContext* c)
 {
        ASDCP::JP2K::MXFReader reader;
-       Kumu::Result_t r = reader.OpenRead (mxf_path.string().c_str());
+       Kumu::Result_t r = reader.OpenRead (path.string().c_str());
        if (ASDCP_FAILURE (r)) {
-               boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path, r));
+               boost::throw_exception (FileError ("could not open MXF file for reading", path, r));
        }
 
        /* XXX: unfortunate guesswork on this buffer size */
index 9108926203b57b936aefc7e4941b48ccee682281..d4853d52adbe342d8f1e91d52bcb406d294fa617 100644 (file)
@@ -46,7 +46,7 @@ class XYZImage;
 class MonoPictureFrame : public boost::noncopyable
 {
 public:
-       MonoPictureFrame (boost::filesystem::path mxf_path, int n, ASDCP::AESDecContext *);
+       MonoPictureFrame (boost::filesystem::path path, int n, ASDCP::AESDecContext *);
        MonoPictureFrame (boost::filesystem::path path);
        MonoPictureFrame ();
        ~MonoPictureFrame ();
diff --git a/src/mono_picture_mxf.cc b/src/mono_picture_mxf.cc
deleted file mode 100644 (file)
index faae8cd..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-    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.
-
-*/
-
-#include "mono_picture_mxf.h"
-#include "mono_picture_mxf_writer.h"
-#include "AS_DCP.h"
-#include "KM_fileio.h"
-#include "exceptions.h"
-#include "dcp_assert.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 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"));
-       }
-
-       read_picture_descriptor (desc);
-       
-       ASDCP::WriterInfo info;
-       if (ASDCP_FAILURE (reader.FillWriterInfo (info))) {
-               boost::throw_exception (DCPReadError ("could not read video MXF information"));
-       }
-
-       _id = read_writer_info (info);
-}
-
-MonoPictureMXF::MonoPictureMXF (Fraction 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 Asset> other, EqualityOptions opt, NoteHandler note) const
-{
-       if (!dynamic_pointer_cast<const MonoPictureMXF> (other)) {
-               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);
-       DCP_ASSERT (other_picture);
-
-       for (int i = 0; i < _intrinsic_duration; ++i) {
-               if (i >= other_picture->intrinsic_duration()) {
-                       return false;
-               }
-               
-               note (DCP_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);
-               
-               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, Standard standard, bool overwrite)
-{
-       /* XXX: can't we use shared_ptr here? */
-       return shared_ptr<MonoPictureMXFWriter> (new MonoPictureMXFWriter (this, file, standard, overwrite));
-}
-
-string
-MonoPictureMXF::cpl_node_name () const
-{
-       return "MainPicture";
-}
diff --git a/src/mono_picture_mxf.h b/src/mono_picture_mxf.h
deleted file mode 100644 (file)
index 4e5211c..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-    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.
-
-*/
-
-#ifndef LIBDCP_MONO_PICTURE_MXF_H
-#define LIBDCP_MONO_PICTURE_MXF_H
-
-#include "picture_mxf.h"
-
-namespace dcp {
-
-class MonoPictureMXFWriter;    
-
-/** @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 (Fraction edit_rate);
-
-       /** 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 Asset> other,
-               EqualityOptions opt,
-               NoteHandler note
-               ) const;
-       
-       boost::shared_ptr<const MonoPictureFrame> get_frame (int n) const;
-
-private:
-       std::string cpl_node_name () const;
-};
-
-}      
-
-#endif
diff --git a/src/mono_picture_mxf_writer.cc b/src/mono_picture_mxf_writer.cc
deleted file mode 100644 (file)
index f0914cd..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-    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.
-
-*/
-
-/** @file  src/mono_picture_mxf_writer.cc
- *  @brief MonoPictureMXFWriter class
- */
-
-#include "AS_DCP.h"
-#include "KM_fileio.h"
-#include "mono_picture_mxf_writer.h"
-#include "exceptions.h"
-#include "picture_mxf.h"
-#include "dcp_assert.h"
-
-#include "picture_mxf_writer_common.cc"
-
-using std::istream;
-using std::ostream;
-using std::string;
-using boost::shared_ptr;
-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, Standard standard, bool overwrite)
-       : PictureMXFWriter (asset, file, standard, overwrite)
-       , _state (new MonoPictureMXFWriter::ASDCPState)
-{
-
-}
-
-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
-MonoPictureMXFWriter::write (uint8_t* data, int size)
-{
-       DCP_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, _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)
-{
-       DCP_ASSERT (_started);
-       DCP_ASSERT (!_finalized);
-
-       Kumu::Result_t r = _state->mxf_writer.FakeWriteFrame (size);
-       if (ASDCP_FAILURE (r)) {
-               boost::throw_exception (MXFFileError ("error in writing video MXF", _file.string(), r));
-       }
-
-       ++_frames_written;
-}
-
-void
-MonoPictureMXFWriter::finalize ()
-{
-       Kumu::Result_t r = _state->mxf_writer.Finalize();
-       if (ASDCP_FAILURE (r)) {
-               boost::throw_exception (MXFFileError ("error in finalizing video MXF", _file.string(), r));
-       }
-
-       _picture_mxf->_intrinsic_duration = _frames_written;
-       PictureMXFWriter::finalize ();
-}
-
diff --git a/src/mono_picture_mxf_writer.h b/src/mono_picture_mxf_writer.h
deleted file mode 100644 (file)
index 7cad54e..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-    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.
-
-*/
-
-/** @file  src/mono_picture_mxf_writer.h
- *  @brief MonoPictureMXFWriter class
- */
-
-#ifndef LIBDCP_MONO_PICTURE_MXF_WRITER_H
-#define LIBDCP_MONO_PICTURE_MXF_WRITER_H
-
-#include "picture_mxf_writer.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/utility.hpp>
-#include <stdint.h>
-#include <string>
-#include <fstream>
-
-namespace dcp {
-
-/** @class MonoPictureMXFWriter
- *  @brief 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 MonoPictureMXF 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, Standard standard, 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;
-};
-
-}
-
-#endif
index e05ddbcdc072d97ea8632daafe5f236dd4f71ec4..a9f1bfa3b7fe4f94f058d2a4e5243d87d9b4e462 100644 (file)
--- a/src/mxf.h
+++ b/src/mxf.h
@@ -39,7 +39,7 @@ namespace dcp
 {
 
 class MXFMetadata;
-class PictureMXFWriter;        
+class PictureAssetWriter;      
 
 /** @class MXF
  *  @brief Parent class for classes which represent MXF files.
@@ -88,7 +88,7 @@ public:
        
 protected:
        template <class P, class Q>
-       friend void start (PictureMXFWriter* writer, boost::shared_ptr<P> state, Standard standard, Q* mxf, uint8_t* data, int size);
+       friend void start (PictureAssetWriter* writer, boost::shared_ptr<P> state, Standard standard, Q* mxf, uint8_t* data, int size);
 
        std::string read_writer_info (ASDCP::WriterInfo const &);
        /** Fill in a ADSCP::WriteInfo struct.
diff --git a/src/mxf_writer.cc b/src/mxf_writer.cc
deleted file mode 100644 (file)
index ab1eac1..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-    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.
-
-*/
-
-/** @file  src/mxf_writer.h
- *  @brief MXFWriter class.
- */
-
-#include "mxf_writer.h"
-#include "mxf.h"
-#include "dcp_assert.h"
-#include "AS_DCP.h"
-#include "KM_prng.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)
-       , _encryption_context (0)
-{
-       if (mxf->key ()) {
-               _encryption_context = new ASDCP::AESEncContext;
-               if (ASDCP_FAILURE (_encryption_context->InitKey (mxf->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");
-               }
-       }
-}
-
-MXFWriter::~MXFWriter ()
-{
-       delete _encryption_context;
-}
-
-void
-MXFWriter::finalize ()
-{
-       DCP_ASSERT (!_finalized);
-       _finalized = true;
-}
diff --git a/src/mxf_writer.h b/src/mxf_writer.h
deleted file mode 100644 (file)
index c7924c9..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-    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.
-
-*/
-
-/** @file  src/mxf_writer.h
- *  @brief MXFWriter class.
- */
-
-#ifndef LIBDCP_MXF_WRITER_H
-#define LIBDCP_MXF_WRITER_H
-
-#include <boost/filesystem.hpp>
-
-namespace ASDCP {
-       class AESEncContext;
-}
-
-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:
-       virtual ~MXFWriter ();
-       virtual void finalize ();
-
-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;
-       ASDCP::AESEncContext* _encryption_context;
-};
-
-}
-
-#endif
diff --git a/src/picture_asset.cc b/src/picture_asset.cc
new file mode 100644 (file)
index 0000000..ef3ff1f
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+    Copyright (C) 2012-2015 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 "picture_asset.h"
+#include "util.h"
+#include "exceptions.h"
+#include "xyz_image.h"
+#include "picture_asset_writer.h"
+#include "dcp_assert.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 <list>
+#include <stdexcept>
+#include <iostream>
+#include <sstream>
+
+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 namespace dcp;
+
+PictureAsset::PictureAsset (boost::filesystem::path file)
+       : Asset (file)
+       , _intrinsic_duration (0)
+{
+
+}
+
+PictureAsset::PictureAsset (Fraction edit_rate)
+       : _edit_rate (edit_rate)
+       , _intrinsic_duration (0)
+{
+
+}
+
+void
+PictureAsset::read_picture_descriptor (ASDCP::JP2K::PictureDescriptor const & desc)
+{
+       _size.width = desc.StoredWidth;
+       _size.height = desc.StoredHeight;
+       _edit_rate = Fraction (desc.EditRate.Numerator, desc.EditRate.Denominator);
+       _intrinsic_duration = desc.ContainerDuration;
+       _frame_rate = Fraction (desc.SampleRate.Numerator, desc.SampleRate.Denominator);
+       _screen_aspect_ratio = Fraction (desc.AspectRatio.Numerator, desc.AspectRatio.Denominator);
+}
+
+bool
+PictureAsset::descriptor_equals (
+       ASDCP::JP2K::PictureDescriptor const & a, ASDCP::JP2K::PictureDescriptor const & b, NoteHandler 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 (DCP_ERROR, "video MXF picture descriptors differ");
+               return false;
+       }
+
+       if (a.ContainerDuration != b.ContainerDuration) {
+               note (DCP_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, NoteHandler 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 (DCP_NOTE, "J2K identical");
+               /* Easy result; the J2K data is identical */
+               return true;
+       }
+               
+       /* Decompress the images to bitmaps */
+       shared_ptr<XYZImage> image_A = decompress_j2k (const_cast<uint8_t*> (data_A), size_A, 0);
+       shared_ptr<XYZImage> 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 (DCP_ERROR, String::compose ("image sizes for frame %1 differ", frame));
+                       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 (DCP_NOTE, String::compose ("mean difference %1, deviation %2", mean, std_dev));
+       
+       if (mean > opt.max_mean_pixel_error) {
+               note (
+                       DCP_ERROR,
+                       String::compose ("mean %1 out of range %2 in frame %3", mean, opt.max_mean_pixel_error, frame)
+                       );
+               
+               return false;
+       }
+
+       if (std_dev > opt.max_std_dev_pixel_error) {
+               note (
+                       DCP_ERROR,
+                       String::compose ("standard deviation %1 out of range %2 in frame %3", std_dev, opt.max_std_dev_pixel_error, frame)
+                       );
+               
+               return false;
+       }
+
+       return true;
+}
+
+string
+PictureAsset::pkl_type (Standard standard) const
+{
+       switch (standard) {
+       case INTEROP:
+               return "application/x-smpte-mxf;asdcpKind=Picture";
+       case SMPTE:
+               return "application/mxf";
+       default:
+               DCP_ASSERT (false);
+       }
+}
diff --git a/src/picture_asset.h b/src/picture_asset.h
new file mode 100644 (file)
index 0000000..51b69e7
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+    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.
+
+*/
+
+#ifndef LIBDCP_PICTURE_ASSET_H
+#define LIBDCP_PICTURE_ASSET_H
+
+/** @file  src/picture_asset.h
+ *  @brief PictureAsset class.
+ */
+
+#include "mxf.h"
+#include "util.h"
+#include "metadata.h"
+#include <openjpeg.h>
+
+namespace ASDCP {
+       namespace JP2K {
+               struct PictureDescriptor;
+       }
+}
+
+namespace dcp
+{
+
+class MonoPictureFrame;        
+class StereoPictureFrame;
+class PictureAssetWriter;
+
+/** @class PictureAsset
+ *  @brief An asset made up of JPEG2000 data.
+ */
+class PictureAsset : public Asset, public MXF
+{
+public:
+       PictureAsset (boost::filesystem::path file);
+       PictureAsset (Fraction edit_rate);
+
+       virtual boost::shared_ptr<PictureAssetWriter> start_write (
+               boost::filesystem::path file,
+               Standard standard,
+               bool overwrite
+               ) = 0;
+
+       Size size () const {
+               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;
+       }
+
+       void set_screen_aspect_ratio (Fraction r) {
+               _screen_aspect_ratio = r;
+       }
+
+       Fraction edit_rate () const {
+               return _edit_rate;
+       }
+
+       int64_t intrinsic_duration () const {
+               return _intrinsic_duration;
+       }
+
+protected:
+       friend class MonoPictureAssetWriter;
+       friend class StereoPictureAssetWriter;
+
+       bool frame_buffer_equals (
+               int frame, EqualityOptions opt, NoteHandler 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,
+               NoteHandler note
+               ) const;
+
+       void read_picture_descriptor (ASDCP::JP2K::PictureDescriptor const &);
+
+       Fraction _edit_rate;
+       /** The total length of this content in video frames.  The amount of
+        *  content presented may be less than this.
+        */
+       int64_t _intrinsic_duration;
+       /** picture size in pixels */
+       Size _size;
+       Fraction _frame_rate;
+       Fraction _screen_aspect_ratio;
+
+private:
+       std::string pkl_type (Standard standard) const;
+};
+       
+
+}
+
+#endif
diff --git a/src/picture_asset_writer.cc b/src/picture_asset_writer.cc
new file mode 100644 (file)
index 0000000..b47aaab
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+    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.
+
+*/
+
+#include "KM_fileio.h"
+#include "picture_asset_writer.h"
+#include "exceptions.h"
+#include "picture_asset.h"
+#include "AS_DCP.h"
+#include <inttypes.h>
+#include <stdint.h>
+
+using std::istream;
+using std::ostream;
+using std::string;
+using boost::shared_ptr;
+using namespace dcp;
+
+PictureAssetWriter::PictureAssetWriter (PictureAsset* asset, boost::filesystem::path file, Standard standard, bool overwrite)
+       : AssetWriter (asset, file)
+       , _picture_asset (asset)
+       , _started (false)
+       , _standard (standard)
+       , _overwrite (overwrite)
+{
+       asset->set_file (file);
+}
diff --git a/src/picture_asset_writer.h b/src/picture_asset_writer.h
new file mode 100644 (file)
index 0000000..48832e4
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+    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.
+
+*/
+
+/** @file  src/picture_asset_writer.h
+ *  @brief PictureAssetWriter and FrameInfo classes.
+ */
+
+#ifndef LIBDCP_PICTURE_ASSET_WRITER_H
+#define LIBDCP_PICTURE_ASSET_WRITER_H
+
+#include "metadata.h"
+#include "types.h"
+#include "asset_writer.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <stdint.h>
+#include <string>
+#include <fstream>
+
+namespace dcp {
+
+class PictureAsset;    
+
+/** @class FrameInfo
+ *  @brief Information about a single frame (either a monoscopic frame or a left *or* right eye stereoscopic frame)
+ */
+struct FrameInfo
+{
+       FrameInfo ()
+               : offset (0)
+               , size (0)
+       {}
+                 
+       FrameInfo (uint64_t o, uint64_t s, std::string h)
+               : offset (o)
+               , size (s)
+               , hash (h)
+       {}
+
+       uint64_t offset;
+       uint64_t size;
+       std::string hash;
+};
+
+/** @class PictureAssetWriter
+ *  @brief Parent class for classes which write picture assets.
+ */
+class PictureAssetWriter : public AssetWriter
+{
+public:
+       virtual FrameInfo write (uint8_t *, int) = 0;
+       virtual void fake_write (int) = 0;
+
+protected:
+       template <class P, class Q>
+       friend void start (PictureAssetWriter *, boost::shared_ptr<P>, Standard, Q *, uint8_t *, int);
+
+       PictureAssetWriter (PictureAsset *, boost::filesystem::path, Standard standard, bool);
+
+       PictureAsset* _picture_asset;
+       bool _started;
+       Standard _standard;
+       bool _overwrite;
+};
+
+}
+
+#endif
diff --git a/src/picture_asset_writer_common.cc b/src/picture_asset_writer_common.cc
new file mode 100644 (file)
index 0000000..b463cb4
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+    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.
+
+*/
+
+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;
+};
+
+template <class P, class Q>
+void dcp::start (PictureAssetWriter* writer, shared_ptr<P> state, Standard standard, 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().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, mxf->id(), standard);
+       
+       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;
+}
diff --git a/src/picture_mxf.cc b/src/picture_mxf.cc
deleted file mode 100644 (file)
index caa3d1a..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
-    Copyright (C) 2012-2015 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 "picture_mxf.h"
-#include "util.h"
-#include "exceptions.h"
-#include "xyz_image.h"
-#include "picture_mxf_writer.h"
-#include "dcp_assert.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 <list>
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-
-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 namespace dcp;
-
-PictureMXF::PictureMXF (boost::filesystem::path file)
-       : Asset (file)
-       , _intrinsic_duration (0)
-{
-
-}
-
-PictureMXF::PictureMXF (Fraction edit_rate)
-       : _edit_rate (edit_rate)
-       , _intrinsic_duration (0)
-{
-
-}
-
-void
-PictureMXF::read_picture_descriptor (ASDCP::JP2K::PictureDescriptor const & desc)
-{
-       _size.width = desc.StoredWidth;
-       _size.height = desc.StoredHeight;
-       _edit_rate = Fraction (desc.EditRate.Numerator, desc.EditRate.Denominator);
-       _intrinsic_duration = desc.ContainerDuration;
-       _frame_rate = Fraction (desc.SampleRate.Numerator, desc.SampleRate.Denominator);
-       _screen_aspect_ratio = Fraction (desc.AspectRatio.Numerator, desc.AspectRatio.Denominator);
-}
-
-bool
-PictureMXF::descriptor_equals (
-       ASDCP::JP2K::PictureDescriptor const & a, ASDCP::JP2K::PictureDescriptor const & b, NoteHandler 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 (DCP_ERROR, "video MXF picture descriptors differ");
-               return false;
-       }
-
-       if (a.ContainerDuration != b.ContainerDuration) {
-               note (DCP_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, NoteHandler 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 (DCP_NOTE, "J2K identical");
-               /* Easy result; the J2K data is identical */
-               return true;
-       }
-               
-       /* Decompress the images to bitmaps */
-       shared_ptr<XYZImage> image_A = decompress_j2k (const_cast<uint8_t*> (data_A), size_A, 0);
-       shared_ptr<XYZImage> 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 (DCP_ERROR, String::compose ("image sizes for frame %1 differ", frame));
-                       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 (DCP_NOTE, String::compose ("mean difference %1, deviation %2", mean, std_dev));
-       
-       if (mean > opt.max_mean_pixel_error) {
-               note (
-                       DCP_ERROR,
-                       String::compose ("mean %1 out of range %2 in frame %3", mean, opt.max_mean_pixel_error, frame)
-                       );
-               
-               return false;
-       }
-
-       if (std_dev > opt.max_std_dev_pixel_error) {
-               note (
-                       DCP_ERROR,
-                       String::compose ("standard deviation %1 out of range %2 in frame %3", std_dev, opt.max_std_dev_pixel_error, frame)
-                       );
-               
-               return false;
-       }
-
-       return true;
-}
-
-string
-PictureMXF::pkl_type (Standard standard) const
-{
-       switch (standard) {
-       case INTEROP:
-               return "application/x-smpte-mxf;asdcpKind=Picture";
-       case SMPTE:
-               return "application/mxf";
-       default:
-               DCP_ASSERT (false);
-       }
-}
diff --git a/src/picture_mxf.h b/src/picture_mxf.h
deleted file mode 100644 (file)
index c506651..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-    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.
-
-*/
-
-#ifndef LIBDCP_PICTURE_MXF_H
-#define LIBDCP_PICTURE_MXF_H
-
-/** @file  src/picture_mxf.h
- *  @brief PictureMXF class.
- */
-
-#include "mxf.h"
-#include "util.h"
-#include "metadata.h"
-#include <openjpeg.h>
-
-namespace ASDCP {
-       namespace JP2K {
-               struct PictureDescriptor;
-       }
-}
-
-namespace dcp
-{
-
-class MonoPictureFrame;        
-class StereoPictureFrame;
-class PictureMXFWriter;
-
-/** @class PictureMXF
- *  @brief An asset made up of JPEG2000 data.
- */
-class PictureMXF : public Asset, 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;
-
-       Size size () const {
-               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;
-       }
-
-       void set_screen_aspect_ratio (Fraction r) {
-               _screen_aspect_ratio = r;
-       }
-
-       Fraction edit_rate () const {
-               return _edit_rate;
-       }
-
-       int64_t intrinsic_duration () const {
-               return _intrinsic_duration;
-       }
-
-protected:
-       friend class MonoPictureMXFWriter;
-       friend class StereoPictureMXFWriter;
-
-       bool frame_buffer_equals (
-               int frame, EqualityOptions opt, NoteHandler 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,
-               NoteHandler note
-               ) const;
-
-       void read_picture_descriptor (ASDCP::JP2K::PictureDescriptor const &);
-
-       Fraction _edit_rate;
-       /** The total length of this content in video frames.  The amount of
-        *  content presented may be less than this.
-        */
-       int64_t _intrinsic_duration;
-       /** picture size in pixels */
-       Size _size;
-       Fraction _frame_rate;
-       Fraction _screen_aspect_ratio;
-
-private:
-       std::string pkl_type (Standard standard) const;
-};
-       
-
-}
-
-#endif
diff --git a/src/picture_mxf_writer.cc b/src/picture_mxf_writer.cc
deleted file mode 100644 (file)
index 4593c49..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-    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.
-
-*/
-
-#include "KM_fileio.h"
-#include "picture_mxf_writer.h"
-#include "exceptions.h"
-#include "picture_mxf.h"
-#include "AS_DCP.h"
-#include <inttypes.h>
-#include <stdint.h>
-
-using std::istream;
-using std::ostream;
-using std::string;
-using boost::shared_ptr;
-using namespace dcp;
-
-PictureMXFWriter::PictureMXFWriter (PictureMXF* mxf, boost::filesystem::path file, Standard standard, bool overwrite)
-       : MXFWriter (mxf, file)
-       , _picture_mxf (mxf)
-       , _started (false)
-       , _standard (standard)
-       , _overwrite (overwrite)
-{
-       mxf->set_file (file);
-}
diff --git a/src/picture_mxf_writer.h b/src/picture_mxf_writer.h
deleted file mode 100644 (file)
index 6626f8b..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-    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.
-
-*/
-
-/** @file  src/picture_mxf_writer.h
- *  @brief PictureMXFWriter and FrameInfo classes.
- */
-
-#ifndef LIBDCP_PICTURE_MXF_WRITER_H
-#define LIBDCP_PICTURE_MXF_WRITER_H
-
-#include "metadata.h"
-#include "types.h"
-#include "mxf_writer.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/utility.hpp>
-#include <stdint.h>
-#include <string>
-#include <fstream>
-
-namespace dcp {
-
-class PictureMXF;      
-
-/** @class FrameInfo
- *  @brief Information about a single frame (either a monoscopic frame or a left *or* right eye stereoscopic frame)
- */
-struct FrameInfo
-{
-       FrameInfo ()
-               : offset (0)
-               , size (0)
-       {}
-                 
-       FrameInfo (uint64_t o, uint64_t s, std::string h)
-               : offset (o)
-               , size (s)
-               , hash (h)
-       {}
-
-       uint64_t offset;
-       uint64_t size;
-       std::string hash;
-};
-
-/** @class PictureMXFWriter
- *  @brief Parent class for classes which write picture MXF files.
- */
-class PictureMXFWriter : public MXFWriter
-{
-public:
-       virtual FrameInfo write (uint8_t *, int) = 0;
-       virtual void fake_write (int) = 0;
-
-protected:
-       template <class P, class Q>
-       friend void start (PictureMXFWriter *, boost::shared_ptr<P>, Standard, Q *, uint8_t *, int);
-
-       PictureMXFWriter (PictureMXF *, boost::filesystem::path, Standard standard, bool);
-
-       PictureMXF* _picture_mxf;
-       bool _started;
-       Standard _standard;
-       bool _overwrite;
-};
-
-}
-
-#endif
diff --git a/src/picture_mxf_writer_common.cc b/src/picture_mxf_writer_common.cc
deleted file mode 100644 (file)
index b625d1f..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-    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.
-
-*/
-
-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;
-};
-
-template <class P, class Q>
-void dcp::start (PictureMXFWriter* writer, shared_ptr<P> state, Standard standard, 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().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, mxf->id(), standard);
-       
-       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;
-}
index 3a046297b2648d69f20a1588a480807a0f533078..106fbf40613519a2747f692cb917510d8304b24f 100644 (file)
 
 #include "reel.h"
 #include "util.h"
-#include "picture_mxf.h"
-#include "mono_picture_mxf.h"
-#include "stereo_picture_mxf.h"
-#include "sound_mxf.h"
+#include "picture_asset.h"
+#include "mono_picture_asset.h"
+#include "stereo_picture_asset.h"
+#include "sound_asset.h"
 #include "subtitle_asset.h"
 #include "reel_mono_picture_asset.h"
 #include "reel_stereo_picture_asset.h"
@@ -140,10 +140,10 @@ Reel::add (DecryptedKDM const & kdm)
 
        for (list<DecryptedKDMKey>::iterator i = keys.begin(); i != keys.end(); ++i) {
                if (i->id() == _main_picture->key_id()) {
-                       _main_picture->mxf()->set_key (i->key ());
+                       _main_picture->asset()->set_key (i->key ());
                }
                if (i->id() == _main_sound->key_id()) {
-                       _main_sound->mxf()->set_key (i->key ());
+                       _main_sound->asset()->set_key (i->key ());
                }
        }
 }
@@ -167,14 +167,14 @@ void
 Reel::resolve_refs (list<shared_ptr<Object> > objects)
 {
        if (_main_picture) {
-               _main_picture->asset().resolve (objects);
+               _main_picture->asset_ref().resolve (objects);
        }
 
        if (_main_sound) {
-               _main_sound->asset().resolve (objects);
+               _main_sound->asset_ref().resolve (objects);
        }
 
        if (_main_subtitle) {
-               _main_subtitle->asset().resolve (objects);
+               _main_subtitle->asset_ref().resolve (objects);
        }
 }
index 7f129f906afc0488ecfa45af68e62424f6a348d0..d56a492b837ee225edbc35fddae390f128091c33 100644 (file)
@@ -33,7 +33,7 @@ using namespace dcp;
 
 ReelAsset::ReelAsset ()
        : Object (make_uuid ())
-       , _asset (_id)
+       , _asset_ref (_id)
        , _edit_rate (Fraction (24, 1))
        , _intrinsic_duration (0)
        , _entry_point (0)
@@ -50,7 +50,7 @@ ReelAsset::ReelAsset ()
  */
 ReelAsset::ReelAsset (shared_ptr<Asset> asset, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point)
        : Object (asset->id ())
-       , _asset (asset)
+       , _asset_ref (asset)
        , _edit_rate (edit_rate)
        , _intrinsic_duration (intrinsic_duration)
        , _entry_point (entry_point)
@@ -63,7 +63,7 @@ ReelAsset::ReelAsset (shared_ptr<Asset> asset, Fraction edit_rate, int64_t intri
 
 ReelAsset::ReelAsset (shared_ptr<const cxml::Node> node)
        : Object (node->string_child ("Id"))
-       , _asset (_id)
+       , _asset_ref (_id)
        , _annotation_text (node->optional_string_child ("AnnotationText").get_value_or (""))
        , _edit_rate (Fraction (node->string_child ("EditRate")))
        , _intrinsic_duration (node->number_child<int64_t> ("IntrinsicDuration"))
@@ -73,7 +73,7 @@ ReelAsset::ReelAsset (shared_ptr<const cxml::Node> node)
 {
        if (_id.length() > 9) {
                _id = _id.substr (9);
-               _asset.set_id (_id);
+               _asset_ref.set_id (_id);
        }
 }
 
@@ -91,7 +91,7 @@ ReelAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
         a->add_child("IntrinsicDuration")->add_child_text (raw_convert<string> (_intrinsic_duration));
         a->add_child("EntryPoint")->add_child_text (raw_convert<string> (_entry_point));
         a->add_child("Duration")->add_child_text (raw_convert<string> (_duration));
-       a->add_child("Hash")->add_child_text (_asset.object()->hash ());
+       a->add_child("Hash")->add_child_text (_asset_ref.object()->hash ());
 }
 
 pair<string, string>
@@ -143,8 +143,8 @@ ReelAsset::equals (shared_ptr<const ReelAsset> other, EqualityOptions opt, NoteH
                }
        }
 
-       if (_asset.resolved () && other->_asset.resolved ()) {
-               return _asset->equals (other->_asset.object (), opt, note);
+       if (_asset_ref.resolved () && other->_asset_ref.resolved ()) {
+               return _asset_ref->equals (other->_asset_ref.object (), opt, note);
        }
 
        return true;
index 7588c063f349256da6d3c2a22a9e244442e4e285..118f10a126bc50ccc98bce98337c00db4fa78f57 100644 (file)
@@ -55,8 +55,8 @@ public:
        virtual bool equals (boost::shared_ptr<const ReelAsset>, EqualityOptions, NoteHandler) const;
 
        /** @return a Ref to our actual asset */
-       Ref<Asset>& asset () {
-               return _asset;
+       Ref<Asset>& asset_ref () {
+               return _asset_ref;
        }
 
        int64_t entry_point () const {
@@ -81,7 +81,7 @@ protected:
        /** Reference to the asset (MXF or XML file) that this reel entry
         *  applies to.
         */
-       Ref<Asset> _asset;
+       Ref<Asset> _asset_ref;
 
 private:
        
index b4ed6301615b30e591c68c00bf9f4ebd7fccf7ff..d41cc2ac1ceb72261f7650a6e749955fc183109e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2015 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
@@ -22,7 +22,7 @@
  */
 
 #include "reel_mono_picture_asset.h"
-#include "mono_picture_mxf.h"
+#include "mono_picture_asset.h"
 #include <libcxml/cxml.h>
 
 using std::string;
@@ -34,8 +34,8 @@ ReelMonoPictureAsset::ReelMonoPictureAsset ()
 
 }
 
-ReelMonoPictureAsset::ReelMonoPictureAsset (boost::shared_ptr<MonoPictureMXF> mxf, int64_t entry_point)
-       : ReelPictureAsset (mxf, entry_point)
+ReelMonoPictureAsset::ReelMonoPictureAsset (boost::shared_ptr<MonoPictureAsset> asset, int64_t entry_point)
+       : ReelPictureAsset (asset, entry_point)
 {
 
 }
index a25550a4132e957b0cf47f5823332f4307342c03..5fcb31c8caa570210d11ce28a57d0de3e6db9eb5 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2015 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
 
 namespace dcp {
 
-class MonoPictureMXF;  
+class MonoPictureAsset;        
 
 /** @class ReelMonoPictureAsset
- *  @brief Part of a Reel's description which refers to a monoscopic picture MXF.
+ *  @brief Part of a Reel's description which refers to a monoscopic picture asset.
  */
 class ReelMonoPictureAsset : public ReelPictureAsset
 {
 public:
        ReelMonoPictureAsset ();
-       ReelMonoPictureAsset (boost::shared_ptr<MonoPictureMXF> content, int64_t entry_point);
+       ReelMonoPictureAsset (boost::shared_ptr<MonoPictureAsset> asset, int64_t entry_point);
        ReelMonoPictureAsset (boost::shared_ptr<const cxml::Node>);
 
 private:
index c9637549d88d7e7fa498e3aea9f31ca4fa680182..2dc3af731df116d9f0ef135a7c9252d7f6158c02 100644 (file)
@@ -37,7 +37,7 @@ class ReelMXFAsset : public ReelAsset
 {
 public:
        ReelMXFAsset ();
-       ReelMXFAsset (boost::shared_ptr<Asset> mxf, boost::optional<std::string> key_id, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point);
+       ReelMXFAsset (boost::shared_ptr<Asset> asset, boost::optional<std::string> key_id, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point);
        ReelMXFAsset (boost::shared_ptr<const cxml::Node>);
 
        /** @return the 4-character key type for this MXF (MDIK, MDAK, etc.) */
index d222095cb264f1c4e57d203f192c0d680d96ed11..fd18dc3015d7bc1827ba1b9577c8f386804d3977 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 #include "reel_picture_asset.h"
-#include "picture_mxf.h"
+#include "picture_asset.h"
 #include "dcp_assert.h"
 #include "compose.hpp"
 #include <libcxml/cxml.h>
@@ -43,7 +43,7 @@ ReelPictureAsset::ReelPictureAsset ()
 
 }
 
-ReelPictureAsset::ReelPictureAsset (shared_ptr<PictureMXF> asset, int64_t entry_point)
+ReelPictureAsset::ReelPictureAsset (shared_ptr<PictureAsset> asset, int64_t entry_point)
        : ReelMXFAsset (asset, asset->key_id(), asset->edit_rate(), asset->intrinsic_duration(), entry_point)
        , _frame_rate (asset->frame_rate ())
        , _screen_aspect_ratio (asset->screen_aspect_ratio ())
index fd4d11fce33a2e1b047ca398d67707d57b97e3a6..a41cd9d2c390dd481a5b151cecddce97eaeec83c 100644 (file)
 #define LIBDCP_REEL_PICTURE_ASSET_H
 
 #include "reel_mxf_asset.h"
-#include "picture_mxf.h"
+#include "picture_asset.h"
 
 namespace dcp {
 
 /** @class ReelPictureAsset
- *  @brief Part of a Reel's description which refers to a picture MXF.
+ *  @brief Part of a Reel's description which refers to a picture asset.
  */
 class ReelPictureAsset : public ReelMXFAsset
 {
 public:
        ReelPictureAsset ();
-       ReelPictureAsset (boost::shared_ptr<PictureMXF> asset, int64_t entry_point);
+       ReelPictureAsset (boost::shared_ptr<PictureAsset> asset, int64_t entry_point);
        ReelPictureAsset (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, NoteHandler) const;
 
-       /** @return the PictureMXF that this object refers to */
-       boost::shared_ptr<PictureMXF> mxf () {
-               return boost::dynamic_pointer_cast<PictureMXF> (_asset.object ());
+       /** @return the PictureAsset that this object refers to */
+       boost::shared_ptr<PictureAsset> asset () {
+               return boost::dynamic_pointer_cast<PictureAsset> (_asset_ref.object ());
        }
 
        /** @return picture frame rate */
index 504d376ddf9d30dba364d01f8d6aaaa2c67b31dd..b3ca5234f6d13e880bda39f785825ea7ec4a1dbc 100644 (file)
@@ -29,7 +29,7 @@ using std::string;
 using boost::shared_ptr;
 using namespace dcp;
 
-ReelSoundAsset::ReelSoundAsset (shared_ptr<SoundMXF> asset, int64_t entry_point)
+ReelSoundAsset::ReelSoundAsset (shared_ptr<SoundAsset> asset, int64_t entry_point)
        : ReelMXFAsset (asset, asset->key_id(), asset->edit_rate(), asset->intrinsic_duration(), entry_point)
 {
 
index 9266742944d061c89bbb3c8b6b5930da3a06f65f..d7eee59d8301f96ef6219b06ba9aea1c0a3699c8 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 #include "reel_mxf_asset.h"
-#include "sound_mxf.h"
+#include "sound_asset.h"
 #include <boost/shared_ptr.hpp>
 #include <string>
 
@@ -34,19 +34,19 @@ namespace dcp {
 class ReelSoundAsset : public ReelMXFAsset
 {
 public:
-       ReelSoundAsset (boost::shared_ptr<dcp::SoundMXF> content, int64_t entry_point);
+       ReelSoundAsset (boost::shared_ptr<dcp::SoundAsset> content, int64_t entry_point);
        ReelSoundAsset (boost::shared_ptr<const cxml::Node>);
 
        void write_to_cpl (xmlpp::Node* node, Standard standard) const;
 
-       /** @return the SoundMXF that this object refers to */
-       boost::shared_ptr<SoundMXF> mxf () {
-               return boost::dynamic_pointer_cast<SoundMXF> (_asset.object ());
+       /** @return the SoundAsset that this object refers to */
+       boost::shared_ptr<SoundAsset> asset () {
+               return boost::dynamic_pointer_cast<SoundAsset> (_asset_ref.object ());
        }
 
-       /** @return the SoundMXF that this object refers to */
-       boost::shared_ptr<const SoundMXF> mxf () const {
-               return boost::dynamic_pointer_cast<const SoundMXF> (_asset.object ());
+       /** @return the SoundAsset that this object refers to */
+       boost::shared_ptr<const SoundAsset> asset () const {
+               return boost::dynamic_pointer_cast<const SoundAsset> (_asset_ref.object ());
        }
        
 private:
index 09178dc20c57846e36a0a008808a7d63e9f38404..e6e17f63549c82f72056b6f408b70fcb98c02eca 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 #include "reel_stereo_picture_asset.h"
-#include "stereo_picture_mxf.h"
+#include "stereo_picture_asset.h"
 #include <libcxml/cxml.h>
 
 using std::string;
@@ -36,7 +36,7 @@ ReelStereoPictureAsset::ReelStereoPictureAsset ()
 
 }
 
-ReelStereoPictureAsset::ReelStereoPictureAsset (boost::shared_ptr<StereoPictureMXF> mxf, int64_t entry_point)
+ReelStereoPictureAsset::ReelStereoPictureAsset (boost::shared_ptr<StereoPictureAsset> mxf, int64_t entry_point)
        : ReelPictureAsset (mxf, entry_point)
 {
 
index 57cc4da15e07b5a11f18f99e6def9122c9f99c18..df939a9c7fba837d672f342781a6b06af182f185 100644 (file)
@@ -28,7 +28,7 @@
 
 namespace dcp {
 
-class StereoPictureMXF;        
+class StereoPictureAsset;      
 
 /** @class ReelStereoPictureAsset
  *  @brief Part of a Reel's description which refers to a stereoscopic picture MXF.
@@ -37,7 +37,7 @@ class ReelStereoPictureAsset : public ReelPictureAsset
 {
 public:
        ReelStereoPictureAsset ();
-       ReelStereoPictureAsset (boost::shared_ptr<StereoPictureMXF> content, int64_t entry_point);
+       ReelStereoPictureAsset (boost::shared_ptr<StereoPictureAsset> content, int64_t entry_point);
        ReelStereoPictureAsset (boost::shared_ptr<const cxml::Node>);
 
 private:
index f296fdc64da75755e72c8a886b622392e3b42020..55881f7ea44c6c7468ffb13846d0bc16b82da9ae 100644 (file)
@@ -41,7 +41,7 @@ public:
        ReelSubtitleAsset (boost::shared_ptr<const cxml::Node>);
 
        boost::shared_ptr<SubtitleAsset> subtitle_asset () const {
-               return boost::dynamic_pointer_cast<SubtitleAsset> (_asset.object ());
+               return boost::dynamic_pointer_cast<SubtitleAsset> (_asset_ref.object ());
        }
 
 private:       
diff --git a/src/sound_asset.cc b/src/sound_asset.cc
new file mode 100644 (file)
index 0000000..3d23b42
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+    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.
+
+*/
+
+/** @file  src/sound_mxf.cc
+ *  @brief SoundAsset class.
+ */
+
+#include "sound_asset.h"
+#include "util.h"
+#include "exceptions.h"
+#include "sound_frame.h"
+#include "sound_asset_writer.h"
+#include "compose.hpp"
+#include "KM_fileio.h"
+#include "AS_DCP.h"
+#include "dcp_assert.h"
+#include <libxml++/nodes/element.h>
+#include <boost/filesystem.hpp>
+#include <iostream>
+#include <stdexcept>
+
+using std::string;
+using std::stringstream;
+using std::ostream;
+using std::vector;
+using std::list;
+using boost::shared_ptr;
+using namespace dcp;
+
+SoundAsset::SoundAsset (boost::filesystem::path file)
+       : Asset (file)
+{
+       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 = 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"));
+       }
+
+       _id = read_writer_info (info);
+}
+
+SoundAsset::SoundAsset (Fraction edit_rate, int sampling_rate, int channels)
+       : _edit_rate (edit_rate)
+       , _intrinsic_duration (0)
+       , _channels (channels)
+       , _sampling_rate (sampling_rate)
+{
+
+}
+
+bool
+SoundAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, NoteHandler note) const
+{
+       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 (DCP_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 (DCP_ERROR, String::compose ("sizes of audio data for frame %1 differ", i));
+                       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 (DCP_ERROR, String::compose ("PCM data difference of %1", 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 (file(), n, _decryption_context));
+}
+
+shared_ptr<SoundAssetWriter>
+SoundAsset::start_write (boost::filesystem::path file, Standard standard)
+{
+       /* XXX: can't we use a shared_ptr here? */
+       return shared_ptr<SoundAssetWriter> (new SoundAssetWriter (this, file, standard));
+}
+
+string
+SoundAsset::pkl_type (Standard standard) const
+{
+       switch (standard) {
+       case INTEROP:
+               return "application/x-smpte-mxf;asdcpKind=Sound";
+       case SMPTE:
+               return "application/mxf";
+       default:
+               DCP_ASSERT (false);
+       }
+}
diff --git a/src/sound_asset.h b/src/sound_asset.h
new file mode 100644 (file)
index 0000000..5a7dc21
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+    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.
+
+*/
+
+/** @file  src/sound_asset.h
+ *  @brief SoundAsset class
+ */
+
+#ifndef LIBDCP_SOUND_ASSET_H
+#define LIBDCP_SOUND_ASSET_H
+
+#include "mxf.h"
+#include "types.h"
+#include "metadata.h"
+
+namespace dcp
+{
+
+class SoundFrame;
+class SoundAssetWriter;
+
+/** @class SoundAsset
+ *  @brief Representation of a sound asset
+ */
+class SoundAsset : public Asset, public MXF
+{
+public:
+       SoundAsset (boost::filesystem::path file);
+       SoundAsset (Fraction edit_rate, int sampling_rate, int channels);
+
+       boost::shared_ptr<SoundAssetWriter> start_write (boost::filesystem::path file, Standard standard);
+       
+       bool equals (
+               boost::shared_ptr<const Asset> other,
+               EqualityOptions opt,
+               NoteHandler note
+               ) const;
+
+       boost::shared_ptr<const SoundFrame> get_frame (int n) const;
+
+       /** @return number of channels */
+       int channels () const {
+               return _channels;
+       }
+
+       /** @return sampling rate in Hz */
+       int sampling_rate () const {
+               return _sampling_rate;
+       }
+
+       Fraction edit_rate () const {
+               return _edit_rate;
+       }
+
+       int64_t intrinsic_duration () const {
+               return _intrinsic_duration;
+       }
+       
+private:
+       friend class SoundAssetWriter;
+       
+       std::string pkl_type (Standard standard) const;
+
+       Fraction _edit_rate;
+       /** The total length of this content in video frames.  The amount of
+        *  content presented may be less than this.
+        */
+       int64_t _intrinsic_duration;
+       int _channels;      ///< number of channels
+       int _sampling_rate; ///< sampling rate in Hz
+};
+
+}
+
+#endif
diff --git a/src/sound_asset_writer.cc b/src/sound_asset_writer.cc
new file mode 100644 (file)
index 0000000..8d302ed
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+    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.
+
+*/
+
+#include "sound_asset_writer.h"
+#include "sound_asset.h"
+#include "exceptions.h"
+#include "dcp_assert.h"
+#include "compose.hpp"
+#include "AS_DCP.h"
+
+using namespace dcp;
+
+struct SoundAssetWriter::ASDCPState
+{
+       ASDCP::PCM::MXFWriter mxf_writer;
+       ASDCP::PCM::FrameBuffer frame_buffer;
+       ASDCP::WriterInfo writer_info;
+       ASDCP::PCM::AudioDescriptor audio_desc;
+};
+
+SoundAssetWriter::SoundAssetWriter (SoundAsset* asset, boost::filesystem::path file, Standard standard)
+       : AssetWriter (asset, file)
+       , _state (new SoundAssetWriter::ASDCPState)
+       , _sound_asset (asset)
+       , _frame_buffer_offset (0)
+{
+       /* Derived from ASDCP::Wav::SimpleWaveHeader::FillADesc */
+       _state->audio_desc.EditRate = ASDCP::Rational (_sound_asset->edit_rate().numerator, _sound_asset->edit_rate().denominator);
+       _state->audio_desc.AudioSamplingRate = ASDCP::Rational (_sound_asset->sampling_rate(), 1);
+       _state->audio_desc.Locked = 0;
+       _state->audio_desc.ChannelCount = _sound_asset->channels ();
+       _state->audio_desc.QuantizationBits = 24;
+       _state->audio_desc.BlockAlign = 3 * _sound_asset->channels();
+       _state->audio_desc.AvgBps = _sound_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());
+       
+       _sound_asset->fill_writer_info (&_state->writer_info, _sound_asset->id(), standard);
+       
+       Kumu::Result_t r = _state->mxf_writer.OpenWrite (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", file.string(), r));
+       }
+
+       _sound_asset->set_file (file);
+}
+
+void
+SoundAssetWriter::write (float const * const * data, int frames)
+{
+       DCP_ASSERT (!_finalized);
+       
+       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 < _sound_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 * _sound_asset->channels();
+
+               DCP_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, _encryption_context, 0);
+       if (ASDCP_FAILURE (r)) {
+               boost::throw_exception (MiscError (String::compose ("could not write audio MXF frame (%1)", 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"));
+       }
+
+       _sound_asset->_intrinsic_duration = _frames_written;
+       AssetWriter::finalize ();
+}
diff --git a/src/sound_asset_writer.h b/src/sound_asset_writer.h
new file mode 100644 (file)
index 0000000..8c54b61
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+    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.
+
+*/
+
+/** @file  src/sound_asset_writer.h
+ *  @brief SoundAssetWriter class.
+ */
+
+#include "asset_writer.h"
+#include "types.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/filesystem.hpp>
+
+namespace dcp {
+
+class SoundFrame;
+class SoundAsset;
+
+/** @class SoundAssetWriter
+ *  @brief A helper class for writing to SoundAssets.
+ *
+ *  Objects of this class can only be created with SoundAsset::start_write().
+ *
+ *  Sound samples can be written to the SoundAsset by calling write() with
+ *  a buffer of float values.  finalize() must be called after the last samples
+ *  have been written.
+ */
+class SoundAssetWriter : public AssetWriter
+{
+public:
+       void write (float const * const *, int);
+       void finalize ();
+
+private:
+       friend class SoundAsset;
+
+       SoundAssetWriter (SoundAsset *, boost::filesystem::path, Standard standard);
+
+       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* _sound_asset;
+       int _frame_buffer_offset;
+};
+
+}
+
index c79b29b36a576117600348e97c7a70073e922315..166ac584aaffd860d0c5b6b3be6f944d28f19b85 100644 (file)
 using namespace std;
 using namespace dcp;
 
-SoundFrame::SoundFrame (boost::filesystem::path mxf_path, int n, ASDCP::AESDecContext* c)
+SoundFrame::SoundFrame (boost::filesystem::path path, int n, ASDCP::AESDecContext* c)
 {
        ASDCP::PCM::MXFReader reader;
-       Kumu::Result_t r = reader.OpenRead (mxf_path.string().c_str());
+       Kumu::Result_t r = reader.OpenRead (path.string().c_str());
        if (ASDCP_FAILURE (r)) {
-               boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path, r));
+               boost::throw_exception (FileError ("could not open MXF file for reading", path, r));
        }
 
        /* XXX: unfortunate guesswork on this buffer size */
index 26f738d3524c72156a51221864b3d0d6bb20d44c..8b53dd71edfb556a9845f6ec9ab374ec104f0995 100644 (file)
@@ -44,7 +44,7 @@ namespace dcp {
 class SoundFrame : public boost::noncopyable
 {
 public:
-       SoundFrame (boost::filesystem::path mxf_path, int n, ASDCP::AESDecContext *);
+       SoundFrame (boost::filesystem::path path, int n, ASDCP::AESDecContext *);
        ~SoundFrame ();
 
        uint8_t const * data () const;
diff --git a/src/sound_mxf.cc b/src/sound_mxf.cc
deleted file mode 100644 (file)
index 19a30bf..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
-    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.
-
-*/
-
-/** @file  src/sound_mxf.cc
- *  @brief SoundMXF class.
- */
-
-#include "sound_mxf.h"
-#include "util.h"
-#include "exceptions.h"
-#include "sound_frame.h"
-#include "sound_mxf_writer.h"
-#include "compose.hpp"
-#include "KM_fileio.h"
-#include "AS_DCP.h"
-#include "dcp_assert.h"
-#include <libxml++/nodes/element.h>
-#include <boost/filesystem.hpp>
-#include <iostream>
-#include <stdexcept>
-
-using std::string;
-using std::stringstream;
-using std::ostream;
-using std::vector;
-using std::list;
-using boost::shared_ptr;
-using namespace dcp;
-
-SoundMXF::SoundMXF (boost::filesystem::path file)
-       : Asset (file)
-       , _intrinsic_duration (0)
-       , _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 = 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"));
-       }
-
-       _id = read_writer_info (info);
-}
-
-SoundMXF::SoundMXF (Fraction edit_rate, int sampling_rate, int channels)
-       : _edit_rate (edit_rate)
-       , _intrinsic_duration (0)
-       , _channels (channels)
-       , _sampling_rate (sampling_rate)
-{
-
-}
-
-bool
-SoundMXF::equals (shared_ptr<const Asset> other, EqualityOptions opt, NoteHandler note) const
-{
-       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 (DCP_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 (DCP_ERROR, String::compose ("sizes of audio data for frame %1 differ", i));
-                       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 (DCP_ERROR, String::compose ("PCM data difference of %1", 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(), n, _decryption_context));
-}
-
-shared_ptr<SoundMXFWriter>
-SoundMXF::start_write (boost::filesystem::path file, Standard standard)
-{
-       /* XXX: can't we use a shared_ptr here? */
-       return shared_ptr<SoundMXFWriter> (new SoundMXFWriter (this, file, standard));
-}
-
-string
-SoundMXF::pkl_type (Standard standard) const
-{
-       switch (standard) {
-       case INTEROP:
-               return "application/x-smpte-mxf;asdcpKind=Sound";
-       case SMPTE:
-               return "application/mxf";
-       default:
-               DCP_ASSERT (false);
-       }
-}
diff --git a/src/sound_mxf.h b/src/sound_mxf.h
deleted file mode 100644 (file)
index ed0a60d..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-    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.
-
-*/
-
-/** @file  src/sound_mxf.h
- *  @brief SoundMXF class
- */
-
-#ifndef LIBDCP_SOUND_MXF_H
-#define LIBDCP_SOUND_MXF_H
-
-#include "mxf.h"
-#include "types.h"
-#include "metadata.h"
-
-namespace dcp
-{
-
-class SoundFrame;
-class SoundMXFWriter;
-
-/** @class SoundMXF
- *  @brief Representation of a MXF file containing sound
- */
-class SoundMXF : public Asset, public MXF
-{
-public:
-       SoundMXF (boost::filesystem::path file);
-       SoundMXF (Fraction edit_rate, int sampling_rate, int channels);
-
-       boost::shared_ptr<SoundMXFWriter> start_write (boost::filesystem::path file, Standard standard);
-       
-       bool equals (
-               boost::shared_ptr<const Asset> other,
-               EqualityOptions opt,
-               NoteHandler note
-               ) const;
-
-       boost::shared_ptr<const SoundFrame> get_frame (int n) const;
-
-       /** @return number of channels */
-       int channels () const {
-               return _channels;
-       }
-
-       /** @return sampling rate in Hz */
-       int sampling_rate () const {
-               return _sampling_rate;
-       }
-
-       Fraction edit_rate () const {
-               return _edit_rate;
-       }
-
-       int64_t intrinsic_duration () const {
-               return _intrinsic_duration;
-       }
-       
-private:
-       friend class SoundMXFWriter;
-       
-       std::string pkl_type (Standard standard) const;
-
-       Fraction _edit_rate;
-       /** The total length of this content in video frames.  The amount of
-        *  content presented may be less than this.
-        */
-       int64_t _intrinsic_duration;
-       int _channels;      ///< number of channels
-       int _sampling_rate; ///< sampling rate in Hz
-};
-
-}
-
-#endif
diff --git a/src/sound_mxf_writer.cc b/src/sound_mxf_writer.cc
deleted file mode 100644 (file)
index 71b72aa..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-    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.
-
-*/
-
-#include "sound_mxf_writer.h"
-#include "sound_mxf.h"
-#include "exceptions.h"
-#include "dcp_assert.h"
-#include "compose.hpp"
-#include "AS_DCP.h"
-
-using namespace dcp;
-
-struct SoundMXFWriter::ASDCPState
-{
-       ASDCP::PCM::MXFWriter mxf_writer;
-       ASDCP::PCM::FrameBuffer frame_buffer;
-       ASDCP::WriterInfo writer_info;
-       ASDCP::PCM::AudioDescriptor audio_desc;
-};
-
-SoundMXFWriter::SoundMXFWriter (SoundMXF* m, boost::filesystem::path file, Standard standard)
-       : MXFWriter (m, file)
-       , _state (new SoundMXFWriter::ASDCPState)
-       , _sound_mxf (m)
-       , _frame_buffer_offset (0)
-{
-       /* Derived from ASDCP::Wav::SimpleWaveHeader::FillADesc */
-       _state->audio_desc.EditRate = ASDCP::Rational (_sound_mxf->edit_rate().numerator, _sound_mxf->edit_rate().denominator);
-       _state->audio_desc.AudioSamplingRate = ASDCP::Rational (_sound_mxf->sampling_rate(), 1);
-       _state->audio_desc.Locked = 0;
-       _state->audio_desc.ChannelCount = _sound_mxf->channels ();
-       _state->audio_desc.QuantizationBits = 24;
-       _state->audio_desc.BlockAlign = 3 * _sound_mxf->channels();
-       _state->audio_desc.AvgBps = _sound_mxf->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());
-       
-       _sound_mxf->fill_writer_info (&_state->writer_info, _sound_mxf->id(), standard);
-       
-       Kumu::Result_t r = _state->mxf_writer.OpenWrite (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", file.string(), r));
-       }
-
-       _sound_mxf->set_file (file);
-}
-
-void
-SoundMXFWriter::write (float const * const * data, int frames)
-{
-       DCP_ASSERT (!_finalized);
-       
-       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 < _sound_mxf->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 * _sound_mxf->channels();
-
-               DCP_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, _encryption_context, 0);
-       if (ASDCP_FAILURE (r)) {
-               boost::throw_exception (MiscError (String::compose ("could not write audio MXF frame (%1)", 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"));
-       }
-
-       _sound_mxf->_intrinsic_duration = _frames_written;
-       MXFWriter::finalize ();
-}
diff --git a/src/sound_mxf_writer.h b/src/sound_mxf_writer.h
deleted file mode 100644 (file)
index d79c60d..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-    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.
-
-*/
-
-/** @file  src/sound_mxf_writer.h
- *  @brief SoundMXFWriter class.
- */
-
-#include "mxf_writer.h"
-#include "types.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/filesystem.hpp>
-
-namespace dcp {
-
-class SoundFrame;
-class SoundMXF;
-
-/** @class SoundMXFWriter
- *  @brief A helper class for writing to SoundMXFs.
- *
- *  Objects of this class can only be created with SoundMXF::start_write().
- *
- *  Sound samples can be written to the SoundMXF by calling write() with
- *  a buffer of float values.  finalize() must be called after the last samples
- *  have been written.
- */
-class SoundMXFWriter : public MXFWriter
-{
-public:
-       void write (float const * const *, int);
-       void finalize ();
-
-private:
-       friend class SoundMXF;
-
-       SoundMXFWriter (SoundMXF *, boost::filesystem::path, Standard standard);
-
-       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* _sound_mxf;
-       int _frame_buffer_offset;
-};
-
-}
-
diff --git a/src/stereo_picture_asset.cc b/src/stereo_picture_asset.cc
new file mode 100644 (file)
index 0000000..452c367
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+    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.
+
+*/
+
+#include "AS_DCP.h"
+#include "stereo_picture_asset.h"
+#include "stereo_picture_frame.h"
+#include "exceptions.h"
+#include "stereo_picture_asset_writer.h"
+#include "dcp_assert.h"
+
+using std::string;
+using std::pair;
+using std::make_pair;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using namespace dcp;
+
+StereoPictureAsset::StereoPictureAsset (boost::filesystem::path file)
+       : PictureAsset (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"));
+       }
+
+       read_picture_descriptor (desc);
+
+       ASDCP::WriterInfo info;
+       if (ASDCP_FAILURE (reader.FillWriterInfo (info))) {
+               boost::throw_exception (DCPReadError ("could not read video MXF information"));
+       }
+
+       _id = read_writer_info (info);
+}
+
+StereoPictureAsset::StereoPictureAsset (Fraction edit_rate)
+       : PictureAsset
+         (edit_rate)
+{
+
+}
+
+shared_ptr<const StereoPictureFrame>
+StereoPictureAsset::get_frame (int n) const
+{
+       return shared_ptr<const StereoPictureFrame> (new StereoPictureFrame (file().string(), n));
+}
+
+shared_ptr<PictureAssetWriter>
+StereoPictureAsset::start_write (boost::filesystem::path file, Standard standard, bool overwrite)
+{
+       return shared_ptr<StereoPictureAssetWriter> (new StereoPictureAssetWriter (this, file, standard, overwrite));
+}
+
+bool
+StereoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, NoteHandler note) const
+{
+       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 StereoPictureAsset> other_picture = dynamic_pointer_cast<const StereoPictureAsset> (other);
+       DCP_ASSERT (other_picture);
+
+       for (int i = 0; i < _intrinsic_duration; ++i) {
+               shared_ptr<const StereoPictureFrame> frame_A;
+               shared_ptr<const StereoPictureFrame> frame_B;
+               try {
+                       frame_A = get_frame (i);
+                       frame_B = other_picture->get_frame (i);
+               } catch (DCPReadError& e) {
+                       /* If there was a problem reading the frame data we'll just assume
+                          the two frames are not equal.
+                       */
+                       note (DCP_ERROR, e.what ());
+                       return false;
+               }
+               
+               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;
+}
diff --git a/src/stereo_picture_asset.h b/src/stereo_picture_asset.h
new file mode 100644 (file)
index 0000000..2fe893d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+    Copyright (C) 2012-2015 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 dcp {
+       
+/** A 3D (stereoscopic) picture asset */       
+class StereoPictureAsset : public PictureAsset
+{
+public:
+       StereoPictureAsset (boost::filesystem::path file);
+       StereoPictureAsset (Fraction edit_rate);
+
+       /** Start a progressive write to a StereoPictureAsset */
+       boost::shared_ptr<PictureAssetWriter> start_write (boost::filesystem::path file, Standard, bool);
+
+       bool equals (
+               boost::shared_ptr<const Asset> other,
+               EqualityOptions opt,
+               NoteHandler note
+               ) const;
+       
+       boost::shared_ptr<const StereoPictureFrame> get_frame (int n) const;
+};
+
+}
+
+#endif
diff --git a/src/stereo_picture_asset_writer.cc b/src/stereo_picture_asset_writer.cc
new file mode 100644 (file)
index 0000000..be265d1
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+    Copyright (C) 2012-2015 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 "stereo_picture_asset_writer.h"
+#include "exceptions.h"
+#include "dcp_assert.h"
+#include "picture_asset.h"
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+
+#include "picture_asset_writer_common.cc"
+
+using std::istream;
+using std::ostream;
+using std::string;
+using boost::shared_ptr;
+using namespace dcp;
+
+struct StereoPictureAssetWriter::ASDCPState : public ASDCPStateBase
+{
+       ASDCP::JP2K::MXFSWriter mxf_writer;
+};
+
+StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* mxf, boost::filesystem::path file, Standard standard, bool overwrite)
+       : PictureAssetWriter (mxf, file, standard, overwrite)
+       , _state (new StereoPictureAssetWriter::ASDCPState)
+       , _next_eye (EYE_LEFT)
+{
+
+}
+
+void
+StereoPictureAssetWriter::start (uint8_t* data, int size)
+{
+       dcp::start (this, _state, _standard, _picture_asset, data, size);
+       _picture_asset->set_frame_rate (Fraction (_picture_asset->edit_rate().numerator * 2, _picture_asset->edit_rate().denominator));
+}
+
+/** 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)
+{
+       DCP_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,
+               _encryption_context,
+               0,
+               &hash
+               );
+
+       if (ASDCP_FAILURE (r)) {
+               boost::throw_exception (MXFFileError ("error in writing video MXF", _file.string(), r));
+       }
+
+       _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
+
+       if (_next_eye == EYE_LEFT) {
+               ++_frames_written;
+       }
+                       
+       return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
+}
+
+void
+StereoPictureAssetWriter::fake_write (int size)
+{
+       DCP_ASSERT (_started);
+       DCP_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", _file.string(), r));
+       }
+
+       _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
+       if (_next_eye == EYE_LEFT) {
+               ++_frames_written;
+       }
+}
+
+void
+StereoPictureAssetWriter::finalize ()
+{
+       Kumu::Result_t r = _state->mxf_writer.Finalize();
+       if (ASDCP_FAILURE (r)) {
+               boost::throw_exception (MXFFileError ("error in finalizing video MXF", _file.string(), r));
+       }
+
+       _picture_asset->_intrinsic_duration = _frames_written;
+       PictureAssetWriter::finalize ();
+}
diff --git a/src/stereo_picture_asset_writer.h b/src/stereo_picture_asset_writer.h
new file mode 100644 (file)
index 0000000..bd41b45
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+    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.
+
+*/
+
+#include "picture_asset_writer.h"
+#include "types.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <stdint.h>
+#include <string>
+#include <fstream>
+
+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 StereoPictureAssetWriter : public PictureAssetWriter
+{
+public:
+       /** 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 write (uint8_t* data, int size);
+       void fake_write (int size);
+       void finalize ();
+
+private:
+       friend class StereoPictureAsset;
+
+       StereoPictureAssetWriter (PictureAsset *, boost::filesystem::path file, Standard, 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;
+};
+
+}
index 3ee08303f42f25c7512cadb8b288d191a616d523..855795eb8efb9cf68bffed03c5b54f48616dbb68 100644 (file)
@@ -37,19 +37,19 @@ using namespace dcp;
  *  @param mxf_path Path to the asset's MXF file.
  *  @param n Frame within the asset, not taking EntryPoint into account.
  */
-StereoPictureFrame::StereoPictureFrame (boost::filesystem::path mxf_path, int n)
+StereoPictureFrame::StereoPictureFrame (boost::filesystem::path path, int n)
 {
        ASDCP::JP2K::MXFSReader reader;
-       Kumu::Result_t r = reader.OpenRead (mxf_path.string().c_str());
+       Kumu::Result_t r = reader.OpenRead (path.string().c_str());
        if (ASDCP_FAILURE (r)) {
-               boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path, r));
+               boost::throw_exception (FileError ("could not open MXF file for reading", path, r));
        }
 
        /* XXX: unfortunate guesswork on this buffer size */
        _buffer = new ASDCP::JP2K::SFrameBuffer (4 * Kumu::Megabyte);
 
        if (ASDCP_FAILURE (reader.ReadFrame (n, *_buffer))) {
-               boost::throw_exception (DCPReadError (String::compose ("could not read video frame %1 of %2", n, mxf_path.string())));
+               boost::throw_exception (DCPReadError (String::compose ("could not read video frame %1 of %2", n, path.string())));
        }
 }
 
index 0aeb68493931033e6d5cc02b348ac242cdf20dd1..261bac939fa586df8c45e0ef749a5d422492a176 100644 (file)
@@ -38,7 +38,7 @@ class XYZImage;
 class StereoPictureFrame : public boost::noncopyable
 {
 public:
-       StereoPictureFrame (boost::filesystem::path mxf_path, int n);
+       StereoPictureFrame (boost::filesystem::path path, int n);
        StereoPictureFrame ();
        ~StereoPictureFrame ();
 
diff --git a/src/stereo_picture_mxf.cc b/src/stereo_picture_mxf.cc
deleted file mode 100644 (file)
index 0ac0cc8..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-    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.
-
-*/
-
-#include "AS_DCP.h"
-#include "stereo_picture_mxf.h"
-#include "stereo_picture_frame.h"
-#include "exceptions.h"
-#include "stereo_picture_mxf_writer.h"
-#include "dcp_assert.h"
-
-using std::string;
-using std::pair;
-using std::make_pair;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using namespace dcp;
-
-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"));
-       }
-
-       read_picture_descriptor (desc);
-
-       ASDCP::WriterInfo info;
-       if (ASDCP_FAILURE (reader.FillWriterInfo (info))) {
-               boost::throw_exception (DCPReadError ("could not read video MXF information"));
-       }
-
-       _id = read_writer_info (info);
-}
-
-StereoPictureMXF::StereoPictureMXF (Fraction edit_rate)
-       : PictureMXF
-         (edit_rate)
-{
-
-}
-
-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, Standard standard, bool overwrite)
-{
-       return shared_ptr<StereoPictureMXFWriter> (new StereoPictureMXFWriter (this, file, standard, overwrite));
-}
-
-bool
-StereoPictureMXF::equals (shared_ptr<const Asset> other, EqualityOptions opt, NoteHandler note) const
-{
-       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);
-       DCP_ASSERT (other_picture);
-
-       for (int i = 0; i < _intrinsic_duration; ++i) {
-               shared_ptr<const StereoPictureFrame> frame_A;
-               shared_ptr<const StereoPictureFrame> frame_B;
-               try {
-                       frame_A = get_frame (i);
-                       frame_B = other_picture->get_frame (i);
-               } catch (DCPReadError& e) {
-                       /* If there was a problem reading the frame data we'll just assume
-                          the two frames are not equal.
-                       */
-                       note (DCP_ERROR, e.what ());
-                       return false;
-               }
-               
-               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;
-}
diff --git a/src/stereo_picture_mxf.h b/src/stereo_picture_mxf.h
deleted file mode 100644 (file)
index 9a094d1..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-    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.
-
-*/
-
-#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);
-       StereoPictureMXF (Fraction edit_rate);
-
-       /** 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 Asset> other,
-               EqualityOptions opt,
-               NoteHandler note
-               ) const;
-       
-       boost::shared_ptr<const StereoPictureFrame> get_frame (int n) const;
-};
-
-}
-
-#endif
diff --git a/src/stereo_picture_mxf_writer.cc b/src/stereo_picture_mxf_writer.cc
deleted file mode 100644 (file)
index 7a65556..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-    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.
-
-*/
-
-#include "stereo_picture_mxf_writer.h"
-#include "exceptions.h"
-#include "dcp_assert.h"
-#include "picture_mxf.h"
-#include "AS_DCP.h"
-#include "KM_fileio.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, Standard standard, bool overwrite)
-       : PictureMXFWriter (mxf, file, standard, overwrite)
-       , _state (new StereoPictureMXFWriter::ASDCPState)
-       , _next_eye (EYE_LEFT)
-{
-
-}
-
-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.
- *  @param data JPEG2000 data.
- *  @param size Size of data.
- */
-FrameInfo
-StereoPictureMXFWriter::write (uint8_t* data, int size)
-{
-       DCP_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,
-               _encryption_context,
-               0,
-               &hash
-               );
-
-       if (ASDCP_FAILURE (r)) {
-               boost::throw_exception (MXFFileError ("error in writing video MXF", _file.string(), r));
-       }
-
-       _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
-
-       if (_next_eye == EYE_LEFT) {
-               ++_frames_written;
-       }
-                       
-       return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
-}
-
-void
-StereoPictureMXFWriter::fake_write (int size)
-{
-       DCP_ASSERT (_started);
-       DCP_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", _file.string(), r));
-       }
-
-       _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
-       if (_next_eye == EYE_LEFT) {
-               ++_frames_written;
-       }
-}
-
-void
-StereoPictureMXFWriter::finalize ()
-{
-       Kumu::Result_t r = _state->mxf_writer.Finalize();
-       if (ASDCP_FAILURE (r)) {
-               boost::throw_exception (MXFFileError ("error in finalizing video MXF", _file.string(), r));
-       }
-
-       _picture_mxf->_intrinsic_duration = _frames_written;
-       PictureMXFWriter::finalize ();
-}
diff --git a/src/stereo_picture_mxf_writer.h b/src/stereo_picture_mxf_writer.h
deleted file mode 100644 (file)
index 5491a64..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-    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.
-
-*/
-
-#include "picture_mxf_writer.h"
-#include "types.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/utility.hpp>
-#include <stdint.h>
-#include <string>
-#include <fstream>
-
-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:
-       /** 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 write (uint8_t* data, int size);
-       void fake_write (int size);
-       void finalize ();
-
-private:
-       friend class StereoPictureMXF;
-
-       StereoPictureMXFWriter (PictureMXF *, boost::filesystem::path file, Standard, 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;
-};
-
-}
index a8e63fafc2c8d47bd9120a2763e55c33f5f7324e..626666b4263f6e22217c45c263cf42f040b60a35 100644 (file)
@@ -160,7 +160,6 @@ struct EqualityOptions
                , max_std_dev_pixel_error (0)
                , max_audio_sample_error (0)
                , cpl_annotation_texts_can_differ (false)
-               , mxf_filenames_can_differ (false)
                , reel_annotation_texts_can_differ (false)
                , reel_hashes_can_differ (false)
        {}
@@ -173,8 +172,6 @@ struct EqualityOptions
        int max_audio_sample_error;
        /** true if the <AnnotationText> nodes of CPLs are allowed to differ */
        bool cpl_annotation_texts_can_differ;
-       /** true if MXF file leafnames are allowed to differ */
-       bool mxf_filenames_can_differ;
        /** true if the <AnnotationText> nodes of Reels are allowed to differ */
        bool reel_annotation_texts_can_differ;
        /** true if <Hash>es in Reels can differ */
index 54f3a03b4df0cee6d82408809488e501c72e6513..ac3d9b0c499bd31ff63fc5337cb92ae2a8154766 100644 (file)
@@ -24,14 +24,14 @@ def build(bld):
              local_time.cc
              metadata.cc
              modified_gamma_transfer_function.cc
-             mono_picture_mxf.cc
-             mono_picture_mxf_writer.cc
+             mono_picture_asset.cc
+             mono_picture_asset_writer.cc
              mono_picture_frame.cc
              mxf.cc
-             mxf_writer.cc
+             asset_writer.cc
              object.cc
-             picture_mxf.cc
-             picture_mxf_writer.cc
+             picture_asset.cc
+             picture_asset_writer.cc
              reel.cc
              reel_asset.cc
              reel_mono_picture_asset.cc
@@ -44,11 +44,11 @@ def build(bld):
              signer.cc
              smpte_load_font_node.cc
              smpte_subtitle_asset.cc
-             sound_mxf.cc
-             sound_mxf_writer.cc
+             sound_asset.cc
+             sound_asset_writer.cc
              sound_frame.cc
-             stereo_picture_mxf.cc
-             stereo_picture_mxf_writer.cc
+             stereo_picture_asset.cc
+             stereo_picture_asset_writer.cc
              stereo_picture_frame.cc
              subtitle_node.cc
              subtitle_asset.cc
@@ -83,14 +83,14 @@ def build(bld):
               load_font_node.h
               local_time.h
               metadata.h
-              mono_picture_mxf.h
+              mono_picture_asset.h
               mono_picture_frame.h
               modified_gamma_transfer_function.h
               mxf.h
-              mxf_writer.h
+              asset_writer.h
               object.h
-              picture_mxf.h
-              picture_mxf_writer.h
+              picture_asset.h
+              picture_asset_writer.h
               raw_convert.h
               rgb_xyz.h
               reel.h
@@ -106,9 +106,9 @@ def build(bld):
               smpte_load_font_node.h
               smpte_subtitle_asset.h
               sound_frame.h
-              sound_mxf.h
-              sound_mxf_writer.h
-              stereo_picture_mxf.h
+              sound_asset.h
+              sound_asset_writer.h
+              stereo_picture_asset.h
               stereo_picture_frame.h
               subtitle_node.h
               subtitle_asset.h
index bce57f587b3c9e35817331085bcf21d0e8bed038..691439dbf7d8cda92e49efa7bf113b671a61e647 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "cpl.h"
 #include "reel_mono_picture_asset.h"
-#include "mono_picture_mxf.h"
+#include "mono_picture_asset.h"
 #include <libcxml/cxml.h>
 #include <boost/test/unit_test.hpp>
 
@@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE (cpl_sar)
 {
        shared_ptr<dcp::ReelMonoPictureAsset> pa (
                new dcp::ReelMonoPictureAsset (
-                       shared_ptr<dcp::MonoPictureMXF> (new dcp::MonoPictureMXF ("test/ref/DCP/dcp_test1/video.mxf")),
+                       shared_ptr<dcp::MonoPictureAsset> (new dcp::MonoPictureAsset ("test/ref/DCP/dcp_test1/video.mxf")),
                        0
                        )
                );
index 6da30ffef1fe1c64ba776489df1f7d1c65136f5c..c4950704c24808e7c1c7446c18db7860a4f60a02 100644 (file)
 #include "dcp.h"
 #include "metadata.h"
 #include "cpl.h"
-#include "mono_picture_mxf.h"
-#include "stereo_picture_mxf.h"
-#include "picture_mxf_writer.h"
-#include "sound_mxf_writer.h"
-#include "sound_mxf.h"
+#include "mono_picture_asset.h"
+#include "stereo_picture_asset.h"
+#include "picture_asset_writer.h"
+#include "sound_asset_writer.h"
+#include "sound_asset.h"
 #include "reel.h"
 #include "test.h"
 #include "file.h"
@@ -62,18 +62,18 @@ BOOST_AUTO_TEST_CASE (dcp_test1)
        cpl->set_content_version_label_text ("81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
        cpl->set_metadata (xml_meta);
 
-       shared_ptr<dcp::MonoPictureMXF> mp (new dcp::MonoPictureMXF (dcp::Fraction (24, 1)));
+       shared_ptr<dcp::MonoPictureAsset> mp (new dcp::MonoPictureAsset (dcp::Fraction (24, 1)));
        mp->set_metadata (mxf_meta);
-       shared_ptr<dcp::PictureMXFWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test1/video.mxf", dcp::SMPTE, false);
+       shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test1/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 ());
        }
        picture_writer->finalize ();
 
-       shared_ptr<dcp::SoundMXF> ms (new dcp::SoundMXF (dcp::Fraction (24, 1), 48000, 1));
+       shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1));
        ms->set_metadata (mxf_meta);
-       shared_ptr<dcp::SoundMXFWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test1/audio.mxf", dcp::SMPTE);
+       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test1/audio.mxf", dcp::SMPTE);
 
        SF_INFO info;
        info.format = 0;
@@ -133,9 +133,9 @@ BOOST_AUTO_TEST_CASE (dcp_test2)
        cpl->set_content_version_label_text ("81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
        cpl->set_metadata (xml_meta);
 
-       shared_ptr<dcp::StereoPictureMXF> mp (new dcp::StereoPictureMXF (dcp::Fraction (24, 1)));
+       shared_ptr<dcp::StereoPictureAsset> mp (new dcp::StereoPictureAsset (dcp::Fraction (24, 1)));
        mp->set_metadata (mxf_meta);
-       shared_ptr<dcp::PictureMXFWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test2/video.mxf", dcp::SMPTE, false);
+       shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test2/video.mxf", dcp::SMPTE, false);
        dcp::File j2c ("test/data/32x32_red_square.j2c");
        for (int i = 0; i < 24; ++i) {
                /* Left */
@@ -145,9 +145,9 @@ BOOST_AUTO_TEST_CASE (dcp_test2)
        }
        picture_writer->finalize ();
 
-       shared_ptr<dcp::SoundMXF> ms (new dcp::SoundMXF (dcp::Fraction (24, 1), 48000, 1));
+       shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1));
        ms->set_metadata (mxf_meta);
-       shared_ptr<dcp::SoundMXFWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test2/audio.mxf", dcp::SMPTE);
+       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test2/audio.mxf", dcp::SMPTE);
 
        SF_INFO info;
        info.format = 0;
index 0080fe3e7547f11912be088712d5e5fdeec3824c..0974b85d02a4076a59c37d669c56f1404612cd34 100644 (file)
@@ -22,7 +22,7 @@
 #include "cpl.h"
 #include "decrypted_kdm.h"
 #include "encrypted_kdm.h"
-#include "mono_picture_mxf.h"
+#include "mono_picture_asset.h"
 #include "reel_picture_asset.h"
 #include "reel.h"
 #include "test.h"
@@ -42,10 +42,10 @@ pair<uint8_t*, dcp::Size>
 get_frame (dcp::DCP const & dcp)
 {
        shared_ptr<const dcp::Reel> reel = dcp.cpls().front()->reels().front ();
-       shared_ptr<dcp::PictureMXF> picture = reel->main_picture()->mxf ();
+       shared_ptr<dcp::PictureAsset> picture = reel->main_picture()->asset ();
        BOOST_CHECK (picture);
 
-       shared_ptr<const dcp::MonoPictureMXF> mono_picture = dynamic_pointer_cast<const dcp::MonoPictureMXF> (picture);
+       shared_ptr<const dcp::MonoPictureAsset> mono_picture = dynamic_pointer_cast<const dcp::MonoPictureAsset> (picture);
        shared_ptr<const dcp::MonoPictureFrame> j2k_frame = mono_picture->get_frame (0);
        shared_ptr<dcp::XYZImage> xyz = j2k_frame->xyz_image();
 
index 6dc37b8def2a474a18c1de1bba9f7f758e60cb9b..299e5f9bdd02cff64a9dc55c7f584bc87233fcd9 100644 (file)
 #include "dcp.h"
 #include "signer.h"
 #include "cpl.h"
-#include "mono_picture_mxf.h"
-#include "picture_mxf_writer.h"
-#include "sound_mxf_writer.h"
-#include "sound_mxf.h"
+#include "mono_picture_asset.h"
+#include "picture_asset_writer.h"
+#include "sound_asset_writer.h"
+#include "sound_asset.h"
 #include "reel.h"
 #include "test.h"
 #include "file.h"
@@ -82,20 +82,20 @@ BOOST_AUTO_TEST_CASE (encryption_test)
 
        dcp::Key key;
        
-       shared_ptr<dcp::MonoPictureMXF> mp (new dcp::MonoPictureMXF (dcp::Fraction (24, 1)));
+       shared_ptr<dcp::MonoPictureAsset> mp (new dcp::MonoPictureAsset (dcp::Fraction (24, 1)));
        mp->set_metadata (mxf_metadata);
        mp->set_key (key);
 
-       shared_ptr<dcp::PictureMXFWriter> writer = mp->start_write ("build/test/DCP/encryption_test/video.mxf", dcp::SMPTE, false);
+       shared_ptr<dcp::PictureAssetWriter> writer = mp->start_write ("build/test/DCP/encryption_test/video.mxf", dcp::SMPTE, false);
        dcp::File j2c ("test/data/32x32_red_square.j2c");
        for (int i = 0; i < 24; ++i) {
                writer->write (j2c.data (), j2c.size ());
        }
        writer->finalize ();
 
-       shared_ptr<dcp::SoundMXF> ms (new dcp::SoundMXF (dcp::Fraction (24, 1), 48000, 1));
+       shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1));
        ms->set_key (key);
-       shared_ptr<dcp::SoundMXFWriter> sound_writer = ms->start_write ("build/test/DCP/encryption_test/audio.mxf", dcp::SMPTE);
+       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/encryption_test/audio.mxf", dcp::SMPTE);
        
        SF_INFO info;
        info.format = 0;
index 1d51a711555fda23e65c4724a266e4de43e2d556..257c512db097e9817c1a7d138c042862aeff7f9c 100644 (file)
@@ -19,8 +19,8 @@
 
 #include <boost/test/unit_test.hpp>
 #include <boost/filesystem.hpp>
-#include "mono_picture_mxf_writer.h"
-#include "mono_picture_mxf.h"
+#include "mono_picture_asset_writer.h"
+#include "mono_picture_asset.h"
 #include "KM_util.h"
 
 using std::string;
@@ -48,8 +48,8 @@ BOOST_AUTO_TEST_CASE (recovery)
        
        boost::filesystem::remove_all ("build/test/baz");
        boost::filesystem::create_directories ("build/test/baz");
-       shared_ptr<dcp::MonoPictureMXF> mp (new dcp::MonoPictureMXF (dcp::Fraction (24, 1)));
-       shared_ptr<dcp::PictureMXFWriter> writer = mp->start_write ("build/test/baz/video1.mxf", dcp::SMPTE, false);
+       shared_ptr<dcp::MonoPictureAsset> mp (new dcp::MonoPictureAsset (dcp::Fraction (24, 1)));
+       shared_ptr<dcp::PictureAssetWriter> writer = mp->start_write ("build/test/baz/video1.mxf", dcp::SMPTE, false);
 
        int written_size = 0;
        for (int i = 0; i < 24; ++i) {
@@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE (recovery)
        Kumu::ResetTestRNG ();
 #endif 
 
-       mp.reset (new dcp::MonoPictureMXF (dcp::Fraction (24, 1)));
+       mp.reset (new dcp::MonoPictureAsset (dcp::Fraction (24, 1)));
        writer = mp->start_write ("build/test/baz/video2.mxf", dcp::SMPTE, true);
 
        writer->write (data, size);
index 9f1030da6edd4d0f92c9d1a9a6b2fd340a110484..a719ff452c5a195625d73a86e531f800aca10286 100644 (file)
 #include "decrypted_kdm.h"
 #include "encrypted_kdm.h"
 #include "signer.h"
-#include "mono_picture_mxf.h"
-#include "sound_mxf.h"
+#include "mono_picture_asset.h"
+#include "sound_asset.h"
 #include "reel.h"
 #include "test.h"
 #include "cpl.h"
 #include "mono_picture_frame.h"
 #include "certificate_chain.h"
-#include "mono_picture_mxf_writer.h"
+#include "mono_picture_asset_writer.h"
 #include "reel_picture_asset.h"
 #include "reel_mono_picture_asset.h"
 #include "file.h"
@@ -43,7 +43,7 @@ using std::list;
 using boost::shared_ptr;
 using boost::scoped_array;
 
-/* Build an encrypted picture MXF and a KDM for it and check that the KDM can be decrypted */
+/* Build an encrypted picture asset and a KDM for it and check that the KDM can be decrypted */
 BOOST_AUTO_TEST_CASE (round_trip_test)
 {
        shared_ptr<dcp::Signer> signer (new dcp::Signer ("openssl"));
@@ -51,8 +51,8 @@ BOOST_AUTO_TEST_CASE (round_trip_test)
        boost::filesystem::path work_dir = "build/test/round_trip_test";
        boost::filesystem::create_directory (work_dir);
 
-       shared_ptr<dcp::MonoPictureMXF> mxf_A (new dcp::MonoPictureMXF (dcp::Fraction (24, 1)));
-       shared_ptr<dcp::PictureMXFWriter> writer = mxf_A->start_write (work_dir / "video.mxf", dcp::SMPTE, false);
+       shared_ptr<dcp::MonoPictureAsset> asset_A (new dcp::MonoPictureAsset (dcp::Fraction (24, 1)));
+       shared_ptr<dcp::PictureAssetWriter> writer = asset_A->start_write (work_dir / "video.mxf", dcp::SMPTE, false);
        dcp::File j2c ("test/data/32x32_red_square.j2c");
        for (int i = 0; i < 24; ++i) {
                writer->write (j2c.data (), j2c.size ());
@@ -61,11 +61,11 @@ BOOST_AUTO_TEST_CASE (round_trip_test)
 
        dcp::Key key;
 
-       mxf_A->set_key (key);
+       asset_A->set_key (key);
 
        shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
        shared_ptr<dcp::Reel> reel (new dcp::Reel ());
-       reel->add (shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (mxf_A, 0)));
+       reel->add (shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (asset_A, 0)));
        cpl->add (reel);
 
        /* A KDM using our certificate chain's leaf key pair */
@@ -98,16 +98,16 @@ BOOST_AUTO_TEST_CASE (round_trip_test)
                ++j;
        }
 
-       /* Reload the picture MXF */
-       shared_ptr<dcp::MonoPictureMXF> mxf_B (
-               new dcp::MonoPictureMXF (work_dir / "video.mxf")
+       /* Reload the picture asset */
+       shared_ptr<dcp::MonoPictureAsset> asset_B (
+               new dcp::MonoPictureAsset (work_dir / "video.mxf")
                );
 
        BOOST_CHECK (!kdm_B.keys().empty ());
-       mxf_B->set_key (kdm_B.keys().front().key());
+       asset_B->set_key (kdm_B.keys().front().key());
 
-       shared_ptr<dcp::XYZImage> xyz_A = mxf_A->get_frame(0)->xyz_image ();
-       shared_ptr<dcp::XYZImage> xyz_B = mxf_B->get_frame(0)->xyz_image ();
+       shared_ptr<dcp::XYZImage> xyz_A = asset_A->get_frame(0)->xyz_image ();
+       shared_ptr<dcp::XYZImage> xyz_B = asset_B->get_frame(0)->xyz_image ();
 
        scoped_array<uint8_t> frame_A (new uint8_t[xyz_A->size().width * xyz_A->size().height * 4]);
        dcp::xyz_to_rgba (xyz_A, dcp::ColourConversion::srgb_to_xyz(), frame_A.get());
index c2a454cf1b81d4d735f3e4aaab05cdf0cb4a36c7..2cc10e90c5558e45c444bf508ed36eee5d00f589 100644 (file)
@@ -46,7 +46,6 @@ help (string n)
             << "  -V, --version                show libdcp version\n"
             << "  -h, --help                   show this help\n"
             << "  -v, --verbose                be verbose\n"
-            << "  -n, --mxf-filenames          allow differing MXF filenames\n"
             << "      --cpl-annotation-texts   allow differing CPL annotation texts\n"
             << "  -m, --mean-pixel             maximum allowed mean pixel error (default 5)\n"
             << "  -s, --std-dev-pixel          maximum allowed standard deviation of pixel error (default 5)\n"
@@ -115,7 +114,6 @@ main (int argc, char* argv[])
                        { "version", no_argument, 0, 'V'},
                        { "help", no_argument, 0, 'h'},
                        { "verbose", no_argument, 0, 'v'},
-                       { "mxf-filenames", no_argument, 0, 'n'},
                        { "mean-pixel", required_argument, 0, 'm'},
                        { "std-dev-pixel", required_argument, 0, 's'},
                        { "keep-going", no_argument, 0, 'k'},
@@ -126,7 +124,7 @@ main (int argc, char* argv[])
                        { 0, 0, 0, 0 }
                };
 
-               int c = getopt_long (argc, argv, "Vhvnm:s:kACD:", long_options, &option_index);
+               int c = getopt_long (argc, argv, "Vhvm:s:kACD:", long_options, &option_index);
 
                if (c == -1) {
                        break;
@@ -142,9 +140,6 @@ main (int argc, char* argv[])
                case 'v':
                        verbose = true;
                        break;
-               case 'n':
-                       options.mxf_filenames_can_differ = true;
-                       break;
                case 'm':
                        options.max_mean_pixel_error = atof (optarg);
                        break;
index 119a2106c27e44e4a08a8a9aed32a8032c0a2f9e..965088c20d4b89e29e8dcb50ee3818dcbd836b0f 100644 (file)
@@ -20,8 +20,8 @@
 #include "dcp.h"
 #include "exceptions.h"
 #include "reel.h"
-#include "sound_mxf.h"
-#include "picture_mxf.h"
+#include "sound_asset.h"
+#include "picture_asset.h"
 #include "subtitle_asset.h"
 #include "reel_picture_asset.h"
 #include "reel_sound_asset.h"
@@ -54,22 +54,22 @@ help (string n)
 static void
 main_picture (shared_ptr<Reel> reel)
 {
-       if (reel->main_picture() && reel->main_picture()->mxf()) {
+       if (reel->main_picture() && reel->main_picture()->asset()) {
                cout << "      Picture:  "
-                    << reel->main_picture()->mxf()->size().width
+                    << reel->main_picture()->asset()->size().width
                     << "x"
-                    << reel->main_picture()->mxf()->size().height << "\n";
+                    << reel->main_picture()->asset()->size().height << "\n";
        }
 }
 
 static void
 main_sound (shared_ptr<Reel> reel)
 {
-       if (reel->main_sound() && reel->main_sound()->mxf()) {
+       if (reel->main_sound() && reel->main_sound()->asset()) {
                cout << "      Sound:    "
-                    << reel->main_sound()->mxf()->channels()
+                    << reel->main_sound()->asset()->channels()
                     << " channels at "
-                    << reel->main_sound()->mxf()->sampling_rate() << "Hz\n";
+                    << reel->main_sound()->asset()->sampling_rate() << "Hz\n";
        }
 }