summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/verify.cc14
-rw-r--r--src/verify.h8
-rw-r--r--test/verify_test.cc22
3 files changed, 36 insertions, 8 deletions
diff --git a/src/verify.cc b/src/verify.cc
index 8ea9ae97..61c41743 100644
--- a/src/verify.cc
+++ b/src/verify.cc
@@ -79,6 +79,7 @@
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <map>
+#include <regex>
#include <set>
#include <vector>
@@ -726,6 +727,17 @@ verify_smpte_subtitle_asset (
} else {
notes.push_back ({VerificationNote::Type::WARNING, VerificationNote::Code::MISSED_CHECK_OF_ENCRYPTED});
}
+
+ if (asset->raw_xml()) {
+ /* Deluxe require this in their QC even if it seems never to be mentioned in any standard */
+ cxml::Document doc("SubtitleReel");
+ doc.read_string(*asset->raw_xml());
+ auto issue_date = doc.string_child("IssueDate");
+ std::regex reg("^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d$");
+ if (!std::regex_match(issue_date, reg)) {
+ notes.push_back({VerificationNote::Type::WARNING, VerificationNote::Code::INVALID_SUBTITLE_ISSUE_DATE, issue_date});
+ }
+ }
}
@@ -1955,6 +1967,8 @@ dcp::note_to_string (VerificationNote note)
return String::compose("The ASSETMAP %1 has more than one asset with the same ID", note.note().get());
case VerificationNote::Code::MISSING_SUBTITLE:
return String::compose("The subtitle asset %1 has no subtitles", note.note().get());
+ case VerificationNote::Code::INVALID_SUBTITLE_ISSUE_DATE:
+ return String::compose("<IssueDate> has an invalid value: %1", note.note().get());
}
return "";
diff --git a/src/verify.h b/src/verify.h
index 2e20bc31..1ddb7066 100644
--- a/src/verify.h
+++ b/src/verify.h
@@ -415,7 +415,13 @@ public:
* note contains the asset ID
* file contains the asset filename
*/
- MISSING_SUBTITLE
+ MISSING_SUBTITLE,
+ /** A SMPTE subtitle asset as an <IssueDate> which is not of the form yyyy-mm-ddThh:mm:ss
+ * I can find no reference in a standard to this being required, but the Deluxe delivery
+ * specifications require it and their QC will fail DCPs that don't have it.
+ * note contains the incorrect <IssueDate>
+ */
+ INVALID_SUBTITLE_ISSUE_DATE
};
VerificationNote (Type type, Code code)
diff --git a/test/verify_test.cc b/test/verify_test.cc
index 12bd3b01..eaec1617 100644
--- a/test/verify_test.cc
+++ b/test/verify_test.cc
@@ -834,7 +834,12 @@ BOOST_AUTO_TEST_CASE (verify_valid_smpte_subtitles)
auto reel_asset = make_shared<dcp::ReelSMPTESubtitleAsset>(asset, dcp::Fraction(24, 1), 6046, 0);
auto cpl = write_dcp_with_single_asset (dir, reel_asset);
- check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }});
+ check_verify_result(
+ {dir},
+ {
+ { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() },
+ { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_ISSUE_DATE, string{"2021-04-14T13:19:14.000+02:00"} }
+ });
}
@@ -863,6 +868,7 @@ BOOST_AUTO_TEST_CASE (verify_invalid_smpte_subtitles)
},
{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_START_TIME, canonical(dir / "subs.mxf") },
{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() },
+ { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_ISSUE_DATE, string{"2020-05-09T00:29:21.000+02:00"} }
});
}
@@ -883,6 +889,7 @@ BOOST_AUTO_TEST_CASE (verify_empty_text_node_in_subtitles)
{ dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME },
{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_LANGUAGE, canonical(dir / "subs.mxf") },
{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() },
+ { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_ISSUE_DATE, string{"2021-08-09T18:34:46.000+02:00"} }
});
}
@@ -1386,7 +1393,7 @@ BOOST_AUTO_TEST_CASE (verify_invalid_closed_caption_xml_size_in_bytes)
{
dcp::VerificationNote::Type::BV21_ERROR,
dcp::VerificationNote::Code::INVALID_CLOSED_CAPTION_XML_SIZE_IN_BYTES,
- string("419346"),
+ string("419336"),
canonical(dir / "subs.mxf")
},
{ dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME },
@@ -1426,7 +1433,7 @@ verify_timed_text_asset_too_large (string name)
check_verify_result (
{ dir },
{
- { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_TIMED_TEXT_SIZE_IN_BYTES, string("121695542"), canonical(dir / "subs.mxf") },
+ { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_TIMED_TEXT_SIZE_IN_BYTES, string("121695532"), canonical(dir / "subs.mxf") },
{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_TIMED_TEXT_FONT_SIZE_IN_BYTES, string("121634816"), canonical(dir / "subs.mxf") },
{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_START_TIME, canonical(dir / "subs.mxf") },
{ dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME },
@@ -2359,7 +2366,7 @@ BOOST_AUTO_TEST_CASE (verify_missing_main_subtitle_from_some_reels)
{ dir },
{
{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_MAIN_SUBTITLE_FROM_SOME_REELS },
- { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }
+ { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() },
});
}
@@ -2496,7 +2503,7 @@ verify_text_entry_point_check (path dir, dcp::VerificationNote::Code code, boost
{dir},
{
{ dcp::VerificationNote::Type::BV21_ERROR, code, subs->id() },
- { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }
+ { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() },
});
}
@@ -3114,7 +3121,7 @@ BOOST_AUTO_TEST_CASE (verify_mismatched_subtitle_resource_id)
"<Id>urn:uuid:%1</Id>"
"<ContentTitleText>Content</ContentTitleText>"
"<AnnotationText>Annotation</AnnotationText>"
- "<IssueDate>2018-10-02T12:25:14+02:00</IssueDate>"
+ "<IssueDate>2018-10-02T12:25:14</IssueDate>"
"<ReelNumber>1</ReelNumber>"
"<Language>en-US</Language>"
"<EditRate>25 1</EditRate>"
@@ -3207,7 +3214,8 @@ BOOST_AUTO_TEST_CASE (verify_incorrect_timed_text_id)
{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISMATCHED_TIMED_TEXT_DURATION , "240 0", boost::filesystem::canonical(subs_mxf) },
{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INCORRECT_TIMED_TEXT_ASSET_ID },
{ dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME },
- { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }
+ { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() },
+ { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_ISSUE_DATE, string{"2018-10-02T12:25:14+02:00"} }
});
}