Bv2.1 6.2.1: Check that the sound MXF Language tag conforms to RFC 5646.
authorCarl Hetherington <cth@carlh.net>
Wed, 9 Dec 2020 12:13:23 +0000 (13:13 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 17 Jan 2021 19:13:22 +0000 (20:13 +0100)
BRANCH
src/sound_asset.h
src/verify.cc
test/test.cc
test/test.h
test/verify_test.cc

diff --git a/BRANCH b/BRANCH
index 5413cfb45c8938c0ae9543615eb09e7340b9a2d6..734b0017d5d4b0247b3bfb798a61a3e36da74114 100644 (file)
--- a/BRANCH
+++ b/BRANCH
@@ -10,7 +10,7 @@ Mark things with [Bv2.1_paragraph]
 6.2 Language and Territory must comply with RFC 5646
     - subtitle reel <Language> /
     - subtitle XML <Language> /
-    - sound reel <Language>
+    - sound MXF Language /
     - ccap reel <Language>
     - MainSubtitleLanguageList
     - RFC5646SpokenLanguage
index 91a213b85736bcf833c74f03b20591f121692add..d4b41a1a47f6f41e93091248e84a80d4a00d6d3c 100644 (file)
 #include "sound_frame.h"
 #include "sound_asset_reader.h"
 
+
+namespace dcp {
+       class SoundAsset;
+}
+
+extern std::shared_ptr<dcp::SoundAsset> simple_sound (
+       boost::filesystem::path path, std::string suffix, dcp::MXFMetadata mxf_meta, std::string language
+       );
+
+
 namespace dcp
 {
 
@@ -95,6 +105,9 @@ public:
 
 private:
        friend class SoundAssetWriter;
+       friend std::shared_ptr<dcp::SoundAsset> (::simple_sound) (
+               boost::filesystem::path path, std::string suffix, dcp::MXFMetadata mxf_meta, std::string language
+               );
 
        std::string pkl_type (Standard standard) const {
                return static_pkl_type (standard);
index 89d84eef97c46fe82d503ce0bf74f75f730fa272..eec63d511b01536032b071bad4eb9f4c0d72ff16 100644 (file)
@@ -532,26 +532,31 @@ verify_main_sound_asset (
        list<VerificationNote>& notes
        )
 {
-       stage ("Checking sound asset hash", reel->main_sound()->asset()->file());
+       shared_ptr<dcp::SoundAsset> asset = reel->main_sound()->asset();
+       stage ("Checking sound asset hash", asset->file());
        VerifyAssetResult const r = verify_asset (dcp, reel->main_sound(), progress);
        switch (r) {
                case VERIFY_ASSET_RESULT_BAD:
                        notes.push_back (
                                VerificationNote(
-                                       VerificationNote::VERIFY_ERROR, VerificationNote::SOUND_HASH_INCORRECT, *reel->main_sound()->asset()->file()
+                                       VerificationNote::VERIFY_ERROR, VerificationNote::SOUND_HASH_INCORRECT, *asset->file()
                                        )
                                );
                        break;
                case VERIFY_ASSET_RESULT_CPL_PKL_DIFFER:
                        notes.push_back (
                                VerificationNote(
-                                       VerificationNote::VERIFY_ERROR, VerificationNote::PKL_CPL_SOUND_HASHES_DISAGREE, *reel->main_sound()->asset()->file()
+                                       VerificationNote::VERIFY_ERROR, VerificationNote::PKL_CPL_SOUND_HASHES_DISAGREE, *asset->file()
                                        )
                                );
                        break;
                default:
                        break;
        }
+
+       stage ("Checking sound asset metadata", asset->file());
+
+       verify_language_tag (asset->language(), notes);
 }
 
 
index c24f28cd7397ca2346b5550a4b831adb8962a03b..c8f41d053d4132d89d2297cdc480c4ebbd0220fc 100644 (file)
@@ -271,9 +271,11 @@ simple_picture (boost::filesystem::path path, string suffix)
 
 
 shared_ptr<dcp::SoundAsset>
-simple_sound (boost::filesystem::path path, string suffix, dcp::MXFMetadata mxf_meta)
+simple_sound (boost::filesystem::path path, string suffix, dcp::MXFMetadata mxf_meta, string language)
 {
+       /* Set a valid language, then overwrite it, so that the language parameter can be badly formed */
        shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset(dcp::Fraction(24, 1), 48000, 1, dcp::LanguageTag("en-US"), dcp::SMPTE));
+       ms->_language = language;
        ms->set_metadata (mxf_meta);
        vector<dcp::Channel> active_channels;
        active_channels.push_back (dcp::LEFT);
@@ -325,7 +327,7 @@ make_simple (boost::filesystem::path path, int reels)
                string suffix = reels == 1 ? "" : dcp::String::compose("%1", i);
 
                shared_ptr<dcp::MonoPictureAsset> mp = simple_picture (path, suffix);
-               shared_ptr<dcp::SoundAsset> ms = simple_sound (path, suffix, mxf_meta);
+               shared_ptr<dcp::SoundAsset> ms = simple_sound (path, suffix, mxf_meta, "en-US");
 
                cpl->add (shared_ptr<dcp::Reel> (
                                  new dcp::Reel (
index 4fc88424ce34b0f5b3481438acf99b6cc33978f4..1368973a65c44df69bf370454736e730f152c8e3 100644 (file)
@@ -44,7 +44,7 @@ extern void check_xml (xmlpp::Element* ref, xmlpp::Element* test, std::list<std:
 extern void check_xml (std::string ref, std::string test, std::list<std::string> ignore, bool ignore_whitespace = false);
 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);
+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::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);
index ac2d825bc8ce55a5b3530335e9279f8865be9c70..89b46d725ff143a990f3610363a4996a3bbcacfe 100644 (file)
@@ -36,6 +36,7 @@
 #include "j2k.h"
 #include "reel.h"
 #include "reel_mono_picture_asset.h"
+#include "reel_sound_asset.h"
 #include "cpl.h"
 #include "dcp.h"
 #include "openjpeg_image.h"
@@ -174,6 +175,10 @@ BOOST_AUTO_TEST_CASE (verify_test1)
        BOOST_REQUIRE (st->second);
        BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1/audio.mxf"));
        ++st;
+       BOOST_CHECK_EQUAL (st->first, "Checking sound asset metadata");
+       BOOST_REQUIRE (st->second);
+       BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1/audio.mxf"));
+       ++st;
        BOOST_CHECK_EQUAL (st->first, "Checking PKL");
        BOOST_REQUIRE (st->second);
        BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical(pkl_file));
@@ -481,6 +486,10 @@ BOOST_AUTO_TEST_CASE (verify_test13)
        BOOST_REQUIRE (st->second);
        BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test13/pcm_69cf9eaf-9a99-4776-b022-6902208626c3.mxf"));
        ++st;
+       BOOST_CHECK_EQUAL (st->first, "Checking sound asset metadata");
+       BOOST_REQUIRE (st->second);
+       BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test13/pcm_69cf9eaf-9a99-4776-b022-6902208626c3.mxf"));
+       ++st;
        BOOST_CHECK_EQUAL (st->first, "Checking PKL");
        BOOST_REQUIRE (st->second);
        BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical(pkl_file));
@@ -906,3 +915,30 @@ BOOST_AUTO_TEST_CASE (verify_test26)
        BOOST_CHECK_EQUAL (*i->note(), "wrong-andbad");
 }
 
+
+/* SMPTE DCP with invalid <Language> in the MainSound reel */
+BOOST_AUTO_TEST_CASE (verify_invalid_sound_reel_language)
+{
+       boost::filesystem::path const dir("build/test/verify_invalid_sound_reel_language");
+       prepare_directory (dir);
+
+       shared_ptr<dcp::SoundAsset> sound = simple_sound (dir, "foo", dcp::MXFMetadata(), "frobozz");
+       shared_ptr<dcp::ReelSoundAsset> reel_sound(new dcp::ReelSoundAsset(sound, 0));
+       shared_ptr<dcp::Reel> reel(new dcp::Reel());
+       reel->add (reel_sound);
+       shared_ptr<dcp::CPL> cpl(new dcp::CPL("hello", dcp::FEATURE));
+       cpl->add (reel);
+       shared_ptr<dcp::DCP> dcp(new dcp::DCP(dir));
+       dcp->add (cpl);
+       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);
+       list<dcp::VerificationNote>::const_iterator i = notes.begin ();
+       BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::BAD_LANGUAGE);
+       BOOST_REQUIRE (i->note());
+       BOOST_CHECK_EQUAL (*i->note(), "frobozz");
+}
+