diff options
| author | Carl Hetherington <cth@carlh.net> | 2019-12-06 10:47:04 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2019-12-22 01:21:00 +0100 |
| commit | 30dfa051113792305f9704d5a76ffaf57c21063d (patch) | |
| tree | 4a4055b40bfb64ebf5b7509ef81a104db4a52e46 /src | |
| parent | 9cb23adda9ebe6a76992b68db78ccb638348dac1 (diff) | |
Use VerificationNote for non-fatal errors in DCP::read.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dcp.cc | 41 | ||||
| -rw-r--r-- | src/dcp.h | 8 | ||||
| -rw-r--r-- | src/exceptions.cc | 26 | ||||
| -rw-r--r-- | src/exceptions.h | 36 | ||||
| -rw-r--r-- | src/verify.cc | 37 | ||||
| -rw-r--r-- | src/verify.h | 8 |
6 files changed, 64 insertions, 92 deletions
@@ -58,6 +58,7 @@ #include "font_asset.h" #include "pkl.h" #include "asset_factory.h" +#include "verify.h" #include <asdcp/AS_DCP.h> #include <xmlsec/xmldsig.h> #include <xmlsec/app.h> @@ -95,21 +96,19 @@ DCP::DCP (boost::filesystem::path directory) _directory = boost::filesystem::canonical (_directory); } -/** Call this instead of throwing an exception if the error can be tolerated */ -template<class T> void -survivable_error (bool keep_going, dcp::DCP::ReadErrors* errors, T const & e) -{ - if (keep_going) { - if (errors) { - errors->push_back (shared_ptr<T> (new T (e))); - } - } else { - throw e; - } -} - +/** Read a DCP. This method does not do any deep checking of the DCP's validity, but + * if it comes across any bad things it will do one of two things. + * + * Errors that are so serious that they prevent the method from working will result + * in an exception being thrown. For example, a missing ASSETMAP means that the DCP + * can't be read without a lot of guesswork, so this will throw. + * + * Errors that are not fatal will be added to notes, if it's non-0. For example, + * if the DCP contains a mixture of Interop and SMPTE elements this will result + * in a note being added to the list. + */ void -DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mxf_type) +DCP::read (list<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_mxf_type) { /* Read the ASSETMAP and PKL */ @@ -193,12 +192,16 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx been seen in the wild with a DCP that claims to come from ClipsterDCI 5.10.0.5. */ - survivable_error (keep_going, errors, EmptyAssetPathError(i->first)); + if (notes) { + notes->push_back (VerificationNote(VerificationNote::VERIFY_WARNING, VerificationNote::EMPTY_ASSET_PATH)); + } continue; } if (!boost::filesystem::exists(path)) { - survivable_error (keep_going, errors, MissingAssetError (path)); + if (notes) { + notes->push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::MISSING_ASSET)); + } continue; } @@ -227,13 +230,13 @@ DCP::read (bool keep_going, ReadErrors* errors, bool ignore_incorrect_picture_mx if (root == "CompositionPlaylist") { shared_ptr<CPL> cpl (new CPL (path)); - if (_standard && cpl->standard() && cpl->standard().get() != _standard.get()) { - survivable_error (keep_going, errors, MismatchedStandardError ()); + if (_standard && cpl->standard() && cpl->standard().get() != _standard.get() && notes) { + notes->push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::MISMATCHED_STANDARD)); } _cpls.push_back (cpl); } else if (root == "DCSubtitle") { if (_standard && _standard.get() == SMPTE) { - survivable_error (keep_going, errors, MismatchedStandardError ()); + notes->push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::MISMATCHED_STANDARD)); } other_assets.push_back (shared_ptr<InteropSubtitleAsset> (new InteropSubtitleAsset (path))); } @@ -43,6 +43,7 @@ #include "certificate.h" #include "metadata.h" #include "name_format.h" +#include "verify.h" #include <boost/shared_ptr.hpp> #include <boost/signals2.hpp> #include <string> @@ -83,16 +84,13 @@ public: */ explicit DCP (boost::filesystem::path directory); - typedef std::list<boost::shared_ptr<DCPReadError> > ReadErrors; - /** Read the DCP's structure into this object. - * @param keep_going true to try to keep going in the face of (some) errors. - * @param errors List of errors that will be added to if keep_going is true. + * @param notes List of notes that will be added to if non-0. * @param ignore_incorrect_picture_mxf_type true to try loading MXF files marked as monoscopic * as stereoscopic if the monoscopic load fails; fixes problems some 3D DCPs that (I think) * have an incorrect descriptor in their MXF. */ - void read (bool keep_going = false, ReadErrors* errors = 0, bool ignore_incorrect_picture_mxf_type = false); + void read (std::list<VerificationNote>* notes = 0, bool ignore_incorrect_picture_mxf_type = false); /** Compare this DCP with another, according to various options. * @param other DCP to compare this one to. diff --git a/src/exceptions.cc b/src/exceptions.cc index 19422090..a49c7004 100644 --- a/src/exceptions.cc +++ b/src/exceptions.cc @@ -62,17 +62,6 @@ TimeFormatError::TimeFormatError (string bad_time) } -MissingAssetError::MissingAssetError (boost::filesystem::path path, AssetType type) - : DCPReadError ( - type == MAIN_PICTURE ? String::compose ("Missing asset %1 for main picture", path.filename().string()) : - (type == MAIN_SOUND ? String::compose ("Missing asset %1 for main sound", path.filename().string()) : - (type == MAIN_SUBTITLE ? String::compose ("Missing asset %1 for main subtitle", path.filename().string()) : - String::compose ("Missing asset %1", path.filename().string())))) - , _path (path) -{ - -} - BadContentKindError::BadContentKindError (string content_kind) : DCPReadError (String::compose("Bad content kind '%1'", content_kind)) { @@ -92,12 +81,6 @@ ProgrammingError::ProgrammingError (string file, int line) } -MismatchedStandardError::MismatchedStandardError () - : DCPReadError ("DCP contains both Interop and SMPTE parts") -{ - -} - KDMDecryptionError::KDMDecryptionError (std::string message, int cipher_length, int modulus_dmax) : runtime_error (String::compose ("Could not decrypt KDM (%1) (%2/%3)", message, cipher_length, modulus_dmax)) { @@ -130,15 +113,6 @@ MissingSubtitleImageError::MissingSubtitleImageError (string id) } -/** The <Path> in the ASSETMAP is empty for asset. I can't see how this is valid, - but it's been seen in the wild with a DCP that claims to come from ClipsterDCI 5.10.0.5. - */ -EmptyAssetPathError::EmptyAssetPathError (string id) - : DCPReadError (String::compose("Asset map path is empty for asset %1", id)) -{ - -} - BadKDMDateError::BadKDMDateError (bool starts_too_early) : runtime_error ( starts_too_early ? diff --git a/src/exceptions.h b/src/exceptions.h index 17b18eb2..ccf7a081 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -119,30 +119,6 @@ private: boost::optional<std::string> _detail; }; -/** @class MissingAssetError - * @brief An error of a missing asset. - */ -class MissingAssetError : public DCPReadError -{ -public: - enum AssetType { - MAIN_PICTURE, //< main picture is missing - MAIN_SOUND, //< main sound is missing - MAIN_SUBTITLE, //< main subtitle is missing - UNKNOWN //< something is missing but we don't know what - }; - - MissingAssetError (boost::filesystem::path, AssetType = UNKNOWN); - ~MissingAssetError () throw () {} - - boost::filesystem::path path () const { - return _path; - } - -private: - boost::filesystem::path _path; -}; - class BadContentKindError : public DCPReadError { public: @@ -198,12 +174,6 @@ public: ProgrammingError (std::string file, int line); }; -class MismatchedStandardError : public DCPReadError -{ -public: - MismatchedStandardError (); -}; - class KDMDecryptionError : public std::runtime_error { public: @@ -228,12 +198,6 @@ public: MissingSubtitleImageError (std::string id); }; -class EmptyAssetPathError : public DCPReadError -{ -public: - EmptyAssetPathError (std::string id); -}; - class BadKDMDateError : public std::runtime_error { public: diff --git a/src/verify.cc b/src/verify.cc index 809e9e11..279de556 100644 --- a/src/verify.cc +++ b/src/verify.cc @@ -105,19 +105,14 @@ dcp::verify (vector<boost::filesystem::path> directories, function<void (string, BOOST_FOREACH (shared_ptr<DCP> dcp, dcps) { stage ("Checking DCP", dcp->directory()); - DCP::ReadErrors errors; try { - dcp->read (true, &errors); + dcp->read (¬es); } catch (DCPReadError& e) { notes.push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::GENERAL_READ, string(e.what()))); } catch (XMLError& e) { notes.push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::GENERAL_READ, string(e.what()))); } - BOOST_FOREACH (shared_ptr<DCPReadError> i, errors) { - notes.push_back (VerificationNote(VerificationNote::VERIFY_ERROR, VerificationNote::GENERAL_READ, string(i->what()))); - } - BOOST_FOREACH (shared_ptr<CPL> cpl, dcp->cpls()) { stage ("Checking CPL", cpl->file()); @@ -188,3 +183,33 @@ dcp::verify (vector<boost::filesystem::path> directories, function<void (string, return notes; } + +string +dcp::note_to_string (dcp::VerificationNote note) +{ + switch (note.code()) { + case dcp::VerificationNote::GENERAL_READ: + return *note.note(); + case dcp::VerificationNote::CPL_HASH_INCORRECT: + return "The hash of the CPL in the PKL does not agree with the CPL file"; + case dcp::VerificationNote::INVALID_PICTURE_FRAME_RATE: + return "The picture in a reel has an invalid frame rate"; + case dcp::VerificationNote::PICTURE_HASH_INCORRECT: + return dcp::String::compose("The hash of the picture asset %1 does not agree with the PKL file", note.file()->filename()); + case dcp::VerificationNote::PKL_CPL_PICTURE_HASHES_DISAGREE: + return "The PKL and CPL hashes disagree for a picture asset."; + case dcp::VerificationNote::SOUND_HASH_INCORRECT: + return dcp::String::compose("The hash of the sound asset %1 does not agree with the PKL file", note.file()->filename()); + case dcp::VerificationNote::PKL_CPL_SOUND_HASHES_DISAGREE: + return "The PKL and CPL hashes disagree for a sound asset."; + case dcp::VerificationNote::EMPTY_ASSET_PATH: + return "The asset map contains an empty asset path."; + case dcp::VerificationNote::MISSING_ASSET: + return "The file for an asset in the asset map cannot be found."; + case dcp::VerificationNote::MISMATCHED_STANDARD: + return "The DCP contains both SMPTE and Interop parts."; + } + + return ""; +} + diff --git a/src/verify.h b/src/verify.h index 4b967d1d..e219c6ec 100644 --- a/src/verify.h +++ b/src/verify.h @@ -69,6 +69,12 @@ public: SOUND_HASH_INCORRECT, /** The hash of a main sound is different in the CPL and PKL */ PKL_CPL_SOUND_HASHES_DISAGREE, + /** An assetmap's <Path> entry is empty */ + EMPTY_ASSET_PATH, + /** An file mentioned in an assetmap cannot be found */ + MISSING_ASSET, + /** The DCP contains both SMPTE and Interop-standard components */ + MISMATCHED_STANDARD, }; VerificationNote (Type type, Code code) @@ -117,6 +123,8 @@ std::list<VerificationNote> verify ( boost::function<void (float)> progress ); +std::string note_to_string (dcp::VerificationNote note); + } #endif |
