Use stored has_non_zero_entry_point() instead of parsing the DCP again (#2524).
authorCarl Hetherington <cth@carlh.net>
Wed, 6 Mar 2024 00:17:59 +0000 (01:17 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 11 Mar 2024 08:25:26 +0000 (09:25 +0100)
src/lib/dcp_content.cc
test/text_entry_point_test.cc [new file with mode: 0644]
test/wscript

index 35ef15442ed24f9515360763fe62621eaa1ded87..e583578ecc9a087d6d6a5cd3c814c562e96afd93 100644 (file)
@@ -750,37 +750,16 @@ DCPContent::can_reference_audio (shared_ptr<const Film> film, string& why_not) c
 bool
 DCPContent::can_reference_text (shared_ptr<const Film> film, TextType type, string& why_not) const
 {
-       shared_ptr<DCPDecoder> decoder;
-       try {
-               decoder = make_shared<DCPDecoder>(film, shared_from_this(), false, film->tolerant(), shared_ptr<DCPDecoder>());
-       } catch (dcp::ReadError &) {
-               /* We couldn't read the DCP, so it's probably missing */
-               return false;
-       } catch (DCPError &) {
-               /* We couldn't read the DCP, so it's probably missing */
-               return false;
-       } catch (dcp::KDMDecryptionError &) {
-               /* We have an incorrect KDM */
+       if (_has_non_zero_entry_point[TextType::OPEN_SUBTITLE]) {
+               /// TRANSLATORS: this string will follow "Cannot reference this DCP: "
+               why_not = _("one of its subtitle reels has a non-zero entry point so it must be re-written.");
                return false;
        }
 
-        for (auto i: decoder->reels()) {
-                if (type == TextType::OPEN_SUBTITLE) {
-                       if (i->main_subtitle() && i->main_subtitle()->entry_point().get_value_or(0) != 0) {
-                               /// TRANSLATORS: this string will follow "Cannot reference this DCP: "
-                               why_not = _("one of its subtitle reels has a non-zero entry point so it must be re-written.");
-                               return false;
-                       }
-                }
-               if (type == TextType::CLOSED_CAPTION) {
-                       for (auto j: i->closed_captions()) {
-                               if (j->entry_point().get_value_or(0) != 0) {
-                                       /// TRANSLATORS: this string will follow "Cannot reference this DCP: "
-                                       why_not = _("one of its closed caption has a non-zero entry point so it must be re-written.");
-                                       return false;
-                               }
-                       }
-               }
+       if (_has_non_zero_entry_point[TextType::CLOSED_CAPTION]) {
+               /// TRANSLATORS: this string will follow "Cannot reference this DCP: "
+               why_not = _("one of its closed caption has a non-zero entry point so it must be re-written.");
+               return false;
         }
 
        if (trim_start() != dcpomatic::ContentTime()) {
diff --git a/test/text_entry_point_test.cc b/test/text_entry_point_test.cc
new file mode 100644 (file)
index 0000000..ce4f614
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+    Copyright (C) 2024 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/>.
+
+*/
+
+
+#include "test.h"
+#include "lib/dcp_content.h"
+#include "lib/film.h"
+#include <dcp/cpl.h>
+#include <dcp/dcp.h>
+#include <dcp/reel.h>
+#include <dcp/reel_smpte_subtitle_asset.h>
+#include <dcp/smpte_subtitle_asset.h>
+#include <boost/test/unit_test.hpp>
+
+
+using std::make_shared;
+using std::string;
+
+
+BOOST_AUTO_TEST_CASE(test_text_entry_point)
+{
+       auto const path = boost::filesystem::path("build/test/test_text_entry_point");
+       boost::filesystem::remove_all(path);
+       boost::filesystem::create_directories(path);
+
+       /* Make a "bad" DCP with a non-zero text entry point */
+       dcp::DCP bad_dcp(path / "dcp");
+       auto sub = make_shared<dcp::SMPTESubtitleAsset>();
+       sub->write(path / "dcp" / "subs.mxf");
+       auto reel_sub = make_shared<dcp::ReelSMPTESubtitleAsset>(sub, dcp::Fraction{24, 1}, 42, 6);
+       auto reel = make_shared<dcp::Reel>();
+       reel->add(reel_sub);
+
+       auto cpl = make_shared<dcp::CPL>("foo", dcp::ContentKind::FEATURE, dcp::Standard::SMPTE);
+       bad_dcp.add(cpl);
+       cpl->add(reel);
+
+       bad_dcp.write_xml();
+
+       /* Make a film and add the bad DCP, so that the examiner spots the problem */
+       auto dcp_content = make_shared<DCPContent>(path / "dcp");
+       auto film = new_test_film2("test_text_entry_point/film", { dcp_content });
+       film->write_metadata();
+
+       /* Reload the film to check that the examiner's output is saved and recovered */
+       auto film2 = make_shared<Film>(path / "film");
+       film2->read_metadata();
+
+       string why_not;
+       BOOST_CHECK(!dcp_content->can_reference_text(film2, TextType::OPEN_SUBTITLE, why_not));
+       BOOST_CHECK_EQUAL(why_not, "one of its subtitle reels has a non-zero entry point so it must be re-written.");
+}
+
index 400d8ea74638f9161024efe07a977b803dd4dae3..eb89013383a539832661088cdb1c4665e37f79a7 100644 (file)
@@ -162,6 +162,7 @@ def build(bld):
                  template_test.cc
                  test.cc
                  text_decoder_test.cc
+                 text_entry_point_test.cc
                  threed_test.cc
                  time_calculation_test.cc
                  torture_test.cc