summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-10-20 21:22:17 +0200
committerCarl Hetherington <cth@carlh.net>2026-02-03 21:37:04 +0100
commiteda0b0b0ffecf2d6d67407303a1bd45659ccdfce (patch)
treec57cda863071ca7af8de20ac9bce128b45d93289 /src/lib
parent9b841fddd3aa4a1117b03299bce964c5e4b205d9 (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.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/dcp_content.cc21
-rw-r--r--src/lib/dcp_content.h6
-rw-r--r--src/lib/dcp_decoder.cc4
-rw-r--r--src/lib/dcp_examiner.cc5
-rw-r--r--src/lib/dcp_examiner.h5
-rw-r--r--src/lib/show_playlist_content_store.cc9
6 files changed, 41 insertions, 9 deletions
diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc
index e239e7b70..20d6bac48 100644
--- a/src/lib/dcp_content.cc
+++ b/src/lib/dcp_content.cc
@@ -144,7 +144,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()));
}
@@ -323,6 +333,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();
@@ -445,8 +456,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 71d311bf1..34094b4a1 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;
@@ -262,6 +267,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 a5180822a..c67410f76 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();
@@ -360,8 +363,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 8dd865762..e88788402 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;
}
@@ -233,6 +237,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;
}
}