diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-10-20 21:22:17 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2026-02-16 01:20:38 +0100 |
| commit | 0cb5e386c282ae34dd065e7e294030969645913e (patch) | |
| tree | bac83ad896e18c4f576e60971089fb3288cc8073 | |
| parent | 4cb6ab669032ef0584fde63e62addfe8a71a484c (diff) | |
Replace find_and_resolve_cpls() with storing all CPL IDs in DCPContent (sometimes).
In some places we need other details than the ID, but in lots of places
this saves some disk searching.
| -rw-r--r-- | src/lib/dcp_content.cc | 21 | ||||
| -rw-r--r-- | src/lib/dcp_content.h | 6 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/dcp_examiner.cc | 5 | ||||
| -rw-r--r-- | src/lib/dcp_examiner.h | 5 | ||||
| -rw-r--r-- | src/lib/show_playlist_content_store.cc | 9 | ||||
| -rw-r--r-- | src/tools/dcpomatic_player.cc | 7 | ||||
| -rw-r--r-- | src/wx/content_menu.cc | 8 |
8 files changed, 48 insertions, 17 deletions
diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc index 6e071e5c0..98c49fae4 100644 --- a/src/lib/dcp_content.cc +++ b/src/lib/dcp_content.cc @@ -145,7 +145,17 @@ DCPContent::DCPContent(cxml::ConstNodePtr node, boost::optional<boost::filesyste if (ck) { _content_kind = dcp::ContentKind::from_name(*ck); } - _cpl = node->optional_string_child("CPL"); + for (auto cpl: node->node_children("CPL")) { + _cpls.push_back(cpl->content()); + if (auto selected = cpl->optional_bool_attribute("selected")) { + if (selected) { + _cpl = cpl->content(); + } + } + } + if (!_cpl && !_cpls.empty()) { + _cpl = _cpls.front(); + } for (auto i: node->node_children("ReelLength")) { _reel_lengths.push_back(raw_convert<int64_t>(i->content())); } @@ -340,6 +350,7 @@ DCPContent::examine(shared_ptr<Job> job, bool tolerant) _video_encoding = examiner->video_encoding(); _three_d = examiner->three_d(); _content_kind = examiner->content_kind(); + _cpls = examiner->cpls(); _cpl = examiner->cpl(); _reel_lengths = examiner->reel_lengths(); _markers = examiner->markers(); @@ -466,8 +477,12 @@ DCPContent::as_xml(xmlpp::Element* element, bool with_paths, PathBehaviour path_ if (_content_kind) { cxml::add_text_child(element, "ContentKind", _content_kind->name()); } - if (_cpl) { - cxml::add_text_child(element, "CPL", _cpl.get()); + for (auto cpl: _cpls) { + auto e = cxml::add_child(element, "CPL"); + e->add_child_text(cpl); + if (cpl == _cpl) { + e->set_attribute("selected", "1"); + } } for (auto i: _reel_lengths) { cxml::add_text_child(element, "ReelLength", fmt::to_string(i)); diff --git a/src/lib/dcp_content.h b/src/lib/dcp_content.h index 8a34c4bbe..a76028a67 100644 --- a/src/lib/dcp_content.h +++ b/src/lib/dcp_content.h @@ -166,6 +166,11 @@ public: void set_cpl(std::string id); + std::vector<std::string> cpls() const { + boost::mutex::scoped_lock lm(_mutex); + return _cpls; + } + boost::optional<std::string> cpl() const { boost::mutex::scoped_lock lm(_mutex); return _cpl; @@ -278,6 +283,7 @@ private: boost::optional<VideoEncoding> _video_encoding; boost::optional<dcp::ContentKind> _content_kind; bool _three_d; + std::vector<std::string> _cpls; /** ID of the CPL to use; older metadata might not specify this: in that case * just use the only CPL. */ diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 42119a041..4809d772a 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -101,6 +101,10 @@ DCPDecoder::DCPDecoder(shared_ptr<const Film> film, shared_ptr<const DCPContent> We do this by storing a digest of the important bits of the DCPContent and then checking that's the same before we re-use _reels. + + XXX: this seems a bit dubious - why is a complete re-examine not necessary in this case? + Or why is this done for DCPs only, and not other files that might change? + (see blame for the comment above for some reasons) */ _lazy_digest = calculate_lazy_digest(content); diff --git a/src/lib/dcp_examiner.cc b/src/lib/dcp_examiner.cc index b749c9686..e5e42a923 100644 --- a/src/lib/dcp_examiner.cc +++ b/src/lib/dcp_examiner.cc @@ -119,6 +119,9 @@ DCPExaminer::DCPExaminer(shared_ptr<const DCPContent> content, bool tolerant) selected_cpl->add(decrypt_kdm_with_helpful_error(content->kdm().get())); } + for (auto cpl: cpls) { + _cpls.push_back(cpl->id()); + } _cpl = selected_cpl->id(); _name = selected_cpl->content_title_text(); _content_kind = selected_cpl->content_kind(); @@ -364,8 +367,6 @@ DCPExaminer::DCPExaminer(shared_ptr<const DCPContent> content, bool tolerant) for (auto version: selected_cpl->content_versions()) { _content_versions.push_back(version.label_text); } - - _cpl = selected_cpl->id(); } diff --git a/src/lib/dcp_examiner.h b/src/lib/dcp_examiner.h index 7e73a8b09..12cd32500 100644 --- a/src/lib/dcp_examiner.h +++ b/src/lib/dcp_examiner.h @@ -163,6 +163,10 @@ public: return *_content_kind; } + std::vector<std::string> cpls() const { + return _cpls; + } + std::string cpl() const { return _cpl; } @@ -249,6 +253,7 @@ private: boost::optional<VideoEncoding> _video_encoding; bool _three_d = false; boost::optional<dcp::ContentKind> _content_kind; + std::vector<std::string> _cpls; std::string _cpl; std::list<int64_t> _reel_lengths; std::map<dcp::Marker, dcpomatic::ContentTime> _markers; diff --git a/src/lib/show_playlist_content_store.cc b/src/lib/show_playlist_content_store.cc index 1a9f533af..6e1100c70 100644 --- a/src/lib/show_playlist_content_store.cc +++ b/src/lib/show_playlist_content_store.cc @@ -70,12 +70,13 @@ ShowPlaylistContentStore::update(std::function<bool()> pulse) if (is_directory(i) && contains_assetmap(i)) { auto dcp = make_shared<DCPContent>(i); + examine(dcp); /* Add a Content for each CPL in this DCP, so we can choose CPLs to play * rather than DCPs. */ - for (auto cpl: dcp::find_and_resolve_cpls(dcp->directories(), true)) { + for (auto cpl: dcp->cpls()) { auto copy = dynamic_pointer_cast<DCPContent>(dcp->clone()); - copy->set_cpl(cpl->id()); + copy->set_cpl(cpl); examine(copy); } } else if (i.path().extension() == ".mp4") { @@ -121,8 +122,8 @@ ShowPlaylistContentStore::get(string const& uuid) const { auto iter = std::find_if(_content.begin(), _content.end(), [uuid](shared_ptr<const Content> content) { if (auto dcp = dynamic_pointer_cast<const DCPContent>(content)) { - for (auto cpl: dcp::find_and_resolve_cpls(dcp->directories(), true)) { - if (cpl->id() == uuid) { + for (auto cpl: dcp->cpls()) { + if (cpl == uuid) { return true; } } diff --git a/src/tools/dcpomatic_player.cc b/src/tools/dcpomatic_player.cc index 30a8d1071..b4425fe25 100644 --- a/src/tools/dcpomatic_player.cc +++ b/src/tools/dcpomatic_player.cc @@ -549,8 +549,7 @@ public: if (_film->content().size() == 1) { /* Offer a CPL menu */ - auto first = dynamic_pointer_cast<DCPContent>(_film->content().front()); - if (first) { + if (auto first = dynamic_pointer_cast<DCPContent>(_film->content().front())) { int id = ID_view_cpl; for (auto i: dcp::find_and_resolve_cpls(first->directories(), true)) { auto j = _cpl_menu->AppendRadioItem( @@ -916,7 +915,7 @@ private: { auto dcp = std::dynamic_pointer_cast<DCPContent>(_film->content().front()); DCPOMATIC_ASSERT(dcp); - auto cpls = dcp::find_and_resolve_cpls(dcp->directories(), true); + auto cpls = dcp->cpls(); int id = ev.GetId() - ID_view_cpl; DCPOMATIC_ASSERT(id >= 0); DCPOMATIC_ASSERT(id < int(cpls.size())); @@ -927,7 +926,7 @@ private: } _viewer.set_coalesce_player_changes(true); - dcp->set_cpl((*i)->id()); + dcp->set_cpl(*i); examine_content(); _viewer.set_coalesce_player_changes(false); diff --git a/src/wx/content_menu.cc b/src/wx/content_menu.cc index b75c29660..527e28624 100644 --- a/src/wx/content_menu.cc +++ b/src/wx/content_menu.cc @@ -454,8 +454,8 @@ ContentMenu::kdm() return; } - auto cpls = dcp::find_and_resolve_cpls(dcp->directories(), true); - bool const kdm_matches_any_cpl = std::any_of(cpls.begin(), cpls.end(), [kdm](shared_ptr<const dcp::CPL> cpl) { return cpl->id() == kdm->cpl_id(); }); + auto cpls = dcp->cpls(); + bool const kdm_matches_any_cpl = std::any_of(cpls.begin(), cpls.end(), [kdm](std::string const& cpl) { return cpl == kdm->cpl_id(); }); bool const kdm_matches_selected_cpl = dcp->cpl() || kdm->cpl_id() == dcp->cpl().get(); if (!kdm_matches_any_cpl) { @@ -549,11 +549,11 @@ ContentMenu::cpl_selected(wxCommandEvent& ev) auto dcp = dynamic_pointer_cast<DCPContent>(_content.front()); DCPOMATIC_ASSERT(dcp); - auto cpls = dcp::find_and_resolve_cpls(dcp->directories(), true); + auto cpls = dcp->cpls(); DCPOMATIC_ASSERT(ev.GetId() >= DCPOMATIC_CPL_MENU); DCPOMATIC_ASSERT(ev.GetId() < int(DCPOMATIC_CPL_MENU + cpls.size())); - dcp->set_cpl(cpls[ev.GetId() - DCPOMATIC_CPL_MENU]->id()); + dcp->set_cpl(cpls[ev.GetId() - DCPOMATIC_CPL_MENU]); auto film = _film.lock(); DCPOMATIC_ASSERT(film); |
