Bv2.1 7.2.2: Check that subtitle Language tags are present.
authorCarl Hetherington <cth@carlh.net>
Mon, 14 Dec 2020 22:23:41 +0000 (23:23 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 17 Jan 2021 19:13:22 +0000 (20:13 +0100)
BRANCH
src/verify.cc
src/verify.h
test/test.cc
test/verify_test.cc

diff --git a/BRANCH b/BRANCH
index 290cadc901e2b58764533697cdbd4d8f5fd8332b..09e77d128e4be07bbb3c38bf0ef1e923ccc469c9 100644 (file)
--- a/BRANCH
+++ b/BRANCH
@@ -22,6 +22,8 @@ Mark things with [Bv2.1_paragraph]
 7.2 [/]
 7.2.1
     - Timed text XML files for closed captions must be <= 256kB [/]
-    - Timed text total track asset must be <= 115MB
-    - Font resource <= 10MB
+    - Timed text total track asset must be <= 115MB [/]
+    - Font resource <= 10MB [/]
+7.2.2 Language Element shall be present [/] and contiguous across all MainSubtitles.
+
        
index 428c737fabaadfd0ab99152845928ccda7b726f8..9dc87eece0b553dea6004c37035293bac25beb8c 100644 (file)
@@ -658,6 +658,12 @@ verify_subtitle_asset (
        if (smpte) {
                if (smpte->language()) {
                        verify_language_tag (*smpte->language(), notes);
+               } else {
+                       notes.push_back (
+                               VerificationNote(
+                                       VerificationNote::VERIFY_BV21_ERROR, VerificationNote::MISSING_SUBTITLE_LANGUAGE, *asset->file()
+                                       )
+                               );
                }
                if (boost::filesystem::file_size(*asset->file()) > 115 * 1024 * 1024) {
                        notes.push_back (
@@ -883,6 +889,8 @@ dcp::note_to_string (dcp::VerificationNote note)
                return String::compose("The total size of the timed text asset %1 is larger than the 115MB maximum required by Bv2.1", note.file()->filename());
        case dcp::VerificationNote::TIMED_TEXT_FONTS_TOO_LARGE_IN_BYTES:
                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());
        }
 
        return "";
index c30718ebba9a34570f61c4e82abed1b1b6ef8add..5a120e1000c743ec9548d7c6093b3bbeaf6a76fc 100644 (file)
@@ -108,6 +108,8 @@ public:
                TIMED_TEXT_ASSET_TOO_LARGE_IN_BYTES,
                /** The total size of all a timed text asset's fonts is larger than 10MB [Bv2.1_7.2.1] */
                TIMED_TEXT_FONTS_TOO_LARGE_IN_BYTES,
+               /** Some SMPTE subtitle XML has no <Language> tag [Bv2.1_7.2.2] */
+               MISSING_SUBTITLE_LANGUAGE,
        };
 
        VerificationNote (Type type, Code code)
index 8092df4f52919ed55831c056cc8bfb2564941a9f..502a847bd9c99ba2348e10229751deab1452d6ed 100644 (file)
@@ -403,6 +403,7 @@ make_simple_with_smpte_subs (boost::filesystem::path path)
        shared_ptr<dcp::DCP> dcp = make_simple (path);
 
        shared_ptr<dcp::SMPTESubtitleAsset> subs(new dcp::SMPTESubtitleAsset());
+       subs->set_language (dcp::LanguageTag("de-DE"));
        subs->add (simple_subtitle());
 
        dcp::ArrayData data(4096);
@@ -437,6 +438,7 @@ make_simple_with_smpte_ccaps (boost::filesystem::path path)
        shared_ptr<dcp::DCP> dcp = make_simple (path);
 
        shared_ptr<dcp::SMPTESubtitleAsset> subs(new dcp::SMPTESubtitleAsset());
+       subs->set_language (dcp::LanguageTag("de-DE"));
        subs->add (simple_subtitle());
        subs->write (path / "ccap.mxf");
 
index e468f28631527676df308621bc3644e2dd354d25..1fc66dcd5b98e4cf994496941ca21acf214dce12 100644 (file)
@@ -1192,6 +1192,7 @@ BOOST_AUTO_TEST_CASE (verify_closed_caption_xml_too_large)
                                )
                        );
        }
+       asset->set_language (dcp::LanguageTag("de-DE"));
        asset->write (dir / "subs.mxf");
        shared_ptr<dcp::ReelClosedCaptionAsset> reel_asset(new dcp::ReelClosedCaptionAsset(asset, dcp::Fraction(24, 1), 16 * 24, 0));
        shared_ptr<dcp::Reel> reel(new dcp::Reel());
@@ -1257,6 +1258,7 @@ verify_timed_text_asset_too_large (string name)
                                )
                        )
                );
+       asset->set_language (dcp::LanguageTag("de-DE"));
        asset->write (dir / "subs.mxf");
 
        shared_ptr<T> reel_asset(new T(asset, dcp::Fraction(24, 1), 16 * 24, 0));
@@ -1288,3 +1290,48 @@ BOOST_AUTO_TEST_CASE (verify_subtitle_asset_too_large)
 }
 
 
+BOOST_AUTO_TEST_CASE (verify_missing_language_tag_in_subtitle_xml)
+{
+       boost::filesystem::path dir = "build/test/verify_missing_language_tag_in_subtitle_xml";
+       prepare_directory (dir);
+       shared_ptr<dcp::DCP> dcp = make_simple (dir, 1);
+
+       string const xml =
+               "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+               "<SubtitleReel xmlns=\"http://www.smpte-ra.org/schemas/428-7/2010/DCST\" xmlns:xs=\"http://www.w3.org/2001/schema\">"
+               "<Id>urn:uuid:e6a8ae03-ebbf-41ed-9def-913a87d1493a</Id>"
+               "<ContentTitleText>Content</ContentTitleText>"
+               "<AnnotationText>Annotation</AnnotationText>"
+               "<IssueDate>2018-10-02T12:25:14+02:00</IssueDate>"
+               "<ReelNumber>1</ReelNumber>"
+               "<EditRate>25 1</EditRate>"
+               "<TimeCodeRate>25</TimeCodeRate>"
+               "<StartTime>00:00:00:00</StartTime>"
+               "<LoadFont ID=\"arial\">urn:uuid:e4f0ff0a-9eba-49e0-92ee-d89a88a575f6</LoadFont>"
+               "<SubtitleList>"
+               "<Font ID=\"arial\" Color=\"FFFEFEFE\" Weight=\"normal\" Size=\"42\" Effect=\"border\" EffectColor=\"FF181818\" AspectAdjust=\"1.00\">"
+               "<Subtitle SpotNumber=\"1\" TimeIn=\"00:00:03:00\" TimeOut=\"00:00:04:10\" FadeUpTime=\"00:00:00:00\" FadeDownTime=\"00:00:00:00\">"
+               "<Text Hposition=\"0.0\" Halign=\"center\" Valign=\"bottom\" Vposition=\"13.5\" Direction=\"ltr\">Hello world</Text>"
+               "</Subtitle>"
+               "</Font>"
+               "</SubtitleList>"
+               "</SubtitleReel>";
+
+       FILE* xml_file = dcp::fopen_boost (dir / "subs.xml", "w");
+       BOOST_REQUIRE (xml_file);
+       fwrite (xml.c_str(), xml.size(), 1, xml_file);
+       fclose (xml_file);
+       shared_ptr<dcp::SMPTESubtitleAsset> subs (new dcp::SMPTESubtitleAsset(dir / "subs.xml"));
+       subs->write (dir / "subs.mxf");
+
+       shared_ptr<dcp::ReelSubtitleAsset> reel_subs (new dcp::ReelSubtitleAsset(subs, dcp::Fraction(24, 1), 100, 0));
+       dcp->cpls().front()->reels().front()->add (reel_subs);
+       dcp->write_xml (dcp::SMPTE);
+
+       vector<boost::filesystem::path> dirs;
+       dirs.push_back (dir);
+       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::MISSING_SUBTITLE_LANGUAGE);
+}