diff options
| author | Carl Hetherington <cth@carlh.net> | 2021-04-14 09:56:21 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2021-04-14 16:20:53 +0200 |
| commit | 098007a1ee6a46b6ff11398f94faff5c85951da4 (patch) | |
| tree | 3459f804ad51d8e22a2a0c1e9bcca5cf0e623a6f | |
| parent | 1ffc787c6318815592e8d81c4878488eb6183ca4 (diff) | |
Improve handling of image subtitle IDs in XML (DoM bug #1965)
When reading/writing the XML for image subtitles, we assumed that
the content of the <Image> tag is just the ID of the PNG in the MXF,
without any prefix.
DoM bug #1965 mentions a DCP where this is not the case, and SMPTE
429-5-2009 has an example where there is urn:uuid: in the XML.
This change makes DoM write this urn:uuid: prefix, and accept it if
it's present (but not complain if it's not).
If the urn:uuid: _is_ required in the field, it's a bit surprising
that nobody has complained up to this point. Maybe nobody noticed,
or nobody reported it.
| -rw-r--r-- | src/subtitle_asset.cc | 23 | ||||
| -rw-r--r-- | src/subtitle_asset_internal.cc | 2 | ||||
| -rw-r--r-- | src/warnings.h | 1 | ||||
| -rw-r--r-- | test/data/subs.mxf | bin | 62954 -> 62928 bytes | |||
| -rw-r--r-- | test/smpte_subtitle_test.cc | 40 | ||||
| -rw-r--r-- | test/verify_test.cc | 5 |
6 files changed, 50 insertions, 21 deletions
diff --git a/src/subtitle_asset.cc b/src/subtitle_asset.cc index bb752441..bf4b1c63 100644 --- a/src/subtitle_asset.cc +++ b/src/subtitle_asset.cc @@ -404,11 +404,31 @@ SubtitleAsset::maybe_add_subtitle (string text, vector<ParseState> const & parse ); break; case ParseState::Type::IMAGE: + { + switch (standard) { + case Standard::INTEROP: + if (text.size() >= 4) { + /* Remove file extension */ + text = text.substr(0, text.size() - 4); + } + break; + case Standard::SMPTE: + /* It looks like this urn:uuid: is required, but DoM wasn't expecting it (and not writing it) + * until around 2.15.140 so I guess either: + * a) it is not (always) used in the field, or + * b) nobody noticed / complained. + */ + if (text.substr(0, 9) == "urn:uuid:") { + text = text.substr(9); + } + break; + } + /* Add a subtitle with no image data and we'll fill that in later */ _subtitles.push_back ( make_shared<SubtitleImage>( ArrayData(), - standard == Standard::INTEROP ? text.substr(0, text.size() - 4) : text, + text, ps.in.get(), ps.out.get(), ps.h_position.get_value_or(0), @@ -421,6 +441,7 @@ SubtitleAsset::maybe_add_subtitle (string text, vector<ParseState> const & parse ); break; } + } } diff --git a/src/subtitle_asset_internal.cc b/src/subtitle_asset_internal.cc index 80e861f1..a9200618 100644 --- a/src/subtitle_asset_internal.cc +++ b/src/subtitle_asset_internal.cc @@ -261,7 +261,7 @@ order::Image::as_xml (xmlpp::Element* parent, Context& context) const position_align (e, context, _h_align, _h_position, _v_align, _v_position); if (context.standard == Standard::SMPTE) { - e->add_child_text (_id); + e->add_child_text ("urn:uuid:" + _id); } else { e->add_child_text (_id + ".png"); } diff --git a/src/warnings.h b/src/warnings.h index e751d9c5..88b4b724 100644 --- a/src/warnings.h +++ b/src/warnings.h @@ -42,6 +42,7 @@ _Pragma("GCC diagnostic ignored \"-Wparentheses\"") \ _Pragma("GCC diagnostic ignored \"-Wdeprecated-copy\"") \ _Pragma("GCC diagnostic ignored \"-Wsuggest-override\"") + _Pragma("GCC diagnostic ignored \"-Wunused-function\"") #else #define LIBDCP_DISABLE_WARNINGS \ _Pragma("GCC diagnostic push") \ diff --git a/test/data/subs.mxf b/test/data/subs.mxf Binary files differindex d321e5c6..9e93251f 100644 --- a/test/data/subs.mxf +++ b/test/data/subs.mxf diff --git a/test/smpte_subtitle_test.cc b/test/smpte_subtitle_test.cc index 74b29951..cc6190c2 100644 --- a/test/smpte_subtitle_test.cc +++ b/test/smpte_subtitle_test.cc @@ -161,18 +161,6 @@ BOOST_AUTO_TEST_CASE (read_smpte_subtitle_test2) } -/** And another one featuring image subtitles */ -BOOST_AUTO_TEST_CASE (read_smpte_subtitle_test3) -{ - dcp::SMPTESubtitleAsset subs ("test/data/subs.mxf"); - - BOOST_REQUIRE_EQUAL (subs.subtitles().size(), 1); - auto si = dynamic_pointer_cast<const dcp::SubtitleImage>(subs.subtitles()[0]); - BOOST_REQUIRE (si); - BOOST_CHECK (si->png_image() == dcp::ArrayData("test/data/sub.png")); -} - - /* Write some subtitle content as SMPTE XML and check that it is right */ BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test) { @@ -456,10 +444,13 @@ BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test3) c.set_reel_number (1); c.set_language (dcp::LanguageTag("en")); c.set_content_title_text ("Test"); + c.set_start_time (dcp::Time()); + + boost::filesystem::path const sub_image = "test/data/sub.png"; c.add ( make_shared<dcp::SubtitleImage>( - dcp::ArrayData ("test/data/sub.png"), + dcp::ArrayData(sub_image), dcp::Time (0, 4, 9, 22, 24), dcp::Time (0, 4, 11, 22, 24), 0, @@ -473,8 +464,23 @@ BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test3) c._id = "a6c58cff-3e1e-4b38-acec-a42224475ef6"; - boost::filesystem::create_directories ("build/test/write_smpte_subtitle_test3"); - c.write ("build/test/write_smpte_subtitle_test3/subs.mxf"); - - /* XXX: check this result when we can read them back in again */ + boost::filesystem::path path = "build/test/write_smpte_subtitle_test3"; + boost::filesystem::create_directories (path); + c.write (path / "subs.mxf"); + + dcp::SMPTESubtitleAsset read_back (path / "subs.mxf"); + auto subs = read_back.subtitles (); + BOOST_REQUIRE_EQUAL (subs.size(), 1U); + auto image = dynamic_pointer_cast<const dcp::SubtitleImage>(subs[0]); + BOOST_REQUIRE (image); + + BOOST_CHECK (image->png_image() == dcp::ArrayData(sub_image)); + BOOST_CHECK (image->in() == dcp::Time(0, 4, 9, 22, 24)); + BOOST_CHECK (image->out() == dcp::Time(0, 4, 11, 22, 24)); + BOOST_CHECK_CLOSE (image->h_position(), 0.0, 1); + BOOST_CHECK (image->h_align() == dcp::HAlign::CENTER); + BOOST_CHECK_CLOSE (image->v_position(), 0.8, 1); + BOOST_CHECK (image->v_align() == dcp::VAlign::TOP); + BOOST_CHECK (image->fade_up_time() == dcp::Time(0, 0, 0, 0, 24)); + BOOST_CHECK (image->fade_down_time() == dcp::Time(0, 0, 0, 0, 24)); } diff --git a/test/verify_test.cc b/test/verify_test.cc index 4e26c66e..e1637911 100644 --- a/test/verify_test.cc +++ b/test/verify_test.cc @@ -193,7 +193,7 @@ private: }; -#if 0 +LIBDCP_DISABLE_WARNINGS static void dump_notes (vector<dcp::VerificationNote> const & notes) @@ -202,7 +202,7 @@ dump_notes (vector<dcp::VerificationNote> const & notes) std::cout << dcp::note_to_string(i) << "\n"; } } -#endif +LIBDCP_ENABLE_WARNINGS static @@ -706,6 +706,7 @@ BOOST_AUTO_TEST_CASE (verify_invalid_smpte_subtitles) path const dir("build/test/verify_invalid_smpte_subtitles"); prepare_directory (dir); + /* This broken_smpte.mxf does not use urn:uuid: for its subtitle ID, which we tolerate (rightly or wrongly) */ copy_file ("test/data/broken_smpte.mxf", dir / "subs.mxf"); auto asset = make_shared<dcp::SMPTESubtitleAsset>(dir / "subs.mxf"); auto reel_asset = make_shared<dcp::ReelSMPTESubtitleAsset>(asset, dcp::Fraction(24, 1), 6046, 0); |
