Make some not-so-important CPL read errors non-fatal (DoM #2797). main v1.8.99
authorCarl Hetherington <cth@carlh.net>
Wed, 17 Apr 2024 20:19:02 +0000 (22:19 +0200)
committerCarl Hetherington <cth@carlh.net>
Wed, 17 Apr 2024 20:19:02 +0000 (22:19 +0200)
src/cpl.cc
src/cpl.h
src/dcp.cc
src/verify.cc
src/verify.h

index 5ff86fda7baff36b2e397a9c7dc934f7e1d7740c..6a25863ada9c89d3572c7e3a989c0d85a77f6367 100644 (file)
@@ -104,7 +104,7 @@ CPL::CPL (string annotation_text, ContentKind content_kind, Standard standard)
 }
 
 
-CPL::CPL (boost::filesystem::path file)
+CPL::CPL (boost::filesystem::path file, vector<dcp::VerificationNote>* notes)
        : Asset (file)
        , _content_kind (ContentKind::FEATURE)
 {
@@ -116,7 +116,17 @@ CPL::CPL (boost::filesystem::path file)
        } else if (f.namespace_uri() == cpl_smpte_ns) {
                _standard = Standard::SMPTE;
        } else {
-               boost::throw_exception (XMLError ("Unrecognised CPL namespace " + f.namespace_uri()));
+               if (notes) {
+                       notes->push_back(
+                               dcp::VerificationNote(
+                                       dcp::VerificationNote::Type::ERROR,
+                                       dcp::VerificationNote::Code::INVALID_CPL_NAMESPACE,
+                                       f.namespace_uri(),
+                                       file
+                                       )
+                               );
+               }
+               _standard = Standard::INTEROP;
        }
 
        _id = remove_urn_uuid (f.string_child ("Id"));
@@ -139,7 +149,16 @@ CPL::CPL (boost::filesystem::path file)
                content_version->done ();
        } else if (_standard == Standard::SMPTE) {
                /* ContentVersion is required in SMPTE */
-               throw XMLError ("Missing ContentVersion tag in CPL");
+               if (notes) {
+                       notes->push_back(
+                               dcp::VerificationNote(
+                                       dcp::VerificationNote::Type::ERROR,
+                                       dcp::VerificationNote::Code::MISSING_CPL_CONTENT_VERSION,
+                                       _id,
+                                       file
+                                       )
+                               );
+               }
        }
        auto rating_list = f.node_child ("RatingList");
        for (auto i: rating_list->node_children("Rating")) {
index fb4f3376afc201fd12a5566e07baaad8335dad58..824faaa132217756054a8d5fad66aefe76b985c1 100644 (file)
--- a/src/cpl.h
+++ b/src/cpl.h
@@ -47,6 +47,7 @@
 #include "key.h"
 #include "language_tag.h"
 #include "rating.h"
+#include "verify.h"
 #include <boost/filesystem.hpp>
 #include <boost/function.hpp>
 #include <boost/optional.hpp>
@@ -82,8 +83,11 @@ class CPL : public Asset
 public:
        CPL (std::string annotation_text, ContentKind content_kind, Standard standard);
 
-       /** Construct a CPL object from a XML file */
-       explicit CPL (boost::filesystem::path file);
+       /** Construct a CPL object from a XML file.
+        *  If notes is not null, non-fatal errors will be added.
+        *  Exceptions will be thrown on non-recoverable errors.
+        */
+       explicit CPL(boost::filesystem::path file, std::vector<dcp::VerificationNote>* notes = nullptr);
 
        bool equals (
                std::shared_ptr<const Asset> other,
index d603cfae48694ae71d89ae9f0b57a673efd0381a..eb21b47d1375ef3635ea12dff8836f2be5c77f41 100644 (file)
@@ -234,7 +234,7 @@ DCP::read (vector<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_m
                        delete p;
 
                        if (root == "CompositionPlaylist") {
-                               auto cpl = make_shared<CPL>(path);
+                               auto cpl = make_shared<CPL>(path, notes);
                                if (cpl->standard() != standard && notes) {
                                        notes->push_back ({VerificationNote::Type::ERROR, VerificationNote::Code::MISMATCHED_STANDARD});
                                }
index 9715c020aacd089b8eee7ea87c30baaadec83471..112a5bb5ed810c7e40afbf0c1e02ebaf54811a93 100644 (file)
@@ -2178,6 +2178,10 @@ dcp::note_to_string (VerificationNote note)
                return String::compose("The asset with ID %1 in the asset map actually has an id of %2", note.id().get(), note.other_id().get());
        case VerificationNote::Code::EMPTY_CONTENT_VERSION_LABEL_TEXT:
                return String::compose("The <LabelText> in a <ContentVersion> in CPL %1 is empty", note.id().get());
+       case VerificationNote::Code::INVALID_CPL_NAMESPACE:
+               return String::compose("The namespace %1 in CPL %2 is invalid", note.note().get(), note.file()->filename());
+       case VerificationNote::Code::MISSING_CPL_CONTENT_VERSION:
+               return String::compose("The CPL %1 has no <ContentVersion> tag", note.note().get());
        }
 
        return "";
index 4ca3297ac582d1b01c9f541d7f812b2d320414df..b5d913bdc9b6f9537a852e2f28e316188a5615d1 100644 (file)
@@ -475,6 +475,16 @@ public:
                 *  file contains the CPL filename
                 */
                EMPTY_CONTENT_VERSION_LABEL_TEXT,
+               /** The CPL namespace is not valid.
+                *  note contains the invalid namespace
+                *  file contains the CPL filename
+                */
+               INVALID_CPL_NAMESPACE,
+               /** A SMPTE CPL does not contain a _<ContentVersion>_ tag
+                *  note contains the CPL ID
+                *  file contains the CPL filename
+                */
+               MISSING_CPL_CONTENT_VERSION
        };
 
        VerificationNote (Type type, Code code)