/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
using std::pair;
using std::vector;
using std::list;
+using std::map;
using boost::shared_ptr;
using boost::scoped_ptr;
using boost::optional;
BOOST_FOREACH (cxml::ConstNodePtr i, node->node_children("ReelLength")) {
_reel_lengths.push_back (raw_convert<int64_t> (i->content ()));
}
+
+ BOOST_FOREACH (cxml::ConstNodePtr i, node->node_children("Marker")) {
+ _markers[dcp::marker_from_string(i->string_attribute("type"))] = ContentTime(raw_convert<int64_t>(i->content()));
+ }
}
void
_content_kind = examiner->content_kind ();
_cpl = examiner->cpl ();
_reel_lengths = examiner->reel_lengths ();
+ map<dcp::Marker, dcp::Time> markers = examiner->markers();
+ for (map<dcp::Marker, dcp::Time>::const_iterator i = markers.begin(); i != markers.end(); ++i) {
+ _markers[i->first] = ContentTime(i->second.as_editable_units(DCPTime::HZ));
+ }
}
if (old_texts == texts) {
BOOST_FOREACH (int64_t i, _reel_lengths) {
node->add_child("ReelLength")->add_child_text (raw_convert<string> (i));
}
+
+ for (map<dcp::Marker, ContentTime>::const_iterator i = _markers.begin(); i != _markers.end(); ++i) {
+ xmlpp::Element* marker = node->add_child("Marker");
+ marker->set_attribute("type", dcp::marker_to_string(i->first));
+ marker->add_child_text(raw_convert<string>(i->second.get()));
+ }
}
DCPTime
/*
- Copyright (C) 2014-2019 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
#include <dcp/subtitle_asset.h>
#include <dcp/reel_subtitle_asset.h>
#include <dcp/reel_closed_caption_asset.h>
+#include <dcp/reel_markers_asset.h>
#include <dcp/sound_asset.h>
#include <boost/foreach.hpp>
#include <iostream>
using std::list;
using std::cout;
using std::runtime_error;
+using std::map;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
_text_count[TEXT_CLOSED_CAPTION]++;
}
+ if (i->main_markers ()) {
+ map<dcp::Marker, dcp::Time> rm = i->main_markers()->get();
+ _markers.insert (rm.begin(), rm.end());
+ }
+
if (i->main_picture()) {
_reel_lengths.push_back (i->main_picture()->actual_duration());
} else if (i->main_sound()) {
/*
- Copyright (C) 2014-2019 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
#include "video_examiner.h"
#include "audio_examiner.h"
#include "dcp.h"
+#include <dcp/dcp_time.h>
class DCPContent;
return _reel_lengths;
}
+ std::map<dcp::Marker, dcp::Time> markers () const {
+ return _markers;
+ }
+
private:
boost::optional<double> _video_frame_rate;
boost::optional<dcp::Size> _video_size;
dcp::ContentKind _content_kind;
std::string _cpl;
std::list<int64_t> _reel_lengths;
+ std::map<dcp::Marker, dcp::Time> _markers;
};
/*
- Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
#include "lib/job_manager.h"
#include "lib/config.h"
#include "lib/cross.h"
+#include "lib/video_content.h"
+#include "lib/content_factory.h"
#include <dcp/cpl.h>
#include <boost/test/unit_test.hpp>
using std::vector;
using std::string;
+using std::map;
using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
/** Make an encrypted DCP, import it and make a new unencrypted DCP */
BOOST_AUTO_TEST_CASE (import_dcp_test)
/* Should be 1s red, 1s green, 1s blue */
check_dcp ("test/data/import_dcp_test2", "build/test/import_dcp_test2/" + B->dcp_name());
}
+
+
+/** Check that DCP markers are imported correctly */
+BOOST_AUTO_TEST_CASE (import_dcp_markers_test)
+{
+ /* Make a DCP with some markers */
+ shared_ptr<Film> film = new_test_film2 ("import_dcp_markers_test");
+ shared_ptr<Content> content = content_factory("test/data/flat_red.png").front();
+ film->examine_and_add_content (content);
+ BOOST_REQUIRE (!wait_for_jobs());
+
+ content->video->set_length (24 * 60 * 10);
+
+ film->set_marker(dcp::FFOC, dcpomatic::DCPTime::from_seconds(1.91));
+ film->set_marker(dcp::FFMC, dcpomatic::DCPTime::from_seconds(9.4));
+ film->set_marker(dcp::LFMC, dcpomatic::DCPTime::from_seconds(9.99));
+
+ film->make_dcp ();
+ BOOST_REQUIRE (!wait_for_jobs());
+
+ /* Import the DCP to a new film and check the markers */
+ shared_ptr<Film> film2 = new_test_film2 ("import_dcp_markers_test2");
+ shared_ptr<DCPContent> imported (new DCPContent(film->dir(film->dcp_name())));
+ film2->examine_and_add_content (imported);
+ BOOST_REQUIRE (!wait_for_jobs());
+ film2->write_metadata ();
+
+ BOOST_CHECK_EQUAL (imported->markers().size(), 3);
+
+ map<dcp::Marker, dcpomatic::ContentTime> markers = imported->markers();
+ BOOST_REQUIRE(markers.find(dcp::FFOC) != markers.end());
+ BOOST_CHECK(markers[dcp::FFOC] == dcpomatic::ContentTime(184000));
+ BOOST_REQUIRE(markers.find(dcp::FFMC) != markers.end());
+ BOOST_CHECK(markers[dcp::FFMC] == dcpomatic::ContentTime(904000));
+ BOOST_REQUIRE(markers.find(dcp::LFMC) != markers.end());
+ BOOST_CHECK(markers[dcp::LFMC] == dcpomatic::ContentTime(960000));
+
+ /* Load that film and check that the markers have been loaded */
+ shared_ptr<Film> film3(new Film(boost::filesystem::path("build/test/import_dcp_markers_test2")));
+ film3->read_metadata ();
+ BOOST_REQUIRE (film3->content().size() == 1);
+ shared_ptr<DCPContent> reloaded = dynamic_pointer_cast<DCPContent>(film3->content().front());
+ BOOST_REQUIRE (reloaded);
+
+ BOOST_CHECK_EQUAL (reloaded->markers().size(), 3);
+
+ markers = reloaded->markers();
+ BOOST_REQUIRE(markers.find(dcp::FFOC) != markers.end());
+ BOOST_CHECK(markers[dcp::FFOC] == dcpomatic::ContentTime(184000));
+ BOOST_REQUIRE(markers.find(dcp::FFMC) != markers.end());
+ BOOST_CHECK(markers[dcp::FFMC] == dcpomatic::ContentTime(904000));
+ BOOST_REQUIRE(markers.find(dcp::LFMC) != markers.end());
+ BOOST_CHECK(markers[dcp::LFMC] == dcpomatic::ContentTime(960000));
+}