summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-08-27 22:59:12 +0200
committerCarl Hetherington <cth@carlh.net>2020-09-21 21:57:18 +0200
commitb933775fc54e0b51ad3777d72bf2866f0c04bacc (patch)
treec13133d7cfe9722f3b2eeaa52a8686e029172377 /test
parent1ae2755dbbaa30b6240dfd304c289253a577b424 (diff)
Support CPL metadata.
Diffstat (limited to 'test')
-rw-r--r--test/cpl_metadata_test.cc419
-rw-r--r--test/reel_asset_test.cc56
-rw-r--r--test/ref/cpl_metadata_test1.xml73
-rw-r--r--test/ref/cpl_metadata_test2.xml49
-rw-r--r--test/test.cc39
-rw-r--r--test/test.h5
-rw-r--r--test/verify_test.cc13
-rw-r--r--test/wscript1
8 files changed, 636 insertions, 19 deletions
diff --git a/test/cpl_metadata_test.cc b/test/cpl_metadata_test.cc
new file mode 100644
index 00000000..216ef600
--- /dev/null
+++ b/test/cpl_metadata_test.cc
@@ -0,0 +1,419 @@
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of libdcp.
+
+ libdcp is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ libdcp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libdcp. If not, see <http://www.gnu.org/licenses/>.
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of portions of this program with the
+ OpenSSL library under certain conditions as described in each
+ individual source file, and distribute linked combinations
+ including the two.
+
+ You must obey the GNU General Public License in all respects
+ for all of the code used other than OpenSSL. If you modify
+ file(s) with this exception, you may extend this exception to your
+ version of the file(s), but you are not obligated to do so. If you
+ do not wish to do so, delete this exception statement from your
+ version. If you delete this exception statement from all source
+ files in the program, then also delete it here.
+*/
+
+
+#include "certificate_chain.h"
+#include "cpl.h"
+#include "exceptions.h"
+#include "language_tag.h"
+#include "reel.h"
+#include "reel_subtitle_asset.h"
+#include "test.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/test/unit_test.hpp>
+
+
+using std::list;
+using std::string;
+using std::vector;
+using boost::shared_ptr;
+
+
+BOOST_AUTO_TEST_CASE (cpl_metadata_bad_values_test)
+{
+ dcp::CPL cpl("", dcp::FEATURE);
+ BOOST_CHECK_THROW (cpl.set_version_number(-1), dcp::BadSettingError);
+
+ vector<dcp::ContentVersion> cv;
+ cv.push_back (dcp::ContentVersion("same-id", "version 1"));
+ cv.push_back (dcp::ContentVersion("same-id", "version 2"));
+ BOOST_CHECK_THROW (cpl.set_content_versions(cv), dcp::DuplicateIdError);
+}
+
+
+BOOST_AUTO_TEST_CASE (main_sound_configuration_test1)
+{
+ dcp::MainSoundConfiguration msc("51/L,R,C,LFE,-,-");
+ BOOST_CHECK_EQUAL (msc.to_string(), "51/L,R,C,LFE,-,-");
+ BOOST_CHECK_EQUAL (msc.channels(), 6);
+ BOOST_CHECK_EQUAL (msc.field(), dcp::MainSoundConfiguration::FIVE_POINT_ONE);
+ BOOST_CHECK_EQUAL (msc.mapping(0).get(), dcp::LEFT);
+ BOOST_CHECK_EQUAL (msc.mapping(1).get(), dcp::RIGHT);
+ BOOST_CHECK_EQUAL (msc.mapping(2).get(), dcp::CENTRE);
+ BOOST_CHECK_EQUAL (msc.mapping(3).get(), dcp::LFE);
+ BOOST_CHECK (!msc.mapping(4));
+ BOOST_CHECK (!msc.mapping(5));
+}
+
+
+BOOST_AUTO_TEST_CASE (main_sound_configuration_test2)
+{
+ dcp::MainSoundConfiguration msc("71/L,R,C,LFE,-,-");
+ BOOST_CHECK_EQUAL (msc.to_string(), "71/L,R,C,LFE,-,-");
+ BOOST_CHECK_EQUAL (msc.channels(), 6);
+ BOOST_CHECK_EQUAL (msc.field(), dcp::MainSoundConfiguration::SEVEN_POINT_ONE);
+ BOOST_CHECK_EQUAL (msc.mapping(0).get(), dcp::LEFT);
+ BOOST_CHECK_EQUAL (msc.mapping(1).get(), dcp::RIGHT);
+ BOOST_CHECK_EQUAL (msc.mapping(2).get(), dcp::CENTRE);
+ BOOST_CHECK_EQUAL (msc.mapping(3).get(), dcp::LFE);
+ BOOST_CHECK (!msc.mapping(4));
+ BOOST_CHECK (!msc.mapping(5));
+}
+
+
+BOOST_AUTO_TEST_CASE (main_sound_configuration_test3)
+{
+ dcp::MainSoundConfiguration msc("71/L,-,C,LFE,Lss,Rss");
+ BOOST_CHECK_EQUAL (msc.to_string(), "71/L,-,C,LFE,Lss,Rss");
+ BOOST_CHECK_EQUAL (msc.channels(), 6);
+ BOOST_CHECK_EQUAL (msc.field(), dcp::MainSoundConfiguration::SEVEN_POINT_ONE);
+ BOOST_CHECK_EQUAL (msc.mapping(0).get(), dcp::LEFT);
+ BOOST_CHECK (!msc.mapping(1));
+ BOOST_CHECK_EQUAL (msc.mapping(2).get(), dcp::CENTRE);
+ BOOST_CHECK_EQUAL (msc.mapping(3).get(), dcp::LFE);
+ BOOST_CHECK_EQUAL (msc.mapping(4).get(), dcp::LS);
+ BOOST_CHECK_EQUAL (msc.mapping(5).get(), dcp::RS);
+}
+
+
+BOOST_AUTO_TEST_CASE (main_sound_configuration_test4)
+{
+ dcp::MainSoundConfiguration msc("71/L,-,C,LFE,Lss,Rss,-,-,-,-,-,-,-,-,-");
+ BOOST_CHECK_EQUAL (msc.to_string(), "71/L,-,C,LFE,Lss,Rss,-,-,-,-,-,-,-,-,-");
+ BOOST_CHECK_EQUAL (msc.channels(), 15);
+ BOOST_CHECK_EQUAL (msc.field(), dcp::MainSoundConfiguration::SEVEN_POINT_ONE);
+ BOOST_CHECK_EQUAL (msc.mapping(0).get(), dcp::LEFT);
+ BOOST_CHECK (!msc.mapping(1));
+ BOOST_CHECK_EQUAL (msc.mapping(2).get(), dcp::CENTRE);
+ BOOST_CHECK_EQUAL (msc.mapping(3).get(), dcp::LFE);
+ BOOST_CHECK_EQUAL (msc.mapping(4).get(), dcp::LS);
+ BOOST_CHECK_EQUAL (msc.mapping(5).get(), dcp::RS);
+ for (int i = 6; i < 15; ++i) {
+ BOOST_CHECK (!msc.mapping(i));
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE (main_sound_configuration_test5)
+{
+ dcp::MainSoundConfiguration msc("71/L,-,C,LFE,Lss,Rss,HI,VIN,-,-,Lrs,Rrs,DBOX,Sync,Sign");
+ BOOST_CHECK_EQUAL (msc.to_string(), "71/L,-,C,LFE,Lss,Rss,HI,VIN,-,-,Lrs,Rrs,DBOX,Sync,Sign");
+ BOOST_CHECK_EQUAL (msc.channels(), 15);
+ BOOST_CHECK_EQUAL (msc.field(), dcp::MainSoundConfiguration::SEVEN_POINT_ONE);
+ BOOST_CHECK_EQUAL (msc.mapping(0).get(), dcp::LEFT);
+ BOOST_CHECK (!msc.mapping(1));
+ BOOST_CHECK_EQUAL (msc.mapping(2).get(), dcp::CENTRE);
+ BOOST_CHECK_EQUAL (msc.mapping(3).get(), dcp::LFE);
+ BOOST_CHECK_EQUAL (msc.mapping(4).get(), dcp::LS);
+ BOOST_CHECK_EQUAL (msc.mapping(5).get(), dcp::RS);
+ BOOST_CHECK_EQUAL (msc.mapping(6).get(), dcp::HI);
+ BOOST_CHECK_EQUAL (msc.mapping(7).get(), dcp::VI);
+ BOOST_CHECK (!msc.mapping(8));
+ BOOST_CHECK (!msc.mapping(9));
+ BOOST_CHECK_EQUAL (msc.mapping(10).get(), dcp::BSL);
+ BOOST_CHECK_EQUAL (msc.mapping(11).get(), dcp::BSR);
+ BOOST_CHECK_EQUAL (msc.mapping(12).get(), dcp::MOTION_DATA);
+ BOOST_CHECK_EQUAL (msc.mapping(13).get(), dcp::SYNC_SIGNAL);
+ BOOST_CHECK_EQUAL (msc.mapping(14).get(), dcp::SIGN_LANGUAGE);
+}
+
+
+BOOST_AUTO_TEST_CASE (luminance_test1)
+{
+ BOOST_CHECK_NO_THROW (dcp::Luminance(4, dcp::Luminance::CANDELA_PER_SQUARE_METRE));
+ BOOST_CHECK_THROW (dcp::Luminance(-4, dcp::Luminance::CANDELA_PER_SQUARE_METRE), dcp::MiscError);
+}
+
+
+BOOST_AUTO_TEST_CASE (luminance_test2)
+{
+ shared_ptr<cxml::Document> doc (new cxml::Document("Luminance"));
+
+ doc->read_string (
+ "<Luminance units=\"candela-per-square-metre\">4.5</Luminance>"
+ );
+
+ dcp::Luminance lum (doc);
+ BOOST_CHECK (lum.unit() == dcp::Luminance::CANDELA_PER_SQUARE_METRE);
+ BOOST_CHECK_CLOSE (lum.value(), 4.5, 0.1);
+}
+
+
+BOOST_AUTO_TEST_CASE (luminance_test3)
+{
+ shared_ptr<cxml::Document> doc (new cxml::Document("Luminance"));
+
+ doc->read_string (
+ "<Luminance units=\"candela-per-square-motre\">4.5</Luminance>"
+ );
+
+ BOOST_CHECK_THROW (new dcp::Luminance(doc), dcp::XMLError);
+}
+
+
+BOOST_AUTO_TEST_CASE (luminance_test4)
+{
+ shared_ptr<cxml::Document> doc (new cxml::Document("Luminance"));
+
+ doc->read_string (
+ "<Luminance units=\"candela-per-square-metre\">-4.5</Luminance>"
+ );
+
+ /* We tolerate out-of-range values when reading from XML */
+ dcp::Luminance lum (doc);
+ BOOST_CHECK (lum.unit() == dcp::Luminance::CANDELA_PER_SQUARE_METRE);
+ BOOST_CHECK_CLOSE (lum.value(), -4.5, 0.1);
+}
+
+
+/** A test where most CPL metadata is present */
+BOOST_AUTO_TEST_CASE (cpl_metadata_read_test1)
+{
+ dcp::CPL cpl("test/ref/cpl_metadata_test1.xml");
+
+ BOOST_CHECK_EQUAL (cpl.full_content_title_text().get(), "full-content-title");
+ BOOST_CHECK (cpl.full_content_title_text_language().get() == "de");
+ BOOST_CHECK (cpl.release_territory().get() == "ES");
+ BOOST_CHECK_EQUAL (cpl.version_number().get(), 2);
+ BOOST_CHECK_EQUAL (cpl.status().get(), dcp::FINAL);
+ BOOST_CHECK_EQUAL (cpl.chain().get(), "the-chain");
+ BOOST_CHECK_EQUAL (cpl.distributor().get(), "the-distributor");
+ BOOST_CHECK_EQUAL (cpl.facility().get(), "the-facility");
+ BOOST_CHECK (cpl.luminance() == dcp::Luminance(4.5, dcp::Luminance::FOOT_LAMBERT));
+
+ dcp::MainSoundConfiguration msc(cpl.main_sound_configuration().get());
+ BOOST_CHECK_EQUAL (msc.mapping(0).get(), dcp::LEFT);
+ BOOST_CHECK_EQUAL (msc.mapping(1).get(), dcp::RIGHT);
+ BOOST_CHECK_EQUAL (msc.mapping(2).get(), dcp::CENTRE);
+ BOOST_CHECK_EQUAL (msc.mapping(3).get(), dcp::LFE);
+ BOOST_CHECK (!msc.mapping(4));
+ BOOST_CHECK (!msc.mapping(5));
+ BOOST_CHECK (!msc.mapping(6));
+ BOOST_CHECK (!msc.mapping(7));
+ BOOST_CHECK (!msc.mapping(8));
+ BOOST_CHECK (!msc.mapping(9));
+ BOOST_CHECK (!msc.mapping(10));
+ BOOST_CHECK (!msc.mapping(11));
+ BOOST_CHECK (!msc.mapping(12));
+ BOOST_CHECK_EQUAL (msc.mapping(13).get(), dcp::SYNC_SIGNAL);
+
+ BOOST_CHECK_EQUAL (cpl.main_sound_sample_rate().get(), 48000);
+ BOOST_CHECK (cpl.main_picture_stored_area().get() == dcp::Size(1998, 1080));
+ BOOST_CHECK (cpl.main_picture_active_area().get() == dcp::Size(1440, 1080));
+
+ list<shared_ptr<dcp::Reel> > reels = cpl.reels ();
+ BOOST_REQUIRE_EQUAL (reels.size(), 1);
+ BOOST_CHECK_EQUAL (reels.front()->main_subtitle()->language().get(), dcp::LanguageTag("de-DE"));
+
+ vector<string> asl = cpl.additional_subtitle_languages();
+ BOOST_REQUIRE_EQUAL (asl.size(), 2);
+ BOOST_CHECK_EQUAL (asl[0], "en-US");
+ BOOST_CHECK_EQUAL (asl[1], "fr-ZA");
+
+ BOOST_CHECK (cpl.additional_subtitle_languages() == asl);
+}
+
+
+/** A test where most CPL metadata is present */
+BOOST_AUTO_TEST_CASE (cpl_metadata_write_test1)
+{
+ RNGFixer fix;
+
+ dcp::CPL cpl("", dcp::FEATURE);
+ cpl.set_issue_date ("2020-08-28T13:35:06+02:00");
+
+ vector<dcp::ContentVersion> cv;
+ cv.push_back (dcp::ContentVersion("some-id", "version 1"));
+ cv.push_back (dcp::ContentVersion("another-id", "version 2"));
+ cpl.set_content_versions (cv);
+
+ cpl.set_full_content_title_text ("full-content-title");
+ cpl.set_full_content_title_text_language (dcp::LanguageTag("de"));
+ cpl.set_release_territory (dcp::LanguageTag::RegionSubtag("ES"));
+ cpl.set_version_number (2);
+ cpl.set_status (dcp::FINAL);
+ cpl.set_chain ("the-chain");
+ cpl.set_distributor ("the-distributor");
+ cpl.set_facility ("the-facility");
+ cpl.set_luminance (dcp::Luminance(4.5, dcp::Luminance::FOOT_LAMBERT));
+
+ dcp::MainSoundConfiguration msc(dcp::MainSoundConfiguration::SEVEN_POINT_ONE, 16);
+ msc.set_mapping (0, dcp::LEFT);
+ msc.set_mapping (1, dcp::RIGHT);
+ msc.set_mapping (2, dcp::CENTRE);
+ msc.set_mapping (3, dcp::LFE);
+ msc.set_mapping (13, dcp::SYNC_SIGNAL);
+ cpl.set_main_sound_configuration (msc.to_string());
+
+ cpl.set_main_sound_sample_rate (48000);
+ cpl.set_main_picture_stored_area (dcp::Size(1998, 1080));
+ cpl.set_main_picture_active_area (dcp::Size(1440, 1080));
+
+ shared_ptr<cxml::Document> doc (new cxml::Document("MainSubtitle"));
+
+ doc->read_string (
+ "<MainSubtitle>"
+ "<Id>urn:uuid:8bca1489-aab1-9259-a4fd-8150abc1de12</Id>"
+ "<AnnotationText>Goodbye world!</AnnotationText>"
+ "<EditRate>25 1</EditRate>"
+ "<IntrinsicDuration>1870</IntrinsicDuration>"
+ "<EntryPoint>0</EntryPoint>"
+ "<Duration>525</Duration>"
+ "<KeyId>urn:uuid:540cbf10-ab14-0233-ab1f-fb31501cabfa</KeyId>"
+ "<Hash>3EABjX9BB1CAWhLUtHhrGSyLgOY=</Hash>"
+ "<Language>de-DE</Language>"
+ "</MainSubtitle>"
+ );
+
+ shared_ptr<dcp::Reel> reel(new dcp::Reel());
+ reel->add (black_picture_asset("build/test/cpl_metadata_write_test1"));
+ reel->add (shared_ptr<dcp::ReelSubtitleAsset>(new dcp::ReelSubtitleAsset(doc)));
+ cpl.add (reel);
+
+ vector<dcp::LanguageTag> lt;
+ lt.push_back(dcp::LanguageTag("en-US"));
+ lt.push_back(dcp::LanguageTag("fr-ZA"));
+ cpl.set_additional_subtitle_languages (lt);
+
+ cpl.write_xml ("build/test/cpl_metadata_write_test1.xml", dcp::SMPTE, shared_ptr<dcp::CertificateChain>());
+ check_xml (
+ dcp::file_to_string("test/ref/cpl_metadata_test1.xml"),
+ dcp::file_to_string("build/test/cpl_metadata_write_test1.xml"),
+ list<string>()
+ );
+}
+
+
+/** A test where most CPL metadata is present */
+BOOST_AUTO_TEST_CASE (cpl_metadata_roundtrip_test_1)
+{
+ dcp::CPL cpl ("test/ref/cpl_metadata_test1.xml");
+ cpl.write_xml ("build/test/cpl_metadata_roundtrip_test1.xml", dcp::SMPTE, shared_ptr<dcp::CertificateChain>());
+ list<string> ignore;
+ ignore.push_back ("Id");
+ check_xml (
+ dcp::file_to_string("test/ref/cpl_metadata_test1.xml"),
+ dcp::file_to_string("build/test/cpl_metadata_roundtrip_test1.xml"),
+ ignore
+ );
+}
+
+
+/** A test where only a bare minimum of CPL metadata is present */
+BOOST_AUTO_TEST_CASE (cpl_metadata_write_test2)
+{
+ RNGFixer fix;
+
+ dcp::CPL cpl("", dcp::FEATURE);
+ cpl.set_issue_date ("2020-08-28T13:35:06+02:00");
+ cpl.set_content_version (dcp::ContentVersion("id", "version"));
+
+ dcp::MainSoundConfiguration msc(dcp::MainSoundConfiguration::SEVEN_POINT_ONE, 16);
+ msc.set_mapping (0, dcp::LEFT);
+ msc.set_mapping (1, dcp::RIGHT);
+ msc.set_mapping (2, dcp::CENTRE);
+ msc.set_mapping (3, dcp::LFE);
+ msc.set_mapping (13, dcp::SYNC_SIGNAL);
+ cpl.set_main_sound_configuration (msc.to_string());
+
+ cpl.set_main_sound_sample_rate (48000);
+ cpl.set_main_picture_stored_area (dcp::Size(1998, 1080));
+ cpl.set_main_picture_active_area (dcp::Size(1440, 1080));
+
+ shared_ptr<dcp::Reel> reel(new dcp::Reel());
+ reel->add (black_picture_asset("build/test/cpl_metadata_write_test1"));
+ cpl.add (reel);
+
+ cpl.write_xml ("build/test/cpl_metadata_write_test2.xml", dcp::SMPTE, shared_ptr<dcp::CertificateChain>());
+ check_xml (
+ dcp::file_to_string("test/ref/cpl_metadata_test2.xml"),
+ dcp::file_to_string("build/test/cpl_metadata_write_test2.xml"),
+ list<string>()
+ );
+}
+
+
+/** A test where only a bare minimum of CPL metadata is present */
+BOOST_AUTO_TEST_CASE (cpl_metadata_read_test2)
+{
+ dcp::CPL cpl("test/ref/cpl_metadata_test2.xml");
+
+ BOOST_CHECK_EQUAL (cpl.full_content_title_text().get(), "");
+ BOOST_CHECK (!cpl.full_content_title_text_language());
+ BOOST_CHECK (!cpl.release_territory());
+ BOOST_CHECK (!cpl.version_number());
+ BOOST_CHECK (!cpl.status());
+ BOOST_CHECK (!cpl.chain());
+ BOOST_CHECK (!cpl.distributor());
+ BOOST_CHECK (!cpl.facility());
+ BOOST_CHECK (!cpl.luminance());
+
+ dcp::MainSoundConfiguration msc(cpl.main_sound_configuration().get());
+ BOOST_CHECK_EQUAL (msc.mapping(0).get(), dcp::LEFT);
+ BOOST_CHECK_EQUAL (msc.mapping(1).get(), dcp::RIGHT);
+ BOOST_CHECK_EQUAL (msc.mapping(2).get(), dcp::CENTRE);
+ BOOST_CHECK_EQUAL (msc.mapping(3).get(), dcp::LFE);
+ BOOST_CHECK (!msc.mapping(4));
+ BOOST_CHECK (!msc.mapping(5));
+ BOOST_CHECK (!msc.mapping(6));
+ BOOST_CHECK (!msc.mapping(7));
+ BOOST_CHECK (!msc.mapping(8));
+ BOOST_CHECK (!msc.mapping(9));
+ BOOST_CHECK (!msc.mapping(10));
+ BOOST_CHECK (!msc.mapping(11));
+ BOOST_CHECK (!msc.mapping(12));
+ BOOST_CHECK_EQUAL (msc.mapping(13).get(), dcp::SYNC_SIGNAL);
+
+ BOOST_CHECK_EQUAL (cpl.main_sound_sample_rate().get(), 48000);
+ BOOST_CHECK (cpl.main_picture_stored_area().get() == dcp::Size(1998, 1080));
+ BOOST_CHECK (cpl.main_picture_active_area().get() == dcp::Size(1440, 1080));
+
+ list<shared_ptr<dcp::Reel> > reels = cpl.reels ();
+ BOOST_REQUIRE_EQUAL (reels.size(), 1);
+}
+
+
+/** A test where only a bare minimum of CPL metadata is present */
+BOOST_AUTO_TEST_CASE (cpl_metadata_roundtrip_test_2)
+{
+ dcp::CPL cpl ("test/ref/cpl_metadata_test2.xml");
+ cpl.write_xml ("build/test/cpl_metadata_roundtrip_test2.xml", dcp::SMPTE, shared_ptr<dcp::CertificateChain>());
+ list<string> ignore;
+ ignore.push_back ("Id");
+ check_xml (
+ dcp::file_to_string("test/ref/cpl_metadata_test2.xml"),
+ dcp::file_to_string("build/test/cpl_metadata_roundtrip_test2.xml"),
+ ignore
+ );
+}
+
diff --git a/test/reel_asset_test.cc b/test/reel_asset_test.cc
index 6c701297..45736a7a 100644
--- a/test/reel_asset_test.cc
+++ b/test/reel_asset_test.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2015-2019 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2015-2020 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
@@ -32,11 +32,17 @@
*/
#include "reel_mono_picture_asset.h"
+#include "reel_subtitle_asset.h"
#include <libcxml/cxml.h>
#include <boost/test/unit_test.hpp>
+#include "test.h"
+
+using std::string;
+using boost::optional;
using boost::shared_ptr;
+
/** Test the XML constructor of ReelPictureAsset */
BOOST_AUTO_TEST_CASE (reel_picture_asset_test)
{
@@ -45,11 +51,11 @@ BOOST_AUTO_TEST_CASE (reel_picture_asset_test)
doc->read_string (
"<MainPicture>"
"<Id>urn:uuid:06ac1ca7-9c46-4107-8864-a6448e24b04b</Id>"
- "<AnnotationText></AnnotationText>"
+ "<AnnotationText>Hello world!</AnnotationText>"
"<EditRate>24 1</EditRate>"
"<IntrinsicDuration>187048</IntrinsicDuration>"
- "<EntryPoint>0</EntryPoint>"
- "<Duration>187048</Duration>"
+ "<EntryPoint>42</EntryPoint>"
+ "<Duration>9444</Duration>"
"<Hash>6EQX4NjG8vxIWhLUtHhrGSyLgOY=</Hash>"
"<FrameRate>24 1</FrameRate>"
"<ScreenAspectRatio>2048 858</ScreenAspectRatio>"
@@ -57,5 +63,45 @@ BOOST_AUTO_TEST_CASE (reel_picture_asset_test)
);
dcp::ReelMonoPictureAsset pa (doc);
- BOOST_CHECK_EQUAL (pa.screen_aspect_ratio(), dcp::Fraction (2048, 858));
+ BOOST_CHECK_EQUAL (pa.id(), "06ac1ca7-9c46-4107-8864-a6448e24b04b");
+ BOOST_CHECK_EQUAL (pa.annotation_text(), "Hello world!");
+ BOOST_CHECK_EQUAL (pa.edit_rate(), dcp::Fraction(24, 1));
+ BOOST_CHECK_EQUAL (pa.intrinsic_duration(), 187048);
+ BOOST_CHECK_EQUAL (pa.entry_point().get(), 42L);
+ BOOST_CHECK_EQUAL (pa.duration().get(), 9444L);
+ BOOST_CHECK_EQUAL (pa.hash().get(), string("6EQX4NjG8vxIWhLUtHhrGSyLgOY="));
+ BOOST_CHECK_EQUAL (pa.frame_rate(), dcp::Fraction(24, 1));
+ BOOST_CHECK_EQUAL (pa.screen_aspect_ratio(), dcp::Fraction(2048, 858));
+}
+
+
+/** Test the XML constructor of ReelSubtitleAsset */
+BOOST_AUTO_TEST_CASE (reel_subtitle_asset_test)
+{
+ shared_ptr<cxml::Document> doc (new cxml::Document("MainSubtitle"));
+
+ doc->read_string (
+ "<MainSubtitle>"
+ "<Id>urn:uuid:8bca1489-aab1-9259-a4fd-8150abc1de12</Id>"
+ "<AnnotationText>Goodbye world!</AnnotationText>"
+ "<EditRate>25 1</EditRate>"
+ "<IntrinsicDuration>1870</IntrinsicDuration>"
+ "<EntryPoint>0</EntryPoint>"
+ "<Duration>525</Duration>"
+ "<KeyId>urn:uuid:540cbf10-ab14-0233-ab1f-fb31501cabfa</KeyId>"
+ "<Hash>3EABjX9BB1CAWhLUtHhrGSyLgOY=</Hash>"
+ "<Language>de-DE</Language>"
+ "</MainSubtitle>"
+ );
+
+ dcp::ReelSubtitleAsset ps (doc);
+ BOOST_CHECK_EQUAL (ps.id(), "8bca1489-aab1-9259-a4fd-8150abc1de12");
+ BOOST_CHECK_EQUAL (ps.annotation_text(), "Goodbye world!");
+ BOOST_CHECK_EQUAL (ps.edit_rate(), dcp::Fraction(25, 1));
+ BOOST_CHECK_EQUAL (ps.intrinsic_duration(), 1870);
+ BOOST_CHECK_EQUAL (ps.entry_point().get(), 0L);
+ BOOST_CHECK_EQUAL (ps.duration().get(), 525L);
+ BOOST_CHECK_EQUAL (ps.hash().get(), string("3EABjX9BB1CAWhLUtHhrGSyLgOY="));
+ BOOST_REQUIRE (ps.language());
+ BOOST_CHECK_EQUAL (ps.language()->to_string(), "de-DE");
}
diff --git a/test/ref/cpl_metadata_test1.xml b/test/ref/cpl_metadata_test1.xml
new file mode 100644
index 00000000..b734edbb
--- /dev/null
+++ b/test/ref/cpl_metadata_test1.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CompositionPlaylist xmlns="http://www.smpte-ra.org/schemas/429-7/2006/CPL">
+ <Id>urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b</Id>
+ <AnnotationText></AnnotationText>
+ <IssueDate>2020-08-28T13:35:06+02:00</IssueDate>
+ <Issuer>libdcp1.6.4devel</Issuer>
+ <Creator>libdcp1.6.4devel</Creator>
+ <ContentTitleText></ContentTitleText>
+ <ContentKind>feature</ContentKind>
+ <ContentVersion>
+ <Id>some-id</Id>
+ <LabelText>version 1</LabelText>
+ </ContentVersion>
+ <RatingList/>
+ <ReelList>
+ <Reel>
+ <Id>urn:uuid:8b92bcee-62fc-4a33-a51a-816e9611ce85</Id>
+ <AssetList>
+ <MainPicture>
+ <Id>urn:uuid:46c3eb45-15e5-47d6-8684-d8641e4dc516</Id>
+ <AnnotationText></AnnotationText>
+ <EditRate>24 1</EditRate>
+ <IntrinsicDuration>24</IntrinsicDuration>
+ <EntryPoint>0</EntryPoint>
+ <Duration>24</Duration>
+ <Hash>BM4qh04HOSGF5vop4mhJBE7C4M0=</Hash>
+ <FrameRate>24 1</FrameRate>
+ <ScreenAspectRatio>1998 1080</ScreenAspectRatio>
+ </MainPicture>
+ <MainSubtitle>
+ <Id>urn:uuid:8bca1489-aab1-9259-a4fd-8150abc1de12</Id>
+ <AnnotationText>Goodbye world!</AnnotationText>
+ <EditRate>25 1</EditRate>
+ <IntrinsicDuration>1870</IntrinsicDuration>
+ <EntryPoint>0</EntryPoint>
+ <Duration>525</Duration>
+ <KeyId>urn:uuid:540cbf10-ab14-0233-ab1f-fb31501cabfa</KeyId>
+ <Hash>3EABjX9BB1CAWhLUtHhrGSyLgOY=</Hash>
+ <Language>de-DE</Language>
+ </MainSubtitle>
+ <meta:CompositionMetadataAsset xmlns:meta="http://www.smpte-ra.org/schemas/429-16/2014/CPL-Metadata">
+ <Id>urn:uuid:77e1fb48-ce0c-4d29-bf88-8c3bfec8013a</Id>
+ <EditRate>24 1</EditRate>
+ <IntrinsicDuration>24</IntrinsicDuration>
+ <meta:FullContentTitleText language="de">full-content-title</meta:FullContentTitleText>
+ <meta:ReleaseTerritory>ES</meta:ReleaseTerritory>
+ <meta:VersionNumber status="final">2</meta:VersionNumber>
+ <meta:Chain>the-chain</meta:Chain>
+ <meta:Distributor>the-distributor</meta:Distributor>
+ <meta:Facility>the-facility</meta:Facility>
+ <meta:AlternateContentVersionList>
+ <ContentVersion>
+ <Id>another-id</Id>
+ <LabelText>version 2</LabelText>
+ </ContentVersion>
+ </meta:AlternateContentVersionList>
+ <meta:Luminance units="foot-lambert">4.5</meta:Luminance>
+ <meta:MainSoundConfiguration>71/L,R,C,LFE,-,-,-,-,-,-,-,-,-,Sync,-,-</meta:MainSoundConfiguration>
+ <meta:MainSoundSampleRate>48000 1</meta:MainSoundSampleRate>
+ <meta:MainPictureStoredArea>
+ <meta:Width>1998</meta:Width>
+ <meta:Height>1080</meta:Height>
+ </meta:MainPictureStoredArea>
+ <meta:MainPictureActiveArea>
+ <meta:Width>1440</meta:Width>
+ <meta:Height>1080</meta:Height>
+ </meta:MainPictureActiveArea>
+ <MainSubtitleLanguageList>de-DE en-US fr-ZA</MainSubtitleLanguageList>
+ </meta:CompositionMetadataAsset>
+ </AssetList>
+ </Reel>
+ </ReelList>
+</CompositionPlaylist>
diff --git a/test/ref/cpl_metadata_test2.xml b/test/ref/cpl_metadata_test2.xml
new file mode 100644
index 00000000..d61a7113
--- /dev/null
+++ b/test/ref/cpl_metadata_test2.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CompositionPlaylist xmlns="http://www.smpte-ra.org/schemas/429-7/2006/CPL">
+ <Id>urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b</Id>
+ <AnnotationText></AnnotationText>
+ <IssueDate>2020-08-28T13:35:06+02:00</IssueDate>
+ <Issuer>libdcp1.6.4devel</Issuer>
+ <Creator>libdcp1.6.4devel</Creator>
+ <ContentTitleText></ContentTitleText>
+ <ContentKind>feature</ContentKind>
+ <ContentVersion>
+ <Id>id</Id>
+ <LabelText>version</LabelText>
+ </ContentVersion>
+ <RatingList/>
+ <ReelList>
+ <Reel>
+ <Id>urn:uuid:8b92bcee-62fc-4a33-a51a-816e9611ce85</Id>
+ <AssetList>
+ <MainPicture>
+ <Id>urn:uuid:46c3eb45-15e5-47d6-8684-d8641e4dc516</Id>
+ <AnnotationText></AnnotationText>
+ <EditRate>24 1</EditRate>
+ <IntrinsicDuration>24</IntrinsicDuration>
+ <EntryPoint>0</EntryPoint>
+ <Duration>24</Duration>
+ <Hash>BM4qh04HOSGF5vop4mhJBE7C4M0=</Hash>
+ <FrameRate>24 1</FrameRate>
+ <ScreenAspectRatio>1998 1080</ScreenAspectRatio>
+ </MainPicture>
+ <meta:CompositionMetadataAsset xmlns:meta="http://www.smpte-ra.org/schemas/429-16/2014/CPL-Metadata">
+ <Id>urn:uuid:77e1fb48-ce0c-4d29-bf88-8c3bfec8013a</Id>
+ <EditRate>24 1</EditRate>
+ <IntrinsicDuration>24</IntrinsicDuration>
+ <meta:FullContentTitleText/>
+ <meta:MainSoundConfiguration>71/L,R,C,LFE,-,-,-,-,-,-,-,-,-,Sync,-,-</meta:MainSoundConfiguration>
+ <meta:MainSoundSampleRate>48000 1</meta:MainSoundSampleRate>
+ <meta:MainPictureStoredArea>
+ <meta:Width>1998</meta:Width>
+ <meta:Height>1080</meta:Height>
+ </meta:MainPictureStoredArea>
+ <meta:MainPictureActiveArea>
+ <meta:Width>1440</meta:Width>
+ <meta:Height>1080</meta:Height>
+ </meta:MainPictureActiveArea>
+ </meta:CompositionMetadataAsset>
+ </AssetList>
+ </Reel>
+ </ReelList>
+</CompositionPlaylist>
diff --git a/test/test.cc b/test/test.cc
index 60dabcd4..dd143264 100644
--- a/test/test.cc
+++ b/test/test.cc
@@ -48,6 +48,12 @@
#include "sound_asset.h"
#include "sound_asset_writer.h"
#include "smpte_subtitle_asset.h"
+#include "mono_picture_asset.h"
+#include "openjpeg_image.h"
+#include "j2k.h"
+#include "picture_asset_writer.h"
+#include "reel_mono_picture_asset.h"
+#include "reel_asset.h"
#include "test.h"
#include "util.h"
#include <asdcp/KM_util.h>
@@ -64,9 +70,11 @@ using std::list;
using boost::shared_ptr;
using boost::optional;
+
boost::filesystem::path private_test;
boost::filesystem::path xsd_test = "build/test/xsd with spaces";
+
struct TestConfig
{
TestConfig()
@@ -390,4 +398,35 @@ make_simple_with_smpte_ccaps (boost::filesystem::path path)
}
+shared_ptr<dcp::OpenJPEGImage>
+black_image ()
+{
+ shared_ptr<dcp::OpenJPEGImage> image(new dcp::OpenJPEGImage(dcp::Size(1998, 1080)));
+ int const pixels = 1998 * 1080;
+ for (int i = 0; i < 3; ++i) {
+ memset (image->data(i), 0, pixels * sizeof(int));
+ }
+ return image;
+}
+
+
+shared_ptr<dcp::ReelAsset>
+black_picture_asset (boost::filesystem::path dir, int frames)
+{
+ shared_ptr<dcp::OpenJPEGImage> image = black_image ();
+ dcp::Data frame = dcp::compress_j2k (image, 100000000, 24, false, false);
+ BOOST_REQUIRE (frame.size() < 230000000 / (24 * 8));
+
+ shared_ptr<dcp::MonoPictureAsset> asset(new dcp::MonoPictureAsset(dcp::Fraction(24, 1), dcp::SMPTE));
+ boost::filesystem::create_directories (dir);
+ shared_ptr<dcp::PictureAssetWriter> writer = asset->start_write (dir / "pic.mxf", true);
+ for (int i = 0; i < frames; ++i) {
+ writer->write (frame.data().get(), frame.size());
+ }
+ writer->finalize ();
+
+ return shared_ptr<dcp::ReelAsset>(new dcp::ReelMonoPictureAsset(asset, 0));
+}
+
+
BOOST_GLOBAL_FIXTURE (TestConfig);
diff --git a/test/test.h b/test/test.h
index 6fc2067d..95827af7 100644
--- a/test/test.h
+++ b/test/test.h
@@ -24,7 +24,9 @@
#include "reel.h"
#include "reel_subtitle_asset.h"
#include "subtitle.h"
+#include "reel_asset.h"
#include <boost/filesystem.hpp>
+#include <boost/optional.hpp>
namespace xmlpp {
class Element;
@@ -47,6 +49,8 @@ extern boost::shared_ptr<dcp::DCP> make_simple_with_interop_subs (boost::filesys
extern boost::shared_ptr<dcp::DCP> make_simple_with_smpte_subs (boost::filesystem::path path);
extern boost::shared_ptr<dcp::DCP> make_simple_with_interop_ccaps (boost::filesystem::path path);
extern boost::shared_ptr<dcp::DCP> make_simple_with_smpte_ccaps (boost::filesystem::path path);
+extern boost::shared_ptr<dcp::OpenJPEGImage> black_image ();
+extern boost::shared_ptr<dcp::ReelAsset> black_picture_asset (boost::filesystem::path dir, int frames = 24);
/** Creating an object of this class will make asdcplib's random number generation
* (more) predictable.
@@ -57,4 +61,3 @@ public:
RNGFixer ();
~RNGFixer ();
};
-
diff --git a/test/verify_test.cc b/test/verify_test.cc
index f1213c10..14d498b0 100644
--- a/test/verify_test.cc
+++ b/test/verify_test.cc
@@ -515,19 +515,6 @@ BOOST_AUTO_TEST_CASE (verify_test14)
static
-shared_ptr<dcp::OpenJPEGImage>
-black_image ()
-{
- shared_ptr<dcp::OpenJPEGImage> image(new dcp::OpenJPEGImage(dcp::Size(1998, 1080)));
- int const pixels = 1998 * 1080;
- for (int i = 0; i < 3; ++i) {
- memset (image->data(i), 0, pixels * sizeof(int));
- }
- return image;
-}
-
-
-static
void
dcp_from_frame (dcp::Data const& frame, boost::filesystem::path dir)
{
diff --git a/test/wscript b/test/wscript
index 9958a677..5fd2f430 100644
--- a/test/wscript
+++ b/test/wscript
@@ -67,6 +67,7 @@ def build(bld):
colour_test.cc
colour_conversion_test.cc
combine_test.cc
+ cpl_metadata_test.cc
cpl_sar_test.cc
cpl_ratings_test.cc
dcp_font_test.cc