summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-04-21 23:57:25 +0200
committerCarl Hetherington <cth@carlh.net>2020-04-21 23:57:25 +0200
commitf644c272a6a6384f6bfc6ca16ada6208057402a8 (patch)
tree6b3341998b91b6c5dcd904b0bf37f60d8051453f
parentfa5f3a8bf77209da27acc33cf144e2e4500a2600 (diff)
parent4873cbc567d2c97c6587ab624e4c53abcd23cf23 (diff)
Add option to set project properties from a DCP loaded as content (#1688).
-rw-r--r--src/lib/copy_dcp_details_to_film.cc73
-rw-r--r--src/lib/copy_dcp_details_to_film.h26
-rw-r--r--src/lib/dcp_content.cc53
-rw-r--r--src/lib/dcp_content.h23
-rw-r--r--src/lib/dcp_content_type.cc24
-rw-r--r--src/lib/dcp_content_type.h1
-rw-r--r--src/lib/dcp_examiner.cc12
-rw-r--r--src/lib/dcp_examiner.h18
-rw-r--r--src/lib/film.cc9
-rw-r--r--src/lib/film.h1
-rw-r--r--src/lib/util.h11
-rw-r--r--src/lib/wscript1
-rw-r--r--src/wx/content_menu.cc23
-rw-r--r--src/wx/content_menu.h2
-rw-r--r--test/import_dcp_test.cc104
15 files changed, 365 insertions, 16 deletions
diff --git a/src/lib/copy_dcp_details_to_film.cc b/src/lib/copy_dcp_details_to_film.cc
new file mode 100644
index 000000000..a009735fb
--- /dev/null
+++ b/src/lib/copy_dcp_details_to_film.cc
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "copy_dcp_details_to_film.h"
+#include "dcp_content.h"
+#include "film.h"
+#include "types.h"
+#include "video_content.h"
+#include "audio_content.h"
+#include "ratio.h"
+#include "dcp_content_type.h"
+#include <boost/shared_ptr.hpp>
+#include <map>
+
+using std::map;
+using std::string;
+using boost::shared_ptr;
+
+void
+copy_dcp_details_to_film (shared_ptr<const DCPContent> dcp, shared_ptr<Film> film)
+{
+ string name = dcp->name ();
+ name = name.substr (0, name.find("_"));
+ film->set_name (name);
+ film->set_use_isdcf_name (true);
+ if (dcp->content_kind()) {
+ film->set_dcp_content_type (DCPContentType::from_libdcp_kind(dcp->content_kind().get()));
+ }
+ film->set_encrypted (dcp->encrypted());
+ film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
+ film->set_interop (dcp->standard() == dcp::INTEROP);
+ film->set_three_d (dcp->three_d());
+
+ if (dcp->video) {
+ film->set_container (Ratio::nearest_from_ratio(dcp->video->size().ratio()));
+ film->set_resolution (dcp->resolution());
+ DCPOMATIC_ASSERT (dcp->video_frame_rate());
+ film->set_video_frame_rate (*dcp->video_frame_rate());
+ }
+
+ if (dcp->audio) {
+ film->set_audio_channels (dcp->audio->stream()->channels());
+ }
+
+ map<dcp::Marker, dcpomatic::ContentTime> dcp_markers;
+ map<dcp::Marker, dcpomatic::DCPTime> film_markers;
+ film->clear_markers ();
+ for (map<dcp::Marker, dcpomatic::ContentTime>::const_iterator i = dcp_markers.begin(); i != dcp_markers.end(); ++i) {
+ film->set_marker (i->first, dcpomatic::DCPTime(i->second.get()));
+ }
+
+ film->set_ratings (dcp->ratings());
+ film->set_content_version (dcp->content_version());
+}
+
+
diff --git a/src/lib/copy_dcp_details_to_film.h b/src/lib/copy_dcp_details_to_film.h
new file mode 100644
index 000000000..38eb7fcc9
--- /dev/null
+++ b/src/lib/copy_dcp_details_to_film.h
@@ -0,0 +1,26 @@
+/*
+ Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <boost/shared_ptr.hpp>
+
+class DCPContent;
+class Film;
+
+extern void copy_dcp_details_to_film (boost::shared_ptr<const DCPContent> dcp, boost::shared_ptr<Film> film);
diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc
index 52ac6132c..4280ad13a 100644
--- a/src/lib/dcp_content.cc
+++ b/src/lib/dcp_content.cc
@@ -1,5 +1,5 @@
/*
- 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.
@@ -49,6 +49,7 @@ using std::distance;
using std::pair;
using std::vector;
using std::list;
+using std::map;
using boost::shared_ptr;
using boost::scoped_ptr;
using boost::optional;
@@ -146,6 +147,16 @@ DCPContent::DCPContent (cxml::ConstNodePtr node, int version)
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()));
+ }
+
+ BOOST_FOREACH (cxml::ConstNodePtr i, node->node_children("Rating")) {
+ _ratings.push_back (dcp::Rating(i));
+ }
+
+ _content_version = node->optional_string_child("ContentVersion").get_value_or("");
}
void
@@ -240,6 +251,12 @@ DCPContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
_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));
+ }
+ _ratings = examiner->ratings ();
+ _content_version = examiner->content_version ();
}
if (old_texts == texts) {
@@ -339,6 +356,19 @@ DCPContent::as_xml (xmlpp::Node* node, bool with_paths) const
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()));
+ }
+
+ BOOST_FOREACH (dcp::Rating i, _ratings) {
+ xmlpp::Element* rating = node->add_child("Rating");
+ i.as_xml (rating);
+ }
+
+ node->add_child("ContentVersion")->add_child_text (_content_version);
}
DCPTime
@@ -591,13 +621,8 @@ DCPContent::can_reference_video (shared_ptr<const Film> film, string& why_not) c
return false;
}
- Resolution video_res = RESOLUTION_2K;
- if (video->size().width > 2048 || video->size().height > 1080) {
- video_res = RESOLUTION_4K;
- }
-
- if (film->resolution() != video_res) {
- if (video_res == RESOLUTION_4K) {
+ if (film->resolution() != resolution()) {
+ if (resolution() == RESOLUTION_4K) {
/// TRANSLATORS: this string will follow "Cannot reference this DCP: "
why_not = _("it is 4K and the film is 2K.");
} else {
@@ -723,3 +748,15 @@ DCPContent::kdm_timing_window_valid () const
dcp::LocalTime now;
return _kdm->not_valid_before() < now && now < _kdm->not_valid_after();
}
+
+
+Resolution
+DCPContent::resolution () const
+{
+ if (video->size().width > 2048 || video->size().height > 1080) {
+ return RESOLUTION_4K;
+ }
+
+ return RESOLUTION_2K;
+}
+
diff --git a/src/lib/dcp_content.h b/src/lib/dcp_content.h
index 65bed29bc..6d707670f 100644
--- a/src/lib/dcp_content.h
+++ b/src/lib/dcp_content.h
@@ -144,8 +144,28 @@ public:
return _content_kind;
}
+ dcp::Standard standard () const {
+ boost::mutex::scoped_lock lm (_mutex);
+ DCPOMATIC_ASSERT (_standard);
+ return _standard.get ();
+ }
+
+ std::map<dcp::Marker, dcpomatic::ContentTime> markers () const {
+ return _markers;
+ }
+
bool kdm_timing_window_valid () const;
+ Resolution resolution () const;
+
+ std::vector<dcp::Rating> ratings () const {
+ return _ratings;
+ }
+
+ std::string content_version () const {
+ return _content_version;
+ }
+
private:
friend class reels_test5;
@@ -192,6 +212,9 @@ private:
boost::optional<std::string> _cpl;
/** List of the lengths of the reels in this DCP */
std::list<int64_t> _reel_lengths;
+ std::map<dcp::Marker, dcpomatic::ContentTime> _markers;
+ std::vector<dcp::Rating> _ratings;
+ std::string _content_version;
};
#endif
diff --git a/src/lib/dcp_content_type.cc b/src/lib/dcp_content_type.cc
index 613ed15a5..4fedd366c 100644
--- a/src/lib/dcp_content_type.cc
+++ b/src/lib/dcp_content_type.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2020 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -24,7 +24,7 @@
#include "dcp_content_type.h"
#include "dcpomatic_assert.h"
-#include <cassert>
+#include <boost/foreach.hpp>
#include "i18n.h"
@@ -60,9 +60,9 @@ DCPContentType::setup_dcp_content_types ()
DCPContentType const *
DCPContentType::from_isdcf_name (string n)
{
- for (vector<DCPContentType const *>::const_iterator i = _dcp_content_types.begin(); i != _dcp_content_types.end(); ++i) {
- if ((*i)->isdcf_name() == n) {
- return *i;
+ BOOST_FOREACH (DCPContentType const * i, _dcp_content_types) {
+ if (i->isdcf_name() == n) {
+ return i;
}
}
@@ -70,6 +70,20 @@ DCPContentType::from_isdcf_name (string n)
}
DCPContentType const *
+DCPContentType::from_libdcp_kind (dcp::ContentKind kind)
+{
+ BOOST_FOREACH (DCPContentType const * i, _dcp_content_types) {
+ if (i->libdcp_kind() == kind) {
+ return i;
+ }
+ }
+
+ DCPOMATIC_ASSERT (false);
+ return 0;
+}
+
+
+DCPContentType const *
DCPContentType::from_index (int n)
{
DCPOMATIC_ASSERT (n >= 0 && n < int (_dcp_content_types.size ()));
diff --git a/src/lib/dcp_content_type.h b/src/lib/dcp_content_type.h
index 2685e6edf..eea698217 100644
--- a/src/lib/dcp_content_type.h
+++ b/src/lib/dcp_content_type.h
@@ -51,6 +51,7 @@ public:
}
static DCPContentType const * from_isdcf_name (std::string);
+ static DCPContentType const * from_libdcp_kind (dcp::ContentKind);
static DCPContentType const * from_index (int);
static int as_index (DCPContentType const *);
static std::vector<DCPContentType const *> all ();
diff --git a/src/lib/dcp_examiner.cc b/src/lib/dcp_examiner.cc
index 9bf401125..d04dacdd6 100644
--- a/src/lib/dcp_examiner.cc
+++ b/src/lib/dcp_examiner.cc
@@ -1,5 +1,5 @@
/*
- 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.
@@ -23,6 +23,7 @@
#include "exceptions.h"
#include "image.h"
#include "config.h"
+#include "util.h"
#include <dcp/dcp.h>
#include <dcp/decrypted_kdm.h>
#include <dcp/cpl.h>
@@ -40,6 +41,7 @@
#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>
@@ -49,6 +51,7 @@
using std::list;
using std::cout;
using std::runtime_error;
+using std::map;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
@@ -183,6 +186,11 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant)
_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()) {
@@ -229,6 +237,8 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant)
_standard = cpl->standard().get();
_three_d = !cpl->reels().empty() && cpl->reels().front()->main_picture() &&
dynamic_pointer_cast<dcp::StereoPictureAsset> (cpl->reels().front()->main_picture()->asset());
+ _ratings = list_to_vector (cpl->ratings());
+ _content_version = cpl->content_version_label_text ();
_cpl = cpl->id ();
}
diff --git a/src/lib/dcp_examiner.h b/src/lib/dcp_examiner.h
index e52234e36..21aa8d3ab 100644
--- a/src/lib/dcp_examiner.h
+++ b/src/lib/dcp_examiner.h
@@ -1,5 +1,5 @@
/*
- 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.
@@ -25,6 +25,7 @@
#include "video_examiner.h"
#include "audio_examiner.h"
#include "dcp.h"
+#include <dcp/dcp_time.h>
class DCPContent;
@@ -118,6 +119,18 @@ public:
return _reel_lengths;
}
+ std::map<dcp::Marker, dcp::Time> markers () const {
+ return _markers;
+ }
+
+ std::vector<dcp::Rating> ratings () const {
+ return _ratings;
+ }
+
+ std::string content_version () const {
+ return _content_version;
+ }
+
private:
boost::optional<double> _video_frame_rate;
boost::optional<dcp::Size> _video_size;
@@ -140,4 +153,7 @@ private:
dcp::ContentKind _content_kind;
std::string _cpl;
std::list<int64_t> _reel_lengths;
+ std::map<dcp::Marker, dcp::Time> _markers;
+ std::vector<dcp::Rating> _ratings;
+ std::string _content_version;
};
diff --git a/src/lib/film.cc b/src/lib/film.cc
index ed2c5a372..a89d58a1f 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -1778,6 +1778,15 @@ Film::unset_marker (dcp::Marker type)
_markers.erase (type);
}
+
+void
+Film::clear_markers ()
+{
+ ChangeSignaller<Film> ch (this, MARKERS);
+ _markers.clear ();
+}
+
+
void
Film::set_ratings (vector<dcp::Rating> r)
{
diff --git a/src/lib/film.h b/src/lib/film.h
index c4cd8bef1..86e9be6d9 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -381,6 +381,7 @@ public:
void set_reencode_j2k (bool);
void set_marker (dcp::Marker type, dcpomatic::DCPTime time);
void unset_marker (dcp::Marker type);
+ void clear_markers ();
void set_ratings (std::vector<dcp::Rating> r);
void set_content_version (std::string v);
diff --git a/src/lib/util.h b/src/lib/util.h
index 12c79ea5a..f8e9409f1 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -128,6 +128,17 @@ vector_to_list (std::vector<T> v)
return l;
}
+template <class T>
+std::vector<T>
+list_to_vector (std::list<T> v)
+{
+ std::vector<T> l;
+ BOOST_FOREACH (T& i, v) {
+ l.push_back (i);
+ }
+ return l;
+}
+
extern double db_to_linear (double db);
extern double linear_to_db (double linear);
diff --git a/src/lib/wscript b/src/lib/wscript
index 67bcf8d8b..17f96d61e 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -52,6 +52,7 @@ sources = """
config.cc
content.cc
content_factory.cc
+ copy_dcp_details_to_film.cc
create_cli.cc
cross_common.cc
crypto.cc
diff --git a/src/wx/content_menu.cc b/src/wx/content_menu.cc
index 7cb924a73..d28253c6a 100644
--- a/src/wx/content_menu.cc
+++ b/src/wx/content_menu.cc
@@ -36,6 +36,7 @@
#include "lib/ffmpeg_content.h"
#include "lib/audio_content.h"
#include "lib/config.h"
+#include "lib/copy_dcp_details_to_film.h"
#include <dcp/cpl.h>
#include <dcp/exceptions.h>
#include <wx/wx.h>
@@ -61,6 +62,7 @@ enum {
ID_kdm,
ID_ov,
ID_choose_cpl,
+ ID_set_dcp_settings,
ID_remove
};
@@ -79,6 +81,7 @@ ContentMenu::ContentMenu (wxWindow* p)
_ov = _menu->Append (ID_ov, _("Add OV..."));
_cpl_menu = new wxMenu ();
_choose_cpl = _menu->Append (ID_choose_cpl, _("Choose CPL..."), _cpl_menu);
+ _set_dcp_settings = _menu->Append (ID_set_dcp_settings, _("Set project DCP settings from this DCP"));
_menu->AppendSeparator ();
_remove = _menu->Append (ID_remove, _("Remove"));
@@ -89,6 +92,7 @@ ContentMenu::ContentMenu (wxWindow* p)
_parent->Bind (wxEVT_MENU, boost::bind (&ContentMenu::re_examine, this), ID_re_examine);
_parent->Bind (wxEVT_MENU, boost::bind (&ContentMenu::kdm, this), ID_kdm);
_parent->Bind (wxEVT_MENU, boost::bind (&ContentMenu::ov, this), ID_ov);
+ _parent->Bind (wxEVT_MENU, boost::bind (&ContentMenu::set_dcp_settings, this), ID_set_dcp_settings);
_parent->Bind (wxEVT_MENU, boost::bind (&ContentMenu::remove, this), ID_remove);
_parent->Bind (wxEVT_MENU, boost::bind (&ContentMenu::cpl_selected, this, _1), 1, ID_repeat - 1);
}
@@ -125,6 +129,7 @@ ContentMenu::popup (weak_ptr<Film> film, ContentList c, TimelineContentViewList
if (dcp) {
_kdm->Enable (dcp->encrypted ());
_ov->Enable (dcp->needs_assets ());
+ _set_dcp_settings->Enable (static_cast<bool>(dcp));
try {
DCPExaminer ex (dcp, true);
list<shared_ptr<dcp::CPL> > cpls = ex.cpls ();
@@ -153,9 +158,11 @@ ContentMenu::popup (weak_ptr<Film> film, ContentList c, TimelineContentViewList
_kdm->Enable (false);
_ov->Enable (false);
_choose_cpl->Enable (false);
+ _set_dcp_settings->Enable (false);
}
} else {
_kdm->Enable (false);
+ _set_dcp_settings->Enable (false);
}
_remove->Enable (!_content.empty ());
@@ -165,6 +172,22 @@ ContentMenu::popup (weak_ptr<Film> film, ContentList c, TimelineContentViewList
_pop_up_open = false;
}
+
+void
+ContentMenu::set_dcp_settings ()
+{
+ shared_ptr<Film> film = _film.lock ();
+ if (!film) {
+ return;
+ }
+
+ DCPOMATIC_ASSERT (_content.size() == 1);
+ shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(_content.front());
+ DCPOMATIC_ASSERT (dcp);
+ copy_dcp_details_to_film (dcp, film);
+}
+
+
void
ContentMenu::repeat ()
{
diff --git a/src/wx/content_menu.h b/src/wx/content_menu.h
index a38109b07..fe8cbb56f 100644
--- a/src/wx/content_menu.h
+++ b/src/wx/content_menu.h
@@ -46,6 +46,7 @@ private:
void re_examine ();
void kdm ();
void ov ();
+ void set_dcp_settings ();
void remove ();
void maybe_found_missing (boost::weak_ptr<Job>, boost::weak_ptr<Content>, boost::weak_ptr<Content>);
void cpl_selected (wxCommandEvent& ev);
@@ -66,6 +67,7 @@ private:
wxMenuItem* _kdm;
wxMenuItem* _ov;
wxMenuItem* _choose_cpl;
+ wxMenuItem* _set_dcp_settings;
wxMenuItem* _remove;
};
diff --git a/test/import_dcp_test.cc b/test/import_dcp_test.cc
index 16ebfa454..83dd0c6de 100644
--- a/test/import_dcp_test.cc
+++ b/test/import_dcp_test.cc
@@ -1,5 +1,5 @@
/*
- 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.
@@ -35,12 +35,16 @@
#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)
@@ -94,3 +98,101 @@ 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));
+}
+
+
+/** Check that DCP metadata (ratings and content version) are imported correctly */
+BOOST_AUTO_TEST_CASE (import_dcp_metadata_test)
+{
+ /* Make a DCP with some ratings and a content version */
+ shared_ptr<Film> film = new_test_film2 ("import_dcp_metadata_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 (10);
+
+ std::vector<dcp::Rating> ratings;
+ ratings.push_back (dcp::Rating("BBFC", "15"));
+ ratings.push_back (dcp::Rating("MPAA", "NC-17"));
+ film->set_ratings (ratings);
+
+ film->set_content_version ("Fred");
+
+ film->make_dcp ();
+ BOOST_REQUIRE (!wait_for_jobs());
+
+ /* Import the DCP to a new film and check the metadata */
+ shared_ptr<Film> film2 = new_test_film2 ("import_dcp_metadata_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 (imported->ratings() == ratings);
+ BOOST_CHECK_EQUAL (imported->content_version(), "Fred");
+
+ /* Load that film and check that the metadata has been loaded */
+ shared_ptr<Film> film3(new Film(boost::filesystem::path("build/test/import_dcp_metadata_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 (reloaded->ratings() == ratings);
+ BOOST_CHECK_EQUAL (reloaded->content_version(), "Fred");
+}
+