diff options
| author | Carl Hetherington <cth@carlh.net> | 2020-11-24 01:29:11 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2020-11-26 01:49:33 +0100 |
| commit | 4bee9f40969db94aa7edc7816e1b12a7db3cab07 (patch) | |
| tree | 81548723ac4e6c7a043e5e139b50f98673251f6c | |
| parent | 6e5dec71bf4e7a5ff81ecc115c04e8ec2b540c67 (diff) | |
Calculate hashes for any referenced assets that do not already have one.
This is necessary so that we always include <Hash> in CPLs even
when referencing DCPs that do not have it.
| -rw-r--r-- | cscript | 4 | ||||
| -rw-r--r-- | src/lib/writer.cc | 19 | ||||
| -rw-r--r-- | src/lib/writer.h | 1 | ||||
| -rw-r--r-- | test/cpl_hash_test.cc | 97 | ||||
| -rw-r--r-- | test/wscript | 1 |
5 files changed, 119 insertions, 3 deletions
@@ -370,8 +370,8 @@ def dependencies(target, options): (target.platform == 'osx' and target.bits == 64) or (target.platform == 'windows')) else {} - deps.append(('libdcp', 'e78b38b', cpp_lib_options)) - deps.append(('libsub', 'c7e7bf3', cpp_lib_options)) + deps.append(('libdcp', 'c9865a3', cpp_lib_options)) + deps.append(('libsub', 'b0413a7', cpp_lib_options)) deps.append(('leqm-nrt', 'carl')) deps.append(('rtaudio', 'carl')) # We get our OpenSSL libraries from the environment, but we diff --git a/src/lib/writer.cc b/src/lib/writer.cc index a9700f4f5..4915fe68d 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -38,6 +38,7 @@ #include "text_content.h" #include <dcp/cpl.h> #include <dcp/locale_convert.h> +#include <dcp/reel_mxf.h> #include <boost/foreach.hpp> #include <fstream> #include <cerrno> @@ -557,10 +558,11 @@ Writer::finish () pool.create_thread (boost::bind (&boost::asio::io_service::run, &service)); } + boost::function<void (float)> set_progress = boost::bind (&Writer::set_digest_progress, this, job.get(), _1); BOOST_FOREACH (ReelWriter& i, _reels) { - boost::function<void (float)> set_progress = boost::bind (&Writer::set_digest_progress, this, job.get(), _1); service.post (boost::bind (&ReelWriter::calculate_digests, &i, set_progress)); } + service.post (boost::bind (&Writer::calculate_referenced_digests, this, set_progress)); work.reset (); pool.join_all (); @@ -849,3 +851,18 @@ Writer::set_digest_progress (Job* job, float progress) Waker waker; waker.nudge (); } + + +/** Calculate hashes for any referenced MXF assets which do not already have one */ +void +Writer::calculate_referenced_digests (boost::function<void (float)> set_progress) +{ + BOOST_FOREACH (ReferencedReelAsset const& i, _reel_assets) { + shared_ptr<dcp::ReelMXF> mxf = dynamic_pointer_cast<dcp::ReelMXF>(i.asset); + if (mxf && !mxf->hash()) { + mxf->asset_ref().asset()->hash (set_progress); + mxf->set_hash (mxf->asset_ref().asset()->hash()); + } + } +} + diff --git a/src/lib/writer.h b/src/lib/writer.h index 459bc5a88..4c22ef48e 100644 --- a/src/lib/writer.h +++ b/src/lib/writer.h @@ -125,6 +125,7 @@ private: size_t video_reel (int frame) const; void set_digest_progress (Job* job, float progress); void write_cover_sheet (); + void calculate_referenced_digests (boost::function<void (float)> set_progress); /** our Film */ boost::shared_ptr<const Film> _film; diff --git a/test/cpl_hash_test.cc b/test/cpl_hash_test.cc new file mode 100644 index 000000000..28a9420da --- /dev/null +++ b/test/cpl_hash_test.cc @@ -0,0 +1,97 @@ +/* + Copyright (C) 2020 Carl Hetherington <cth@carlh.net> + + This file is part of DCP-o-matic. + + DCP-o-matic 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. + + DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>. + +*/ + +/** @file test/cpl_hash_test.cc + * @brief Make sure that <Hash> tags are always written to CPLs where required. + * @ingroup feature + */ + + +#include "lib/content_factory.h" +#include "lib/cross.h" +#include "lib/dcp_content.h" +#include "lib/film.h" +#include "test.h" +#include <boost/algorithm/string.hpp> +#include <boost/test/unit_test.hpp> + + +using std::string; +using boost::shared_ptr; + + +BOOST_AUTO_TEST_CASE (hash_added_to_imported_dcp_test) +{ + using namespace boost::filesystem; + + string const ov_name = "hash_added_to_imported_dcp_test_ov"; + shared_ptr<Film> ov = new_test_film2 (ov_name); + ov->examine_and_add_content (content_factory("test/data/flat_red.png").front()); + BOOST_REQUIRE (!wait_for_jobs()); + ov->make_dcp(); + BOOST_REQUIRE (!wait_for_jobs()); + + /* Remove <Hash> tags from the CPL */ + for (directory_iterator i = directory_iterator(String::compose("build/test/%1/%2", ov_name, ov->dcp_name())); i != directory_iterator(); ++i) { + if (boost::algorithm::starts_with(i->path().filename().string(), "cpl_")) { + FILE* in = fopen_boost(i->path(), "r"); + BOOST_REQUIRE (in); + FILE* out = fopen_boost(i->path().string() + ".tmp", "w"); + BOOST_REQUIRE (out); + char buffer[256]; + while (fgets (buffer, sizeof(buffer), in)) { + if (string(buffer).find("Hash") == string::npos) { + fputs (buffer, out); + } + } + fclose (in); + fclose (out); + rename (i->path().string() + ".tmp", i->path()); + } + } + + string const vf_name = "hash_added_to_imported_dcp_test_vf"; + shared_ptr<Film> vf = new_test_film2 (vf_name); + shared_ptr<DCPContent> ov_content(new DCPContent(String::compose("build/test/%1/%2", ov_name, ov->dcp_name()))); + vf->examine_and_add_content (ov_content); + BOOST_REQUIRE (!wait_for_jobs()); + + ov_content->set_reference_video (true); + vf->make_dcp (); + BOOST_REQUIRE (!wait_for_jobs()); + + /* Check for Hash tags in the VF DCP */ + int hashes = 0; + for (directory_iterator i = directory_iterator(String::compose("build/test/%1/%2", vf_name, vf->dcp_name())); i != directory_iterator(); ++i) { + if (boost::algorithm::starts_with(i->path().filename().string(), "cpl_")) { + FILE* in = fopen_boost(i->path(), "r"); + BOOST_REQUIRE (in); + char buffer[256]; + while (fgets (buffer, sizeof(buffer), in)) { + if (string(buffer).find("Hash") != string::npos) { + ++hashes; + } + } + fclose (in); + } + } + BOOST_CHECK_EQUAL (hashes, 2); +} + diff --git a/test/wscript b/test/wscript index 39b96e39d..9037b6227 100644 --- a/test/wscript +++ b/test/wscript @@ -60,6 +60,7 @@ def build(bld): colour_conversion_test.cc config_test.cc content_test.cc + cpl_hash_test.cc create_cli_test.cc crypto_test.cc dcpomatic_time_test.cc |
