set_file (file);
}
-list<shared_ptr<ReelAsset> >
-CPL::reel_assets ()
+list<shared_ptr<ReelMXF> >
+CPL::reel_mxfs ()
{
- list<shared_ptr<ReelAsset> > c;
+ list<shared_ptr<ReelMXF> > c;
BOOST_FOREACH (shared_ptr<Reel> i, _reels) {
if (i->main_picture ()) {
return c;
}
-list<shared_ptr<const ReelAsset> >
-CPL::reel_assets () const
+list<shared_ptr<const ReelMXF> >
+CPL::reel_mxfs () const
{
- list<shared_ptr<const ReelAsset> > c;
+ list<shared_ptr<const ReelMXF> > c;
BOOST_FOREACH (shared_ptr<Reel> i, _reels) {
if (i->main_picture ()) {
/*
- Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2019 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
namespace dcp {
-class ReelAsset;
+class ReelMXF;
class Reel;
class XMLMetadata;
class MXFMetadata;
return _reels;
}
- /** @return the ReelAssets in this CPL in all reels.
+ /** @return the ReelMXFs in this CPL in all reels.
*/
- std::list<boost::shared_ptr<const ReelAsset> > reel_assets () const;
- std::list<boost::shared_ptr<ReelAsset> > reel_assets ();
+ std::list<boost::shared_ptr<const ReelMXF> > reel_mxfs () const;
+ std::list<boost::shared_ptr<ReelMXF> > reel_mxfs ();
bool encrypted () const;
list<shared_ptr<Asset> > assets;
BOOST_FOREACH (shared_ptr<CPL> i, cpls ()) {
assets.push_back (i);
- BOOST_FOREACH (shared_ptr<const ReelAsset> j, i->reel_assets ()) {
+ BOOST_FOREACH (shared_ptr<const ReelMXF> j, i->reel_mxfs()) {
if (ignore_unresolved && !j->asset_ref().resolved()) {
continue;
}
{
/* Create DecryptedKDMKey objects for each encryptable asset */
bool did_one = false;
- BOOST_FOREACH(shared_ptr<const ReelAsset> i, cpl->reel_assets ()) {
- shared_ptr<const ReelMXF> mxf = boost::dynamic_pointer_cast<const ReelMXF> (i);
- if (mxf && mxf->key_id ()) {
- add_key (mxf->key_type(), mxf->key_id().get(), key, cpl->id(), SMPTE);
+ BOOST_FOREACH(shared_ptr<const ReelMXF> i, cpl->reel_mxfs()) {
+ if (i->key_id()) {
+ add_key (i->key_type(), i->key_id().get(), key, cpl->id(), SMPTE);
did_one = true;
}
}
using std::string;
using std::make_pair;
using boost::shared_ptr;
+using boost::optional;
using namespace dcp;
/** Construct a ReelAsset.
*/
ReelAsset::ReelAsset (shared_ptr<Asset> asset, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point)
: Object (asset->id ())
- , _asset_ref (asset)
, _edit_rate (edit_rate)
, _intrinsic_duration (intrinsic_duration)
, _entry_point (entry_point)
, _duration (intrinsic_duration - entry_point)
- , _hash (asset->hash ())
{
/* default _annotation_text to the leaf name of our file */
if (asset->file ()) {
ReelAsset::ReelAsset (shared_ptr<const cxml::Node> node)
: Object (remove_urn_uuid (node->string_child ("Id")))
- , _asset_ref (_id)
, _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"))
- , _hash (node->optional_string_child ("Hash"))
{
}
xmlpp::Node*
-ReelAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
+ReelAsset::write_to_cpl_base (xmlpp::Node* node, Standard standard, optional<string> hash) const
{
xmlpp::Element* a = node->add_child (cpl_node_name (standard));
pair<string, string> const attr = cpl_node_attribute (standard);
a->add_child("IntrinsicDuration")->add_child_text (raw_convert<string> (_intrinsic_duration));
a->add_child("EntryPoint")->add_child_text (raw_convert<string> (_entry_point));
a->add_child("Duration")->add_child_text (raw_convert<string> (_duration));
- if (_hash) {
- a->add_child("Hash")->add_child_text (_hash.get());
+ if (hash) {
+ a->add_child("Hash")->add_child_text (hash.get());
}
return a;
}
}
bool
-ReelAsset::equals (shared_ptr<const ReelAsset> other, EqualityOptions opt, NoteHandler note) const
+ReelAsset::asset_equals (shared_ptr<const ReelAsset> other, EqualityOptions opt, NoteHandler note) const
{
if (_annotation_text != other->_annotation_text) {
string const s = "Reel: annotation texts differ (" + _annotation_text + " vs " + other->_annotation_text + ")\n";
return false;
}
- if (_hash != other->_hash) {
- if (!opt.reel_hashes_can_differ) {
- note (DCP_ERROR, "Reel: hashes differ");
- return false;
- } else {
- note (DCP_NOTE, "Reel: hashes differ");
- }
- }
-
- if (_asset_ref.resolved () && other->_asset_ref.resolved ()) {
- return _asset_ref->equals (other->_asset_ref.asset(), opt, note);
- }
-
return true;
}
ReelAsset (boost::shared_ptr<Asset> asset, 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;
- virtual bool equals (boost::shared_ptr<const ReelAsset>, EqualityOptions, NoteHandler) const;
-
- /** @return a Ref to our actual asset */
- Ref const & asset_ref () const {
- return _asset_ref;
- }
-
- /** @return a Ref to our actual asset */
- Ref & asset_ref () {
- return _asset_ref;
- }
+ virtual xmlpp::Node* write_to_cpl (xmlpp::Node* node, Standard standard) const = 0;
Fraction edit_rate () const {
return _edit_rate;
return _duration;
}
- /** @return the asset's hash, if this ReelAsset has been created from one,
- * otherwise the hash written to the CPL for this asset (if present).
- */
- boost::optional<std::string> hash () const {
- return _hash;
- }
-
std::string annotation_text () const {
return _annotation_text;
}
_annotation_text = at;
}
-protected:
-
- template <class T>
- boost::shared_ptr<T> asset_of_type () const {
- return boost::dynamic_pointer_cast<T> (_asset_ref.asset ());
- }
+ bool asset_equals (boost::shared_ptr<const ReelAsset>, EqualityOptions, NoteHandler) const;
- template <class T>
- boost::shared_ptr<T> asset_of_type () {
- return boost::dynamic_pointer_cast<T> (_asset_ref.asset ());
- }
+protected:
/** @return the node name that this asset uses in the CPL's <Reel> node
* e.g. MainPicture, MainSound etc.
/** @return Any namespace that should be used on the asset's node in the CPL */
virtual std::pair<std::string, std::string> cpl_node_namespace (Standard) const;
- /** Reference to the asset (MXF or XML file) that this reel entry
- * applies to.
- */
- Ref _asset_ref;
+ xmlpp::Node* write_to_cpl_base (xmlpp::Node* node, Standard standard, boost::optional<std::string> hash) const;
private:
std::string _annotation_text; ///< The <AnnotationText> 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
- /** Either our asset's computed hash or the hash read in from the CPL, if it's present */
- boost::optional<std::string> _hash;
};
}
ReelAtmosAsset::ReelAtmosAsset (boost::shared_ptr<AtmosAsset> asset, int64_t entry_point)
: ReelAsset (asset, asset->edit_rate(), asset->intrinsic_duration(), entry_point)
+ , ReelMXF (asset, asset->key_id())
{
}
xmlpp::Node *
ReelAtmosAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
{
- xmlpp::Node* asset = ReelAsset::write_to_cpl (node, standard);
+ xmlpp::Node* asset = write_to_cpl_base (node, standard, hash());
asset->add_child("axd:DataType")->add_child_text("urn:smpte:ul:060e2b34.04010105.0e090604.00000000");
return asset;
}
+
+bool
+ReelAtmosAsset::equals (shared_ptr<const ReelAtmosAsset> other, EqualityOptions opt, NoteHandler note) const
+{
+ if (!asset_equals (other, opt, note)) {
+ return false;
+ }
+ if (!mxf_equals (other, opt, note)) {
+ return false;
+ }
+
+ return true;
+}
}
xmlpp::Node* write_to_cpl (xmlpp::Node* node, Standard standard) const;
+ bool equals (boost::shared_ptr<const ReelAtmosAsset>, EqualityOptions, NoteHandler) const;
private:
std::string key_type () const;
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)
- , ReelMXF (dynamic_pointer_cast<SMPTESubtitleAsset>(asset) ? dynamic_pointer_cast<SMPTESubtitleAsset>(asset)->key_id() : optional<string>())
+ , ReelMXF (asset, dynamic_pointer_cast<SMPTESubtitleAsset>(asset) ? dynamic_pointer_cast<SMPTESubtitleAsset>(asset)->key_id() : optional<string>())
{
}
xmlpp::Node *
ReelClosedCaptionAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
{
- xmlpp::Node* asset = ReelAsset::write_to_cpl (node, standard);
+ xmlpp::Node* asset = write_to_cpl_base (node, standard, hash());
if (key_id()) {
/* Find <Hash> */
return asset;
}
+
+bool
+ReelClosedCaptionAsset::equals (shared_ptr<const ReelClosedCaptionAsset> other, EqualityOptions opt, NoteHandler note) const
+{
+ if (!asset_equals (other, opt, note)) {
+ return false;
+ }
+ if (!mxf_equals (other, opt, note)) {
+ return false;
+ }
+
+ return true;
+}
explicit ReelClosedCaptionAsset (boost::shared_ptr<const cxml::Node>);
xmlpp::Node* write_to_cpl (xmlpp::Node* node, Standard standard) const;
+ bool equals (boost::shared_ptr<const ReelClosedCaptionAsset>, EqualityOptions, NoteHandler) const;
boost::shared_ptr<SubtitleAsset> asset () const {
return asset_of_type<SubtitleAsset> ();
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
using boost::optional;
using namespace dcp;
-ReelMXF::ReelMXF (optional<string> key_id)
- : _key_id (key_id)
+ReelMXF::ReelMXF (shared_ptr<Asset> asset, optional<string> key_id)
+ : _asset_ref (asset)
+ , _key_id (key_id)
+ , _hash (asset->hash())
{
}
ReelMXF::ReelMXF (shared_ptr<const cxml::Node> node)
- : _key_id (node->optional_string_child ("KeyId"))
+ : _asset_ref (remove_urn_uuid(node->string_child("Id")))
+ , _key_id (node->optional_string_child ("KeyId"))
+ , _hash (node->optional_string_child ("Hash"))
{
if (_key_id) {
_key_id = remove_urn_uuid (*_key_id);
}
}
+
+bool
+ReelMXF::mxf_equals (shared_ptr<const ReelMXF> other, EqualityOptions opt, NoteHandler note) const
+{
+ if (_hash != other->_hash) {
+ if (!opt.reel_hashes_can_differ) {
+ note (DCP_ERROR, "Reel: hashes differ");
+ return false;
+ } else {
+ note (DCP_NOTE, "Reel: hashes differ");
+ }
+ }
+
+ if (_asset_ref.resolved() && other->_asset_ref.resolved()) {
+ return _asset_ref->equals (other->_asset_ref.asset(), opt, note);
+ }
+
+ return true;
+}
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
* @brief ReelMXF
*/
-#ifndef LIBDCP_REEL_ENCRYPTABLE_ASSET_H
-#define LIBDCP_REEL_ENCRYPTABLE_ASSET_H
+#ifndef LIBDCP_REEL_MXF_H
+#define LIBDCP_REEL_MXF_H
+#include "ref.h"
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
class ReelMXF
{
public:
- ReelMXF () {}
- explicit ReelMXF (boost::optional<std::string> key_id);
+ explicit ReelMXF (boost::shared_ptr<Asset> asset, boost::optional<std::string> key_id);
explicit ReelMXF (boost::shared_ptr<const cxml::Node>);
virtual ~ReelMXF () {}
/** @return the 4-character key type for this MXF (MDIK, MDAK, etc.) */
virtual std::string key_type () const = 0;
+ /** @return a Ref to our actual asset */
+ Ref const & asset_ref () const {
+ return _asset_ref;
+ }
+
+ /** @return a Ref to our actual asset */
+ Ref & asset_ref () {
+ return _asset_ref;
+ }
+
+ /** @return the asset's hash, if this ReelMXF has been created from one,
+ * otherwise the hash written to the CPL for this asset (if present).
+ */
+ boost::optional<std::string> hash () const {
+ return _hash;
+ }
+
/** @return true if a KeyId is specified for this asset, implying
* that its content is encrypted.
*/
return _key_id;
}
+ bool mxf_equals (boost::shared_ptr<const ReelMXF> other, EqualityOptions opt, NoteHandler note) const;
+
+protected:
+
+ template <class T>
+ boost::shared_ptr<T> asset_of_type () const {
+ return boost::dynamic_pointer_cast<T> (_asset_ref.asset ());
+ }
+
+ template <class T>
+ boost::shared_ptr<T> asset_of_type () {
+ return boost::dynamic_pointer_cast<T> (_asset_ref.asset ());
+ }
+
+ /** Reference to the asset (MXF or XML file) that this reel entry
+ * applies to.
+ */
+ Ref _asset_ref;
+
private:
boost::optional<std::string> _key_id; ///< The <KeyId> from the reel's entry for this asset, if there is one
+ /** Either our asset's computed hash or the hash read in from the CPL, if it's present */
+ boost::optional<std::string> _hash;
};
}
ReelPictureAsset::ReelPictureAsset (shared_ptr<PictureAsset> asset, int64_t entry_point)
: ReelAsset (asset, asset->edit_rate(), asset->intrinsic_duration(), entry_point)
- , ReelMXF (asset->key_id())
+ , ReelMXF (asset, asset->key_id())
, _frame_rate (asset->frame_rate ())
, _screen_aspect_ratio (asset->screen_aspect_ratio ())
{
xmlpp::Node*
ReelPictureAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
{
- xmlpp::Node* asset = ReelAsset::write_to_cpl (node, standard);
+ xmlpp::Node* asset = write_to_cpl_base (node, standard, hash());
asset->add_child("FrameRate")->add_child_text(String::compose("%1 %2", _frame_rate.numerator, _frame_rate.denominator));
if (standard == INTEROP) {
}
bool
-ReelPictureAsset::equals (shared_ptr<const ReelAsset> other, EqualityOptions opt, NoteHandler note) const
+ReelPictureAsset::equals (shared_ptr<const ReelPictureAsset> other, EqualityOptions opt, NoteHandler note) const
{
- if (!ReelAsset::equals (other, opt, note)) {
+ if (!asset_equals (other, opt, note)) {
+ return false;
+ }
+ if (!mxf_equals (other, opt, note)) {
return false;
}
/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2019 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
explicit ReelPictureAsset (boost::shared_ptr<const cxml::Node>);
virtual xmlpp::Node* write_to_cpl (xmlpp::Node* node, Standard standard) const;
- virtual bool equals (boost::shared_ptr<const ReelAsset>, EqualityOptions, NoteHandler) const;
+ bool equals (boost::shared_ptr<const ReelPictureAsset>, EqualityOptions, NoteHandler) const;
/** @return the PictureAsset that this object refers to */
boost::shared_ptr<const PictureAsset> asset () const {
ReelSoundAsset::ReelSoundAsset (shared_ptr<SoundAsset> asset, int64_t entry_point)
: ReelAsset (asset, asset->edit_rate(), asset->intrinsic_duration(), entry_point)
- , ReelMXF (asset->key_id())
+ , ReelMXF (asset, asset->key_id())
{
}
xmlpp::Node *
ReelSoundAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
{
- xmlpp::Node* asset = ReelAsset::write_to_cpl (node, standard);
+ xmlpp::Node* asset = write_to_cpl_base (node, standard, hash());
if (key_id ()) {
/* Find <Hash> */
return asset;
}
+
+bool
+ReelSoundAsset::equals (shared_ptr<const ReelSoundAsset> other, EqualityOptions opt, NoteHandler note) const
+{
+ if (!asset_equals (other, opt, note)) {
+ return false;
+ }
+ if (!mxf_equals (other, opt, note)) {
+ return false;
+ }
+
+ return true;
+}
/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2019 Carl Hetherington <cth@carlh.net>
This file is part of libdcp.
explicit ReelSoundAsset (boost::shared_ptr<const cxml::Node>);
xmlpp::Node* write_to_cpl (xmlpp::Node* node, Standard standard) const;
+ bool equals (boost::shared_ptr<const ReelSoundAsset>, EqualityOptions, NoteHandler) const;
/** @return the SoundAsset that this object refers to */
boost::shared_ptr<SoundAsset> asset () {
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)
- , ReelMXF (dynamic_pointer_cast<SMPTESubtitleAsset>(asset) ? dynamic_pointer_cast<SMPTESubtitleAsset>(asset)->key_id() : optional<string>())
+ , ReelMXF (asset, dynamic_pointer_cast<SMPTESubtitleAsset>(asset) ? dynamic_pointer_cast<SMPTESubtitleAsset>(asset)->key_id() : optional<string>())
{
}
xmlpp::Node *
ReelSubtitleAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
{
- xmlpp::Node* asset = ReelAsset::write_to_cpl (node, standard);
+ xmlpp::Node* asset = write_to_cpl_base (node, standard, hash());
if (key_id ()) {
/* Find <Hash> */
return asset;
}
+
+bool
+ReelSubtitleAsset::equals (shared_ptr<const ReelSubtitleAsset> other, EqualityOptions opt, NoteHandler note) const
+{
+ if (!asset_equals (other, opt, note)) {
+ return false;
+ }
+ if (!mxf_equals (other, opt, note)) {
+ return false;
+ }
+
+ return true;
+}
explicit ReelSubtitleAsset (boost::shared_ptr<const cxml::Node>);
xmlpp::Node* write_to_cpl (xmlpp::Node* node, Standard standard) const;
+ bool equals (boost::shared_ptr<const ReelSubtitleAsset>, EqualityOptions, NoteHandler) const;
boost::shared_ptr<SubtitleAsset> asset () const {
return asset_of_type<SubtitleAsset> ();
};
static Result
-verify_asset (shared_ptr<DCP> dcp, shared_ptr<ReelAsset> reel_asset, function<void (float)> progress)
+verify_asset (shared_ptr<DCP> dcp, shared_ptr<ReelMXF> reel_mxf, function<void (float)> progress)
{
- string const actual_hash = reel_asset->asset_ref()->hash(progress);
+ string const actual_hash = reel_mxf->asset_ref()->hash(progress);
list<shared_ptr<PKL> > pkls = dcp->pkls();
/* We've read this DCP in so it must have at least one PKL */
DCP_ASSERT (!pkls.empty());
- shared_ptr<Asset> asset = reel_asset->asset_ref().asset();
+ shared_ptr<Asset> asset = reel_mxf->asset_ref().asset();
optional<string> pkl_hash;
BOOST_FOREACH (shared_ptr<PKL> i, pkls) {
- pkl_hash = i->hash (reel_asset->asset_ref()->id());
+ pkl_hash = i->hash (reel_mxf->asset_ref()->id());
if (pkl_hash) {
break;
}
DCP_ASSERT (pkl_hash);
- optional<string> cpl_hash = reel_asset->hash();
+ optional<string> cpl_hash = reel_mxf->hash();
if (cpl_hash && *cpl_hash != *pkl_hash) {
return RESULT_CPL_PKL_DIFFER;
}