diff options
| author | Carl Hetherington <cth@carlh.net> | 2019-03-15 22:46:00 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2019-03-17 00:24:07 +0000 |
| commit | 7cc85a6cda9787796b3d191251c0653b6df67ceb (patch) | |
| tree | 1375c6e148d903ad4af834d5db0c8b3dbc703047 | |
| parent | 3537583f15ebca59eb9e5abb85452b54183210ba (diff) | |
Finish initial CPL markers support.markers
| -rw-r--r-- | src/reel.cc | 20 | ||||
| -rw-r--r-- | src/reel.h | 10 | ||||
| -rw-r--r-- | src/reel_asset.cc | 19 | ||||
| -rw-r--r-- | src/reel_asset.h | 7 | ||||
| -rw-r--r-- | src/reel_atmos_asset.cc | 2 | ||||
| -rw-r--r-- | src/reel_closed_caption_asset.cc | 2 | ||||
| -rw-r--r-- | src/reel_markers_asset.cc | 140 | ||||
| -rw-r--r-- | src/reel_markers_asset.h | 61 | ||||
| -rw-r--r-- | src/reel_picture_asset.cc | 2 | ||||
| -rw-r--r-- | src/reel_sound_asset.cc | 2 | ||||
| -rw-r--r-- | src/reel_subtitle_asset.cc | 2 | ||||
| -rw-r--r-- | src/wscript | 1 | ||||
| -rw-r--r-- | test/dcp_test.cc | 1 | ||||
| -rw-r--r-- | test/markers_test.cc | 106 | ||||
| -rw-r--r-- | test/wscript | 3 |
15 files changed, 357 insertions, 21 deletions
diff --git a/src/reel.cc b/src/reel.cc index 4b42ec0e..bda83531 100644 --- a/src/reel.cc +++ b/src/reel.cc @@ -42,6 +42,7 @@ #include "reel_stereo_picture_asset.h" #include "reel_sound_asset.h" #include "reel_subtitle_asset.h" +#include "reel_markers_asset.h" #include "decrypted_kdm_key.h" #include "decrypted_kdm.h" #include "interop_subtitle_asset.h" @@ -84,6 +85,11 @@ Reel::Reel (boost::shared_ptr<const cxml::Node> node) _main_subtitle.reset (new ReelSubtitleAsset (main_subtitle)); } + shared_ptr<cxml::Node> main_markers = asset_list->optional_node_child ("MainMarkers"); + if (main_markers) { + _main_markers.reset (new ReelMarkersAsset (main_markers)); + } + /* XXX: it's not ideal that we silently tolerate Interop or SMPTE nodes here */ /* XXX: not sure if Interop supports multiple closed captions */ list<shared_ptr<cxml::Node> > closed_captions = asset_list->node_children ("MainClosedCaption"); @@ -110,6 +116,10 @@ Reel::write_to_cpl (xmlpp::Element* node, Standard standard) const reel->add_child("Id")->add_child_text ("urn:uuid:" + make_uuid()); xmlpp::Element* asset_list = reel->add_child ("AssetList"); + if (_main_markers) { + _main_markers->write_to_cpl (asset_list, standard); + } + if (_main_picture && dynamic_pointer_cast<ReelMonoPictureAsset> (_main_picture)) { /* Mono pictures come before other stuff... */ _main_picture->write_to_cpl (asset_list, standard); @@ -167,6 +177,10 @@ Reel::equals (boost::shared_ptr<const Reel> other, EqualityOptions opt, NoteHand return false; } + if (_main_markers && !_main_markers->equals (other->_main_markers, opt, note)) { + return false; + } + if (_closed_captions.size() != other->_closed_captions.size()) { return false; } @@ -250,6 +264,7 @@ Reel::add (shared_ptr<ReelAsset> asset) shared_ptr<ReelPictureAsset> p = dynamic_pointer_cast<ReelPictureAsset> (asset); shared_ptr<ReelSoundAsset> so = dynamic_pointer_cast<ReelSoundAsset> (asset); shared_ptr<ReelSubtitleAsset> su = dynamic_pointer_cast<ReelSubtitleAsset> (asset); + shared_ptr<ReelMarkersAsset> m = dynamic_pointer_cast<ReelMarkersAsset> (asset); shared_ptr<ReelClosedCaptionAsset> c = dynamic_pointer_cast<ReelClosedCaptionAsset> (asset); shared_ptr<ReelAtmosAsset> a = dynamic_pointer_cast<ReelAtmosAsset> (asset); if (p) { @@ -258,6 +273,8 @@ Reel::add (shared_ptr<ReelAsset> asset) _main_sound = so; } else if (su) { _main_subtitle = su; + } else if (m) { + _main_markers = m; } else if (c) { _closed_captions.push_back (c); } else if (a) { @@ -319,6 +336,9 @@ Reel::duration () const if (_main_subtitle) { d = max (d, _main_subtitle->duration ()); } + if (_main_markers) { + d = max (d, _main_markers->duration ()); + } BOOST_FOREACH (shared_ptr<ReelClosedCaptionAsset> i, _closed_captions) { d = max (d, i->duration()); } @@ -56,11 +56,12 @@ class ReelAsset; class ReelPictureAsset; class ReelSoundAsset; class ReelSubtitleAsset; +class ReelMarkersAsset; class ReelClosedCaptionAsset; class ReelAtmosAsset; class Content; -/** @brief A reel within a DCP; the part which actually refers to picture, sound and subtitle data */ +/** @brief A reel within a DCP; the part which actually refers to picture, sound, subtitle, marker and Atmos data */ class Reel : public Object { public: @@ -70,11 +71,13 @@ public: boost::shared_ptr<ReelPictureAsset> picture, boost::shared_ptr<ReelSoundAsset> sound = boost::shared_ptr<ReelSoundAsset> (), boost::shared_ptr<ReelSubtitleAsset> subtitle = boost::shared_ptr<ReelSubtitleAsset> (), + boost::shared_ptr<ReelMarkersAsset> markers = boost::shared_ptr<ReelMarkersAsset> (), boost::shared_ptr<ReelAtmosAsset> atmos = boost::shared_ptr<ReelAtmosAsset> () ) : _main_picture (picture) , _main_sound (sound) , _main_subtitle (subtitle) + , _main_markers (markers) , _atmos (atmos) {} @@ -92,6 +95,10 @@ public: return _main_subtitle; } + boost::shared_ptr<ReelMarkersAsset> main_markers () const { + return _main_markers; + } + std::list<boost::shared_ptr<ReelClosedCaptionAsset> > closed_captions () const { return _closed_captions; } @@ -118,6 +125,7 @@ private: boost::shared_ptr<ReelPictureAsset> _main_picture; boost::shared_ptr<ReelSoundAsset> _main_sound; boost::shared_ptr<ReelSubtitleAsset> _main_subtitle; + boost::shared_ptr<ReelMarkersAsset> _main_markers; std::list<boost::shared_ptr<ReelClosedCaptionAsset> > _closed_captions; boost::shared_ptr<ReelAtmosAsset> _atmos; }; diff --git a/src/reel_asset.cc b/src/reel_asset.cc index 22583223..caaf3eee 100644 --- a/src/reel_asset.cc +++ b/src/reel_asset.cc @@ -50,31 +50,28 @@ using boost::optional; using namespace dcp; /** Construct a ReelAsset. - * @param asset Asset that this ReelAsset refers to. + * @param id ID of this ReelAsset (which is that of the MXF, if there is one) * @param edit_rate Edit rate for the asset. * @param intrinsic_duration Intrinsic duration of this asset. * @param entry_point Entry point to use in that asset. */ -ReelAsset::ReelAsset (shared_ptr<Asset> asset, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point) - : Object (asset->id ()) - , _edit_rate (edit_rate) +ReelAsset::ReelAsset (string id, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point) + : Object (id) , _intrinsic_duration (intrinsic_duration) - , _entry_point (entry_point) , _duration (intrinsic_duration - entry_point) + , _edit_rate (edit_rate) + , _entry_point (entry_point) { - /* default _annotation_text to the leaf name of our file */ - if (asset->file ()) { - _annotation_text = asset->file()->leaf().string (); - } + } ReelAsset::ReelAsset (shared_ptr<const cxml::Node> node) : Object (remove_urn_uuid (node->string_child ("Id"))) + , _intrinsic_duration (node->number_child<int64_t> ("IntrinsicDuration")) + , _duration (node->number_child<int64_t> ("Duration")) , _annotation_text (node->optional_string_child ("AnnotationText").get_value_or ("")) , _edit_rate (Fraction (node->string_child ("EditRate"))) - , _intrinsic_duration (node->number_child<int64_t> ("IntrinsicDuration")) , _entry_point (node->number_child<int64_t> ("EntryPoint")) - , _duration (node->number_child<int64_t> ("Duration")) { } diff --git a/src/reel_asset.h b/src/reel_asset.h index 9f024239..4092a97a 100644 --- a/src/reel_asset.h +++ b/src/reel_asset.h @@ -65,7 +65,7 @@ class Asset; class ReelAsset : public Object { public: - ReelAsset (boost::shared_ptr<Asset> asset, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point); + ReelAsset (std::string id, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point); explicit ReelAsset (boost::shared_ptr<const cxml::Node>); virtual xmlpp::Node* write_to_cpl (xmlpp::Node* node, Standard standard) const = 0; @@ -119,12 +119,13 @@ protected: xmlpp::Node* write_to_cpl_base (xmlpp::Node* node, Standard standard, boost::optional<std::string> hash) const; + int64_t _intrinsic_duration; ///< The <IntrinsicDuration> from the reel's entry for this asset + int64_t _duration; ///< The <Duration> from the reel's entry for this asset + private: std::string _annotation_text; ///< The <AnnotationText> from the reel's entry for this asset Fraction _edit_rate; ///< The <EditRate> from the reel's entry for this asset - int64_t _intrinsic_duration; ///< The <IntrinsicDuration> from the reel's entry for this asset int64_t _entry_point; ///< The <EntryPoint> from the reel's entry for this asset - int64_t _duration; ///< The <Duration> from the reel's entry for this asset }; } diff --git a/src/reel_atmos_asset.cc b/src/reel_atmos_asset.cc index f5dbc9fa..1ce8b6ea 100644 --- a/src/reel_atmos_asset.cc +++ b/src/reel_atmos_asset.cc @@ -47,7 +47,7 @@ using boost::shared_ptr; using namespace dcp; ReelAtmosAsset::ReelAtmosAsset (boost::shared_ptr<AtmosAsset> asset, int64_t entry_point) - : ReelAsset (asset, asset->edit_rate(), asset->intrinsic_duration(), entry_point) + : ReelAsset (asset->id(), asset->edit_rate(), asset->intrinsic_duration(), entry_point) , ReelMXF (asset, asset->key_id()) { diff --git a/src/reel_closed_caption_asset.cc b/src/reel_closed_caption_asset.cc index f71c39f6..435c3438 100644 --- a/src/reel_closed_caption_asset.cc +++ b/src/reel_closed_caption_asset.cc @@ -50,7 +50,7 @@ using boost::optional; using namespace dcp; ReelClosedCaptionAsset::ReelClosedCaptionAsset (boost::shared_ptr<SubtitleAsset> asset, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point) - : ReelAsset (asset, edit_rate, intrinsic_duration, entry_point) + : ReelAsset (asset->id(), edit_rate, intrinsic_duration, entry_point) , ReelMXF (asset, dynamic_pointer_cast<SMPTESubtitleAsset>(asset) ? dynamic_pointer_cast<SMPTESubtitleAsset>(asset)->key_id() : optional<string>()) { diff --git a/src/reel_markers_asset.cc b/src/reel_markers_asset.cc new file mode 100644 index 00000000..8c5f66dd --- /dev/null +++ b/src/reel_markers_asset.cc @@ -0,0 +1,140 @@ +/* + Copyright (C) 2019 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 "reel_markers_asset.h" +#include "raw_convert.h" +#include "dcp_assert.h" +#include <libxml++/libxml++.h> +#include <boost/foreach.hpp> + +using std::string; +using std::map; +using std::max; +using boost::optional; +using boost::shared_ptr; +using namespace dcp; + +ReelMarkersAsset::ReelMarkersAsset (Fraction edit_rate, int64_t entry_point) + : ReelAsset (make_uuid(), edit_rate, 0, entry_point) +{ + +} + +ReelMarkersAsset::ReelMarkersAsset (cxml::ConstNodePtr node) + : ReelAsset (node) +{ + cxml::ConstNodePtr list = node->node_child ("MarkerList"); + DCP_ASSERT (list); + BOOST_FOREACH (cxml::ConstNodePtr i, list->node_children("Marker")) { + set (marker_from_string(i->string_child("Label")), dcp::Time(i->number_child<int64_t>("Offset"), edit_rate().as_float(), edit_rate().numerator)); + } +} + +string +ReelMarkersAsset::cpl_node_name (Standard) const +{ + return "MainMarkers"; +} + +void +ReelMarkersAsset::set (Marker m, Time t) +{ + _markers[m] = t; + update_duration (); +} + +void +ReelMarkersAsset::unset (Marker m) +{ + _markers.erase (m); + update_duration (); +} + +optional<Time> +ReelMarkersAsset::get (Marker m) const +{ + map<Marker, Time>::const_iterator i = _markers.find (m); + if (i == _markers.end ()) { + return optional<Time>(); + } + return i->second; +} + +void +ReelMarkersAsset::update_duration () +{ + int const tcr = edit_rate().numerator / edit_rate().denominator; + _intrinsic_duration = 0; + for (map<Marker, Time>::const_iterator i = _markers.begin(); i != _markers.end(); ++i) { + _intrinsic_duration = max(_intrinsic_duration, i->second.as_editable_units(tcr)); + } + _duration = _intrinsic_duration; +} + +xmlpp::Node* +ReelMarkersAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const +{ + int const tcr = edit_rate().numerator / edit_rate().denominator; + xmlpp::Node* asset = write_to_cpl_base (node, standard, optional<string>()); + xmlpp::Node* ml = asset->add_child("MarkerList"); + for (map<Marker, Time>::const_iterator i = _markers.begin(); i != _markers.end(); ++i) { + xmlpp::Node* m = ml->add_child("Marker"); + m->add_child("Label")->add_child_text (marker_to_string(i->first)); + m->add_child("Offset")->add_child_text (raw_convert<string>(i->second.as_editable_units(tcr))); + } + + return asset; +} + +bool +ReelMarkersAsset::equals (shared_ptr<const ReelMarkersAsset> other, EqualityOptions opt, NoteHandler note) const +{ + if (!asset_equals(other, opt, note)) { + return false; + } + + if (get(FFOC) != other->get(FFOC) || + get(LFOC) != other->get(LFOC) || + get(FFTC) != other->get(FFTC) || + get(LFTC) != other->get(LFTC) || + get(FFOI) != other->get(FFOI) || + get(LFOI) != other->get(LFOI) || + get(FFEC) != other->get(FFEC) || + get(LFEC) != other->get(LFEC) || + get(FFMC) != other->get(FFMC) || + get(LFMC) != other->get(LFMC)) { + return false; + } + + return true; +} diff --git a/src/reel_markers_asset.h b/src/reel_markers_asset.h new file mode 100644 index 00000000..4077fbbe --- /dev/null +++ b/src/reel_markers_asset.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2019 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 "reel_asset.h" +#include "dcp_time.h" + +namespace dcp { + +class ReelMarkersAsset : public ReelAsset +{ +public: + ReelMarkersAsset (Fraction edit_rate, int64_t entry_point); + explicit ReelMarkersAsset (boost::shared_ptr<const cxml::Node>); + + xmlpp::Node* write_to_cpl (xmlpp::Node* node, Standard standard) const; + bool equals (boost::shared_ptr<const ReelMarkersAsset>, EqualityOptions, NoteHandler) const; + + void set (Marker, Time); + void unset (Marker); + boost::optional<Time> get (Marker m) const; + +protected: + std::string cpl_node_name (Standard) const; + +private: + void update_duration (); + + std::map<Marker, Time> _markers; +}; + +} diff --git a/src/reel_picture_asset.cc b/src/reel_picture_asset.cc index d2ba358f..5b4ced67 100644 --- a/src/reel_picture_asset.cc +++ b/src/reel_picture_asset.cc @@ -53,7 +53,7 @@ using boost::optional; using namespace dcp; ReelPictureAsset::ReelPictureAsset (shared_ptr<PictureAsset> asset, int64_t entry_point) - : ReelAsset (asset, asset->edit_rate(), asset->intrinsic_duration(), entry_point) + : ReelAsset (asset->id(), asset->edit_rate(), asset->intrinsic_duration(), entry_point) , ReelMXF (asset, asset->key_id()) , _frame_rate (asset->frame_rate ()) , _screen_aspect_ratio (asset->screen_aspect_ratio ()) diff --git a/src/reel_sound_asset.cc b/src/reel_sound_asset.cc index ab763cb3..25259f42 100644 --- a/src/reel_sound_asset.cc +++ b/src/reel_sound_asset.cc @@ -45,7 +45,7 @@ using boost::shared_ptr; using namespace dcp; ReelSoundAsset::ReelSoundAsset (shared_ptr<SoundAsset> asset, int64_t entry_point) - : ReelAsset (asset, asset->edit_rate(), asset->intrinsic_duration(), entry_point) + : ReelAsset (asset->id(), asset->edit_rate(), asset->intrinsic_duration(), entry_point) , ReelMXF (asset, asset->key_id()) { diff --git a/src/reel_subtitle_asset.cc b/src/reel_subtitle_asset.cc index 1bb8ccca..a90513d5 100644 --- a/src/reel_subtitle_asset.cc +++ b/src/reel_subtitle_asset.cc @@ -47,7 +47,7 @@ using boost::optional; using namespace dcp; ReelSubtitleAsset::ReelSubtitleAsset (boost::shared_ptr<SubtitleAsset> asset, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point) - : ReelAsset (asset, edit_rate, intrinsic_duration, entry_point) + : ReelAsset (asset->id(), edit_rate, intrinsic_duration, entry_point) , ReelMXF (asset, dynamic_pointer_cast<SMPTESubtitleAsset>(asset) ? dynamic_pointer_cast<SMPTESubtitleAsset>(asset)->key_id() : optional<string>()) { diff --git a/src/wscript b/src/wscript index ae881a8b..4b39a979 100644 --- a/src/wscript +++ b/src/wscript @@ -81,6 +81,7 @@ def build(bld): reel_mono_picture_asset.cc reel_mxf.cc reel_picture_asset.cc + reel_markers_asset.cc reel_sound_asset.cc reel_stereo_picture_asset.cc reel_subtitle_asset.cc diff --git a/test/dcp_test.cc b/test/dcp_test.cc index 2e1344c5..b6e14d25 100644 --- a/test/dcp_test.cc +++ b/test/dcp_test.cc @@ -281,6 +281,7 @@ BOOST_AUTO_TEST_CASE (dcp_test5) shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (mp, 0)), shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0)), shared_ptr<dcp::ReelSubtitleAsset> (), + shared_ptr<dcp::ReelMarkersAsset> (), shared_ptr<dcp::ReelAtmosAsset> (new dcp::ReelAtmosAsset (am, 0)) ) )); diff --git a/test/markers_test.cc b/test/markers_test.cc new file mode 100644 index 00000000..813736de --- /dev/null +++ b/test/markers_test.cc @@ -0,0 +1,106 @@ +/* + Copyright (C) 2019 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 "cpl.h" +#include "reel.h" +#include "reel_markers_asset.h" +#include <boost/shared_ptr.hpp> +#include <boost/test/unit_test.hpp> + +using std::string; +using boost::shared_ptr; + +BOOST_AUTO_TEST_CASE (markers_write_test) +{ + dcp::CPL cpl("Markers test", dcp::TEST); + + shared_ptr<dcp::ReelMarkersAsset> asset (new dcp::ReelMarkersAsset(dcp::Fraction(24, 1), 0)); + asset->set (dcp::FFOC, dcp::Time(1, 1, 9, 16, 24)); + asset->set (dcp::LFOC, dcp::Time(2, 5, 3, 0, 24)); + asset->set (dcp::FFTC, dcp::Time(0, 6, 4, 2, 24)); + asset->set (dcp::LFTC, dcp::Time(0, 6, 4, 18, 24)); + asset->set (dcp::FFOI, dcp::Time(3, 6, 4, 18, 24)); + asset->set (dcp::LFOI, dcp::Time(3, 2, 4, 18, 24)); + asset->set (dcp::FFEC, dcp::Time(3, 2, 7, 18, 24)); + asset->set (dcp::LFEC, dcp::Time(3, 2, 8, 18, 24)); + asset->set (dcp::FFMC, dcp::Time(4, 2, 8, 18, 24)); + asset->set (dcp::LFMC, dcp::Time(4, 3, 8, 18, 24)); + + shared_ptr<dcp::Reel> reel (new dcp::Reel()); + reel->add (asset); + + cpl.add (reel); + + cpl.write_xml ("build/test/markers_test.xml", dcp::SMPTE, shared_ptr<dcp::CertificateChain>()); +} + +static void +note_handler (dcp::NoteType, string) +{ + +} + +BOOST_AUTO_TEST_CASE (markers_read_test, * boost::unit_test::depends_on("markers_write_test")) +{ + dcp::CPL cpl ("build/test/markers_test.xml"); + BOOST_CHECK_EQUAL (cpl.reels().size(), 1); + shared_ptr<dcp::Reel> reel = cpl.reels().front(); + shared_ptr<dcp::ReelMarkersAsset> markers = reel->main_markers (); + BOOST_REQUIRE (markers); + + BOOST_REQUIRE (markers->get(dcp::FFOC)); + BOOST_CHECK (markers->get(dcp::FFOC) == dcp::Time(1, 1, 9, 16, 24)); + BOOST_REQUIRE (markers->get(dcp::LFOC)); + BOOST_CHECK (markers->get(dcp::LFOC) == dcp::Time(2, 5, 3, 0, 24)); + BOOST_REQUIRE (markers->get(dcp::FFTC)); + BOOST_CHECK (markers->get (dcp::FFTC) == dcp::Time(0, 6, 4, 2, 24)); + BOOST_REQUIRE (markers->get(dcp::LFTC)); + BOOST_CHECK (markers->get (dcp::LFTC) == dcp::Time(0, 6, 4, 18, 24)); + BOOST_REQUIRE (markers->get(dcp::FFOI)); + BOOST_CHECK (markers->get (dcp::FFOI) == dcp::Time(3, 6, 4, 18, 24)); + BOOST_REQUIRE (markers->get(dcp::LFOI)); + BOOST_CHECK (markers->get (dcp::LFOI) == dcp::Time(3, 2, 4, 18, 24)); + BOOST_REQUIRE (markers->get(dcp::FFEC)); + BOOST_CHECK (markers->get (dcp::FFEC) == dcp::Time(3, 2, 7, 18, 24)); + BOOST_REQUIRE (markers->get(dcp::LFEC)); + BOOST_CHECK (markers->get (dcp::LFEC) == dcp::Time(3, 2, 8, 18, 24)); + BOOST_REQUIRE (markers->get(dcp::FFMC)); + BOOST_CHECK (markers->get (dcp::FFMC) == dcp::Time(4, 2, 8, 18, 24)); + BOOST_REQUIRE (markers->get(dcp::LFMC)); + BOOST_CHECK (markers->get (dcp::LFMC) == dcp::Time(4, 3, 8, 18, 24)); + + BOOST_CHECK (markers->equals(markers, dcp::EqualityOptions(), boost::bind(¬e_handler, _1, _2))); + + shared_ptr<dcp::ReelMarkersAsset> markers2 (new dcp::ReelMarkersAsset(dcp::Fraction(24, 1), 0)); + BOOST_CHECK (!markers->equals(markers2, dcp::EqualityOptions(), boost::bind(¬e_handler, _1, _2))); +} diff --git a/test/wscript b/test/wscript index 5838df68..53d84617 100644 --- a/test/wscript +++ b/test/wscript @@ -1,5 +1,5 @@ # -# Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net> +# Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net> # # This file is part of libdcp. # @@ -80,6 +80,7 @@ def build(bld): interop_load_font_test.cc local_time_test.cc make_digest_test.cc + markers_test.cc kdm_test.cc raw_convert_test.cc read_dcp_test.cc |
