X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=test%2Fverify_test.cc;h=fd76209bc2ee177e72fff245d895863ce8bb58b9;hb=36310b78f8fd84554f2c87dc513bd04efe0fd69a;hp=1789aafede67c01d46509038e88dbd7a05beb197;hpb=33942a6c7ab40dfe1ccb87e80497fc0b5390b76a;p=libdcp.git diff --git a/test/verify_test.cc b/test/verify_test.cc index 1789aafe..fd76209b 100644 --- a/test/verify_test.cc +++ b/test/verify_test.cc @@ -48,6 +48,7 @@ #include "reel_closed_caption_asset.h" #include "reel_stereo_picture_asset.h" #include "reel_subtitle_asset.h" +#include "reel_markers_asset.h" #include "compose.hpp" #include "test.h" #include @@ -66,7 +67,9 @@ using boost::optional; using std::shared_ptr; -static list > > stages; +static list>> stages; +static string const dcp_test1_pkl = "pkl_2b9b857f-ab4a-440e-a313-1ace0f1cfc95.xml"; +static string const dcp_test1_cpl = "cpl_81fb54df-e1bf-4647-8788-ea7ba154375b.xml"; static void stage (string s, optional p) @@ -108,7 +111,9 @@ write_dcp_with_single_asset (boost::filesystem::path dir, shared_ptr(); reel->add (reel_asset); - auto cpl = make_shared("hello", dcp::FEATURE); + reel->add (simple_markers()); + + auto cpl = make_shared("hello", dcp::TRAILER); cpl->add (reel); auto dcp = make_shared(dir); dcp->add (cpl); @@ -138,7 +143,9 @@ public: void replace (string a, string b) { + auto old_content = _content; boost::algorithm::replace_all (_content, a, b); + BOOST_REQUIRE (_content != old_content); } private: @@ -162,7 +169,6 @@ void check_verify_result (vector dir, vector> types_and_codes) { auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - dump_notes (notes); BOOST_REQUIRE_EQUAL (notes.size(), types_and_codes.size()); auto i = notes.begin(); auto j = types_and_codes.begin(); @@ -206,8 +212,8 @@ BOOST_AUTO_TEST_CASE (verify_test1) auto directories = setup (1, 1); auto notes = dcp::verify (directories, &stage, &progress, xsd_test); - boost::filesystem::path const cpl_file = "build/test/verify_test1/cpl_81fb54df-e1bf-4647-8788-ea7ba154375b.xml"; - boost::filesystem::path const pkl_file = "build/test/verify_test1/pkl_cd49971e-bf4c-4594-8474-54ebef09a40c.xml"; + boost::filesystem::path const cpl_file = boost::filesystem::path("build") / "test" / "verify_test1" / dcp_test1_cpl; + boost::filesystem::path const pkl_file = boost::filesystem::path("build") / "test" / "verify_test1" / dcp_test1_pkl; boost::filesystem::path const assetmap_file = "build/test/verify_test1/ASSETMAP.xml"; auto st = stages.begin(); @@ -284,7 +290,7 @@ BOOST_AUTO_TEST_CASE (verify_test3) auto directories = setup (1, 3); { - Editor e ("build/test/verify_test3/pkl_cd49971e-bf4c-4594-8474-54ebef09a40c.xml"); + Editor e (boost::filesystem::path("build") / "test" / "verify_test3" / dcp_test1_pkl); e.replace ("", "x"); } @@ -306,7 +312,7 @@ BOOST_AUTO_TEST_CASE (verify_test4) auto directories = setup (1, 4); { - Editor e ("build/test/verify_test4/cpl_81fb54df-e1bf-4647-8788-ea7ba154375b.xml"); + Editor e (boost::filesystem::path("build") / "test" / "verify_test4" / dcp_test1_cpl); e.replace ("", "x"); } @@ -314,21 +320,21 @@ BOOST_AUTO_TEST_CASE (verify_test4) BOOST_REQUIRE_EQUAL (notes.size(), 1); BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::GENERAL_READ); - BOOST_CHECK_EQUAL (*notes.front().note(), "Bad content kind 'xfeature'"); + BOOST_CHECK_EQUAL (*notes.front().note(), "Bad content kind 'xtrailer'"); } static boost::filesystem::path cpl (int n) { - return dcp::String::compose("build/test/verify_test%1/cpl_81fb54df-e1bf-4647-8788-ea7ba154375b.xml", n); + return dcp::String::compose("build/test/verify_test%1/%2", n, dcp_test1_cpl); } static boost::filesystem::path pkl (int n) { - return dcp::String::compose("build/test/verify_test%1/pkl_cd49971e-bf4c-4594-8474-54ebef09a40c.xml", n); + return dcp::String::compose("build/test/verify_test%1/%2", n, dcp_test1_pkl); } static @@ -383,6 +389,10 @@ BOOST_AUTO_TEST_CASE (verify_test8) 8, &cpl, "http://www.smpte-ra.org/schemas/429-7/2006/CPL", "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#", { dcp::VerificationNote::MISMATCHED_STANDARD, + dcp::VerificationNote::XML_VALIDATION_ERROR, + dcp::VerificationNote::XML_VALIDATION_ERROR, + dcp::VerificationNote::XML_VALIDATION_ERROR, + dcp::VerificationNote::XML_VALIDATION_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT } ); @@ -415,7 +425,7 @@ BOOST_AUTO_TEST_CASE (verify_test11) { check_verify_result_after_replace ( 11, &pkl, - "urn:uuid:cd4", "urn:uuid:xd4", + "urn:uuid:2b9", "urn:uuid:xb9", { dcp::VerificationNote::XML_VALIDATION_ERROR } ); } @@ -425,7 +435,7 @@ BOOST_AUTO_TEST_CASE (verify_test12) { check_verify_result_after_replace ( 12, &asset_map, - "urn:uuid:63c", "urn:uuid:x3c", + "urn:uuid:07e", "urn:uuid:x7e", { dcp::VerificationNote::XML_VALIDATION_ERROR } ); } @@ -437,8 +447,8 @@ BOOST_AUTO_TEST_CASE (verify_test13) auto directories = setup (3, 13); auto notes = dcp::verify (directories, &stage, &progress, xsd_test); - boost::filesystem::path const cpl_file = "build/test/verify_test13/cpl_cbfd2bc0-21cf-4a8f-95d8-9cddcbe51296.xml"; - boost::filesystem::path const pkl_file = "build/test/verify_test13/pkl_d87a950c-bd6f-41f6-90cc-56ccd673e131.xml"; + boost::filesystem::path const cpl_file = boost::filesystem::path("build") / "test" / "verify_test13" / "cpl_cbfd2bc0-21cf-4a8f-95d8-9cddcbe51296.xml"; + boost::filesystem::path const pkl_file = boost::filesystem::path("build") / "test" / "verify_test13" / "pkl_d87a950c-bd6f-41f6-90cc-56ccd673e131.xml"; boost::filesystem::path const assetmap_file = "build/test/verify_test13/ASSETMAP"; auto st = stages.begin(); @@ -539,8 +549,10 @@ BOOST_AUTO_TEST_CASE (verify_test15) check_verify_result ( { dir }, - {{ dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::PICTURE_FRAME_TOO_LARGE_IN_BYTES }} - ); + { + { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::PICTURE_FRAME_TOO_LARGE_IN_BYTES }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } @@ -565,8 +577,10 @@ BOOST_AUTO_TEST_CASE (verify_test16) check_verify_result ( { dir }, - {{ dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::PICTURE_FRAME_NEARLY_TOO_LARGE_IN_BYTES }} - ); + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::PICTURE_FRAME_NEARLY_TOO_LARGE_IN_BYTES }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } @@ -582,8 +596,7 @@ BOOST_AUTO_TEST_CASE (verify_test17) boost::filesystem::remove_all (dir); dcp_from_frame (frame, dir); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE_EQUAL (notes.size(), 0); + check_verify_result ({ dir }, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } @@ -636,8 +649,7 @@ BOOST_AUTO_TEST_CASE (verify_test20) auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); write_dcp_with_single_asset (dir, reel_asset); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE_EQUAL (notes.size(), 0); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } @@ -656,7 +668,8 @@ BOOST_AUTO_TEST_CASE (verify_test21) { { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME } + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } }); } @@ -682,7 +695,10 @@ BOOST_AUTO_TEST_CASE (verify_test22) check_verify_result ( { vf_dir }, - {{ dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::EXTERNAL_ASSET }}); + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::EXTERNAL_ASSET }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } @@ -698,7 +714,10 @@ BOOST_AUTO_TEST_CASE (verify_test23) auto reel = make_shared(); reel->add (reel_asset); - auto cpl = make_shared("hello", dcp::FEATURE); + + reel->add (simple_markers(16 * 24 - 1)); + + auto cpl = make_shared("hello", dcp::TRAILER); cpl->add (reel); cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-"); cpl->set_main_sound_sample_rate (48000); @@ -709,8 +728,7 @@ BOOST_AUTO_TEST_CASE (verify_test23) dcp.add (cpl); dcp.write_xml (dcp::SMPTE); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_CHECK (notes.empty()); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } @@ -735,12 +753,15 @@ BOOST_AUTO_TEST_CASE (verify_test24) auto reel = make_shared(); reel->add (black_picture_asset(dir)); - auto cpl = make_shared("hello", dcp::FEATURE); + auto cpl = make_shared("hello", dcp::TRAILER); cpl->add (reel); cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-"); cpl->set_main_sound_sample_rate (48000); cpl->set_main_picture_stored_area (dcp::Size(1998, 1080)); cpl->set_main_picture_active_area (dcp::Size(1440, 1080)); + cpl->set_version_number (1); + + reel->add (simple_markers()); dcp::DCP dcp (dir); dcp.add (cpl); @@ -770,7 +791,7 @@ BOOST_AUTO_TEST_CASE (verify_test25) auto reel = make_shared(); reel->add (black_picture_asset(dir)); - auto cpl = make_shared("hello", dcp::FEATURE); + auto cpl = make_shared("hello", dcp::TRAILER); cpl->add (reel); cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-"); cpl->set_main_sound_sample_rate (48000); @@ -807,7 +828,7 @@ BOOST_AUTO_TEST_CASE (verify_test26) write_dcp_with_single_asset (dir, reel_asset); auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE_EQUAL (notes.size(), 2U); + BOOST_REQUIRE_EQUAL (notes.size(), 3U); auto i = notes.begin(); BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::BAD_LANGUAGE); BOOST_REQUIRE (i->note()); @@ -816,6 +837,8 @@ BOOST_AUTO_TEST_CASE (verify_test26) BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::BAD_LANGUAGE); BOOST_REQUIRE (i->note()); BOOST_CHECK_EQUAL (*i->note(), "wrong-andbad"); + i++; + BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::MISSING_CPL_METADATA); } @@ -833,7 +856,7 @@ BOOST_AUTO_TEST_CASE (verify_invalid_closed_caption_languages) write_dcp_with_single_asset (dir, reel_asset); auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE_EQUAL (notes.size(), 2U); + BOOST_REQUIRE_EQUAL (notes.size(), 3U); auto i = notes.begin (); BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::BAD_LANGUAGE); BOOST_REQUIRE (i->note()); @@ -842,6 +865,8 @@ BOOST_AUTO_TEST_CASE (verify_invalid_closed_caption_languages) BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::BAD_LANGUAGE); BOOST_REQUIRE (i->note()); BOOST_CHECK_EQUAL (*i->note(), "wrong-andbad"); + i++; + BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::MISSING_CPL_METADATA); } @@ -860,7 +885,9 @@ BOOST_AUTO_TEST_CASE (verify_various_invalid_languages) auto sound = simple_sound (dir, "foo", dcp::MXFMetadata(), "frobozz"); auto reel_sound = make_shared(sound, 0); reel->add (reel_sound); - auto cpl = make_shared("hello", dcp::FEATURE); + reel->add (simple_markers()); + + auto cpl = make_shared("hello", dcp::TRAILER); cpl->add (reel); cpl->_additional_subtitle_languages.push_back("this-is-wrong"); cpl->_additional_subtitle_languages.push_back("andso-is-this"); @@ -868,6 +895,7 @@ BOOST_AUTO_TEST_CASE (verify_various_invalid_languages) cpl->set_main_sound_sample_rate (48000); cpl->set_main_picture_stored_area (dcp::Size(1998, 1080)); cpl->set_main_picture_active_area (dcp::Size(1440, 1080)); + cpl->set_version_number (1); cpl->_release_territory = "fred-jim"; auto dcp = make_shared(dir); dcp->add (cpl); @@ -891,7 +919,6 @@ BOOST_AUTO_TEST_CASE (verify_various_invalid_languages) BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::BAD_LANGUAGE); BOOST_REQUIRE (i->note()); BOOST_CHECK_EQUAL (*i->note(), "frobozz"); - ++i; } @@ -922,9 +949,14 @@ check_picture_size (int width, int height, int frame_rate, bool three_d) picture_writer->finalize (); auto d = make_shared(dcp_path); - auto cpl = make_shared("A Test DCP", dcp::FEATURE); + auto cpl = make_shared("A Test DCP", dcp::TRAILER); cpl->set_annotation_text ("A Test DCP"); cpl->set_issue_date ("2012-07-17T04:45:18+00:00"); + cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-"); + cpl->set_main_sound_sample_rate (48000); + cpl->set_main_picture_stored_area (dcp::Size(1998, 1080)); + cpl->set_main_picture_active_area (dcp::Size(1998, 1080)); + cpl->set_version_number (1); auto reel = make_shared(); @@ -934,6 +966,8 @@ check_picture_size (int width, int height, int frame_rate, bool three_d) reel->add (make_shared(std::dynamic_pointer_cast(mp), 0)); } + reel->add (simple_markers(frame_rate)); + cpl->add (reel); d->add (cpl); @@ -1084,7 +1118,8 @@ BOOST_AUTO_TEST_CASE (verify_closed_caption_xml_too_large) { { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME }, { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::CLOSED_CAPTION_XML_TOO_LARGE_IN_BYTES }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY } + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }, }); } @@ -1123,7 +1158,8 @@ verify_timed_text_asset_too_large (string name) { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TIMED_TEXT_ASSET_TOO_LARGE_IN_BYTES }, { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TIMED_TEXT_FONTS_TOO_LARGE_IN_BYTES }, { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY } + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }, }); } @@ -1139,7 +1175,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 = "" @@ -1169,7 +1205,7 @@ BOOST_AUTO_TEST_CASE (verify_missing_language_tag_in_subtitle_xml) auto subs = make_shared(dir / "subs.xml"); subs->write (dir / "subs.mxf"); - auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 100, 0); + auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 240, 0); dcp->cpls().front()->reels().front()->add(reel_subs); dcp->write_xml (dcp::SMPTE); @@ -1222,7 +1258,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 = "" @@ -1252,7 +1288,7 @@ BOOST_AUTO_TEST_CASE (verify_missing_start_time_tag_in_subtitle_xml) auto subs = make_shared(dir / "subs.xml"); subs->write (dir / "subs.mxf"); - auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 100, 0); + auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 240, 0); dcp->cpls().front()->reels().front()->add(reel_subs); dcp->write_xml (dcp::SMPTE); @@ -1269,7 +1305,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 = "" @@ -1300,7 +1336,7 @@ BOOST_AUTO_TEST_CASE (verify_non_zero_start_time_tag_in_subtitle_xml) auto subs = make_shared(dir / "subs.xml"); subs->write (dir / "subs.mxf"); - auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 100, 0); + auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 240, 0); dcp->cpls().front()->reels().front()->add(reel_subs); dcp->write_xml (dcp::SMPTE); @@ -1355,7 +1391,11 @@ BOOST_AUTO_TEST_CASE (verify_text_too_early) dcp_with_text (dir, {{ 4 * 24 - 1, 5 * 24 }}); check_verify_result ( { dir }, - {{ dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY }}); + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); + } @@ -1364,8 +1404,7 @@ BOOST_AUTO_TEST_CASE (verify_text_not_too_early) auto const dir = boost::filesystem::path("build/test/verify_text_not_too_early"); /* Just late enough */ dcp_with_text (dir, {{ 4 * 24, 5 * 24 }}); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE (notes.empty()); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } @@ -1383,6 +1422,9 @@ BOOST_AUTO_TEST_CASE (verify_text_early_on_second_reel) auto reel_asset1 = make_shared(asset1, dcp::Fraction(24, 1), 16 * 24, 0); auto reel1 = make_shared(); reel1->add (reel_asset1); + auto markers1 = make_shared(dcp::Fraction(24, 1), 16 * 24, 0); + markers1->set (dcp::Marker::FFOC, dcp::Time(1, 24, 24)); + reel1->add (markers1); auto asset2 = make_shared(); asset2->set_start_time (dcp::Time()); @@ -1393,16 +1435,18 @@ BOOST_AUTO_TEST_CASE (verify_text_early_on_second_reel) auto reel_asset2 = make_shared(asset2, dcp::Fraction(24, 1), 16 * 24, 0); auto reel2 = make_shared(); reel2->add (reel_asset2); + auto markers2 = make_shared(dcp::Fraction(24, 1), 16 * 24, 0); + markers2->set (dcp::Marker::LFOC, dcp::Time(16 * 24 - 1, 24, 24)); + reel2->add (markers2); - auto cpl = make_shared("hello", dcp::FEATURE); + auto cpl = make_shared("hello", dcp::TRAILER); cpl->add (reel1); cpl->add (reel2); auto dcp = make_shared(dir); dcp->add (cpl); dcp->write_xml (dcp::SMPTE); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE (notes.empty()); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } @@ -1415,7 +1459,12 @@ BOOST_AUTO_TEST_CASE (verify_text_too_close) { 4 * 24, 5 * 24 }, { 5 * 24 + 1, 6 * 24 }, }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_TOO_CLOSE }}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_TOO_CLOSE }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } @@ -1428,8 +1477,7 @@ BOOST_AUTO_TEST_CASE (verify_text_not_too_close) { 4 * 24, 5 * 24 }, { 5 * 24 + 16, 8 * 24 }, }); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE (notes.empty()); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } @@ -1437,7 +1485,12 @@ BOOST_AUTO_TEST_CASE (verify_text_too_short) { auto const dir = boost::filesystem::path("build/test/verify_text_too_short"); dcp_with_text (dir, {{ 4 * 24, 4 * 24 + 1 }}); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_TOO_SHORT }}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_TOO_SHORT }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } @@ -1445,14 +1498,13 @@ BOOST_AUTO_TEST_CASE (verify_text_not_too_short) { auto const dir = boost::filesystem::path("build/test/verify_text_not_too_short"); dcp_with_text (dir, {{ 4 * 24, 4 * 24 + 17 }}); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE (notes.empty()); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } BOOST_AUTO_TEST_CASE (verify_too_many_subtitle_lines1) { - auto const dir = boost::filesystem::path ("verify_too_many_subtitle_lines1"); + auto const dir = boost::filesystem::path ("build/test/verify_too_many_subtitle_lines1"); dcp_with_text ( dir, { @@ -1461,13 +1513,18 @@ BOOST_AUTO_TEST_CASE (verify_too_many_subtitle_lines1) { 96, 200, 0.2, "four" }, { 96, 200, 0.3, "lines" } }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::TOO_MANY_SUBTITLE_LINES}}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::TOO_MANY_SUBTITLE_LINES }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } BOOST_AUTO_TEST_CASE (verify_not_too_many_subtitle_lines1) { - auto const dir = boost::filesystem::path ("verify_not_too_many_subtitle_lines1"); + auto const dir = boost::filesystem::path ("build/test/verify_not_too_many_subtitle_lines1"); dcp_with_text ( dir, { @@ -1475,14 +1532,13 @@ BOOST_AUTO_TEST_CASE (verify_not_too_many_subtitle_lines1) { 96, 200, 0.1, "have" }, { 96, 200, 0.2, "four" }, }); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE (notes.empty()); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } BOOST_AUTO_TEST_CASE (verify_too_many_subtitle_lines2) { - auto const dir = boost::filesystem::path ("verify_too_many_subtitle_lines2"); + auto const dir = boost::filesystem::path ("build/test/verify_too_many_subtitle_lines2"); dcp_with_text ( dir, { @@ -1491,13 +1547,18 @@ BOOST_AUTO_TEST_CASE (verify_too_many_subtitle_lines2) { 150, 180, 0.2, "four" }, { 150, 180, 0.3, "lines" } }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::TOO_MANY_SUBTITLE_LINES}}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::TOO_MANY_SUBTITLE_LINES }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } BOOST_AUTO_TEST_CASE (verify_not_too_many_subtitle_lines2) { - auto const dir = boost::filesystem::path ("verify_not_too_many_subtitle_lines2"); + auto const dir = boost::filesystem::path ("build/test/verify_not_too_many_subtitle_lines2"); dcp_with_text ( dir, { @@ -1506,38 +1567,47 @@ BOOST_AUTO_TEST_CASE (verify_not_too_many_subtitle_lines2) { 150, 180, 0.2, "four" }, { 190, 250, 0.3, "lines" } }); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE (notes.empty()); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } BOOST_AUTO_TEST_CASE (verify_subtitle_lines_too_long1) { - auto const dir = boost::filesystem::path ("verify_subtitle_lines_too_long1"); + auto const dir = boost::filesystem::path ("build/test/verify_subtitle_lines_too_long1"); dcp_with_text ( dir, { { 96, 300, 0.0, "012345678901234567890123456789012345678901234567890123" } }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_LINE_LONGER_THAN_RECOMMENDED }}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_LINE_LONGER_THAN_RECOMMENDED }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } BOOST_AUTO_TEST_CASE (verify_subtitle_lines_too_long2) { - auto const dir = boost::filesystem::path ("verify_subtitle_lines_too_long2"); + auto const dir = boost::filesystem::path ("build/test/verify_subtitle_lines_too_long2"); dcp_with_text ( dir, { { 96, 300, 0.0, "012345678901234567890123456789012345678901234567890123456789012345678901234567890" } }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_LINE_TOO_LONG }}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_LINE_TOO_LONG }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } BOOST_AUTO_TEST_CASE (verify_too_many_closed_caption_lines1) { - auto const dir = boost::filesystem::path ("verify_too_many_closed_caption_lines1"); + auto const dir = boost::filesystem::path ("build/test/verify_too_many_closed_caption_lines1"); dcp_with_text ( dir, { @@ -1546,13 +1616,18 @@ BOOST_AUTO_TEST_CASE (verify_too_many_closed_caption_lines1) { 96, 200, 0.2, "four" }, { 96, 200, 0.3, "lines" } }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TOO_MANY_CLOSED_CAPTION_LINES}}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TOO_MANY_CLOSED_CAPTION_LINES}, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } BOOST_AUTO_TEST_CASE (verify_not_too_many_closed_caption_lines1) { - auto const dir = boost::filesystem::path ("verify_not_too_many_closed_caption_lines1"); + auto const dir = boost::filesystem::path ("build/test/verify_not_too_many_closed_caption_lines1"); dcp_with_text ( dir, { @@ -1560,14 +1635,13 @@ BOOST_AUTO_TEST_CASE (verify_not_too_many_closed_caption_lines1) { 96, 200, 0.1, "have" }, { 96, 200, 0.2, "four" }, }); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE (notes.empty()); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } BOOST_AUTO_TEST_CASE (verify_too_many_closed_caption_lines2) { - auto const dir = boost::filesystem::path ("verify_too_many_closed_caption_lines2"); + auto const dir = boost::filesystem::path ("build/test/verify_too_many_closed_caption_lines2"); dcp_with_text ( dir, { @@ -1576,13 +1650,18 @@ BOOST_AUTO_TEST_CASE (verify_too_many_closed_caption_lines2) { 150, 180, 0.2, "four" }, { 150, 180, 0.3, "lines" } }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TOO_MANY_CLOSED_CAPTION_LINES}}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TOO_MANY_CLOSED_CAPTION_LINES}, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } BOOST_AUTO_TEST_CASE (verify_not_too_many_closed_caption_lines2) { - auto const dir = boost::filesystem::path ("verify_not_too_many_closed_caption_lines2"); + auto const dir = boost::filesystem::path ("build/test/verify_not_too_many_closed_caption_lines2"); dcp_with_text ( dir, { @@ -1591,26 +1670,30 @@ BOOST_AUTO_TEST_CASE (verify_not_too_many_closed_caption_lines2) { 150, 180, 0.2, "four" }, { 190, 250, 0.3, "lines" } }); - auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - BOOST_REQUIRE (notes.empty()); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } BOOST_AUTO_TEST_CASE (verify_closed_caption_lines_too_long1) { - auto const dir = boost::filesystem::path ("verify_closed_caption_lines_too_long1"); + auto const dir = boost::filesystem::path ("build/test/verify_closed_caption_lines_too_long1"); dcp_with_text ( dir, { { 96, 300, 0.0, "0123456789012345678901234567890123" } }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::CLOSED_CAPTION_LINE_TOO_LONG }}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::CLOSED_CAPTION_LINE_TOO_LONG }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); } BOOST_AUTO_TEST_CASE (verify_sound_sampling_rate_must_be_48k) { - boost::filesystem::path const dir("verify_sound_sampling_rate_must_be_48k"); + boost::filesystem::path const dir("build/test/verify_sound_sampling_rate_must_be_48k"); prepare_directory (dir); auto picture = simple_picture (dir, "foo"); @@ -1620,11 +1703,465 @@ BOOST_AUTO_TEST_CASE (verify_sound_sampling_rate_must_be_48k) auto sound = simple_sound (dir, "foo", dcp::MXFMetadata(), "de-DE", 24, 96000); auto reel_sound = make_shared(sound, 0); reel->add (reel_sound); - auto cpl = make_shared("hello", dcp::FEATURE); + reel->add (simple_markers()); + auto cpl = make_shared("hello", dcp::TRAILER); cpl->add (reel); auto dcp = make_shared(dir); dcp->add (cpl); dcp->write_xml (dcp::SMPTE); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::INVALID_SOUND_FRAME_RATE }}); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::INVALID_SOUND_FRAME_RATE }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); +} + + +BOOST_AUTO_TEST_CASE (verify_cpl_must_have_annotation_text) +{ + boost::filesystem::path const dir("build/test/verify_cpl_must_have_annotation_text"); + auto dcp = make_simple (dir); + dcp->write_xml (dcp::SMPTE); + BOOST_REQUIRE_EQUAL (dcp->cpls().size(), 1U); + + { + BOOST_REQUIRE (dcp->cpls()[0]->file()); + Editor e(dcp->cpls()[0]->file().get()); + e.replace("A Test DCP", ""); + } + + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_ANNOTATION_TEXT_IN_CPL }, + { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT } + }); +} + + +BOOST_AUTO_TEST_CASE (verify_cpl_annotation_text_should_be_same_as_content_title_text) +{ + boost::filesystem::path const dir("build/test/verify_cpl_annotation_text_should_be_same_as_content_title_text"); + auto dcp = make_simple (dir); + dcp->write_xml (dcp::SMPTE); + BOOST_REQUIRE_EQUAL (dcp->cpls().size(), 1U); + + { + BOOST_REQUIRE (dcp->cpls()[0]->file()); + Editor e(dcp->cpls()[0]->file().get()); + e.replace("A Test DCP", "A Test DCP 1"); + } + + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::CPL_ANNOTATION_TEXT_DIFFERS_FROM_CONTENT_TITLE_TEXT }, + { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT } + }); +} + + +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 (new dcp::DCP(dir)); + shared_ptr cpl (new dcp::CPL("A Test DCP", dcp::TRAILER)); + + shared_ptr mp = simple_picture (dir, "", 24); + shared_ptr ms = simple_sound (dir, "", dcp::MXFMetadata(), "en-US", 25); + + auto reel = make_shared( + make_shared(mp, 0), + make_shared(ms, 0) + ); + + reel->add (simple_markers()); + cpl->add (reel); + + dcp->add (cpl); + dcp->write_xml (dcp::SMPTE); + + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISMATCHED_ASSET_DURATION }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); +} + + + +static +void +verify_subtitles_must_be_in_all_reels_check (boost::filesystem::path dir, bool add_to_reel1, bool add_to_reel2) +{ + boost::filesystem::remove_all (dir); + boost::filesystem::create_directories (dir); + auto dcp = make_shared(dir); + auto cpl = make_shared("A Test DCP", dcp::TRAILER); + + auto subs = make_shared(); + subs->set_language (dcp::LanguageTag("de-DE")); + subs->set_start_time (dcp::Time()); + subs->add (simple_subtitle()); + subs->write (dir / "subs.mxf"); + auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 240, 0); + + auto reel1 = make_shared( + make_shared(simple_picture(dir, "", 240), 0), + make_shared(simple_sound(dir, "", dcp::MXFMetadata(), "en-US", 240), 0) + ); + + if (add_to_reel1) { + reel1->add (make_shared(subs, dcp::Fraction(24, 1), 240, 0)); + } + + auto markers1 = make_shared(dcp::Fraction(24, 1), 240, 0); + markers1->set (dcp::Marker::FFOC, dcp::Time(1, 24, 24)); + reel1->add (markers1); + + cpl->add (reel1); + + auto reel2 = make_shared( + make_shared(simple_picture(dir, "", 240), 0), + make_shared(simple_sound(dir, "", dcp::MXFMetadata(), "en-US", 240), 0) + ); + + if (add_to_reel2) { + reel2->add (make_shared(subs, dcp::Fraction(24, 1), 240, 0)); + } + + auto markers2 = make_shared(dcp::Fraction(24, 1), 240, 0); + markers2->set (dcp::Marker::LFOC, dcp::Time(239, 24, 24)); + reel2->add (markers2); + + cpl->add (reel2); + + dcp->add (cpl); + dcp->write_xml (dcp::SMPTE); } + + +BOOST_AUTO_TEST_CASE (verify_subtitles_must_be_in_all_reels) +{ + { + boost::filesystem::path dir ("build/test/verify_subtitles_must_be_in_all_reels1"); + verify_subtitles_must_be_in_all_reels_check (dir, true, false); + check_verify_result ( + { dir }, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MAIN_SUBTITLE_NOT_IN_ALL_REELS }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); + + } + + { + boost::filesystem::path dir ("build/test/verify_subtitles_must_be_in_all_reels2"); + verify_subtitles_must_be_in_all_reels_check (dir, true, true); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + } + + { + boost::filesystem::path dir ("build/test/verify_subtitles_must_be_in_all_reels1"); + verify_subtitles_must_be_in_all_reels_check (dir, false, false); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + } +} + + +static +void +verify_closed_captions_must_be_in_all_reels_check (boost::filesystem::path dir, int caps_in_reel1, int caps_in_reel2) +{ + boost::filesystem::remove_all (dir); + boost::filesystem::create_directories (dir); + auto dcp = make_shared(dir); + auto cpl = make_shared("A Test DCP", dcp::TRAILER); + + auto subs = make_shared(); + subs->set_language (dcp::LanguageTag("de-DE")); + subs->set_start_time (dcp::Time()); + subs->add (simple_subtitle()); + subs->write (dir / "subs.mxf"); + + auto reel1 = make_shared( + make_shared(simple_picture(dir, "", 240), 0), + make_shared(simple_sound(dir, "", dcp::MXFMetadata(), "en-US", 240), 0) + ); + + for (int i = 0; i < caps_in_reel1; ++i) { + reel1->add (make_shared(subs, dcp::Fraction(24, 1), 240, 0)); + } + + auto markers1 = make_shared(dcp::Fraction(24, 1), 240, 0); + markers1->set (dcp::Marker::FFOC, dcp::Time(1, 24, 24)); + reel1->add (markers1); + + cpl->add (reel1); + + auto reel2 = make_shared( + make_shared(simple_picture(dir, "", 240), 0), + make_shared(simple_sound(dir, "", dcp::MXFMetadata(), "en-US", 240), 0) + ); + + for (int i = 0; i < caps_in_reel2; ++i) { + reel2->add (make_shared(subs, dcp::Fraction(24, 1), 240, 0)); + } + + auto markers2 = make_shared(dcp::Fraction(24, 1), 240, 0); + markers2->set (dcp::Marker::LFOC, dcp::Time(239, 24, 24)); + reel2->add (markers2); + + cpl->add (reel2); + + dcp->add (cpl); + dcp->write_xml (dcp::SMPTE); + +} + + +BOOST_AUTO_TEST_CASE (verify_closed_captions_must_be_in_all_reels) +{ + { + boost::filesystem::path dir ("build/test/verify_closed_captions_must_be_in_all_reels1"); + verify_closed_captions_must_be_in_all_reels_check (dir, 3, 4); + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::CLOSED_CAPTION_ASSET_COUNTS_DIFFER }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); + } + + { + boost::filesystem::path dir ("build/test/verify_closed_captions_must_be_in_all_reels2"); + verify_closed_captions_must_be_in_all_reels_check (dir, 4, 4); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + } + + { + boost::filesystem::path dir ("build/test/verify_closed_captions_must_be_in_all_reels3"); + verify_closed_captions_must_be_in_all_reels_check (dir, 0, 0); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + } +} + + +template +void +verify_text_entry_point_check (boost::filesystem::path dir, dcp::VerificationNote::Code code, boost::function)> adjust) +{ + boost::filesystem::remove_all (dir); + boost::filesystem::create_directories (dir); + auto dcp = make_shared(dir); + auto cpl = make_shared("A Test DCP", dcp::TRAILER); + + auto subs = make_shared(); + subs->set_language (dcp::LanguageTag("de-DE")); + subs->set_start_time (dcp::Time()); + subs->add (simple_subtitle()); + subs->write (dir / "subs.mxf"); + auto reel_text = make_shared(subs, dcp::Fraction(24, 1), 240, 0); + adjust (reel_text); + + auto reel = make_shared( + make_shared(simple_picture(dir, "", 240), 0), + make_shared(simple_sound(dir, "", dcp::MXFMetadata(), "en-US", 240), 0) + ); + + reel->add (reel_text); + + reel->add (simple_markers(240)); + + cpl->add (reel); + + dcp->add (cpl); + dcp->write_xml (dcp::SMPTE); + + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, code }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + }); +} + + +BOOST_AUTO_TEST_CASE (verify_text_entry_point) +{ + verify_text_entry_point_check ( + "build/test/verify_subtitle_entry_point_must_be_present", + dcp::VerificationNote::MISSING_SUBTITLE_ENTRY_POINT, + [](shared_ptr asset) { + asset->unset_entry_point (); + } + ); + + verify_text_entry_point_check ( + "build/test/verify_subtitle_entry_point_must_be_zero", + dcp::VerificationNote::SUBTITLE_ENTRY_POINT_NON_ZERO, + [](shared_ptr asset) { + asset->set_entry_point (4); + } + ); + + verify_text_entry_point_check ( + "build/test/verify_closed_caption_entry_point_must_be_present", + dcp::VerificationNote::MISSING_CLOSED_CAPTION_ENTRY_POINT, + [](shared_ptr asset) { + asset->unset_entry_point (); + } + ); + + verify_text_entry_point_check ( + "build/test/verify_closed_caption_entry_point_must_be_zero", + dcp::VerificationNote::CLOSED_CAPTION_ENTRY_POINT_NON_ZERO, + [](shared_ptr asset) { + asset->set_entry_point (9); + } + ); +} + + +BOOST_AUTO_TEST_CASE (verify_assets_must_have_hashes) +{ + RNGFixer fix; + + boost::filesystem::path const dir("build/test/verify_assets_must_have_hashes"); + auto dcp = make_simple (dir); + dcp->write_xml (dcp::SMPTE); + BOOST_REQUIRE_EQUAL (dcp->cpls().size(), 1U); + + { + BOOST_REQUIRE (dcp->cpls()[0]->file()); + Editor e(dcp->cpls()[0]->file().get()); + e.replace("XGhFVrqZqapOJx5Fh2SLjj48Yjg=", ""); + } + + check_verify_result ( + {dir}, + { + { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_HASH } + }); +} + + +static +void +verify_markers_test ( + boost::filesystem::path dir, + vector> markers, + vector> types_and_codes + ) +{ + auto dcp = make_simple (dir); + dcp->cpls()[0]->set_content_kind (dcp::FEATURE); + auto markers_asset = make_shared(dcp::Fraction(24, 1), 24, 0); + for (auto const& i: markers) { + markers_asset->set (i.first, i.second); + } + dcp->cpls()[0]->reels()[0]->add(markers_asset); + dcp->write_xml (dcp::SMPTE); + check_verify_result ({dir}, types_and_codes); +} + + +BOOST_AUTO_TEST_CASE (verify_markers) +{ + verify_markers_test ( + "build/test/verify_markers_all_correct", + { + { dcp::Marker::FFEC, dcp::Time(12, 24, 24) }, + { dcp::Marker::FFMC, dcp::Time(13, 24, 24) }, + { dcp::Marker::FFOC, dcp::Time(1, 24, 24) }, + { dcp::Marker::LFOC, dcp::Time(23, 24, 24) } + }, + {} + ); + + verify_markers_test ( + "build/test/verify_markers_missing_ffec", + { + { dcp::Marker::FFMC, dcp::Time(13, 24, 24) }, + { dcp::Marker::FFOC, dcp::Time(1, 24, 24) }, + { dcp::Marker::LFOC, dcp::Time(23, 24, 24) } + }, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_FFEC_IN_FEATURE } + }); + + verify_markers_test ( + "build/test/verify_markers_missing_ffmc", + { + { dcp::Marker::FFEC, dcp::Time(12, 24, 24) }, + { dcp::Marker::FFOC, dcp::Time(1, 24, 24) }, + { dcp::Marker::LFOC, dcp::Time(23, 24, 24) } + }, + { + { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_FFMC_IN_FEATURE } + }); + + verify_markers_test ( + "build/test/verify_markers_missing_ffoc", + { + { dcp::Marker::FFEC, dcp::Time(12, 24, 24) }, + { dcp::Marker::FFMC, dcp::Time(13, 24, 24) }, + { dcp::Marker::LFOC, dcp::Time(23, 24, 24) } + }, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_FFOC} + }); + + verify_markers_test ( + "build/test/verify_markers_missing_lfoc", + { + { dcp::Marker::FFEC, dcp::Time(12, 24, 24) }, + { dcp::Marker::FFMC, dcp::Time(13, 24, 24) }, + { dcp::Marker::FFOC, dcp::Time(1, 24, 24) } + }, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_LFOC } + }); + + verify_markers_test ( + "build/test/verify_markers_incorrect_ffoc", + { + { dcp::Marker::FFEC, dcp::Time(12, 24, 24) }, + { dcp::Marker::FFMC, dcp::Time(13, 24, 24) }, + { dcp::Marker::FFOC, dcp::Time(3, 24, 24) }, + { dcp::Marker::LFOC, dcp::Time(23, 24, 24) } + }, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::INCORRECT_FFOC } + }); + + verify_markers_test ( + "build/test/verify_markers_incorrect_lfoc", + { + { dcp::Marker::FFEC, dcp::Time(12, 24, 24) }, + { dcp::Marker::FFMC, dcp::Time(13, 24, 24) }, + { dcp::Marker::FFOC, dcp::Time(1, 24, 24) }, + { dcp::Marker::LFOC, dcp::Time(18, 24, 24) } + }, + { + { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::INCORRECT_LFOC } + }); +} + + +BOOST_AUTO_TEST_CASE (verify_cpl_metadata_version) +{ + boost::filesystem::path dir = "build/test/verify_cpl_metadata_version"; + prepare_directory (dir); + auto dcp = make_simple (dir); + dcp->cpls()[0]->unset_version_number(); + dcp->write_xml (dcp::SMPTE); + check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA_VERSION_NUMBER }}); +} +