Check sound; various fixups.
authorCarl Hetherington <cth@carlh.net>
Tue, 31 Jul 2012 11:41:33 +0000 (12:41 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 31 Jul 2012 11:41:33 +0000 (12:41 +0100)
src/asset.h
src/dcp.cc
src/sound_asset.cc
src/sound_asset.h
src/xml.cc
tools/dcpdiff.cc

index e078f44bd6e8da5efec9982d8f035b19bc2e88fb..f6d1725650d512fe1f181c2679a4a2d3a4fb0237 100644 (file)
@@ -70,6 +70,7 @@ public:
 
 protected:
        friend class PictureAsset;
+       friend class SoundAsset;
        
        /** Fill in a ADSCP::WriteInfo struct.
         *  @param w struct to fill in.
index 6b834a703a61ebab7bb756da9c7cd539e9d6ab78..322859e7288d1a6f6c2d5c354e5c77f06119c157 100644 (file)
@@ -262,21 +262,50 @@ DCP::DCP (string directory)
                }
        }
 
+       if (cpl_file.empty ()) {
+               throw FileError ("no CPL file found", "");
+       }
+
+       if (pkl_file.empty ()) {
+               throw FileError ("no PKL file found", "");
+       }
+
+       if (asset_map_file.empty ()) {
+               throw FileError ("no AssetMap file found", "");
+       }
+
        /* Read the XML */
-       CPL cpl (cpl_file);
-       PKL pkl (pkl_file);
-       AssetMap asset_map (asset_map_file);
+       shared_ptr<CPL> cpl;
+       try {
+               cpl.reset (new CPL (cpl_file));
+       } catch (FileError& e) {
+               throw FileError ("could not load CPL file", cpl_file);
+       }
+
+       shared_ptr<PKL> pkl;
+       try {
+               pkl.reset (new PKL (pkl_file));
+       } catch (FileError& e) {
+               throw FileError ("could not load PKL file", pkl_file);
+       }
+
+       shared_ptr<AssetMap> asset_map;
+       try {
+               asset_map.reset (new AssetMap (asset_map_file));
+       } catch (FileError& e) {
+               throw FileError ("could not load AssetMap file", asset_map_file);
+       }
 
        /* Cross-check */
        /* XXX */
 
        /* Now cherry-pick the required bits into our own data structure */
        
-       _name = cpl.annotation_text;
-       _content_kind = cpl.content_kind;
+       _name = cpl->annotation_text;
+       _content_kind = cpl->content_kind;
+
+       shared_ptr<CPLAssetList> cpl_assets = cpl->reels.front()->asset_list;
 
-       shared_ptr<CPLAssetList> cpl_assets = cpl.reels.front()->asset_list;
-       
        /* XXX */
        _fps = cpl_assets->main_picture->frame_rate.numerator;
        _length = cpl_assets->main_picture->duration;
@@ -296,7 +325,7 @@ DCP::DCP (string directory)
                _assets.push_back (shared_ptr<SoundAsset> (
                                           new SoundAsset (
                                                   _directory,
-                                                  cpl_assets->main_picture->annotation_text,
+                                                  cpl_assets->main_sound->annotation_text,
                                                   _fps,
                                                   _length
                                                   )
index 34508d5bbd4ee78fc8a7663187492a343c172fa0..dae66f900659ff17346e2b7f90fe06920272767d 100644 (file)
@@ -24,6 +24,8 @@
 #include <iostream>
 #include <stdexcept>
 #include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include "KM_fileio.h"
 #include "AS_DCP.h"
 #include "sound_asset.h"
 #include "util.h"
@@ -176,3 +178,72 @@ SoundAsset::write_to_cpl (ostream& s) const
          << "        </MainSound>\n";
 }
 
+list<string>
+SoundAsset::equals (shared_ptr<const Asset> other, EqualityFlags flags) const
+{
+       list<string> notes = Asset::equals (other, flags);
+                    
+       if (flags & MXF_INSPECT) {
+               ASDCP::PCM::MXFReader reader_A;
+               if (ASDCP_FAILURE (reader_A.OpenRead (mxf_path().c_str()))) {
+                       cout << "failed " << mxf_path() << "\n";
+                       throw FileError ("could not open MXF file for reading", mxf_path().string());
+               }
+
+               ASDCP::PCM::MXFReader reader_B;
+               if (ASDCP_FAILURE (reader_B.OpenRead (other->mxf_path().c_str()))) {
+                       cout << "failed " << other->mxf_path() << "\n";
+                       throw FileError ("could not open MXF file for reading", mxf_path().string());
+               }
+
+               ASDCP::PCM::AudioDescriptor desc_A;
+               if (ASDCP_FAILURE (reader_A.FillAudioDescriptor (desc_A))) {
+                       throw DCPReadError ("could not read audio MXF information");
+               }
+               ASDCP::PCM::AudioDescriptor desc_B;
+               if (ASDCP_FAILURE (reader_B.FillAudioDescriptor (desc_B))) {
+                       throw 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 ||
+                       ) {
+               
+                       notes.push_back ("audio MXF picture descriptors differ");
+               }
+
+               ASDCP::PCM::FrameBuffer buffer_A (1 * Kumu::Megabyte);
+               ASDCP::PCM::FrameBuffer buffer_B (1 * Kumu::Megabyte);
+
+               for (int i = 0; i < _length; ++i) {
+                       if (ASDCP_FAILURE (reader_A.ReadFrame (0, buffer_A))) {
+                               throw DCPReadError ("could not read audio frame");
+                       }
+
+                       if (ASDCP_FAILURE (reader_B.ReadFrame (0, buffer_B))) {
+                               throw DCPReadError ("could not read audio frame");
+                       }
+
+                       if (buffer_A.Size() != buffer_B.Size()) {
+                               notes.push_back ("sizes of video data for frame " + lexical_cast<string>(i) + " differ");
+                               continue;
+                       }
+
+                       if (memcmp (buffer_A.RoData(), buffer_B.RoData(), buffer_A.Size()) != 0) {
+                               notes.push_back ("PCM data for frame " + lexical_cast<string>(i) + " differ");
+                               continue;
+                       }
+               }
+       }
+
+       return notes;
+}
index 4fbec895f874001677e9b675d2ea80c65848219f..2d797998cb0e7f830da7cb11dbcc1639f9c736a3 100644 (file)
@@ -84,6 +84,8 @@ public:
         */
        void write_to_cpl (std::ostream& s) const;
 
+       std::list<std::string> equals (boost::shared_ptr<const Asset> other, EqualityFlags flags) const;
+       
 private:
        void construct (sigc::slot<std::string, Channel> get_path);
        std::string path_from_channel (Channel channel, std::vector<std::string> const & files);
index da4ae7435cb870109796c6e170a0f42c7e9d4c5e..4ab6a2e7bcd5460009447ff83b5b31ed76b2422a 100644 (file)
@@ -1,6 +1,7 @@
 #include <sstream>
 #include <iostream>
 #include <boost/lexical_cast.hpp>
+#include <boost/filesystem.hpp>
 #include <libxml++/libxml++.h>
 #include "xml.h"
 #include "exceptions.h"
@@ -125,6 +126,10 @@ XMLNode::done ()
 
 XMLFile::XMLFile (string file, string root_name)
 {
+       if (!filesystem::exists (file)) {
+               throw FileError ("XML file does not exist", file);
+       }
+       
        _parser = new xmlpp::DomParser;
        _parser->parse_file (file);
        if (!_parser) {
index 9dd488edc74147588233224198239390284a341e..df5eb3d00444ee0a079a0017136bfa0e37d92d56 100644 (file)
@@ -1,7 +1,10 @@
+#include <boost/filesystem.hpp>
 #include <getopt.h>
 #include "dcp.h"
+#include "exceptions.h"
 
 using namespace std;
+using namespace boost;
 using namespace libdcp;
 
 static void
@@ -55,15 +58,38 @@ main (int argc, char* argv[])
                exit (EXIT_FAILURE);
        }
 
-       DCP a (argv[optind]);
-       DCP b (argv[optind + 1]);
+       if (!filesystem::exists (argv[optind])) {
+               cerr << argv[0] << ": DCP " << argv[optind] << " not found.\n";
+               exit (EXIT_FAILURE);
+       }
+
+       if (!filesystem::exists (argv[optind + 1])) {
+               cerr << argv[0] << ": DCP " << argv[optind + 1] << " not found.\n";
+               exit (EXIT_FAILURE);
+       }
+
+       DCP* a = 0;
+       try {
+               a = new DCP (argv[optind]);
+       } catch (FileError& e) {
+               cerr << "Could not read DCP " << argv[optind] << "; " << e.what() << " " << e.filename() << "\n";
+               exit (EXIT_FAILURE);
+       }
+
+       DCP* b = 0;
+       try {
+               b = new DCP (argv[optind + 1]);
+       } catch (FileError& e) {
+               cerr << "Could not read DCP " << argv[optind + 1] << "; " << e.what() << " " << e.filename() << "\n";
+               exit (EXIT_FAILURE);
+       }
 
        EqualityFlags flags = EqualityFlags (LIBDCP_METADATA | MXF_INSPECT);
        if (bitwise) {
                flags = EqualityFlags (flags | MXF_BITWISE);
        }
 
-       list<string> notes = a.equals (b, flags);
+       list<string> notes = a->equals (*b, flags);
        if (notes.empty ()) {
                cout << "DCPs identical\n";
                exit (EXIT_SUCCESS);