diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-07-31 12:41:33 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-07-31 12:41:33 +0100 |
| commit | e3636c080d3d24471e85f519d69af4c11d5ecbd0 (patch) | |
| tree | f165bc8174ef9fd5668bf3667b167e8601ff9d90 | |
| parent | 32e93176fa91b215d68dee24e7887a21041da54c (diff) | |
Check sound; various fixups.
| -rw-r--r-- | src/asset.h | 1 | ||||
| -rw-r--r-- | src/dcp.cc | 45 | ||||
| -rw-r--r-- | src/sound_asset.cc | 71 | ||||
| -rw-r--r-- | src/sound_asset.h | 2 | ||||
| -rw-r--r-- | src/xml.cc | 5 | ||||
| -rw-r--r-- | tools/dcpdiff.cc | 32 |
6 files changed, 145 insertions, 11 deletions
diff --git a/src/asset.h b/src/asset.h index e078f44b..f6d17256 100644 --- a/src/asset.h +++ b/src/asset.h @@ -70,6 +70,7 @@ public: protected: friend class PictureAsset; + friend class SoundAsset; /** Fill in a ADSCP::WriteInfo struct. * @param w struct to fill in. @@ -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 ) diff --git a/src/sound_asset.cc b/src/sound_asset.cc index 34508d5b..dae66f90 100644 --- a/src/sound_asset.cc +++ b/src/sound_asset.cc @@ -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; +} diff --git a/src/sound_asset.h b/src/sound_asset.h index 4fbec895..2d797998 100644 --- a/src/sound_asset.h +++ b/src/sound_asset.h @@ -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); @@ -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) { diff --git a/tools/dcpdiff.cc b/tools/dcpdiff.cc index 9dd488ed..df5eb3d0 100644 --- a/tools/dcpdiff.cc +++ b/tools/dcpdiff.cc @@ -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); |
