diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-12-08 23:54:25 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-12-09 02:38:50 +0100 |
| commit | 1df6f4a08a2f3b67c1637068ae4714c1cba2e1e7 (patch) | |
| tree | 92be307e0ba7a6659b8943245d44703d48354bb2 | |
| parent | f043af026316728c4ac2b84357a77d84082c06a1 (diff) | |
Add DCP::cpl_summaries().v1.10.42
DCP-o-matic needs to know some basic CPL details as quickly as possible,
and this is faster than doing read() and then cpls().
| -rw-r--r-- | src/cpl_summary.h | 80 | ||||
| -rw-r--r-- | src/dcp.cc | 53 | ||||
| -rw-r--r-- | src/dcp.h | 7 | ||||
| -rw-r--r-- | src/wscript | 1 | ||||
| -rw-r--r-- | test/cpl_summary_test.cc | 115 | ||||
| -rw-r--r-- | test/wscript | 1 |
6 files changed, 257 insertions, 0 deletions
diff --git a/src/cpl_summary.h b/src/cpl_summary.h new file mode 100644 index 00000000..1475fad5 --- /dev/null +++ b/src/cpl_summary.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2025 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#ifndef LIBDCP_CPL_SUMMARY_H +#define LIBDCP_CPL_SUMMARY_H + + +#include <boost/filesystem.hpp> +#include <boost/optional.hpp> +#include <string> + + +namespace dcp { + + +class CPLSummary +{ +public: + CPLSummary( + boost::filesystem::path dcp_directory_, + std::string cpl_id_, + boost::optional<std::string> annotation_text_, + boost::filesystem::path cpl_file_, + bool encrypted_, + time_t last_write_time_ + ) + : dcp_directory(dcp_directory_) + , cpl_id(cpl_id_) + , cpl_annotation_text(annotation_text_) + , cpl_file(cpl_file_) + , encrypted(encrypted_) + , last_write_time(last_write_time_) + {} + + boost::filesystem::path dcp_directory; + std::string cpl_id; + boost::optional<std::string> cpl_annotation_text; + boost::filesystem::path cpl_file; + /** true if this CPL has any encrypted assets */ + bool encrypted; + time_t last_write_time; +}; + + +} + + +#endif + @@ -58,6 +58,7 @@ #include "raw_convert.h" #include "reel_asset.h" #include "reel_text_asset.h" +#include "scope_guard.h" #include "smpte_text_asset.h" #include "sound_asset.h" #include "stereo_j2k_picture_asset.h" @@ -638,3 +639,55 @@ DCP::set_annotation_text(string annotation_text) _new_annotation_text = annotation_text; } + +vector<CPLSummary> +DCP::cpl_summaries() const +{ + auto asset_map = read_assetmap(); + vector<PKL> pkls; + for (auto const& i: asset_map.pkl_paths()) { + pkls.push_back(PKL(i)); + } + + vector<CPLSummary> cpls; + + for (auto const& id_and_path: asset_map.asset_ids_and_paths()) { + optional<string> pkl_type; + for (auto const& pkl: pkls) { + pkl_type = pkl.type(id_and_path.first); + if (pkl_type) { + break; + } + } + + if (!pkl_type) { + continue; + } + + if ( + pkl_type == remove_parameters(CPL::static_pkl_type(Standard::INTEROP)) || + pkl_type == remove_parameters(CPL::static_pkl_type(Standard::SMPTE))) { + + auto parser = new xmlpp::DomParser; + dcp::ScopeGuard sg = [parser]() { delete parser; }; + + try { + parser->parse_file(dcp::filesystem::fix_long_path(id_and_path.second).string()); + } catch (std::exception& e) { + throw ReadError(String::compose("XML error in %1", id_and_path.second.string()), e.what()); + } + + if (parser->get_document()->get_root_node()->get_name() == "CompositionPlaylist") { + auto cpl = CPL(id_and_path.second); + cpls.push_back( + CPLSummary( + _directory, cpl.id(), cpl.annotation_text(), *cpl.file(), cpl.any_encrypted(), filesystem::last_write_time(_directory) + ) + ); + } + } + } + + return cpls; +} + @@ -44,6 +44,7 @@ #include "asset_map.h" #include "certificate.h" #include "compose.hpp" +#include "cpl_summary.h" #include "metadata.h" #include "name_format.h" #include "util.h" @@ -117,6 +118,12 @@ public: */ void read (std::vector<VerificationNote>* notes = nullptr, bool ignore_incorrect_picture_mxf_type = false); + /** Return summaries of the CPLs in this DCP. This should only be used if the information + * in CPLSummary is all you need. It's faster than read(), but if you need more than + * the CPLSummary you will need to just call read(). + */ + std::vector<CPLSummary> cpl_summaries() const; + /** Compare this DCP with another, according to various options. * @param other DCP to compare this one to. * @param options Options to define what "equality" means. diff --git a/src/wscript b/src/wscript index 3dc2ec12..04356b4f 100644 --- a/src/wscript +++ b/src/wscript @@ -158,6 +158,7 @@ def build(bld): compose.hpp content_kind.h cpl.h + cpl_summary.h crypto_context.h data.h dcp.h diff --git a/test/cpl_summary_test.cc b/test/cpl_summary_test.cc new file mode 100644 index 00000000..2f6ee839 --- /dev/null +++ b/test/cpl_summary_test.cc @@ -0,0 +1,115 @@ +/* + Copyright (C) 2025 Carl Hetherington <cth@carlh.net> + + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + libdcp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libdcp. If not, see <http://www.gnu.org/licenses/>. + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. +*/ + + +#include "dcp.h" +#include "filesystem.h" +#include "test.h" +#include <boost/test/unit_test.hpp> + + +BOOST_AUTO_TEST_CASE(cpl_summary_test1) +{ + auto const name = "TONEPLATES-SMPTE-PLAINTEXT_TST_F_XX-XX_ITL-TD_51-XX_2K_WOE_20111001_WOE_OV"; + auto const dir = private_test / name; + dcp::DCP dcp(dir); + auto cpls = dcp.cpl_summaries(); + + BOOST_REQUIRE_EQUAL(cpls.size(), 1U); + + BOOST_CHECK_EQUAL(cpls[0].dcp_directory, dcp::filesystem::canonical(dir)); + BOOST_CHECK_EQUAL(cpls[0].cpl_id, "0435b2ae-741b-4853-ad7c-6014060344aa"); + BOOST_REQUIRE(static_cast<bool>(cpls[0].cpl_annotation_text)); + BOOST_CHECK_EQUAL(*cpls[0].cpl_annotation_text, name); + BOOST_CHECK_EQUAL( + cpls[0].cpl_file, + dcp::filesystem::canonical(dir / "cpl_0435b2ae-741b-4853-ad7c-6014060344aa_.xml") + ); + BOOST_CHECK(!cpls[0].encrypted); + BOOST_CHECK(cpls[0].last_write_time > 0); +} + + +BOOST_AUTO_TEST_CASE(cpl_summary_test2) +{ + auto const name = "TONEPLATES-SMPTE-ENCRYPTED_TST_F_XX-XX_ITL-TD_51-XX_2K_WOE_20111001_WOE_OV"; + auto const dir = private_test / name; + dcp::DCP dcp(dir); + auto cpls = dcp.cpl_summaries(); + + BOOST_REQUIRE_EQUAL(cpls.size(), 1U); + + BOOST_CHECK_EQUAL(cpls[0].dcp_directory, dcp::filesystem::canonical(dir)); + BOOST_CHECK_EQUAL(cpls[0].cpl_id, "eece17de-77e8-4a55-9347-b6bab5724b9f"); + BOOST_REQUIRE(static_cast<bool>(cpls[0].cpl_annotation_text)); + BOOST_CHECK_EQUAL(*cpls[0].cpl_annotation_text, name); + BOOST_CHECK_EQUAL( + cpls[0].cpl_file, + dcp::filesystem::canonical(dir / "cpl_eece17de-77e8-4a55-9347-b6bab5724b9f_.xml") + ); + BOOST_CHECK(cpls[0].encrypted); + BOOST_CHECK(cpls[0].last_write_time > 0); +} + + +BOOST_AUTO_TEST_CASE(cpl_summary_test3) +{ + auto const name = "data/SMPTE_TST-B1PB2P_S_EN-EN-CCAP_5171-HI-VI_2K_ISDCF_20151123_DPPT_SMPTE_combo/"; + auto const dir = private_test / name; + dcp::DCP dcp(dir); + auto cpls = dcp.cpl_summaries(); + + BOOST_REQUIRE_EQUAL(cpls.size(), 2U); + + BOOST_CHECK_EQUAL(cpls[0].dcp_directory, dcp::filesystem::canonical(dir)); + BOOST_CHECK_EQUAL(cpls[0].cpl_id, "0f404021-652a-4cca-8a7e-c181c5bb83f9"); + BOOST_REQUIRE(!static_cast<bool>(cpls[0].cpl_annotation_text)); + BOOST_CHECK_EQUAL( + cpls[0].cpl_file, + dcp::filesystem::canonical(dir / "CPL_SMPTE_TST-B1P_S_EN-EN-CCAP_51-HI-VI_2K_ISDCF_20151123_DPPT_SMPTE-mod.xml") + ); + BOOST_CHECK(!cpls[0].encrypted); + BOOST_CHECK(cpls[0].last_write_time > 0); + + BOOST_CHECK_EQUAL(cpls[1].dcp_directory, dcp::filesystem::canonical(dir)); + BOOST_CHECK_EQUAL(cpls[1].cpl_id, "29e1a00b-0e19-4d5b-a1d6-24e97b331de6"); + BOOST_REQUIRE(!static_cast<bool>(cpls[1].cpl_annotation_text)); + BOOST_CHECK_EQUAL( + cpls[1].cpl_file, + dcp::filesystem::canonical(dir / "CPL_SMPTE_TST-B2P_S_EN-EN-CCAP_71-HI-VI_2K_ISDCF_20151123_DPPT_SMPTE-mod.xml") + ); + BOOST_CHECK(!cpls[1].encrypted); + BOOST_CHECK(cpls[1].last_write_time > 0); +} + + diff --git a/test/wscript b/test/wscript index 5e94b1f7..b4f526bf 100644 --- a/test/wscript +++ b/test/wscript @@ -76,6 +76,7 @@ def build(bld): cpl_test.cc cpl_metadata_test.cc cpl_sar_test.cc + cpl_summary_test.cc cpl_ratings_test.cc dcp_font_test.cc dcp_test.cc |
