X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=test%2Freels_test.cc;h=d4a783f91a72a30acd2e08b5ec8385f2d4d5995e;hb=521424e747dced3ade9600fc62c48526e199ef16;hp=db974d38463cb452148416fb81b6063b341e409e;hpb=94ab538738526948c5a52ed1222be1e484255541;p=dcpomatic.git diff --git a/test/reels_test.cc b/test/reels_test.cc index db974d384..d4a783f91 100644 --- a/test/reels_test.cc +++ b/test/reels_test.cc @@ -25,27 +25,32 @@ */ -#include "lib/film.h" -#include "lib/ratio.h" +#include "lib/content_factory.h" +#include "lib/dcp_content.h" +#include "lib/dcp_content_type.h" #include "lib/ffmpeg_content.h" +#include "lib/film.h" #include "lib/image_content.h" -#include "lib/dcp_content_type.h" -#include "lib/dcp_content.h" -#include "lib/video_content.h" +#include "lib/make_dcp.h" +#include "lib/ratio.h" #include "lib/string_text_file_content.h" -#include "lib/content_factory.h" +#include "lib/video_content.h" #include "test.h" +#include +#include +#include +#include #include #include -using std::list; using std::cout; -using std::vector; -using std::string; -using std::shared_ptr; -using std::make_shared; using std::function; +using std::list; +using std::make_shared; +using std::shared_ptr; +using std::string; +using std::vector; using namespace dcpomatic; @@ -105,21 +110,21 @@ BOOST_AUTO_TEST_CASE (reels_test2) film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST")); { - shared_ptr c (new ImageContent("test/data/flat_red.png")); + auto c = make_shared("test/data/flat_red.png"); film->examine_and_add_content (c); BOOST_REQUIRE (!wait_for_jobs()); c->video->set_length (24); } { - shared_ptr c (new ImageContent("test/data/flat_green.png")); + auto c = make_shared("test/data/flat_green.png"); film->examine_and_add_content (c); BOOST_REQUIRE (!wait_for_jobs()); c->video->set_length (24); } { - shared_ptr c (new ImageContent("test/data/flat_blue.png")); + auto c = make_shared("test/data/flat_blue.png"); film->examine_and_add_content (c); BOOST_REQUIRE (!wait_for_jobs()); c->video->set_length (24); @@ -129,6 +134,8 @@ BOOST_AUTO_TEST_CASE (reels_test2) BOOST_CHECK_EQUAL (film->reels().size(), 3U); BOOST_REQUIRE (!wait_for_jobs()); + film->set_audio_channels(16); + make_and_verify_dcp (film); check_dcp ("test/data/reels_test2", film->dir (film->dcp_name())); @@ -136,6 +143,7 @@ BOOST_AUTO_TEST_CASE (reels_test2) auto c = make_shared(film->dir(film->dcp_name())); auto film2 = new_test_film2 ("reels_test2b", {c}); film2->set_reel_type (ReelType::BY_VIDEO_CONTENT); + film2->set_audio_channels(16); auto r = film2->reels (); BOOST_CHECK_EQUAL (r.size(), 3U); @@ -152,7 +160,7 @@ BOOST_AUTO_TEST_CASE (reels_test2) c->set_reference_video (true); c->set_reference_audio (true); - make_and_verify_dcp (film2, {dcp::VerificationNote::Code::EXTERNAL_ASSET}); + make_and_verify_dcp(film2, {dcp::VerificationNote::Code::EXTERNAL_ASSET}, false); } @@ -195,7 +203,7 @@ BOOST_AUTO_TEST_CASE (reels_test4) /* 4 piece of 1s-long content */ shared_ptr content[4]; for (int i = 0; i < 4; ++i) { - content[i].reset (new ImageContent("test/data/flat_green.png")); + content[i] = make_shared("test/data/flat_green.png"); film->examine_and_add_content (content[i]); BOOST_REQUIRE (!wait_for_jobs()); content[i]->video->set_length (24); @@ -205,6 +213,8 @@ BOOST_AUTO_TEST_CASE (reels_test4) film->examine_and_add_content (subs); BOOST_REQUIRE (!wait_for_jobs()); + film->set_audio_channels(16); + auto reels = film->reels(); BOOST_REQUIRE_EQUAL (reels.size(), 4U); auto i = reels.begin (); @@ -235,6 +245,7 @@ BOOST_AUTO_TEST_CASE (reels_test4) BOOST_AUTO_TEST_CASE (reels_test5) { auto dcp = make_shared("test/data/reels_test4"); + dcp->check_font_ids(); auto film = new_test_film2 ("reels_test5", {dcp}); film->set_sequence (false); @@ -252,7 +263,7 @@ BOOST_AUTO_TEST_CASE (reels_test5) } { - dcp->set_trim_start (ContentTime::from_seconds (0.5)); + dcp->set_trim_start(film, ContentTime::from_seconds(0.5)); auto p = dcp->reels (film); BOOST_REQUIRE_EQUAL (p.size(), 4U); auto i = p.begin(); @@ -274,7 +285,7 @@ BOOST_AUTO_TEST_CASE (reels_test5) } { - dcp->set_trim_start (ContentTime::from_seconds (1.5)); + dcp->set_trim_start(film, ContentTime::from_seconds(1.5)); auto p = dcp->reels (film); BOOST_REQUIRE_EQUAL (p.size(), 3U); auto i = p.begin(); @@ -295,12 +306,16 @@ BOOST_AUTO_TEST_CASE (reels_test6) film->set_reel_type (ReelType::BY_LENGTH); /* This is just over 2.5s at 100Mbit/s; should correspond to 60 frames */ film->set_reel_length (31253154); + /* dcp_inspect and clairmeta both give errors about reel <1s in length */ make_and_verify_dcp ( film, { dcp::VerificationNote::Code::INVALID_INTRINSIC_DURATION, dcp::VerificationNote::Code::INVALID_DURATION, - }); + }, + false, + false + ); } @@ -309,8 +324,8 @@ BOOST_AUTO_TEST_CASE (reels_test6) */ BOOST_AUTO_TEST_CASE (reels_test7) { - auto A = content_factory("test/data/flat_red.png").front(); - auto B = content_factory("test/data/awkward_length.wav").front(); + auto A = content_factory("test/data/flat_red.png")[0]; + auto B = content_factory("test/data/awkward_length.wav")[0]; auto film = new_test_film2 ("reels_test7", { A, B }); film->set_video_frame_rate (24); A->video->set_length (2 * 24); @@ -345,7 +360,7 @@ BOOST_AUTO_TEST_CASE (reels_test9) make_and_verify_dcp (film); auto B = make_shared(film->dir(film->dcp_name())); - auto film2 = new_test_film2("reels_test9b", {B, content_factory("test/data/dcp_sub4.xml").front()}); + auto film2 = new_test_film2("reels_test9b", {B, content_factory("test/data/dcp_sub4.xml")[0]}); B->set_reference_video(true); B->set_reference_audio(true); film2->set_reel_type(ReelType::BY_VIDEO_CONTENT); @@ -380,7 +395,7 @@ BOOST_AUTO_TEST_CASE (reels_test10) /* Now try to make the VF; this used to fail */ auto ov_dcp = make_shared(ov->dir(ov->dcp_name())); - auto vf = new_test_film2("reels_test10_vf", {ov_dcp, content_factory("test/data/15s.srt").front()}); + auto vf = new_test_film2("reels_test10_vf", {ov_dcp, content_factory("test/data/15s.srt")[0]}); vf->set_reel_type (ReelType::BY_VIDEO_CONTENT); ov_dcp->set_reference_video (true); ov_dcp->set_reference_audio (true); @@ -392,7 +407,8 @@ BOOST_AUTO_TEST_CASE (reels_test10) dcp::VerificationNote::Code::MISSING_SUBTITLE_LANGUAGE, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME, dcp::VerificationNote::Code::INVALID_SUBTITLE_DURATION, - }); + }, + false); } @@ -405,7 +421,7 @@ BOOST_AUTO_TEST_CASE (reels_test11) auto film = new_test_film2 ("reels_test11", {A}); film->set_video_frame_rate (24); A->video->set_length (240); - A->set_video_frame_rate (24); + A->set_video_frame_rate(film, 24); A->set_position (film, DCPTime::from_seconds(1)); film->set_reel_type (ReelType::BY_VIDEO_CONTENT); make_and_verify_dcp (film); @@ -434,11 +450,11 @@ BOOST_AUTO_TEST_CASE (reels_test12) film->set_sequence (false); A->video->set_length (240); - A->set_video_frame_rate (24); + A->set_video_frame_rate(film, 24); A->set_position (film, DCPTime::from_seconds(1)); B->video->set_length (120); - B->set_video_frame_rate (24); + B->set_video_frame_rate(film, 24); B->set_position (film, DCPTime::from_seconds(14)); auto r = film->reels (); @@ -492,7 +508,7 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short1) make_and_verify_dcp (film); vector dirs = { film->dir(film->dcp_name(false)) }; - auto notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd()); + auto notes = dcp::verify(dirs, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); dump_notes (notes); BOOST_REQUIRE (notes.empty()); } @@ -517,7 +533,7 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short2) make_and_verify_dcp (film); vector dirs = { film->dir(film->dcp_name(false)) }; - auto const notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd()); + auto const notes = dcp::verify(dirs, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); dump_notes (notes); BOOST_REQUIRE (notes.empty()); } @@ -538,7 +554,7 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short3) make_and_verify_dcp (film); - auto const notes = dcp::verify({}, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd()); + auto const notes = dcp::verify({}, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); dump_notes (notes); BOOST_REQUIRE (notes.empty()); } @@ -564,12 +580,81 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short4) BOOST_CHECK (film->reels().front() == dcpomatic::DCPTimePeriod(dcpomatic::DCPTime(), dcpomatic::DCPTime::from_frames(263, 24))); film->write_metadata (); - film->make_dcp (TranscodeJob::ChangedBehaviour::IGNORE); + make_dcp (film, TranscodeJob::ChangedBehaviour::IGNORE); BOOST_REQUIRE (!wait_for_jobs()); vector dirs = { film->dir(film->dcp_name(false)) }; - auto const notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd()); + auto const notes = dcp::verify(dirs, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); dump_notes (notes); BOOST_REQUIRE (notes.empty()); } + +/** Create a long DCP A then insert it repeatedly into a new project, trimming it differently each time. + * Make a DCP B from that project which refers to A and splits into reels. This was found to go wrong + * when looking at #2268. + */ +BOOST_AUTO_TEST_CASE (repeated_dcp_into_reels) +{ + /* Make a 20s DCP */ + auto A = make_shared("test/data/flat_red.png"); + auto film1 = new_test_film2("repeated_dcp_into_reels1", { A }); + auto constexpr frame_rate = 24; + auto constexpr length_in_seconds = 20; + auto constexpr total_frames = frame_rate * length_in_seconds; + film1->set_video_frame_rate(frame_rate); + A->video->set_length(total_frames); + make_and_verify_dcp(film1); + + /* Make a new project that includes this long DCP 4 times, each + * trimmed to a quarter of the original, i.e. + * /----------------------|----------------------|----------------------|----------------------\ + * | 1st quarter of film1 | 2nd quarter of film1 | 3rd quarter of film1 | 4th quarter of film1 | + * \----------------------|----------------------|----------------------|_---------------------/ + */ + + shared_ptr original_dcp[4] = { + make_shared(film1->dir(film1->dcp_name(false))), + make_shared(film1->dir(film1->dcp_name(false))), + make_shared(film1->dir(film1->dcp_name(false))), + make_shared(film1->dir(film1->dcp_name(false))) + }; + + auto film2 = new_test_film2("repeated_dcp_into_reels2", { original_dcp[0], original_dcp[1], original_dcp[2], original_dcp[3] }); + film2->set_reel_type(ReelType::BY_VIDEO_CONTENT); + film2->set_video_frame_rate(frame_rate); + film2->set_sequence(false); + + for (int i = 0; i < 4; ++i) { + original_dcp[i]->set_position(film2, DCPTime::from_frames(total_frames * i / 4, frame_rate)); + original_dcp[i]->set_trim_start(film2, ContentTime::from_frames(total_frames * i / 4, frame_rate)); + original_dcp[i]->set_trim_end (ContentTime::from_frames(total_frames * (4 - i - 1) / 4, frame_rate)); + original_dcp[i]->set_reference_video(true); + original_dcp[i]->set_reference_audio(true); + } + + make_and_verify_dcp(film2, { dcp::VerificationNote::Code::EXTERNAL_ASSET }, false); + + dcp::DCP check1(film1->dir(film1->dcp_name())); + check1.read(); + BOOST_REQUIRE(!check1.cpls().empty()); + BOOST_REQUIRE(!check1.cpls()[0]->reels().empty()); + auto picture = check1.cpls()[0]->reels()[0]->main_picture()->asset(); + BOOST_REQUIRE(picture); + auto sound = check1.cpls()[0]->reels()[0]->main_sound()->asset(); + BOOST_REQUIRE(sound); + + dcp::DCP check2(film2->dir(film2->dcp_name())); + check2.read(); + BOOST_REQUIRE(!check2.cpls().empty()); + auto cpl = check2.cpls()[0]; + BOOST_REQUIRE_EQUAL(cpl->reels().size(), 4U); + for (int i = 0; i < 4; ++i) { + BOOST_REQUIRE_EQUAL(cpl->reels()[i]->main_picture()->entry_point().get_value_or(0), total_frames * i / 4); + BOOST_REQUIRE_EQUAL(cpl->reels()[i]->main_picture()->duration().get_value_or(0), total_frames / 4); + BOOST_REQUIRE_EQUAL(cpl->reels()[i]->main_picture()->id(), picture->id()); + BOOST_REQUIRE_EQUAL(cpl->reels()[i]->main_sound()->entry_point().get_value_or(0), total_frames * i / 4); + BOOST_REQUIRE_EQUAL(cpl->reels()[i]->main_sound()->duration().get_value_or(0), total_frames / 4); + BOOST_REQUIRE_EQUAL(cpl->reels()[i]->main_sound()->id(), sound->id()); + } +}