Add Film::possible_reel_types().
authorCarl Hetherington <cth@carlh.net>
Mon, 5 May 2025 23:07:39 +0000 (01:07 +0200)
committerCarl Hetherington <cth@carlh.net>
Wed, 7 May 2025 23:29:35 +0000 (01:29 +0200)
src/lib/film.cc
src/lib/film.h
test/film_test.cc

index f0af131eade7ff28501f5ff564e9e850dc97c9a3..c969ff6995dafeac2b5fb2e88c75a8fefbbfbd95 100644 (file)
@@ -2469,3 +2469,44 @@ Film::write_remembered_assets(vector<RememberedAsset> const& assets) const
                LOG_ERROR("Could not write assets file %1", file(assets_file));
        }
 }
+
+
+vector<ReelType>
+Film::possible_reel_types() const
+{
+       auto film_reels = reels_for_type(ReelType::SINGLE);
+
+       bool referring = false;
+       bool dcp_reel_not_present = false;
+
+       for (auto c: content()) {
+               if (auto dcp = dynamic_pointer_cast<DCPContent>(c)) {
+                       if (dcp->reference_anything()) {
+                               referring = true;
+                               try {
+                                       for (auto const& dcp_reel: dcp->reels(shared_from_this())) {
+                                               if (std::find(film_reels.begin(), film_reels.end(), dcp_reel) == film_reels.end()) {
+                                                       dcp_reel_not_present = true;
+                                               }
+                                       }
+                               } catch (dcp::ReadError &) {
+                                       /* We couldn't read the DCP; it's probably missing */
+                               }
+                       }
+               }
+       }
+
+       if (referring && !dcp_reel_not_present) {
+               /* We're referring to some DCP content but single-reel mode is possible.
+                * We'll disallow BY_LENGTH and CUSTOM just for an easy life.
+                */
+
+               return { ReelType::SINGLE, ReelType::BY_VIDEO_CONTENT };
+       } else if (referring && dcp_reel_not_present) {
+               /* We have to use by-video */
+               return { ReelType::BY_VIDEO_CONTENT };
+       }
+
+       return { ReelType::SINGLE, ReelType::BY_VIDEO_CONTENT, ReelType::BY_LENGTH, ReelType::CUSTOM };
+}
+
index 2699daa4e37813243daecdefda0045d89aa7cb1b..c14b0f4fa9a8bab243b4b0b5bdf6b158f94dd676 100644 (file)
@@ -426,6 +426,9 @@ public:
 
        void add_ffoc_lfoc(Markers& markers) const;
 
+       /** @return Reel types that are allowed given the current state of the film */
+       std::vector<ReelType> possible_reel_types() const;
+
        void set_ui_state(std::string key, std::string value);
        boost::optional<std::string> ui_state(std::string key) const;
        void read_ui_state();
index 3493c79cea588793ee61ff7bd72376fb004eb0f3..820c15624366ba79d0926744aa150dc81fc8038f 100644 (file)
 
 
 #include "lib/content_factory.h"
+#include "lib/dcp_content.h"
 #include "lib/film.h"
+#include "lib/job_manager.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 
 
+using std::make_shared;
+
+
 BOOST_AUTO_TEST_CASE(film_contains_atmos_content_test)
 {
        auto atmos = content_factory("test/data/atmos_0.mxf")[0];
@@ -44,3 +49,40 @@ BOOST_AUTO_TEST_CASE(film_contains_atmos_content_test)
        BOOST_CHECK(!film4->contains_atmos_content());
 }
 
+
+BOOST_AUTO_TEST_CASE(film_possible_reel_types_test1)
+{
+       auto film = new_test_film("film_possible_reel_types_test1");
+       BOOST_CHECK_EQUAL(film->possible_reel_types().size(), 4U);
+
+       film->examine_and_add_content(content_factory("test/data/flat_red.png")[0]);
+       BOOST_REQUIRE(!wait_for_jobs());
+       BOOST_CHECK_EQUAL(film->possible_reel_types().size(), 4U);
+
+       auto dcp = make_shared<DCPContent>("test/data/reels_test2");
+       film->examine_and_add_content(dcp);
+       BOOST_REQUIRE(!wait_for_jobs());
+       BOOST_CHECK_EQUAL(film->possible_reel_types().size(), 4U);
+
+       /* If we don't do this the set_reference_video will be overridden by the Film's
+        * check_settings_consistency() stuff.
+        */
+       film->set_reel_type(ReelType::BY_VIDEO_CONTENT);
+       dcp->set_reference_video(true);
+       BOOST_CHECK_EQUAL(film->possible_reel_types().size(), 1U);
+}
+
+
+BOOST_AUTO_TEST_CASE(film_possible_reel_types_test2)
+{
+       auto film = new_test_film("film_possible_reel_types_test2");
+
+       auto dcp = make_shared<DCPContent>("test/data/dcp_digest_test_dcp");
+       film->examine_and_add_content(dcp);
+       BOOST_REQUIRE(!wait_for_jobs());
+       BOOST_CHECK_EQUAL(film->possible_reel_types().size(), 4U);
+
+       dcp->set_reference_video(true);
+       BOOST_CHECK_EQUAL(film->possible_reel_types().size(), 2U);
+}
+