Cleanup: move EqualityOptions into its own file.
[libdcp.git] / src / reel.cc
index becac8983c02b328155adc087c09cfd91f8d00d9..a8481d593f03db5a8f60517353da65a7d8fd3508 100644 (file)
  */
 
 
-#include "reel.h"
-#include "util.h"
-#include "picture_asset.h"
+#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 "reel_mono_picture_asset.h"
-#include "reel_stereo_picture_asset.h"
-#include "reel_sound_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_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 <libxml++/nodes/element.h>
 #include <stdint.h>
 
@@ -115,7 +118,14 @@ Reel::Reel (std::shared_ptr<const cxml::Node> node, dcp::Standard standard)
                closed_captions = asset_list->node_children ("ClosedCaption");
        }
        for (auto i: closed_captions) {
-               _closed_captions.push_back (make_shared<ReelClosedCaptionAsset>(i));
+               switch (standard) {
+                       case Standard::INTEROP:
+                               _closed_captions.push_back (make_shared<ReelInteropClosedCaptionAsset>(i));
+                               break;
+                       case Standard::SMPTE:
+                               _closed_captions.push_back (make_shared<ReelSMPTEClosedCaptionAsset>(i));
+                               break;
+               }
        }
 
        auto atmos = asset_list->optional_node_child ("AuxData");
@@ -170,7 +180,7 @@ Reel::write_to_cpl (xmlpp::Element* node, Standard standard) const
 
 
 bool
-Reel::equals (std::shared_ptr<const Reel> other, EqualityOptions opt, NoteHandler note) const
+Reel::equals(std::shared_ptr<const Reel> 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");
@@ -270,17 +280,10 @@ Reel::any_encrypted () const
                }
        }
 
-       bool esub = false;
-       if (_main_subtitle) {
-               if (auto enc = dynamic_pointer_cast<ReelEncryptableAsset>(_main_picture)) {
-                       esub = enc->encrypted();
-               }
-       }
-
        return (
                (_main_picture && _main_picture->encrypted()) ||
                (_main_sound && _main_sound->encrypted()) ||
-               esub ||
+               (_main_subtitle && _main_subtitle->encrypted()) ||
                ecc ||
                (_atmos && _atmos->encrypted())
                );
@@ -297,18 +300,10 @@ Reel::all_encrypted () const
                }
        }
 
-       /* It's ok if there's no subtitle, or it's not encryptable */
-       bool esub = true;
-       if (_main_subtitle) {
-               if (auto enc = dynamic_pointer_cast<ReelEncryptableAsset>(_main_picture)) {
-                       esub = enc->encrypted();
-               }
-       }
-
        return (
                (!_main_picture || _main_picture->encrypted()) &&
                (!_main_sound || _main_sound->encrypted()) &&
-               esub &&
+               (!_main_subtitle || _main_subtitle->encrypted()) &&
                ecc &&
                (!_atmos || _atmos->encrypted())
               );
@@ -318,30 +313,38 @@ 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) {
-                       auto smpte = dynamic_pointer_cast<ReelSMPTESubtitleAsset>(_main_picture);
-                       if (smpte && i.id() == smpte->key_id()) {
+                       auto smpte = dynamic_pointer_cast<ReelSMPTESubtitleAsset>(_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<SMPTESubtitleAsset> (j->asset());
-                               if (s) {
-                                       s->set_key (i.key());
-                               }
+                       auto smpte = dynamic_pointer_cast<ReelSMPTESubtitleAsset>(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());
                }
        }
@@ -351,24 +354,20 @@ Reel::add (DecryptedKDM const & kdm)
 void
 Reel::add (shared_ptr<ReelAsset> asset)
 {
-       auto p = dynamic_pointer_cast<ReelPictureAsset> (asset);
-       auto so = dynamic_pointer_cast<ReelSoundAsset> (asset);
-       auto su = dynamic_pointer_cast<ReelSubtitleAsset> (asset);
-       auto m = dynamic_pointer_cast<ReelMarkersAsset> (asset);
-       auto c = dynamic_pointer_cast<ReelClosedCaptionAsset> (asset);
-       auto a = dynamic_pointer_cast<ReelAtmosAsset> (asset);
-       if (p) {
+       if (auto p = dynamic_pointer_cast<ReelPictureAsset>(asset)) {
                _main_picture = p;
-       } else if (so) {
+       } else if (auto so = dynamic_pointer_cast<ReelSoundAsset>(asset)) {
                _main_sound = so;
-       } else if (su) {
+       } else if (auto su = dynamic_pointer_cast<ReelSubtitleAsset>(asset)) {
                _main_subtitle = su;
-       } else if (m) {
+       } else if (auto m = dynamic_pointer_cast<ReelMarkersAsset>(asset)) {
                _main_markers = m;
-       } else if (c) {
+       } else if (auto c = dynamic_pointer_cast<ReelClosedCaptionAsset>(asset)) {
                _closed_captions.push_back (c);
-       } else if (a) {
+       } else if (auto a = dynamic_pointer_cast<ReelAtmosAsset>(asset)) {
                _atmos = a;
+       } else {
+               DCP_ASSERT(false);
        }
 }
 
@@ -432,6 +431,10 @@ Reel::resolve_refs (vector<shared_ptr<Asset>> assets)
        if (_atmos) {
                _atmos->asset_ref().resolve (assets);
        }
+
+       for (auto const& i: _kdms) {
+               give_kdm_to_assets (i);
+       }
 }