Clean up DCP comparison a bit.
authorCarl Hetherington <cth@carlh.net>
Tue, 2 Oct 2012 20:51:56 +0000 (21:51 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 2 Oct 2012 20:51:56 +0000 (21:51 +0100)
14 files changed:
src/asset.h
src/dcp.cc
src/dcp.h
src/mxf_asset.cc
src/mxf_asset.h
src/picture_asset.cc
src/picture_asset.h
src/reel.cc
src/reel.h
src/sound_asset.cc
src/sound_asset.h
src/subtitle_asset.h
src/types.h
tools/dcpdiff.cc

index eab24d28339e5b4ac15361679fe30e49dad7753a..32fd93aee759837637a80451ddc6ecf2db999dc6 100644 (file)
@@ -68,7 +68,7 @@ public:
                return _uuid;
        }
 
-       virtual std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityOptions opt) const = 0;
+       virtual bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const = 0;
 
 protected:
        friend class PictureAsset;
index fb7fb2881e4412fc32f55cb805bcc909208b3c24..9a83edfd07fad07e52de0ff7cb050ec9f09bc7d3 100644 (file)
@@ -245,26 +245,26 @@ DCP::read (bool require_mxfs)
 
 }
 
-list<string>
-DCP::equals (DCP const & other, EqualityOptions opt) const
+bool
+DCP::equals (DCP const & other, EqualityOptions opt, list<string>& notes) const
 {
-       list<string> notes;
-
        if (_cpls.size() != other._cpls.size()) {
                notes.push_back ("CPL counts differ");
+               return false;
        }
 
        list<shared_ptr<const CPL> >::const_iterator a = _cpls.begin ();
        list<shared_ptr<const CPL> >::const_iterator b = other._cpls.begin ();
 
        while (a != _cpls.end ()) {
-               list<string> n = (*a)->equals (*b->get(), opt);
-               notes.merge (n);
+               if (!(*a)->equals (*b->get(), opt, notes)) {
+                       return false;
+               }
                ++a;
                ++b;
        }
 
-       return notes;
+       return true;
 }
 
 
@@ -509,39 +509,44 @@ CPL::write_to_assetmap (ostream& s) const
        
        
        
-list<string>
-CPL::equals (CPL const & other, EqualityOptions opt) const
+bool
+CPL::equals (CPL const & other, EqualityOptions opt, list<string>& notes) const
 {
-       list<string> notes;
-       
-       if (opt.flags & LIBDCP_METADATA) {
-               if (_name != other._name) {
-                       notes.push_back ("names differ");
-               }
-               if (_content_kind != other._content_kind) {
-                       notes.push_back ("content kinds differ");
-               }
-               if (_fps != other._fps) {
-                       notes.push_back ("frames per second differ");
-               }
-               if (_length != other._length) {
-                       notes.push_back ("lengths differ");
-               }
+       if (_name != other._name) {
+               notes.push_back ("names differ");
+               return false;
+       }
+
+       if (_content_kind != other._content_kind) {
+               notes.push_back ("content kinds differ");
+               return false;
+       }
+
+       if (_fps != other._fps) {
+               notes.push_back ("frames per second differ");
+               return false;
+       }
+
+       if (_length != other._length) {
+               notes.push_back ("lengths differ");
+               return false;
        }
 
        if (_reels.size() != other._reels.size()) {
                notes.push_back ("reel counts differ");
+               return false;
        }
        
        list<shared_ptr<const Reel> >::const_iterator a = _reels.begin ();
        list<shared_ptr<const Reel> >::const_iterator b = other._reels.begin ();
        
        while (a != _reels.end ()) {
-               list<string> n = (*a)->equals (*b, opt);
-               notes.merge (n);
+               if (!(*a)->equals (*b, opt, notes)) {
+                       return false;
+               }
                ++a;
                ++b;
        }
 
-       return notes;
+       return true;
 }
index 79be5ca59fda265a2a4d1d5d37058e9e193a4c3a..1ae5cf9791ec77c82060cb4f0fd1bd8cd18c8200 100644 (file)
--- a/src/dcp.h
+++ b/src/dcp.h
@@ -83,7 +83,7 @@ public:
 
        std::list<boost::shared_ptr<const Asset> > assets () const;
        
-       std::list<std::string> equals (CPL const & other, EqualityOptions options) const;
+       bool equals (CPL const & other, EqualityOptions options, std::list<std::string>& notes) const;
        
        void write_xml () const;
        void write_to_assetmap (std::ostream& s) const;
@@ -139,10 +139,10 @@ public:
        /** Compare this DCP with another, according to various options.
         *  @param other DCP to compare this one to.
         *  @param options Options to define just what "equality" means.
-        *  @return An empty list if the DCPs are equal; otherwise a list of messages
-        *  which explain the ways in which they differ.
+        *  @param notes Filled in with notes about differences.
+        *  @return true if the DCPs are equal according to EqualityOptions, otherwise false.
         */
-       std::list<std::string> equals (DCP const & other, EqualityOptions options) const;
+       bool equals (DCP const & other, EqualityOptions options, std::list<std::string>& notes) const;
 
        void add_cpl (boost::shared_ptr<CPL> cpl);
 
index 2246c55d103ea458c0f7ad247f3722773edbdb4e..d0e02c8bfd12718379707ab56428549492805501 100644 (file)
@@ -57,37 +57,40 @@ MXFAsset::fill_writer_info (ASDCP::WriterInfo* writer_info) const
        assert (c == Kumu::UUID_Length);
 }
 
-list<string>
-MXFAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
+bool
+MXFAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, list<string>& notes) const
 {
        shared_ptr<const MXFAsset> other_mxf = dynamic_pointer_cast<const MXFAsset> (other);
        if (!other_mxf) {
-               return list<string> ();
+               notes.push_back ("comparing an MXF asset with a non-MXF asset");
+               return false;
        }
        
-       list<string> notes;
+       if (_file_name != other_mxf->_file_name) {
+               notes.push_back ("MXF names differ");
+               return false;
+       }
+
+       if (_fps != other_mxf->_fps) {
+               notes.push_back ("MXF frames per second differ");
+               return false;
+       }
        
-       if (opt.flags & LIBDCP_METADATA) {
-               if (_file_name != other_mxf->_file_name) {
-                       notes.push_back ("MXF names differ");
-               }
-               if (_fps != other_mxf->_fps) {
-                       notes.push_back ("MXF frames per second differ");
-               }
-               if (_length != other_mxf->_length) {
-                       notes.push_back ("MXF lengths differ");
-               }
+       if (_length != other_mxf->_length) {
+               notes.push_back ("MXF lengths differ");
+               return false;
        }
        
-       if (opt.flags & MXF_BITWISE) {
+       if (opt.bitwise) {
 
                if (digest() != other_mxf->digest()) {
                        notes.push_back ("MXF digests differ");
+                       return false;
                }
                
                if (filesystem::file_size (path()) != filesystem::file_size (other_mxf->path())) {
                        notes.push_back (path().string() + " and " + other_mxf->path().string() + " sizes differ");
-                       return notes;
+                       return false;
                }
                
                ifstream a (path().string().c_str(), ios::binary);
@@ -106,14 +109,14 @@ MXFAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
 
                        if (memcmp (abuffer, bbuffer, t) != 0) {
                                notes.push_back (path().string() + " and " + other_mxf->path().string() + " content differs");
-                               return notes;
+                               return false;
                        }
 
                        n -= t;
                }
        }
 
-       return notes;
+       return true;
 }
 
 int
index 7f36b30a0b9476902ea4856b3038f8ea3f4b41fc..240e042da87dfc5d5a3d693a619ba07e3549d0ce 100644 (file)
@@ -38,7 +38,7 @@ public:
         */
        MXFAsset (std::string directory, std::string file_name, sigc::signal1<void, float>* progress, int fps, int entry_point, int length);
 
-       virtual std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityOptions opt) const;
+       virtual bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const;
        
        int length () const;
 
index a1d8321dc05274836b745b25dbb21022d201a0e4..898fe75b64fd4ad8e883c2940df3c9cd13626291 100644 (file)
@@ -63,12 +63,14 @@ PictureAsset::write_to_cpl (ostream& s) const
          << "        </MainPicture>\n";
 }
 
-list<string>
-PictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
+bool
+PictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, list<string>& notes) const
 {
-       list<string> notes = MXFAsset::equals (other, opt);
+       if (!MXFAsset::equals (other, opt, notes)) {
+               return false;
+       }
                     
-       if (opt.flags & MXF_INSPECT) {
+       if (!opt.bitwise) {
                ASDCP::JP2K::MXFReader reader_A;
                if (ASDCP_FAILURE (reader_A.OpenRead (path().string().c_str()))) {
                        throw MXFFileError ("could not open MXF file for reading", path().string());
@@ -119,7 +121,7 @@ PictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
 //             }
        }
 
-       return notes;
+       return true;
 }
 
 
@@ -229,139 +231,134 @@ MonoPictureAsset::get_frame (int n) const
 }
 
 
-list<string>
-MonoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
+bool
+MonoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, list<string>& notes) const
 {
-       list<string> notes = PictureAsset::equals (other, opt);
+       if (!PictureAsset::equals (other, opt, notes)) {
+               return false;
+       }
 
        shared_ptr<const MonoPictureAsset> other_picture = dynamic_pointer_cast<const MonoPictureAsset> (other);
        assert (other_picture);
 
-       for (int i = 0; i < _length; ++i) {
-               shared_ptr<const MonoPictureFrame> frame_A = get_frame (i);
-               shared_ptr<const MonoPictureFrame> frame_B = other_picture->get_frame (i);
-
-               list<string> n = frame_buffer_equals (
-                       i, opt,
-                       frame_A->j2k_frame()->RoData(), frame_A->j2k_frame()->Size(),
-                       frame_B->j2k_frame()->RoData(), frame_B->j2k_frame()->Size()
-                       );
-
-               notes.merge (n);
+       if (!opt.bitwise) {
+               for (int i = 0; i < _length; ++i) {
+                       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, notes,
+                                   frame_A->j2k_frame()->RoData(), frame_A->j2k_frame()->Size(),
+                                   frame_B->j2k_frame()->RoData(), frame_B->j2k_frame()->Size()
+                                   )) {
+                               return false;
+                       }
+               }
        }
 
-       return notes;
+       return true;
 }
 
-list<string>
-StereoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
+bool
+StereoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, list<string>& notes) const
 {
-       list<string> notes = PictureAsset::equals (other, opt);
+       if (!PictureAsset::equals (other, opt, notes)) {
+               return false;
+       }
        
        shared_ptr<const StereoPictureAsset> other_picture = dynamic_pointer_cast<const StereoPictureAsset> (other);
        assert (other_picture);
-       
-       for (int i = 0; i < _length; ++i) {
-               shared_ptr<const StereoPictureFrame> frame_A = get_frame (i);
-               shared_ptr<const StereoPictureFrame> frame_B = other_picture->get_frame (i);
-
-               list<string> n = frame_buffer_equals (
-                       i, opt,
-                       frame_A->j2k_frame()->Left.RoData(), frame_A->j2k_frame()->Left.Size(),
-                       frame_B->j2k_frame()->Left.RoData(), frame_B->j2k_frame()->Left.Size()
-                       );
-
-               notes.merge (n);
 
-               n = frame_buffer_equals (
-                       i, opt,
-                       frame_A->j2k_frame()->Right.RoData(), frame_A->j2k_frame()->Right.Size(),
-                       frame_B->j2k_frame()->Right.RoData(), frame_B->j2k_frame()->Right.Size()
-                       );
+       if (!opt.bitwise) {
+       
+               for (int i = 0; i < _length; ++i) {
+                       shared_ptr<const StereoPictureFrame> frame_A = get_frame (i);
+                       shared_ptr<const StereoPictureFrame> frame_B = other_picture->get_frame (i);
+                       
+                       if (!frame_buffer_equals (
+                               i, opt, notes,
+                               frame_A->j2k_frame()->Left.RoData(), frame_A->j2k_frame()->Left.Size(),
+                               frame_B->j2k_frame()->Left.RoData(), frame_B->j2k_frame()->Left.Size()
+                                   )) {
+                               return false;
+                       }
 
-               notes.merge (n);
+                       if (!frame_buffer_equals (
+                                   i, opt, notes,
+                                   frame_A->j2k_frame()->Right.RoData(), frame_A->j2k_frame()->Right.Size(),
+                                   frame_B->j2k_frame()->Right.RoData(), frame_B->j2k_frame()->Right.Size()
+                                   )) {
+                               return false;
+                       }
+               }
        }
 
-       return notes;
+       return true;
 }
 
-list<string>
+bool
 PictureAsset::frame_buffer_equals (
-       int frame, EqualityOptions opt, uint8_t const * data_A, unsigned int size_A, uint8_t const * data_B, unsigned int size_B
+       int frame, EqualityOptions opt, list<string>& notes, uint8_t const * data_A, unsigned int size_A, uint8_t const * data_B, unsigned int size_B
        ) const
 {
-       list<string> notes;
+       if (size_A == size_B && memcmp (data_A, data_B, size_A) == 0) {
+               /* Easy result; the J2K data is identical */
+               return true;
+       }
+               
+       /* Decompress the images to bitmaps */
+       opj_image_t* image_A = decompress_j2k (const_cast<uint8_t*> (data_A), size_A, 0);
+       opj_image_t* image_B = decompress_j2k (const_cast<uint8_t*> (data_B), size_B, 0);
+       
+       /* Compare them */
        
-       bool j2k_same = true;
-       if (size_A != size_B) {
-               notes.push_back ("sizes of video data for frame " + lexical_cast<string>(frame) + " differ");
-               j2k_same = false;
-       } else if (memcmp (data_A, data_B, size_A) != 0) {
-               notes.push_back ("J2K data for frame " + lexical_cast<string>(frame) + " differ");
-               j2k_same = false;
+       if (image_A->numcomps != image_B->numcomps) {
+               notes.push_back ("image component counts for frame " + lexical_cast<string>(frame) + " differ");
+               return false;
        }
        
-       if (!j2k_same) {
-               
-               if (opt.verbose) {
-                       cout << "J2K images for " << frame << " differ; checking by pixel\n";
-               }
-               
-               /* Decompress the images to bitmaps */
-               opj_image_t* image_A = decompress_j2k (const_cast<uint8_t*> (data_A), size_A, 0);
-               opj_image_t* image_B = decompress_j2k (const_cast<uint8_t*> (data_B), size_B, 0);
-               
-               /* Compare them */
-               
-               if (image_A->numcomps != image_B->numcomps) {
-                       notes.push_back ("image component counts for frame " + lexical_cast<string>(frame) + " differ");
-               }
-               
-               vector<int> abs_diffs (image_A->comps[0].w * image_A->comps[0].h * image_A->numcomps);
-               int d = 0;
-               int max_diff = 0;
-               
-               for (int c = 0; c < image_A->numcomps; ++c) {
-                       
-                       if (image_A->comps[c].w != image_B->comps[c].w || image_A->comps[c].h != image_B->comps[c].h) {
-                               notes.push_back ("image sizes for frame " + lexical_cast<string>(frame) + " differ");
-                       }
-                       
-                       int const pixels = image_A->comps[c].w * image_A->comps[c].h;
-                       for (int j = 0; j < pixels; ++j) {
-                               int const t = abs (image_A->comps[c].data[j] - image_B->comps[c].data[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());
+       vector<int> abs_diffs (image_A->comps[0].w * image_A->comps[0].h * image_A->numcomps);
+       int d = 0;
+       int max_diff = 0;
+       
+       for (int c = 0; c < image_A->numcomps; ++c) {
                
-               if (mean > opt.max_mean_pixel_error || std_dev > opt.max_std_dev_pixel_error) {
-                       notes.push_back ("mean or standard deviation out of range for " + lexical_cast<string>(frame));
+               if (image_A->comps[c].w != image_B->comps[c].w || image_A->comps[c].h != image_B->comps[c].h) {
+                       notes.push_back ("image sizes for frame " + lexical_cast<string>(frame) + " differ");
+                       return false;
                }
                
-               if (opt.verbose) {
-                       cout << "\tmax pixel error " << max_diff << ", mean pixel error " << mean << ", standard deviation " << std_dev << "\n";
+               int const pixels = image_A->comps[c].w * image_A->comps[c].h;
+               for (int j = 0; j < pixels; ++j) {
+                       int const t = abs (image_A->comps[c].data[j] - image_B->comps[c].data[j]);
+                       abs_diffs[d++] = t;
+                       max_diff = max (max_diff, t);
                }
+       }
                
-               opj_image_destroy (image_A);
-               opj_image_destroy (image_B);
+       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());
+       
+       if (mean > opt.max_mean_pixel_error || std_dev > opt.max_std_dev_pixel_error) {
+               notes.push_back ("mean or standard deviation out of range for " + lexical_cast<string>(frame));
+               return false;
        }
+       
+       opj_image_destroy (image_A);
+       opj_image_destroy (image_B);
 
-       return notes;
+       return true;
 }
 
 
index baea22c3098487c0c70acc68f6b0d95d2f1f3161..da3eb7d00e9f5e7bfdb21bfc143e8c1833d86ea5 100644 (file)
@@ -41,7 +41,7 @@ public:
         */
        void write_to_cpl (std::ostream& s) const;
 
-       std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityOptions opt) const;
+       bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const;
 
        int width () const {
                return _width;
@@ -53,8 +53,9 @@ public:
 
 protected:     
 
-       std::list<std::string> frame_buffer_equals (
-               int frame, EqualityOptions opt, uint8_t const * data_A, unsigned int size_A, uint8_t const * data_B, unsigned int size_B
+       bool frame_buffer_equals (
+               int frame, EqualityOptions opt, std::list<std::string>& notes,
+               uint8_t const * data_A, unsigned int size_A, uint8_t const * data_B, unsigned int size_B
                ) const;
        
        /** picture width in pixels */
@@ -114,7 +115,7 @@ public:
        MonoPictureAsset (std::string directory, std::string mxf_name, int fps, int entry_point, int length);
        
        boost::shared_ptr<const MonoPictureFrame> get_frame (int n) const;
-       std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityOptions opt) const;
+       bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const;
 
 private:
        std::string path_from_list (int f, std::vector<std::string> const & files) const;
@@ -128,7 +129,7 @@ public:
        StereoPictureAsset (std::string directory, std::string mxf_name, int fps, int entry_point, int length);
        
        boost::shared_ptr<const StereoPictureFrame> get_frame (int n) const;
-       std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityOptions opt) const;
+       bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const;
 };
        
 
index 50426cc1b617b918470cb6ddcbad48e0cfe8c72d..52a4f0fbd0a1c014c91a51e98d8c70006e5ad91c 100644 (file)
@@ -46,38 +46,36 @@ Reel::write_to_cpl (ostream& s) const
        }
 }
        
-list<string>
-Reel::equals (boost::shared_ptr<const Reel> other, EqualityOptions opt) const
+bool
+Reel::equals (boost::shared_ptr<const Reel> other, EqualityOptions opt, list<string>& notes) const
 {
-       list<string> o;
-       
        if ((_main_picture && !other->_main_picture) || (!_main_picture && other->_main_picture)) {
-               o.push_back ("reel has different assets");
+               notes.push_back ("reel has different assets");
+               return false;
        }
        
-       if (_main_picture) {
-               list<string> m = _main_picture->equals (other->_main_picture, opt);
-               o.merge (m);
+       if (_main_picture && !_main_picture->equals (other->_main_picture, opt, notes)) {
+               return false;
        }
 
        if ((_main_sound && !other->_main_sound) || (!_main_sound && other->_main_sound)) {
-               o.push_back ("reel has different assets");
+               notes.push_back ("reel has different assets");
+               return false;
        }
        
-       if (_main_sound) {
-               list<string> m = _main_sound->equals (other->_main_sound, opt);
-               o.merge (m);
+       if (_main_sound && !_main_sound->equals (other->_main_sound, opt, notes)) {
+               return false;
        }
 
        if ((_main_subtitle && !other->_main_subtitle) || (!_main_subtitle && other->_main_subtitle)) {
-               o.push_back ("reel has different assets");
+               notes.push_back ("reel has different assets");
+               return false;
        }
        
-       if (_main_subtitle) {
-               list<string> m = _main_subtitle->equals (other->_main_subtitle, opt);
-               o.merge (m);
+       if (_main_subtitle && !_main_subtitle->equals (other->_main_subtitle, opt, notes)) {
+               return false;
        }
 
-       return o;
+       return true;
 }
 
index 58caed31c2b17972ad28224777fb6bf01720ab5c..08a438ddbeed51e9f6d62252789fc0072ef9abe1 100644 (file)
@@ -54,7 +54,7 @@ public:
 
        void write_to_cpl (std::ostream & s) const;
 
-       std::list<std::string> equals (boost::shared_ptr<const Reel> other, EqualityOptions opt) const;
+       bool equals (boost::shared_ptr<const Reel> other, EqualityOptions opt, std::list<std::string>& notes) const;
 
 private:
        boost::shared_ptr<const PictureAsset> _main_picture;
index 86ce69cf7f6ddec82bd8bf9bdb867da78fbc3b03..9395a48765a31cfe8a320a0e7dd47dceae62bba7 100644 (file)
@@ -193,12 +193,14 @@ SoundAsset::write_to_cpl (ostream& s) const
          << "        </MainSound>\n";
 }
 
-list<string>
-SoundAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
+bool
+SoundAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, list<string>& notes) const
 {
-       list<string> notes = MXFAsset::equals (other, opt);
+       if (!MXFAsset::equals (other, opt, notes)) {
+               return false;
+       }
                     
-       if (opt.flags & MXF_INSPECT) {
+       if (!opt.bitwise) {
                ASDCP::PCM::MXFReader reader_A;
                if (ASDCP_FAILURE (reader_A.OpenRead (path().string().c_str()))) {
                        throw MXFFileError ("could not open MXF file for reading", path().string());
@@ -232,6 +234,7 @@ SoundAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
                        ) {
                
                        notes.push_back ("audio MXF picture descriptors differ");
+                       return false;
                }
 
                ASDCP::PCM::FrameBuffer buffer_A (1 * Kumu::Megabyte);
@@ -248,17 +251,17 @@ SoundAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
 
                        if (buffer_A.Size() != buffer_B.Size()) {
                                notes.push_back ("sizes of audio data for frame " + lexical_cast<string>(i) + " differ");
-                               continue;
+                               return false;
                        }
 
                        if (memcmp (buffer_A.RoData(), buffer_B.RoData(), buffer_A.Size()) != 0) {
                                notes.push_back ("PCM data for MXF frame " + lexical_cast<string>(i) + " differ");
-                               continue;
+                               return false;
                        }
                }
        }
 
-       return notes;
+       return true;
 }
 
 shared_ptr<const SoundFrame>
index 3f42a522b3a3953704fcf63b11df44b4efe3e884..a19d67268241fccddd40d7a12f5e5a44e1bcb0b7 100644 (file)
@@ -87,7 +87,7 @@ public:
         */
        void write_to_cpl (std::ostream& s) const;
 
-       std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityOptions opt) const;
+       bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const;
 
        boost::shared_ptr<const SoundFrame> get_frame (int n) const;
        
index d02e364c6fefabfc20862dc9f3b0b787bb8faba9..66f75cbedd6de0d9598f77ba187cf7e308ef5363 100644 (file)
@@ -183,9 +183,10 @@ public:
        SubtitleAsset (std::string directory, std::string xml);
 
        void write_to_cpl (std::ostream&) const {}
-       virtual std::list<std::string> equals (boost::shared_ptr<const Asset>, EqualityOptions) const {
+       virtual bool equals (boost::shared_ptr<const Asset>, EqualityOptions, std::list<std::string>& notes) const {
                /* XXX */
-               return std::list<std::string> ();
+               notes.push_back ("subtitle assets not compared yet");
+               return true;
        }
 
        std::string language () const {
index 314b674b92af2f5b27cdd8dfc0bbd27ac0a04a86..7c98a3b352ff4b7d588975b0c268174e23fc4bf0 100644 (file)
@@ -85,15 +85,12 @@ public:
 extern bool operator== (Fraction const & a, Fraction const & b);
 extern bool operator!= (Fraction const & a, Fraction const & b);
        
-enum EqualityFlags {
-       LIBDCP_METADATA = 0x1,
-       MXF_BITWISE = 0x2,
-       MXF_INSPECT = 0x4
-};
-
 struct EqualityOptions {
-       EqualityFlags flags;
-       bool verbose;
+       /** true to do a bitwise comparison.
+        *  false to compare PCM and image data, possibly allowing
+        *  some variation in values.
+        */
+       bool bitwise;
        double max_mean_pixel_error;
        double max_std_dev_pixel_error;
 };
index 6141b8ff2e45bd168005bf4c3d8433d3f762939c..c9139e7ba36b74e0d7bec2fcd95d56897009d815 100644 (file)
@@ -14,7 +14,6 @@ help (string n)
        cerr << "Syntax: " << n << " [OPTION] <DCP> <DCP>\n"
             << "  -b, --bitwise      bitwise check\n"
             << "  -v, --version      show libdcp version\n"
-            << "  -d, --verbose      be verbose\n"
             << "  -h, --help         show this help\n"
             << "\n"
             << "The <DCP>s are the DCP directories to compare.\n"
@@ -26,8 +25,7 @@ int
 main (int argc, char* argv[])
 {
        EqualityOptions options;
-       options.flags = EqualityFlags (LIBDCP_METADATA | MXF_INSPECT);
-       options.verbose = false;
+       options.bitwise = false;
        
        int option_index = 0;
        while (1) {
@@ -35,7 +33,6 @@ main (int argc, char* argv[])
                        { "bitwise", no_argument, 0, 'b'},
                        { "version", no_argument, 0, 'v'},
                        { "help", no_argument, 0, 'h'},
-                       { "verbose", no_argument, 0, 'd'},
                        { 0, 0, 0, 0 }
                };
 
@@ -47,7 +44,7 @@ main (int argc, char* argv[])
 
                switch (c) {
                case 'b':
-                       options.flags = EqualityFlags (options.flags | MXF_BITWISE);
+                       options.bitwise = true;
                        break;
                case 'v':
                        cout << "dcpdiff version " << LIBDCP_VERSION << "\n";
@@ -55,9 +52,6 @@ main (int argc, char* argv[])
                case 'h':
                        help (argv[0]);
                        exit (EXIT_SUCCESS);
-               case 'd':
-                       options.verbose = true;
-                       break;
                }
        }
 
@@ -97,15 +91,17 @@ main (int argc, char* argv[])
        options.max_mean_pixel_error = 5;
        options.max_std_dev_pixel_error = 5;
 
-       list<string> notes = a->equals (*b, options);
-       if (notes.empty ()) {
-               cout << "DCPs equal\n";
-               exit (EXIT_SUCCESS);
-       }
+       list<string> notes;
+       bool equals = a->equals (*b, options, notes);
 
        for (list<string>::iterator i = notes.begin(); i != notes.end(); ++i) {
                cout << "  " << *i << "\n";
        }
 
+       if (equals) {
+               cout << "DCPs equal\n";
+               exit (EXIT_SUCCESS);
+       }
+
        exit (EXIT_FAILURE);
 }