Don't give an error on verifying Interop DCPs with possibly-incorrectly
authorCarl Hetherington <cth@carlh.net>
Thu, 22 Apr 2021 19:56:38 +0000 (21:56 +0200)
committerCarl Hetherington <cth@carlh.net>
Thu, 22 Apr 2021 19:56:38 +0000 (21:56 +0200)
marked 3D assets.

This also adds a warning into the verification output.

I don't know if this is actually a standard violation but they
have been seen in the wild made by "reputable" DCP creation software.

DoM bug #1976.

src/asset_factory.cc
src/asset_factory.h
src/dcp.cc
src/verify.cc
src/verify.h
test/verify_test.cc

index e02281d2f980c9b4ab9bf705ec008e084d60cd8f..bab656782bddae21dca3ab88d23441df4666c56f 100644 (file)
@@ -54,7 +54,7 @@ using namespace dcp;
 
 
 shared_ptr<Asset>
-dcp::asset_factory (boost::filesystem::path path, bool ignore_incorrect_picture_mxf_type)
+dcp::asset_factory (boost::filesystem::path path, bool ignore_incorrect_picture_mxf_type, bool* found_threed_marked_as_twod)
 {
        /* XXX: asdcplib does not appear to support discovery of read MXFs standard
           (Interop / SMPTE)
@@ -74,7 +74,11 @@ dcp::asset_factory (boost::filesystem::path path, bool ignore_incorrect_picture_
                } catch (dcp::MXFFileError& e) {
                        if (ignore_incorrect_picture_mxf_type && e.number() == ASDCP::RESULT_SFORMAT) {
                                /* Tried to load it as mono but the error says it's stereo; try that instead */
-                               return make_shared<StereoPictureAsset>(path);
+                               auto stereo = make_shared<StereoPictureAsset>(path);
+                               if (stereo && found_threed_marked_as_twod) {
+                                       *found_threed_marked_as_twod = true;
+                               }
+                               return stereo;
                        } else {
                                throw;
                        }
index 2dd04559a664e8e6ce41d2bfcd7b04b0b2570908..0e60de03084c9e9a3178720b51b698fbf243bd23 100644 (file)
@@ -47,7 +47,13 @@ namespace dcp {
 class Asset;
 
 
-std::shared_ptr<Asset> asset_factory (boost::filesystem::path path, bool ignore_incorrect_picture_mxf_type);
+/** Create an Asset from a file.
+ *  @param ignore_incorrect_picture_mxf_type true to ignore cases where a stereo picture asset is marked
+ *  as 2D; if this is false an exception will be thrown in that case.
+ *  @param ignored_incorrect_picture_mxf_type if this is non-null it will be set to true if a 3D asset was
+ *  marked as 2D, otherwise it will be left alone.
+ */
+std::shared_ptr<Asset> asset_factory (boost::filesystem::path path, bool ignore_incorrect_picture_mxf_type, bool* found_threed_marked_as_twod = nullptr);
 
 
 }
index cea79ba4ee6cfb0c4152a1b5db48757349af7315..3316b60e98727b233161627a41fa4eeb7413ab8f 100644 (file)
@@ -261,7 +261,11 @@ DCP::read (vector<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_m
                        *pkl_type == remove_parameters(SMPTESubtitleAsset::static_pkl_type(*_standard))
                        ) {
 
-                       other_assets.push_back (asset_factory(path, ignore_incorrect_picture_mxf_type));
+                       bool found_threed_marked_as_twod = false;
+                       other_assets.push_back (asset_factory(path, ignore_incorrect_picture_mxf_type, &found_threed_marked_as_twod));
+                       if (found_threed_marked_as_twod && notes) {
+                               notes->push_back ({VerificationNote::Type::WARNING, VerificationNote::Code::THREED_ASSET_MARKED_AS_TWOD, path});
+                       }
                } else if (*pkl_type == remove_parameters(FontAsset::static_pkl_type(*_standard))) {
                        other_assets.push_back (make_shared<FontAsset>(i.first, path));
                } else if (*pkl_type == "image/png") {
index c9d9b24d04e6081663490b77f6d67de1011c836c..7948767a84d8045fcd8c43faf26e6956284b19a4 100644 (file)
@@ -1131,7 +1131,7 @@ dcp::verify (
                stage ("Checking DCP", dcp->directory());
                bool carry_on = true;
                try {
-                       dcp->read (&notes);
+                       dcp->read (&notes, true);
                } catch (MissingAssetmapError& e) {
                        notes.push_back ({VerificationNote::Type::ERROR, VerificationNote::Code::FAILED_READ, string(e.what())});
                        carry_on = false;
@@ -1472,6 +1472,8 @@ dcp::note_to_string (VerificationNote note)
                return String::compose("The instantaneous bit rate of the picture asset %1 is close to the limit of 250Mbit/s in at least one place.", note.file()->filename());
        case VerificationNote::Code::EXTERNAL_ASSET:
                return String::compose("The asset %1 that this DCP refers to is not included in the DCP.  It may be a VF.", note.note().get());
+       case VerificationNote::Code::THREED_ASSET_MARKED_AS_TWOD:
+               return String::compose("The asset %1 is 3D but its MXF is marked as 2D.", note.file()->filename());
        case VerificationNote::Code::INVALID_STANDARD:
                return "This DCP does not use the SMPTE standard.";
        case VerificationNote::Code::INVALID_LANGUAGE:
index 169845b7b1bfa596c35fe37c7da670910e2058b8..08be77c6333e107bdbe302bf4165395904831f95 100644 (file)
@@ -153,6 +153,10 @@ public:
                 *  note contains the asset ID
                 */
                EXTERNAL_ASSET,
+               /** A stereoscopic asset has an MXF which is marked as being monoscopic
+                *  file contains the asset filename
+                */
+               THREED_ASSET_MARKED_AS_TWOD,
                /** DCP is Interop, not SMPTE [Bv2.1_6.1] */
                INVALID_STANDARD,
                /** A language or territory does not conform to RFC 5646 [Bv2.1_6.2.1].
index e1637911a9434ae1d24c2d7b1e5e0f70b3124ab7..42da70059d946a9a0a613d501d145139ef19fc70 100644 (file)
@@ -2952,3 +2952,23 @@ BOOST_AUTO_TEST_CASE (verify_incorrect_timed_text_id)
                        { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }
                });
 }
+
+
+/** Check a DCP with a 3D asset marked as 2D */
+BOOST_AUTO_TEST_CASE (verify_threed_marked_as_twod)
+{
+       check_verify_result (
+               { private_test / "data" / "xm" },
+               {
+                       {
+                               dcp::VerificationNote::Type::WARNING,
+                               dcp::VerificationNote::Code::THREED_ASSET_MARKED_AS_TWOD, boost::filesystem::canonical(find_file(private_test / "data" / "xm", "j2c"))
+                       },
+                       {
+                               dcp::VerificationNote::Type::BV21_ERROR,
+                               dcp::VerificationNote::Code::INVALID_STANDARD
+                       },
+               });
+
+}
+