summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-12-15 00:51:34 +0100
committerCarl Hetherington <cth@carlh.net>2021-01-17 20:13:22 +0100
commite182156f75a74457c4452cc3bfe91d778d0d7148 (patch)
tree7c929330d3953a76c801d4ba22bc9936da7c94d2
parent7c5237f7f45b85a6030b345cf4542ed4059fa5c9 (diff)
Bv2.1 7.2.2: Check that subtitle languages are the same for all reels.
-rw-r--r--BRANCH2
-rw-r--r--src/verify.cc33
-rw-r--r--src/verify.h2
-rw-r--r--test/test.h1
-rw-r--r--test/verify_test.cc36
5 files changed, 67 insertions, 7 deletions
diff --git a/BRANCH b/BRANCH
index 09e77d12..7b9aab02 100644
--- a/BRANCH
+++ b/BRANCH
@@ -24,6 +24,6 @@ Mark things with [Bv2.1_paragraph]
- Timed text XML files for closed captions must be <= 256kB [/]
- Timed text total track asset must be <= 115MB [/]
- Font resource <= 10MB [/]
-7.2.2 Language Element shall be present [/] and contiguous across all MainSubtitles.
+7.2.2 Language Element shall be present [/] and contiguous across all MainSubtitles [/]
diff --git a/src/verify.cc b/src/verify.cc
index 1b476ef2..0b7def3c 100644
--- a/src/verify.cc
+++ b/src/verify.cc
@@ -640,12 +640,19 @@ verify_closed_caption_reel (shared_ptr<const ReelClosedCaptionAsset> reel_asset,
}
+struct State
+{
+ boost::optional<string> subtitle_language;
+};
+
+
static void
verify_subtitle_asset (
shared_ptr<const SubtitleAsset> asset,
function<void (string, optional<boost::filesystem::path>)> stage,
boost::filesystem::path xsd_dtd_directory,
- list<VerificationNote>& notes
+ list<VerificationNote>& notes,
+ State& state
)
{
stage ("Checking subtitle XML", asset->file());
@@ -657,7 +664,17 @@ verify_subtitle_asset (
shared_ptr<const SMPTESubtitleAsset> smpte = dynamic_pointer_cast<const SMPTESubtitleAsset>(asset);
if (smpte) {
if (smpte->language()) {
- verify_language_tag (*smpte->language(), notes);
+ string const language = *smpte->language();
+ verify_language_tag (language, notes);
+ if (!state.subtitle_language) {
+ state.subtitle_language = language;
+ } else if (state.subtitle_language != language) {
+ notes.push_back (
+ VerificationNote(
+ VerificationNote::VERIFY_BV21_ERROR, VerificationNote::SUBTITLE_LANGUAGES_DIFFER, *asset->file()
+ )
+ );
+ }
} else {
notes.push_back (
VerificationNote(
@@ -696,10 +713,11 @@ verify_closed_caption_asset (
shared_ptr<const SubtitleAsset> asset,
function<void (string, optional<boost::filesystem::path>)> stage,
boost::filesystem::path xsd_dtd_directory,
- list<VerificationNote>& notes
+ list<VerificationNote>& notes,
+ State& state
)
{
- verify_subtitle_asset (asset, stage, xsd_dtd_directory, notes);
+ verify_subtitle_asset (asset, stage, xsd_dtd_directory, notes, state);
if (asset->raw_xml().size() > 256 * 1024) {
notes.push_back (
@@ -722,6 +740,7 @@ dcp::verify (
xsd_dtd_directory = boost::filesystem::canonical (xsd_dtd_directory);
list<VerificationNote> notes;
+ State state;
list<shared_ptr<DCP> > dcps;
BOOST_FOREACH (boost::filesystem::path i, directories) {
@@ -804,14 +823,14 @@ dcp::verify (
if (reel->main_subtitle()) {
verify_main_subtitle_reel (reel->main_subtitle(), notes);
if (reel->main_subtitle()->asset_ref().resolved()) {
- verify_subtitle_asset (reel->main_subtitle()->asset(), stage, xsd_dtd_directory, notes);
+ verify_subtitle_asset (reel->main_subtitle()->asset(), stage, xsd_dtd_directory, notes, state);
}
}
BOOST_FOREACH (shared_ptr<dcp::ReelClosedCaptionAsset> i, reel->closed_captions()) {
verify_closed_caption_reel (i, notes);
if (i->asset_ref().resolved()) {
- verify_closed_caption_asset (i->asset(), stage, xsd_dtd_directory, notes);
+ verify_closed_caption_asset (i->asset(), stage, xsd_dtd_directory, notes, state);
}
}
}
@@ -891,6 +910,8 @@ dcp::note_to_string (dcp::VerificationNote note)
return String::compose("The total size of the fonts in timed text asset %1 is larger than the 10MB maximum required by Bv2.1", note.file()->filename());
case dcp::VerificationNote::MISSING_SUBTITLE_LANGUAGE:
return String::compose("The XML for a SMPTE subtitle asset has no <Language> tag, which is required by Bv2.1", note.file()->filename());
+ case dcp::VerificationNote::SUBTITLE_LANGUAGES_DIFFER:
+ return String::compose("Some subtitle assets have different <Language> tags than others", note.file()->filename());
}
return "";
diff --git a/src/verify.h b/src/verify.h
index 8a049dd5..170aeb8b 100644
--- a/src/verify.h
+++ b/src/verify.h
@@ -110,6 +110,8 @@ public:
TIMED_TEXT_FONTS_TOO_LARGE_IN_BYTES,
/** Some SMPTE subtitle XML has no <Language> tag [Bv2.1_7.2.2] */
MISSING_SUBTITLE_LANGUAGE,
+ /** Not all subtitle assets specify the same <Language> tag [Bv2.1_7.2.2] */
+ SUBTITLE_LANGUAGES_DIFFER,
};
VerificationNote (Type type, Code code)
diff --git a/test/test.h b/test/test.h
index 1d9cd921..10f99ce1 100644
--- a/test/test.h
+++ b/test/test.h
@@ -45,6 +45,7 @@ extern void check_xml (std::string ref, std::string test, std::list<std::string>
extern void check_file (boost::filesystem::path ref, boost::filesystem::path check);
extern std::shared_ptr<dcp::MonoPictureAsset> simple_picture (boost::filesystem::path path, std::string suffix);
extern std::shared_ptr<dcp::SoundAsset> simple_sound (boost::filesystem::path path, std::string suffix, dcp::MXFMetadata mxf_meta, std::string language);
+extern std::shared_ptr<dcp::Subtitle> simple_subtitle ();
extern std::shared_ptr<dcp::DCP> make_simple (boost::filesystem::path path, int reels = 1);
extern std::shared_ptr<dcp::DCP> make_simple_with_interop_subs (boost::filesystem::path path);
extern std::shared_ptr<dcp::DCP> make_simple_with_smpte_subs (boost::filesystem::path path);
diff --git a/test/verify_test.cc b/test/verify_test.cc
index 24d583b6..9bb3859a 100644
--- a/test/verify_test.cc
+++ b/test/verify_test.cc
@@ -1335,3 +1335,39 @@ BOOST_AUTO_TEST_CASE (verify_missing_language_tag_in_subtitle_xml)
BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::VERIFY_BV21_ERROR);
BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::MISSING_SUBTITLE_LANGUAGE);
}
+
+
+BOOST_AUTO_TEST_CASE (verify_inconsistent_subtitle_languages)
+{
+ boost::filesystem::path path ("build/test/verify_inconsistent_subtitle_languages");
+ shared_ptr<dcp::DCP> dcp = make_simple (path, 2);
+ shared_ptr<dcp::CPL> cpl = dcp->cpls().front();
+
+ {
+ shared_ptr<dcp::SMPTESubtitleAsset> subs(new dcp::SMPTESubtitleAsset());
+ subs->set_language (dcp::LanguageTag("de-DE"));
+ subs->add (simple_subtitle());
+ subs->write (path / "subs1.mxf");
+ shared_ptr<dcp::ReelSubtitleAsset> reel_subs(new dcp::ReelSubtitleAsset(subs, dcp::Fraction(24, 1), 240, 0));
+ cpl->reels().front()->add (reel_subs);
+ }
+
+ {
+ shared_ptr<dcp::SMPTESubtitleAsset> subs(new dcp::SMPTESubtitleAsset());
+ subs->set_language (dcp::LanguageTag("en-US"));
+ subs->add (simple_subtitle());
+ subs->write (path / "subs2.mxf");
+ shared_ptr<dcp::ReelSubtitleAsset> reel_subs(new dcp::ReelSubtitleAsset(subs, dcp::Fraction(24, 1), 240, 0));
+ cpl->reels().back()->add (reel_subs);
+ }
+
+ dcp->write_xml (dcp::SMPTE);
+
+ vector<boost::filesystem::path> dirs;
+ dirs.push_back (path);
+ list<dcp::VerificationNote> notes = dcp::verify (dirs, &stage, &progress, xsd_test);
+ BOOST_REQUIRE_EQUAL (notes.size(), 1U);
+ BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::VERIFY_BV21_ERROR);
+ BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::SUBTITLE_LANGUAGES_DIFFER);
+}
+