Pass tolerant flag into Content::examine() and the ExamineContentJob.
authorCarl Hetherington <cth@carlh.net>
Sun, 19 Jan 2025 23:31:32 +0000 (00:31 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 20 Jan 2025 19:36:46 +0000 (20:36 +0100)
Along the way this helps to fix #2942.

30 files changed:
src/lib/atmos_mxf_content.cc
src/lib/atmos_mxf_content.h
src/lib/check_content_job.cc
src/lib/content.cc
src/lib/content.h
src/lib/dcp_content.cc
src/lib/dcp_content.h
src/lib/dcp_subtitle_content.cc
src/lib/dcp_subtitle_content.h
src/lib/examine_content_job.cc
src/lib/examine_content_job.h
src/lib/fcpxml_content.cc
src/lib/fcpxml_content.h
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_content.h
src/lib/film.cc
src/lib/image_content.cc
src/lib/image_content.h
src/lib/string_text_file_content.cc
src/lib/string_text_file_content.h
src/lib/transcode_job.cc
src/lib/video_mxf_content.cc
src/lib/video_mxf_content.h
src/tools/dcpomatic_player.cc
src/wx/content_menu.cc
src/wx/content_view.cc
src/wx/playlist_controls.cc
test/dcp_decoder_test.cc
test/remake_id_test.cc
test/vf_test.cc

index 6b2a64d68f2a7d4a2369c65d4e7939d52903fc75..df044a5d4a0335888f05567ae891f6b0f3315723 100644 (file)
@@ -75,10 +75,10 @@ AtmosMXFContent::valid_mxf (boost::filesystem::path path)
 
 
 void
-AtmosMXFContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
+AtmosMXFContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool tolerant)
 {
        job->set_progress_unknown ();
-       Content::examine (film, job);
+       Content::examine(film, job, tolerant);
        auto a = make_shared<dcp::AtmosAsset>(path(0));
 
        {
index b0bdeb92f13d1d8bdfd6c59991394986fd1fca99..135371739893494eca8f9bee91eca0eb83f062cd 100644 (file)
@@ -37,7 +37,7 @@ public:
                return std::dynamic_pointer_cast<const AtmosMXFContent> (Content::shared_from_this());
        }
 
-       void examine (std::shared_ptr<const Film> film, std::shared_ptr<Job> job) override;
+       void examine(std::shared_ptr<const Film> film, std::shared_ptr<Job> job, bool tolerant) override;
        std::string summary () const override;
 
        void as_xml(
index 2028b01ac0f2672b1367967539361a8636b9e877..bb43158aeadb68261b3609cb51128575967116f2 100644 (file)
@@ -82,7 +82,7 @@ CheckContentJob::run ()
 
        if (!changed.empty()) {
                for (auto i: changed) {
-                       JobManager::instance()->add(make_shared<ExamineContentJob>(_film, i));
+                       JobManager::instance()->add(make_shared<ExamineContentJob>(_film, i, false));
                }
                set_message (_("Some files have been changed since they were added to the project.\n\nThese files will now be re-examined, so you may need to check their settings."));
        }
index 5c44cb47a426d7f055e33aebfc67c2b6c14bf146..5e6dd7e31ed326e4415c5c970ebda57ddcc4317f 100644 (file)
@@ -181,7 +181,7 @@ Content::calculate_digest () const
 
 
 void
-Content::examine (shared_ptr<const Film>, shared_ptr<Job> job)
+Content::examine(shared_ptr<const Film>, shared_ptr<Job> job, bool)
 {
        if (job) {
                job->sub (_("Computing digest"));
index 29dce2c9eccab634f765001fdae37c47e6095696..1b4f2b40c6ebd855afadc217489c4cbbfe060273 100644 (file)
@@ -86,8 +86,10 @@ public:
        /** Examine the content to establish digest, frame rates and any other
         *  useful metadata.
         *  @param job Job to use to report progress, or 0.
+        *  @param tolerant true to try to carry on in the presence of problems with the content,
+        *  false to throw exceptions in these cases.
         */
-       virtual void examine (std::shared_ptr<const Film> film, std::shared_ptr<Job> job);
+       virtual void examine(std::shared_ptr<const Film> film, std::shared_ptr<Job> job, bool tolerant);
 
        virtual void take_settings_from (std::shared_ptr<const Content> c);
 
index 5b4f163e14fed139290e04c856f3fb1b6e219916..ae2a08c29b90a69e660a55c1ec71ab9d52933220 100644 (file)
@@ -229,7 +229,7 @@ DCPContent::read_sub_directory (boost::filesystem::path p)
 
 /** @param film Film, or 0 */
 void
-DCPContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
+DCPContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool tolerant)
 {
        bool const needed_assets = needs_assets ();
        bool const needed_kdm = needs_kdm ();
@@ -248,9 +248,9 @@ DCPContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
        if (job) {
                job->set_progress_unknown ();
        }
-       Content::examine (film, job);
+       Content::examine(film, job, tolerant);
 
-       auto examiner = make_shared<DCPExaminer>(shared_from_this(), film ? film->tolerant() : true);
+       auto examiner = make_shared<DCPExaminer>(shared_from_this(), tolerant);
 
        if (examiner->has_video()) {
                {
index e781633d4400860fdd29c47ffe7a6fa02a7afbfc..8545adf063e987b7da258500d80b41d2e0ac78f6 100644 (file)
@@ -73,7 +73,7 @@ public:
        dcpomatic::DCPTime full_length (std::shared_ptr<const Film> film) const override;
        dcpomatic::DCPTime approximate_length () const override;
 
-       void examine (std::shared_ptr<const Film> film, std::shared_ptr<Job>) override;
+       void examine(std::shared_ptr<const Film> film, std::shared_ptr<Job>, bool tolerant) override;
        std::string summary () const override;
        std::string technical_summary () const override;
 
index 21c1b4de9d9f8f6fc2b0e3ed9c543bd51348aa3e..21159fcac021d6f4f0c132e8340668be37466610 100644 (file)
@@ -57,9 +57,9 @@ DCPSubtitleContent::DCPSubtitleContent(cxml::ConstNodePtr node, boost::optional<
 }
 
 void
-DCPSubtitleContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
+DCPSubtitleContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool tolerant)
 {
-       Content::examine (film, job);
+       Content::examine(film, job, tolerant);
 
        auto subtitle_asset = load(path(0));
 
index 14d36fb6962400f75ce2231734dbbdee94033390..dde3139a8b2c6893dcf8742c551f649bf9ce2e4e 100644 (file)
@@ -27,7 +27,7 @@ public:
        DCPSubtitleContent (boost::filesystem::path);
        DCPSubtitleContent (cxml::ConstNodePtr, boost::optional<boost::filesystem::path> film_directory, int);
 
-       void examine (std::shared_ptr<const Film> film, std::shared_ptr<Job>) override;
+       void examine (std::shared_ptr<const Film> film, std::shared_ptr<Job>, bool tolerant) override;
        std::string summary () const override;
        std::string technical_summary () const override;
 
index baa11ac93218820152ab5f3230d110fa0a9446df..799cda2abcd1e1e082420faf673eabd44febd206 100644 (file)
@@ -34,9 +34,10 @@ using std::cout;
 using std::shared_ptr;
 
 
-ExamineContentJob::ExamineContentJob (shared_ptr<const Film> film, shared_ptr<Content> c)
-       : Job (film)
-       , _content (c)
+ExamineContentJob::ExamineContentJob(shared_ptr<const Film> film, shared_ptr<Content> content, bool tolerant)
+       : Job(film)
+       , _content(content)
+       , _tolerant(tolerant)
 {
 
 }
@@ -65,7 +66,7 @@ ExamineContentJob::json_name () const
 void
 ExamineContentJob::run ()
 {
-       _content->examine (_film, shared_from_this());
+       _content->examine(_film, shared_from_this(), _tolerant);
        set_progress (1);
        set_state (FINISHED_OK);
 }
index 601b285844a0466dd66f5e652cb582602028ea8f..cdcba34300ef4d993c4b2e56c508b78c89be6aa5 100644 (file)
@@ -28,7 +28,7 @@ class Content;
 class ExamineContentJob : public Job
 {
 public:
-       ExamineContentJob (std::shared_ptr<const Film>, std::shared_ptr<Content>);
+       ExamineContentJob(std::shared_ptr<const Film> film, std::shared_ptr<Content> content, bool tolerant);
        ~ExamineContentJob ();
 
        std::string name () const override;
@@ -41,4 +41,6 @@ public:
 
 private:
        std::shared_ptr<Content> _content;
+
+       bool _tolerant;
 };
index cac3305efdb04f9b2da83ed955cb88b1976ac54c..e72ce2d7db2cdffe50ac1cd62f9db0af5e4859dd 100644 (file)
@@ -50,9 +50,9 @@ FCPXMLContent::FCPXMLContent(cxml::ConstNodePtr node, optional<boost::filesystem
 
 
 void
-FCPXMLContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job)
+FCPXMLContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool tolerant)
 {
-       Content::examine(film, job);
+       Content::examine(film, job, tolerant);
 
        auto sequence = dcpomatic::fcpxml::load(path(0));
 
index 701fd6d02c241fd49d99796c80410a672b578067..229ac757dadf27af47336c31142c3b77e6481221 100644 (file)
@@ -41,7 +41,7 @@ public:
                return std::dynamic_pointer_cast<const FCPXMLContent>(Content::shared_from_this());
        }
 
-       void examine(std::shared_ptr<const Film> film, std::shared_ptr<Job>) override;
+       void examine(std::shared_ptr<const Film> film, std::shared_ptr<Job>, bool tolerant) override;
        std::string summary() const override;
        std::string technical_summary() const override;
        void as_xml(xmlpp::Element*, bool with_paths, PathBehaviour path_behaviour, boost::optional<boost::filesystem::path> film_directory) const override;
index 49e4933a68c2b63779dd4eef4bfbb54b2f41b2f9..8434197c5267ebbfe8d4f04c4af478fac21fee8b 100644 (file)
@@ -257,7 +257,7 @@ FFmpegContent::as_xml(xmlpp::Element* element, bool with_paths, PathBehaviour pa
 
 
 void
-FFmpegContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
+FFmpegContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool tolerant)
 {
        ContentChangeSignaller cc1 (this, FFmpegContentProperty::SUBTITLE_STREAMS);
        ContentChangeSignaller cc2 (this, FFmpegContentProperty::SUBTITLE_STREAM);
@@ -266,7 +266,7 @@ FFmpegContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
                job->set_progress_unknown ();
        }
 
-       Content::examine (film, job);
+       Content::examine(film, job, tolerant);
 
        auto examiner = make_shared<FFmpegExaminer>(shared_from_this (), job);
 
index a0fe9a0c03c41d1b44b977eadf9f38e31296e4c7..ca2f566193d761a296c3c07c84335429453677a0 100644 (file)
@@ -66,7 +66,7 @@ public:
                return std::dynamic_pointer_cast<const FFmpegContent> (Content::shared_from_this ());
        }
 
-       void examine (std::shared_ptr<const Film> film, std::shared_ptr<Job>) override;
+       void examine(std::shared_ptr<const Film> film, std::shared_ptr<Job>, bool tolerant) override;
        void take_settings_from (std::shared_ptr<const Content> c) override;
        std::string summary () const override;
        std::string technical_summary () const override;
index e2df95e32c03427037d54a6680de8973ee2f6452..dd702a3fddf86b6402c59e2ca54cb1af62e789f4 100644 (file)
@@ -1422,7 +1422,7 @@ Film::examine_and_add_content (shared_ptr<Content> content, bool disable_audio_a
                run_ffprobe (content->path(0), file("ffprobe.log"));
        }
 
-       auto j = make_shared<ExamineContentJob>(shared_from_this(), content);
+       auto j = make_shared<ExamineContentJob>(shared_from_this(), content, false);
 
        _job_connections.push_back (
                j->Finished.connect (bind (&Film::maybe_add_content, this, weak_ptr<Job>(j), weak_ptr<Content>(content), disable_audio_analysis))
index e7ba88194785ef622984a159471956668ff92563..218c0e80cca766b930b8c7b55b7508fdbc458c80 100644 (file)
@@ -112,7 +112,7 @@ ImageContent::as_xml(xmlpp::Element* element, bool with_paths, PathBehaviour pat
 
 
 void
-ImageContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
+ImageContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool tolerant)
 {
        if (_path_to_scan) {
                job->sub (_("Scanning image files"));
@@ -136,7 +136,7 @@ ImageContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
                set_paths (paths);
        }
 
-       Content::examine (film, job);
+       Content::examine(film, job, tolerant);
 
        auto examiner = make_shared<ImageExaminer>(film, shared_from_this(), job);
        video->take_from_examiner(film, examiner);
index 73ae696adaccc6159bae36c8cc16a89d83162572..4b3b13380e3f6fb8d20ff0d52f22ee64c2a0bed6 100644 (file)
@@ -37,7 +37,7 @@ public:
                return std::dynamic_pointer_cast<const ImageContent> (Content::shared_from_this ());
        };
 
-       void examine (std::shared_ptr<const Film> film, std::shared_ptr<Job>) override;
+       void examine(std::shared_ptr<const Film> film, std::shared_ptr<Job>, bool tolerant) override;
        std::string summary () const override;
        std::string technical_summary () const override;
 
index 6b5492af96de5445e58b28e5bd2d14fbed85adf2..5ecf50a12445646c7c0e6e0bdb2daa070e03a6d1 100644 (file)
@@ -78,9 +78,9 @@ font_names(StringTextFile const& string_text_file)
 
 
 void
-StringTextFileContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
+StringTextFileContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool tolerant)
 {
-       Content::examine (film, job);
+       Content::examine(film, job, tolerant);
        StringTextFile file (shared_from_this());
 
        only_text()->clear_fonts();
index abfd729067613d99b06a035ba96adeb1ec77dfa6..f634a14d200188ff664c0fb4394546ee77e9d8ee 100644 (file)
@@ -42,7 +42,7 @@ public:
                return std::dynamic_pointer_cast<const StringTextFileContent> (Content::shared_from_this ());
        }
 
-       void examine (std::shared_ptr<const Film> film, std::shared_ptr<Job>) override;
+       void examine(std::shared_ptr<const Film> film, std::shared_ptr<Job>, bool tolerant) override;
        std::string summary () const override;
        std::string technical_summary () const override;
 
index f1373fb4a71bea0df561b5781f4f92ce8b5cc99c..c6da1338131a176e2c816bf677d7759c80432806 100644 (file)
@@ -102,7 +102,7 @@ TranscodeJob::run ()
                        switch (_changed) {
                        case ChangedBehaviour::EXAMINE_THEN_STOP:
                                for (auto i: changed) {
-                                       JobManager::instance()->add(make_shared<ExamineContentJob>(_film, i));
+                                       JobManager::instance()->add(make_shared<ExamineContentJob>(_film, i, false));
                                }
                                set_progress (1);
                                set_message (_("Some files have been changed since they were added to the project.\n\nThese files will now be re-examined, so you may need to check their settings before trying again."));
index ded81e6bf4673484962025c1a8982a7256331b49..779344ac11b95ce08cf42ca8336e3a5589ad7977 100644 (file)
@@ -87,11 +87,11 @@ VideoMXFContent::valid_mxf (boost::filesystem::path path)
 
 
 void
-VideoMXFContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
+VideoMXFContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool tolerant)
 {
        job->set_progress_unknown ();
 
-       Content::examine (film, job);
+       Content::examine(film, job, tolerant);
 
        video.reset (new VideoContent (this));
        auto examiner = make_shared<VideoMXFExaminer>(shared_from_this());
index 0def6008c484d77310540053a72a84db98618e1b..4c2d051b0e85df890a053c862b9df944dcff1f70 100644 (file)
@@ -36,7 +36,7 @@ public:
                return std::dynamic_pointer_cast<const VideoMXFContent>(Content::shared_from_this());
        }
 
-       void examine (std::shared_ptr<const Film> film, std::shared_ptr<Job> job) override;
+       void examine(std::shared_ptr<const Film> film, std::shared_ptr<Job> job, bool tolerant) override;
        std::string summary () const override;
        std::string technical_summary () const override;
        std::string identifier () const override;
index 15ccf0a77cfd555bf451cd39c185119bc8ff4342..0ae5acf26292c72d407287207c6a3a85f2f06989 100644 (file)
@@ -404,7 +404,7 @@ public:
                try {
                        _stress.set_suspended (true);
                        auto dcp = make_shared<DCPContent>(dir);
-                       auto job = make_shared<ExamineContentJob>(film, dcp);
+                       auto job = make_shared<ExamineContentJob>(film, dcp, true);
 
                        auto add_dcp_to_film = [this](weak_ptr<Film> weak_film, weak_ptr<Job> weak_job, weak_ptr<Content> weak_content)
                        {
@@ -579,7 +579,7 @@ private:
                DCPOMATIC_ASSERT (_film);
                auto dcp = dynamic_pointer_cast<DCPContent>(_film->content().front());
                DCPOMATIC_ASSERT (dcp);
-               dcp->examine (_film, shared_ptr<Job>());
+               dcp->examine(_film, {}, true);
 
                /* Examining content re-creates the TextContent objects, so we must re-enable them */
                for (auto i: dcp->text) {
@@ -733,7 +733,7 @@ private:
                        auto dcp = std::dynamic_pointer_cast<DCPContent>(_film->content().front());
                        DCPOMATIC_ASSERT(dcp);
                        dcp->add_ov (wx_to_std(c->GetPath()));
-                       JobManager::instance()->add(make_shared<ExamineContentJob>(_film, dcp));
+                       JobManager::instance()->add(make_shared<ExamineContentJob>(_film, dcp, true));
                        bool const ok = display_progress(variant::wx::dcpomatic_player(), _("Loading content"));
                        if (!ok || !report_errors_from_last_job(this)) {
                                return;
index cd2b8c914dfb1f958f1419e8fe3c7919a007ff30..b2010d4bf13c5760b07c2ecae3e50474e09087d7 100644 (file)
@@ -394,7 +394,7 @@ ContentMenu::re_examine ()
        }
 
        for (auto i: _content) {
-               JobManager::instance()->add(make_shared<ExamineContentJob>(film, i));
+               JobManager::instance()->add(make_shared<ExamineContentJob>(film, i, false));
        }
 }
 
@@ -448,7 +448,7 @@ ContentMenu::kdm ()
 
        auto film = _film.lock ();
        DCPOMATIC_ASSERT (film);
-       JobManager::instance()->add (make_shared<ExamineContentJob>(film, dcp));
+       JobManager::instance()->add(make_shared<ExamineContentJob>(film, dcp, false));
 }
 
 void
@@ -466,7 +466,7 @@ ContentMenu::ov ()
                dcp->add_ov(dialog.path());
                auto film = _film.lock();
                DCPOMATIC_ASSERT (film);
-               JobManager::instance()->add (make_shared<ExamineContentJob>(film, dcp));
+               JobManager::instance()->add (make_shared<ExamineContentJob>(film, dcp, false));
        }
 }
 
@@ -531,7 +531,7 @@ ContentMenu::cpl_selected (wxCommandEvent& ev)
 
        auto film = _film.lock ();
        DCPOMATIC_ASSERT (film);
-       JobManager::instance()->add (make_shared<ExamineContentJob>(film, dcp));
+       JobManager::instance()->add(make_shared<ExamineContentJob>(film, dcp, false));
 }
 
 
index 7a34906ddef1479fb006378e441a47968d3702a3..6a5a3793dbda0537ebdf31fff154e7e4cb2733c4 100644 (file)
@@ -107,7 +107,7 @@ ContentView::update ()
                        }
 
                        if (content) {
-                               auto job = make_shared<ExamineContentJob>(shared_ptr<Film>(), content);
+                               auto job = make_shared<ExamineContentJob>(shared_ptr<Film>(), content, false);
                                jm->add (job);
                                jobs.push_back (job);
                        }
index 0e1977a67c365dabc7ee60a0c6d1014248af3df5..917edfd23cda096b62dddf422f9cadeae407f31b 100644 (file)
@@ -342,7 +342,7 @@ PlaylistControls::select_playlist (int selected, int position)
                        if (kdm) {
                                try {
                                        dcp->add_kdm (*kdm);
-                                       dcp->examine (_film, shared_ptr<Job>());
+                                       dcp->examine(_film, shared_ptr<Job>(), true);
                                } catch (KDMError& e) {
                                        error_dialog(this, _("Could not load KDM."));
                                }
index 6e2bdcb6ac3d22ace10800c8363621fd45e07903..fcecb82e4de9a76b72b57138869ee0157e20e978 100644 (file)
@@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE (check_reuse_old_data_test)
        reels = decoder->reels();
 
        vf_content->add_ov (ov->dir(ov->dcp_name(false)));
-       JobManager::instance()->add (make_shared<ExamineContentJob>(test, vf_content));
+       JobManager::instance()->add(make_shared<ExamineContentJob>(test, vf_content, false));
        BOOST_REQUIRE (!wait_for_jobs());
        decoder = std::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder);
        BOOST_REQUIRE (decoder);
@@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE (check_reuse_old_data_test)
        reels = decoder->reels();
 
        encrypted_content->add_kdm (kdm);
-       JobManager::instance()->add (make_shared<ExamineContentJob>(test, encrypted_content));
+       JobManager::instance()->add(make_shared<ExamineContentJob>(test, encrypted_content, false));
        BOOST_REQUIRE (!wait_for_jobs());
        decoder = std::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder);
        BOOST_REQUIRE (decoder);
index a919fa12aacef467ef5bf7821fc590e84df09c46..84937c3ab661dd57bae6578a0372ac5f6e5335e9 100644 (file)
@@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE (remake_id_test2)
        auto dcp_content = make_shared<DCPContent>(film->dir(film->dcp_name()));
        auto film2 = new_test_film("remake_id_test2_2", { dcp_content });
        dcp_content->add_kdm(kdm);
-       JobManager::instance()->add(make_shared<ExamineContentJob>(film2, dcp_content));
+       JobManager::instance()->add(make_shared<ExamineContentJob>(film2, dcp_content, false));
        BOOST_REQUIRE(!wait_for_jobs());
        make_and_verify_dcp (film2);
 }
index cda3cdee1479fafbfe8d357fe43bd7e875330e8f..cb51169109b437da8faf39f6c10852bdacae0b68 100644 (file)
@@ -423,7 +423,7 @@ BOOST_AUTO_TEST_CASE(test_duplicate_font_id_in_vf)
 
        auto test = new_test_film(name + "_test", { vf_dcp });
        vf_dcp->add_ov(ov->dir(ov->dcp_name(false)));
-       JobManager::instance()->add(make_shared<ExamineContentJob>(test, vf_dcp));
+       JobManager::instance()->add(make_shared<ExamineContentJob>(test, vf_dcp, false));
        BOOST_CHECK(!wait_for_jobs());
 
        make_and_verify_dcp(