X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Freel.cc;h=def3a4ae6a18104f9860e79367286f49e9838b51;hb=0d31c86d6dfad9f437f5613d41cace9cc5928474;hp=25019d359a511d5f249ea81d362806871a54e77f;hpb=5fbcd3a8dc711c6c42efabbac72ab0408f504ea2;p=libdcp.git diff --git a/src/reel.cc b/src/reel.cc index 25019d35..def3a4ae 100644 --- a/src/reel.cc +++ b/src/reel.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2020 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of libdcp. @@ -31,31 +31,38 @@ files in the program, then also delete it here. */ -#include "reel.h" -#include "util.h" -#include "picture_asset.h" + +/** @file src/reel.cc + * @brief Reel class + */ + + +#include "decrypted_kdm.h" +#include "decrypted_kdm_key.h" +#include "equality_options.h" +#include "interop_subtitle_asset.h" #include "mono_picture_asset.h" -#include "stereo_picture_asset.h" -#include "sound_asset.h" -#include "subtitle_asset.h" +#include "picture_asset.h" +#include "reel.h" +#include "reel_atmos_asset.h" +#include "reel_closed_caption_asset.h" +#include "reel_interop_closed_caption_asset.h" +#include "reel_interop_subtitle_asset.h" +#include "reel_markers_asset.h" #include "reel_mono_picture_asset.h" -#include "reel_stereo_picture_asset.h" +#include "reel_smpte_closed_caption_asset.h" +#include "reel_smpte_subtitle_asset.h" #include "reel_sound_asset.h" +#include "reel_stereo_picture_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" #include "smpte_subtitle_asset.h" -#include "reel_atmos_asset.h" -#include "reel_closed_caption_asset.h" +#include "sound_asset.h" +#include "stereo_picture_asset.h" +#include "subtitle_asset.h" +#include "util.h" #include #include -/* Centos 6 does not have this */ -#ifndef INT64_MAX -#define INT64_MAX 0x7fffffffffffffff -#endif using std::string; using std::cout; @@ -66,34 +73,42 @@ using std::dynamic_pointer_cast; using std::vector; using namespace dcp; -Reel::Reel (std::shared_ptr node) + +Reel::Reel (std::shared_ptr node, dcp::Standard standard) : Object (remove_urn_uuid (node->string_child ("Id"))) { auto asset_list = node->node_child ("AssetList"); auto main_picture = asset_list->optional_node_child ("MainPicture"); if (main_picture) { - _main_picture.reset (new ReelMonoPictureAsset (main_picture)); + _main_picture = make_shared(main_picture); } auto main_stereoscopic_picture = asset_list->optional_node_child ("MainStereoscopicPicture"); if (main_stereoscopic_picture) { - _main_picture.reset (new ReelStereoPictureAsset (main_stereoscopic_picture)); + _main_picture = make_shared(main_stereoscopic_picture); } auto main_sound = asset_list->optional_node_child ("MainSound"); if (main_sound) { - _main_sound.reset (new ReelSoundAsset (main_sound)); + _main_sound = make_shared(main_sound); } auto main_subtitle = asset_list->optional_node_child ("MainSubtitle"); if (main_subtitle) { - _main_subtitle.reset (new ReelSubtitleAsset (main_subtitle)); + switch (standard) { + case Standard::INTEROP: + _main_subtitle = make_shared(main_subtitle); + break; + case Standard::SMPTE: + _main_subtitle = make_shared(main_subtitle); + break; + } } auto main_markers = asset_list->optional_node_child ("MainMarkers"); if (main_markers) { - _main_markers.reset (new ReelMarkersAsset (main_markers)); + _main_markers = make_shared(main_markers); } /* XXX: it's not ideal that we silently tolerate Interop or SMPTE nodes here */ @@ -103,7 +118,14 @@ Reel::Reel (std::shared_ptr node) closed_captions = asset_list->node_children ("ClosedCaption"); } for (auto i: closed_captions) { - _closed_captions.push_back (make_shared(i)); + switch (standard) { + case Standard::INTEROP: + _closed_captions.push_back (make_shared(i)); + break; + case Standard::SMPTE: + _closed_captions.push_back (make_shared(i)); + break; + } } auto atmos = asset_list->optional_node_child ("AuxData"); @@ -115,12 +137,13 @@ Reel::Reel (std::shared_ptr node) node->done (); } + xmlpp::Element * Reel::write_to_cpl (xmlpp::Element* node, Standard standard) const { - auto reel = node->add_child ("Reel"); - reel->add_child("Id")->add_child_text("urn:uuid:" + _id); - xmlpp::Element* asset_list = reel->add_child ("AssetList"); + auto reel = cxml::add_child(node, "Reel"); + cxml::add_text_child(reel, "Id", "urn:uuid:" + _id); + auto asset_list = cxml::add_child(reel, "AssetList"); if (_main_markers) { _main_markers->write_to_cpl (asset_list, standard); @@ -155,8 +178,9 @@ Reel::write_to_cpl (xmlpp::Element* node, Standard standard) const return asset_list; } + bool -Reel::equals (std::shared_ptr other, EqualityOptions opt, NoteHandler note) const +Reel::equals(std::shared_ptr other, EqualityOptions const& opt, NoteHandler note) const { if ((_main_picture && !other->_main_picture) || (!_main_picture && other->_main_picture)) { note (NoteType::ERROR, "Reel: picture assets differ"); @@ -181,7 +205,31 @@ Reel::equals (std::shared_ptr other, EqualityOptions opt, NoteHandle return false; } - if (_main_subtitle && !_main_subtitle->equals (other->_main_subtitle, opt, note)) { + bool same_type = false; + + { + auto interop = dynamic_pointer_cast(_main_subtitle); + auto interop_other = dynamic_pointer_cast(other->_main_subtitle); + if (interop && interop_other) { + same_type = true; + if (!interop->equals(interop_other, opt, note)) { + return false; + } + } + } + + { + auto smpte = dynamic_pointer_cast(_main_subtitle); + auto smpte_other = dynamic_pointer_cast(other->_main_subtitle); + if (smpte && smpte_other) { + same_type = true; + if (!smpte->equals(smpte_other, opt, note)) { + return false; + } + } + } + + if ((_main_subtitle || other->_main_subtitle) && !same_type) { return false; } @@ -221,6 +269,7 @@ Reel::equals (std::shared_ptr other, EqualityOptions opt, NoteHandle return true; } + bool Reel::any_encrypted () const { @@ -260,62 +309,69 @@ Reel::all_encrypted () const ); } + void Reel::add (DecryptedKDM const & kdm) { - auto keys = kdm.keys (); + give_kdm_to_assets (kdm); + /* We have to keep the KDMs that we are given, as they will not be passed to unresolved assets. + * After we resolve some assets we will re-call give_kdm_to_assets() with all the KDMs that + * we have been given so far. + */ + _kdms.push_back (kdm); +} - for (auto const& i: keys) { - if (_main_picture && i.id() == _main_picture->key_id()) { + +void +Reel::give_kdm_to_assets (DecryptedKDM const & kdm) +{ + for (auto const& i: kdm.keys()) { + if (_main_picture && i.id() == _main_picture->key_id() && _main_picture->asset_ref().resolved()) { _main_picture->asset()->set_key (i.key()); } - if (_main_sound && i.id() == _main_sound->key_id()) { + if (_main_sound && i.id() == _main_sound->key_id() && _main_sound->asset_ref().resolved()) { _main_sound->asset()->set_key (i.key()); } - if (_main_subtitle && i.id() == _main_subtitle->key_id()) { - shared_ptr s = dynamic_pointer_cast (_main_subtitle->asset()); - if (s) { - s->set_key (i.key()); + if (_main_subtitle) { + auto smpte = dynamic_pointer_cast(_main_subtitle); + if (smpte && i.id() == smpte->key_id() && smpte->asset_ref().resolved()) { + smpte->smpte_asset()->set_key(i.key()); } } for (auto j: _closed_captions) { - if (i.id() == j->key_id()) { - auto s = dynamic_pointer_cast (j->asset()); - if (s) { - s->set_key (i.key()); - } + auto smpte = dynamic_pointer_cast(j); + if (smpte && i.id() == smpte->key_id() && smpte->asset_ref().resolved()) { + smpte->smpte_asset()->set_key(i.key()); } } - if (_atmos && i.id() == _atmos->key_id()) { + if (_atmos && i.id() == _atmos->key_id() && _atmos->asset_ref().resolved()) { _atmos->asset()->set_key (i.key()); } } } + void Reel::add (shared_ptr asset) { - auto p = dynamic_pointer_cast (asset); - auto so = dynamic_pointer_cast (asset); - auto su = dynamic_pointer_cast (asset); - auto m = dynamic_pointer_cast (asset); - auto c = dynamic_pointer_cast (asset); - auto a = dynamic_pointer_cast (asset); - if (p) { + if (auto p = dynamic_pointer_cast(asset)) { _main_picture = p; - } else if (so) { + } else if (auto so = dynamic_pointer_cast(asset)) { _main_sound = so; - } else if (su) { + } else if (auto su = dynamic_pointer_cast(asset)) { _main_subtitle = su; - } else if (m) { + } else if (auto m = dynamic_pointer_cast(asset)) { _main_markers = m; - } else if (c) { + } else if (auto c = dynamic_pointer_cast(asset)) { _closed_captions.push_back (c); - } else if (a) { + } else if (auto a = dynamic_pointer_cast(asset)) { _atmos = a; + } else { + DCP_ASSERT(false); } } + vector> Reel::assets () const { @@ -336,19 +392,20 @@ Reel::assets () const return a; } + void Reel::resolve_refs (vector> assets) { if (_main_picture) { - _main_picture->asset_ref().resolve (assets); + _main_picture->asset_ref().resolve(assets); } if (_main_sound) { - _main_sound->asset_ref().resolve (assets); + _main_sound->asset_ref().resolve(assets); } if (_main_subtitle) { - _main_subtitle->asset_ref().resolve (assets); + _main_subtitle->asset_ref().resolve(assets); /* Interop subtitle handling is all special cases */ if (_main_subtitle->asset_ref().resolved()) { @@ -374,8 +431,13 @@ Reel::resolve_refs (vector> assets) if (_atmos) { _atmos->asset_ref().resolve (assets); } + + for (auto const& i: _kdms) { + give_kdm_to_assets (i); + } } + int64_t Reel::duration () const {