X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fdcp_content.cc;h=f39b2fb4a221c8070199d01aa3629972fc07a352;hb=f9068dcbfbb09082e29e2a779ef1a7a2f6ee849e;hp=0eef075d7c0b9eddcb58c7dfd544af212e90b21c;hpb=d2137ac5db409e686b4d9b3fa567935a5e416d41;p=dcpomatic.git diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc index 0eef075d7..f39b2fb4a 100644 --- a/src/lib/dcp_content.cc +++ b/src/lib/dcp_content.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington + Copyright (C) 2014-2015 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,38 +17,68 @@ */ -#include #include "dcp_content.h" #include "dcp_examiner.h" #include "job.h" #include "film.h" +#include "config.h" #include "compose.hpp" +#include "dcp_decoder.h" +#include +#include +#include +#include +#include +#include +#include +#include #include "i18n.h" using std::string; +using std::cout; +using std::distance; +using std::pair; +using std::list; using boost::shared_ptr; +using boost::optional; -DCPContent::DCPContent (shared_ptr f, boost::filesystem::path p) - : Content (f) - , VideoContent (f) - , SingleStreamAudioContent (f) - , SubtitleContent (f) +int const DCPContentProperty::CAN_BE_PLAYED = 600; +int const DCPContentProperty::REFERENCE_VIDEO = 601; +int const DCPContentProperty::REFERENCE_AUDIO = 602; +int const DCPContentProperty::REFERENCE_SUBTITLE = 603; + +DCPContent::DCPContent (shared_ptr film, boost::filesystem::path p) + : Content (film) + , VideoContent (film) + , SingleStreamAudioContent (film) + , SubtitleContent (film) , _has_subtitles (false) - , _directory (p) + , _encrypted (false) + , _kdm_valid (false) + , _reference_video (false) + , _reference_audio (false) + , _reference_subtitle (false) { read_directory (p); } -DCPContent::DCPContent (shared_ptr f, cxml::ConstNodePtr node, int version) - : Content (f, node) - , VideoContent (f, node, version) - , SingleStreamAudioContent (f, node, version) - , SubtitleContent (f, node, version) +DCPContent::DCPContent (shared_ptr film, cxml::ConstNodePtr node, int version) + : Content (film, node) + , VideoContent (film, node, version) + , SingleStreamAudioContent (film, node, version) + , SubtitleContent (film, node, version) { _name = node->string_child ("Name"); _has_subtitles = node->bool_child ("HasSubtitles"); - _directory = node->string_child ("Directory"); + _encrypted = node->bool_child ("Encrypted"); + if (node->optional_node_child ("KDM")) { + _kdm = dcp::EncryptedKDM (node->string_child ("KDM")); + } + _kdm_valid = node->bool_child ("KDMValid"); + _reference_video = node->optional_bool_child ("ReferenceVideo").get_value_or (false); + _reference_audio = node->optional_bool_child ("ReferenceAudio").get_value_or (false); + _reference_subtitle = node->optional_bool_child ("ReferenceSubtitle").get_value_or (false); } void @@ -66,16 +96,26 @@ DCPContent::read_directory (boost::filesystem::path p) void DCPContent::examine (shared_ptr job) { + bool const could_be_played = can_be_played (); + job->set_progress_unknown (); Content::examine (job); - + shared_ptr examiner (new DCPExaminer (shared_from_this ())); take_from_video_examiner (examiner); take_from_audio_examiner (examiner); - boost::mutex::scoped_lock lm (_mutex); - _name = examiner->name (); - _has_subtitles = examiner->has_subtitles (); + { + boost::mutex::scoped_lock lm (_mutex); + _name = examiner->name (); + _has_subtitles = examiner->has_subtitles (); + _encrypted = examiner->encrypted (); + _kdm_valid = examiner->kdm_valid (); + } + + if (could_be_played != can_be_played ()) { + signal_changed (DCPContentProperty::CAN_BE_PLAYED); + } } string @@ -106,26 +146,123 @@ DCPContent::as_xml (xmlpp::Node* node) const boost::mutex::scoped_lock lm (_mutex); node->add_child("Name")->add_child_text (_name); node->add_child("HasSubtitles")->add_child_text (_has_subtitles ? "1" : "0"); - node->add_child("Directory")->add_child_text (_directory.string ()); + node->add_child("Encrypted")->add_child_text (_encrypted ? "1" : "0"); + if (_kdm) { + node->add_child("KDM")->add_child_text (_kdm->as_xml ()); + } + node->add_child("KDMValid")->add_child_text (_kdm_valid ? "1" : "0"); + node->add_child("ReferenceVideo")->add_child_text (_reference_video ? "1" : "0"); + node->add_child("ReferenceAudio")->add_child_text (_reference_audio ? "1" : "0"); + node->add_child("ReferenceSubtitle")->add_child_text (_reference_subtitle ? "1" : "0"); } DCPTime DCPContent::full_length () const { shared_ptr film = _film.lock (); - assert (film); - return DCPTime (video_length (), FrameRateChange (video_frame_rate (), film->video_frame_rate ())); + DCPOMATIC_ASSERT (film); + FrameRateChange const frc (video_frame_rate (), film->video_frame_rate ()); + return DCPTime::from_frames (llrint (video_length () * frc.factor ()), film->video_frame_rate ()); } string DCPContent::identifier () const { - return SubtitleContent::identifier (); + SafeStringStream s; + s << VideoContent::identifier() << "_" << SubtitleContent::identifier () << " " + << (_reference_video ? "1" : "0") + << (_reference_subtitle ? "1" : "0"); + return s.str (); +} + +void +DCPContent::add_kdm (dcp::EncryptedKDM k) +{ + _kdm = k; } bool -DCPContent::has_subtitles () const +DCPContent::can_be_played () const { boost::mutex::scoped_lock lm (_mutex); - return _has_subtitles; + return !_encrypted || _kdm_valid; +} + +boost::filesystem::path +DCPContent::directory () const +{ + optional smallest; + boost::filesystem::path dir; + for (size_t i = 0; i < number_of_paths(); ++i) { + boost::filesystem::path const p = path (i).parent_path (); + size_t const d = distance (p.begin(), p.end()); + if (!smallest || d < smallest.get ()) { + dir = p; + } + } + + return dir; +} + +void +DCPContent::add_properties (list >& p) const +{ + SingleStreamAudioContent::add_properties (p); +} + +void +DCPContent::set_default_colour_conversion () +{ + /* Default to no colour conversion for DCPs */ + unset_colour_conversion (); +} + +void +DCPContent::set_reference_video (bool r) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _reference_video = r; + } + + signal_changed (DCPContentProperty::REFERENCE_VIDEO); +} + +void +DCPContent::set_reference_audio (bool r) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _reference_audio = r; + } + + signal_changed (DCPContentProperty::REFERENCE_AUDIO); +} + +void +DCPContent::set_reference_subtitle (bool r) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _reference_subtitle = r; + } + + signal_changed (DCPContentProperty::REFERENCE_SUBTITLE); +} + +list +DCPContent::reel_split_points () const +{ + list s; + DCPDecoder decoder (shared_from_this(), false); + DCPTime t = position(); + + shared_ptr film = _film.lock (); + DCPOMATIC_ASSERT (film); + BOOST_FOREACH (shared_ptr k, decoder.reels()) { + s.push_back (t); + t += DCPTime::from_frames (k->main_picture()->duration(), film->video_frame_rate()); + } + + return s; }