Bv2.1 8.2: all parts of a reel must have the same duration.
authorCarl Hetherington <cth@carlh.net>
Thu, 14 Jan 2021 22:38:30 +0000 (23:38 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 17 Jan 2021 19:13:23 +0000 (20:13 +0100)
src/verify.cc
src/verify.h
test/test.cc
test/verify_test.cc

index dc43570633ec1d0563ca4c7d26aa18900d67f344..a7f3f1da9a58cd8e2b8fe80903c95cf981c6872a 100644 (file)
@@ -1065,6 +1065,18 @@ dcp::verify (
                                        }
                                }
 
+                               if (dcp->standard() == dcp::SMPTE) {
+                                       boost::optional<int64_t> duration;
+                                       for (auto i: reel->assets()) {
+                                               if (!duration) {
+                                                       duration = i->actual_duration();
+                                               } else if (*duration != i->actual_duration()) {
+                                                       notes.push_back (VerificationNote(VerificationNote::VERIFY_BV21_ERROR, VerificationNote::MISMATCHED_ASSET_DURATION, i->id()));
+                                                       break;
+                                               }
+                                       }
+                               }
+
                                if (reel->main_picture()) {
                                        /* Check reel stuff */
                                        auto const frame_rate = reel->main_picture()->frame_rate();
@@ -1242,6 +1254,8 @@ dcp::note_to_string (dcp::VerificationNote note)
                return "The CPL has no <AnnotationText> tag, which is required by Bv2.1";
        case dcp::VerificationNote::CPL_ANNOTATION_TEXT_DIFFERS_FROM_CONTENT_TITLE_TEXT:
                return "The CPL's <AnnotationText> differs from its <ContentTitleText>, which Bv2.1 advises against.";
+       case dcp::VerificationNote::MISMATCHED_ASSET_DURATION:
+               return "All assets in a reel do not have the same duration, which is required by Bv2.1";
        }
 
        return "";
index cab8ba4f9048706d833729bed85900e2909c821e..3b2629f996414cb9e081bd59aadb832363b8192d 100644 (file)
@@ -137,6 +137,8 @@ public:
                MISSING_ANNOTATION_TEXT_IN_CPL,
                /** The <AnnotationText> is not the same as the <ContentTitleText> [Bv2.1_8.1] */
                CPL_ANNOTATION_TEXT_DIFFERS_FROM_CONTENT_TITLE_TEXT,
+               /** At least one asset in a reel does not have the same duration as the others */
+               MISMATCHED_ASSET_DURATION,
        };
 
        VerificationNote (Type type, Code code)
index f110c9cbf2413209523fffe010b47add5b99484b..ba309f0e5228cc5188932cac7ff8bc8f7df20aa1 100644 (file)
@@ -402,7 +402,7 @@ make_simple_with_interop_subs (boost::filesystem::path path)
 shared_ptr<dcp::DCP>
 make_simple_with_smpte_subs (boost::filesystem::path path)
 {
-       shared_ptr<dcp::DCP> dcp = make_simple (path);
+       shared_ptr<dcp::DCP> dcp = make_simple (path, 1, 240);
 
        shared_ptr<dcp::SMPTESubtitleAsset> subs(new dcp::SMPTESubtitleAsset());
        subs->set_language (dcp::LanguageTag("de-DE"));
@@ -437,7 +437,7 @@ make_simple_with_interop_ccaps (boost::filesystem::path path)
 shared_ptr<dcp::DCP>
 make_simple_with_smpte_ccaps (boost::filesystem::path path)
 {
-       shared_ptr<dcp::DCP> dcp = make_simple (path);
+       shared_ptr<dcp::DCP> dcp = make_simple (path, 1, 240);
 
        shared_ptr<dcp::SMPTESubtitleAsset> subs(new dcp::SMPTESubtitleAsset());
        subs->set_language (dcp::LanguageTag("de-DE"));
index 6ed6b092333d73e2157462cc11d2aa54e237efc2..86b98d2be620a4dd8c3cb2ad0ca45b26cedd937d 100644 (file)
@@ -1139,7 +1139,7 @@ BOOST_AUTO_TEST_CASE (verify_missing_language_tag_in_subtitle_xml)
 {
        boost::filesystem::path dir = "build/test/verify_missing_language_tag_in_subtitle_xml";
        prepare_directory (dir);
-       auto dcp = make_simple (dir, 1);
+       auto dcp = make_simple (dir, 1, 240);
 
        string const xml =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
@@ -1169,7 +1169,7 @@ BOOST_AUTO_TEST_CASE (verify_missing_language_tag_in_subtitle_xml)
        auto subs = make_shared<dcp::SMPTESubtitleAsset>(dir / "subs.xml");
        subs->write (dir / "subs.mxf");
 
-       auto reel_subs = make_shared<dcp::ReelSubtitleAsset>(subs, dcp::Fraction(24, 1), 100, 0);
+       auto reel_subs = make_shared<dcp::ReelSubtitleAsset>(subs, dcp::Fraction(24, 1), 240, 0);
        dcp->cpls().front()->reels().front()->add(reel_subs);
        dcp->write_xml (dcp::SMPTE);
 
@@ -1222,7 +1222,7 @@ BOOST_AUTO_TEST_CASE (verify_missing_start_time_tag_in_subtitle_xml)
 {
        boost::filesystem::path dir = "build/test/verify_missing_start_time_tag_in_subtitle_xml";
        prepare_directory (dir);
-       auto dcp = make_simple (dir, 1);
+       auto dcp = make_simple (dir, 1, 240);
 
        string const xml =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
@@ -1252,7 +1252,7 @@ BOOST_AUTO_TEST_CASE (verify_missing_start_time_tag_in_subtitle_xml)
        auto subs = make_shared<dcp::SMPTESubtitleAsset>(dir / "subs.xml");
        subs->write (dir / "subs.mxf");
 
-       auto reel_subs = make_shared<dcp::ReelSubtitleAsset>(subs, dcp::Fraction(24, 1), 100, 0);
+       auto reel_subs = make_shared<dcp::ReelSubtitleAsset>(subs, dcp::Fraction(24, 1), 240, 0);
        dcp->cpls().front()->reels().front()->add(reel_subs);
        dcp->write_xml (dcp::SMPTE);
 
@@ -1269,7 +1269,7 @@ BOOST_AUTO_TEST_CASE (verify_non_zero_start_time_tag_in_subtitle_xml)
 {
        boost::filesystem::path dir = "build/test/verify_non_zero_start_time_tag_in_subtitle_xml";
        prepare_directory (dir);
-       auto dcp = make_simple (dir, 1);
+       auto dcp = make_simple (dir, 1, 240);
 
        string const xml =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
@@ -1300,7 +1300,7 @@ BOOST_AUTO_TEST_CASE (verify_non_zero_start_time_tag_in_subtitle_xml)
        auto subs = make_shared<dcp::SMPTESubtitleAsset>(dir / "subs.xml");
        subs->write (dir / "subs.mxf");
 
-       auto reel_subs = make_shared<dcp::ReelSubtitleAsset>(subs, dcp::Fraction(24, 1), 100, 0);
+       auto reel_subs = make_shared<dcp::ReelSubtitleAsset>(subs, dcp::Fraction(24, 1), 240, 0);
        dcp->cpls().front()->reels().front()->add(reel_subs);
        dcp->write_xml (dcp::SMPTE);
 
@@ -1673,3 +1673,28 @@ BOOST_AUTO_TEST_CASE (verify_cpl_annotation_text_should_be_same_as_content_title
                });
 }
 
+
+BOOST_AUTO_TEST_CASE (verify_reel_assets_durations_must_match)
+{
+       boost::filesystem::path const dir("build/test/verify_reel_assets_durations_must_match");
+       boost::filesystem::remove_all (dir);
+       boost::filesystem::create_directories (dir);
+       shared_ptr<dcp::DCP> dcp (new dcp::DCP(dir));
+       shared_ptr<dcp::CPL> cpl (new dcp::CPL("A Test DCP", dcp::FEATURE));
+
+       shared_ptr<dcp::MonoPictureAsset> mp = simple_picture (dir, "", 24);
+       shared_ptr<dcp::SoundAsset> ms = simple_sound (dir, "", dcp::MXFMetadata(), "en-US", 25);
+
+       cpl->add (
+               make_shared<dcp::Reel>(
+                       make_shared<dcp::ReelMonoPictureAsset>(mp, 0),
+                       make_shared<dcp::ReelSoundAsset>(ms, 0)
+                       )
+                );
+
+       dcp->add (cpl);
+       dcp->write_xml (dcp::SMPTE);
+
+       check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISMATCHED_ASSET_DURATION }});
+}
+