From 35dfc1d705561fc41737a076b92fbb03a432b38d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 4 Nov 2025 21:03:36 +0100 Subject: Re-examine files created before we stopped auto-generating stream IDs. --- src/lib/check_content_job.cc | 14 ++++++++++++-- src/lib/film.cc | 14 ++++++++++++++ test/data | 2 +- test/film_metadata_test.cc | 25 +++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/lib/check_content_job.cc b/src/lib/check_content_job.cc index 1d3bec659..98e8c7989 100644 --- a/src/lib/check_content_job.cc +++ b/src/lib/check_content_job.cc @@ -24,6 +24,7 @@ #include "dcp_content.h" #include "examine_content_job.h" #include "film.h" +#include "ffmpeg_content.h" #include "job_manager.h" #include "string_text_file_content.h" #include @@ -67,8 +68,6 @@ CheckContentJob::run() set_progress_unknown(); auto content = _film->content(); - std::vector> changed; - std::copy_if(content.begin(), content.end(), std::back_inserter(changed), [](shared_ptr c) { return c->changed(); }); if (_film->last_written_by_earlier_than(2, 17, 17)) { for (auto c: content) { @@ -80,11 +79,22 @@ CheckContentJob::run() } } + std::vector> changed; + std::copy_if(content.begin(), content.end(), std::back_inserter(changed), [](shared_ptr c) { return c->changed(); }); if (!changed.empty()) { JobManager::instance()->add(make_shared(_film, changed, 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.")); } + if (_film->last_written_by_earlier_than(2, 18, 30)) { + std::vector> needs_upgrade; + std::copy_if(content.begin(), content.end(), std::back_inserter(needs_upgrade), [](shared_ptr c) { return static_cast(dynamic_pointer_cast(c)); }); + if (!needs_upgrade.empty()) { + JobManager::instance()->add(make_shared(_film, needs_upgrade, false)); + set_message(_("Some files must be re-examined due to a bug fix in DCP-o-matic. You may need to check their settings.")); + } + } + set_progress(1); set_state(FINISHED_OK); } diff --git a/src/lib/film.cc b/src/lib/film.cc index b8f983add..5e46d8615 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -762,6 +762,20 @@ Film::read_metadata(optional path) } set_dirty(false); + + /* Clear out possibly-invalid stream IDs (that were created by auto-numbering in previous versions + * which doesn't happen in this one). The content will be re-examined after the film is loaded. + * Before 2.18.26 we wrote IDs which might now fail. In 2.18.30 we added this check, to mistrust + * any existing IDs and to re-create them. + */ + if (last_written_by_earlier_than(2, 18, 30)) { + for (auto content: _playlist->content()) { + if (auto ffmpeg = dynamic_pointer_cast(content)) { + ffmpeg->remove_stream_ids(); + } + } + } + return notes; } diff --git a/test/data b/test/data index 9428f5618..7bc927ee1 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 9428f56181723c56917a901780d8e2c4b486b396 +Subproject commit 7bc927ee1c828ce5f6f8e376176c8a44f193ed1e diff --git a/test/film_metadata_test.cc b/test/film_metadata_test.cc index 600dbf56d..2592938a7 100644 --- a/test/film_metadata_test.cc +++ b/test/film_metadata_test.cc @@ -25,11 +25,15 @@ */ +#include "lib/check_content_job.h" #include "lib/content.h" #include "lib/content_factory.h" #include "lib/dcp_content.h" #include "lib/dcp_content_type.h" +#include "lib/image.h" #include "lib/film.h" +#include "lib/job_manager.h" +#include "lib/player.h" #include "lib/ratio.h" #include "lib/text_content.h" #include "lib/video_content.h" @@ -236,3 +240,24 @@ BOOST_AUTO_TEST_CASE(effect_node_not_inserted_incorrectly) BOOST_CHECK(!doc.node_child("Playlist")->node_child("Content")->node_child("Text")->optional_node_child("Effect")); } + +BOOST_AUTO_TEST_CASE(can_load_film_with_now_invalid_stream_ids) +{ + auto const name = std::string{"can_load_film_with_now_invalid_stream_ids"}; + auto film = new_test_film(name); + boost::filesystem::remove(film->file("metadata.xml")); + boost::filesystem::copy_file(boost::filesystem::path("test/data") / (name + ".xml"), film->file("metadata.xml")); + { + Editor editor(film->file("metadata.xml")); + auto const replace = boost::filesystem::current_path() / boost::filesystem::path("test") / "data" / "phil.mkv"; + editor.replace("phil.mkv", replace.string()); + } + film->read_metadata(); + + auto player = make_shared(film, Image::Alignment::COMPACT, true); + + auto check = make_shared(film); + JobManager::instance()->add(make_shared(film)); + BOOST_CHECK(!wait_for_jobs()); +} + -- cgit v1.2.3