Add basic CCAP support.
authorCarl Hetherington <cth@carlh.net>
Mon, 4 Sep 2017 22:34:11 +0000 (23:34 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 4 Sep 2017 22:34:11 +0000 (23:34 +0100)
18 files changed:
src/reel.cc
src/reel.h
src/reel_asset.cc
src/reel_asset.h
src/reel_atmos_asset.cc
src/reel_atmos_asset.h
src/reel_closed_caption_asset.cc [new file with mode: 0644]
src/reel_closed_caption_asset.h [new file with mode: 0644]
src/reel_mono_picture_asset.cc
src/reel_mono_picture_asset.h
src/reel_picture_asset.cc
src/reel_sound_asset.cc
src/reel_sound_asset.h
src/reel_stereo_picture_asset.cc
src/reel_stereo_picture_asset.h
src/reel_subtitle_asset.cc
src/reel_subtitle_asset.h
src/wscript

index 89fc3a45bc4e0e46856b3bb37d54c33f0e27b297..1804f3dcdd5a5a7bb106bb8a6bf310d198a9a4fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of libdcp.
 
@@ -47,6 +47,7 @@
 #include "interop_subtitle_asset.h"
 #include "smpte_subtitle_asset.h"
 #include "reel_atmos_asset.h"
+#include "reel_closed_caption_asset.h"
 #include <libxml++/nodes/element.h>
 
 using std::string;
@@ -82,6 +83,16 @@ Reel::Reel (boost::shared_ptr<const cxml::Node> node)
                _main_subtitle.reset (new ReelSubtitleAsset (main_subtitle));
        }
 
+       /* XXX: it's not ideal that we silently tolerate Interop or SMPTE nodes here */
+       shared_ptr<cxml::Node> closed_caption = asset_list->optional_node_child ("cc-cpl:MainClosedCaption");
+       if (closed_caption) {
+               _closed_caption.reset (new ReelClosedCaptionAsset (closed_caption));
+       }
+       closed_caption = asset_list->optional_node_child ("tt:ClosedCaption");
+       if (closed_caption) {
+               _closed_caption.reset (new ReelClosedCaptionAsset (closed_caption));
+       }
+
        shared_ptr<cxml::Node> atmos = asset_list->optional_node_child ("AuxData");
        if (atmos) {
                _atmos.reset (new ReelAtmosAsset (atmos));
@@ -111,6 +122,10 @@ Reel::write_to_cpl (xmlpp::Element* node, Standard standard) const
                _main_subtitle->write_to_cpl (asset_list, standard);
        }
 
+       if (_closed_caption) {
+               _closed_caption->write_to_cpl (asset_list, standard);
+       }
+
        if (_main_picture && dynamic_pointer_cast<ReelStereoPictureAsset> (_main_picture)) {
                /* ... but stereo pictures must come after */
                _main_picture->write_to_cpl (asset_list, standard);
@@ -151,6 +166,10 @@ Reel::equals (boost::shared_ptr<const Reel> other, EqualityOptions opt, NoteHand
                return false;
        }
 
+       if (_closed_caption && !_closed_caption->equals (other->_closed_caption, opt, note)) {
+               return false;
+       }
+
        if ((_atmos && !other->_atmos) || (!_atmos && other->_atmos)) {
                note (DCP_ERROR, "Reel: assets differ");
                return false;
@@ -169,6 +188,8 @@ Reel::encrypted () const
        return (
                (_main_picture && _main_picture->encrypted ()) ||
                (_main_sound && _main_sound->encrypted ()) ||
+               (_main_subtitle && _main_subtitle->encrypted ()) ||
+               (_closed_caption && _closed_caption->encrypted ()) ||
                (_atmos && _atmos->encrypted ())
                );
 }
@@ -191,6 +212,12 @@ Reel::add (DecryptedKDM const & kdm)
                                s->set_key (i->key ());
                        }
                }
+               if (_closed_caption && i->id() == _closed_caption->key_id()) {
+                       shared_ptr<SMPTESubtitleAsset> s = dynamic_pointer_cast<SMPTESubtitleAsset> (_closed_caption->asset());
+                       if (s) {
+                               s->set_key (i->key ());
+                       }
+               }
                if (_atmos && i->id() == _atmos->key_id()) {
                        _atmos->asset()->set_key (i->key ());
                }
@@ -203,6 +230,7 @@ Reel::add (shared_ptr<ReelAsset> asset)
        shared_ptr<ReelPictureAsset> p = dynamic_pointer_cast<ReelPictureAsset> (asset);
        shared_ptr<ReelSoundAsset> so = dynamic_pointer_cast<ReelSoundAsset> (asset);
        shared_ptr<ReelSubtitleAsset> su = dynamic_pointer_cast<ReelSubtitleAsset> (asset);
+       shared_ptr<ReelClosedCaptionAsset> c = dynamic_pointer_cast<ReelClosedCaptionAsset> (asset);
        shared_ptr<ReelAtmosAsset> a = dynamic_pointer_cast<ReelAtmosAsset> (asset);
        if (p) {
                _main_picture = p;
@@ -210,6 +238,8 @@ Reel::add (shared_ptr<ReelAsset> asset)
                _main_sound = so;
        } else if (su) {
                _main_subtitle = su;
+       } else if (c) {
+               _closed_caption = c;
        } else if (a) {
                _atmos = a;
        }
@@ -238,6 +268,18 @@ Reel::resolve_refs (list<shared_ptr<Asset> > assets)
                }
        }
 
+       if (_closed_caption) {
+               _closed_caption->asset_ref().resolve(assets);
+
+               /* Interop subtitle handling is all special cases */
+               if (_closed_caption->asset_ref().resolved()) {
+                       shared_ptr<InteropSubtitleAsset> iop = dynamic_pointer_cast<InteropSubtitleAsset> (_closed_caption->asset_ref().asset());
+                       if (iop) {
+                               iop->resolve_fonts (assets);
+                       }
+               }
+       }
+
        if (_atmos) {
                _atmos->asset_ref().resolve (assets);
        }
@@ -257,6 +299,9 @@ Reel::duration () const
        if (_main_subtitle) {
                d = max (d, _main_subtitle->duration ());
        }
+       if (_closed_caption) {
+               d = max (d, _closed_caption->duration ());
+       }
        if (_atmos) {
                d = max (d, _atmos->duration ());
        }
index 6a5d7f52498f9c8ec45e86160682c9ed048814a9..193da52f1a5183719befae4084a6f79e9612cbcb 100644 (file)
@@ -56,6 +56,7 @@ class ReelAsset;
 class ReelPictureAsset;
 class ReelSoundAsset;
 class ReelSubtitleAsset;
+class ReelClosedCaptionAsset;
 class ReelAtmosAsset;
 class Content;
 
@@ -113,6 +114,7 @@ private:
        boost::shared_ptr<ReelPictureAsset> _main_picture;
        boost::shared_ptr<ReelSoundAsset> _main_sound;
        boost::shared_ptr<ReelSubtitleAsset> _main_subtitle;
+       boost::shared_ptr<ReelClosedCaptionAsset> _closed_caption;
        boost::shared_ptr<ReelAtmosAsset> _atmos;
 };
 
index bed05dfa1520ee1a92e7db1de41ade704754ad32..f96ee2c08b6aca83a416ab5232a0d09e7f02e274 100644 (file)
@@ -95,12 +95,12 @@ ReelAsset::ReelAsset (shared_ptr<const cxml::Node> node)
 void
 ReelAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
 {
-        xmlpp::Element* a = node->add_child (cpl_node_name ());
+        xmlpp::Element* a = node->add_child (cpl_node_name (standard));
         pair<string, string> const attr = cpl_node_attribute (standard);
         if (!attr.first.empty ()) {
                 a->set_attribute (attr.first, attr.second);
         }
-        pair<string, string> const ns = cpl_node_namespace ();
+        pair<string, string> const ns = cpl_node_namespace (standard);
         if (!ns.first.empty ()) {
                 a->set_namespace_declaration (ns.first, ns.second);
         }
@@ -122,7 +122,7 @@ ReelAsset::cpl_node_attribute (Standard) const
 }
 
 pair<string, string>
-ReelAsset::cpl_node_namespace () const
+ReelAsset::cpl_node_namespace (Standard) const
 {
        return make_pair ("", "");
 }
index d1d2e1b6bf9857a1951fb91a3626340a4fcfdfa7..af367cd3a0a79ac067ff746cfb89f691d5a4426e 100644 (file)
@@ -132,13 +132,13 @@ protected:
        /** @return the node name that this asset uses in the CPL's &lt;Reel&gt; node
         *  e.g. MainPicture, MainSound etc.
         */
-       virtual std::string cpl_node_name () const = 0;
+       virtual std::string cpl_node_name (Standard) const = 0;
 
        /** @return Any attribute that should be used on the asset's node in the CPL */
        virtual std::pair<std::string, std::string> cpl_node_attribute (Standard) const;
 
        /** @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 () const;
+       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.
index 8726b39c68dc0cb532112a0a62582e930d23d5c4..8c1c21aeefb6b7a6bc8f4ac63798087af4c97557 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2016-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of libdcp.
 
@@ -60,13 +60,13 @@ ReelAtmosAsset::ReelAtmosAsset (boost::shared_ptr<const cxml::Node> node)
 }
 
 string
-ReelAtmosAsset::cpl_node_name () const
+ReelAtmosAsset::cpl_node_name (Standard) const
 {
        return "axd:AuxData";
 }
 
 pair<string, string>
-ReelAtmosAsset::cpl_node_namespace () const
+ReelAtmosAsset::cpl_node_namespace (Standard) const
 {
        return make_pair ("http://www.dolby.com/schemas/2012/AD", "axd");
 }
@@ -83,6 +83,6 @@ ReelAtmosAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
        ReelAsset::write_to_cpl (node, standard);
 
        /* Find <axd:AuxData> */
-       xmlpp::Node* mp = find_child (node, cpl_node_name ());
+       xmlpp::Node* mp = find_child (node, cpl_node_name (standard));
        mp->add_child("axd:DataType")->add_child_text ("urn:smpte:ul:060e2b34.04010105.0e090604.00000000");
 }
index e7ea51aad4c6021149c4d87c30c454e8adb702af..31f5293e135887372ca495672568a733a1aa9fd9 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2016-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of libdcp.
 
@@ -63,8 +63,8 @@ public:
 
 private:
        std::string key_type () const;
-       std::string cpl_node_name () const;
-       std::pair<std::string, std::string> cpl_node_namespace () const;
+       std::string cpl_node_name (Standard standard) const;
+       std::pair<std::string, std::string> cpl_node_namespace (Standard) const;
 };
 
 }
diff --git a/src/reel_closed_caption_asset.cc b/src/reel_closed_caption_asset.cc
new file mode 100644 (file)
index 0000000..4fb729c
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
+
+    This file is part of libdcp.
+
+    libdcp 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.
+
+    libdcp 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 libdcp.  If not, see <http://www.gnu.org/licenses/>.
+
+    In addition, as a special exception, the copyright holders give
+    permission to link the code of portions of this program with the
+    OpenSSL library under certain conditions as described in each
+    individual source file, and distribute linked combinations
+    including the two.
+
+    You must obey the GNU General Public License in all respects
+    for all of the code used other than OpenSSL.  If you modify
+    file(s) with this exception, you may extend this exception to your
+    version of the file(s), but you are not obligated to do so.  If you
+    do not wish to do so, delete this exception statement from your
+    version.  If you delete this exception statement from all source
+    files in the program, then also delete it here.
+*/
+
+/** @file  src/reel_closed_caption_asset.cc
+ *  @brief ReelClosedCaptionAsset class.
+ */
+
+#include "subtitle_asset.h"
+#include "reel_closed_caption_asset.h"
+#include "smpte_subtitle_asset.h"
+#include "dcp_assert.h"
+#include <libxml++/libxml++.h>
+
+using std::string;
+using std::pair;
+using std::make_pair;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using boost::optional;
+using namespace dcp;
+
+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>())
+{
+
+}
+
+ReelClosedCaptionAsset::ReelClosedCaptionAsset (boost::shared_ptr<const cxml::Node> node)
+       : ReelAsset (node)
+       , ReelMXF (node)
+{
+       node->ignore_child ("Language");
+       node->done ();
+}
+
+string
+ReelClosedCaptionAsset::cpl_node_name (Standard standard) const
+{
+       switch (standard) {
+       case INTEROP:
+               return "cc-cpl:MainClosedCaption";
+       case SMPTE:
+               return "tt:ClosedCaption";
+       }
+
+       DCP_ASSERT (false);
+}
+
+pair<string, string>
+ReelClosedCaptionAsset::cpl_node_namespace (Standard standard) const
+{
+       switch (standard) {
+       case INTEROP:
+               return make_pair ("http://www.digicine.com/PROTO-ASDCP-CC-CPL-20070926#", "cc-cpl");
+       case SMPTE:
+               return make_pair ("http://www.smpte-ra.org/schemas/429-12/2008/TT", "tt");
+       }
+
+       DCP_ASSERT (false);
+}
+
+string
+ReelClosedCaptionAsset::key_type () const
+{
+       return "MDSK";
+}
+
+void
+ReelClosedCaptionAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
+{
+       ReelAsset::write_to_cpl (node, standard);
+
+        if (key_id ()) {
+               /* Find our main tag */
+               xmlpp::Node* ms = find_child (node, cpl_node_name (standard));
+               /* Find <Hash> */
+               xmlpp::Node* hash = find_child (ms, "Hash");
+               ms->add_child_before (hash, "KeyId")->add_child_text ("urn:uuid:" + key_id().get ());
+       }
+}
diff --git a/src/reel_closed_caption_asset.h b/src/reel_closed_caption_asset.h
new file mode 100644 (file)
index 0000000..2cf65ad
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
+
+    This file is part of libdcp.
+
+    libdcp 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.
+
+    libdcp 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 libdcp.  If not, see <http://www.gnu.org/licenses/>.
+
+    In addition, as a special exception, the copyright holders give
+    permission to link the code of portions of this program with the
+    OpenSSL library under certain conditions as described in each
+    individual source file, and distribute linked combinations
+    including the two.
+
+    You must obey the GNU General Public License in all respects
+    for all of the code used other than OpenSSL.  If you modify
+    file(s) with this exception, you may extend this exception to your
+    version of the file(s), but you are not obligated to do so.  If you
+    do not wish to do so, delete this exception statement from your
+    version.  If you delete this exception statement from all source
+    files in the program, then also delete it here.
+*/
+
+/** @file  src/reel_closed_caption_asset.h
+ *  @brief ReelClosedCaptionAsset class.
+ */
+
+#ifndef LIBDCP_REEL_CLOSED_CAPTION_ASSET_H
+#define LIBDCP_REEL_CLOSED_CAPTION_ASSET_H
+
+#include "reel_asset.h"
+#include "reel_mxf.h"
+#include "subtitle_asset.h"
+
+namespace dcp {
+
+class SubtitleAsset;
+
+/** @class ReelClosedCaptionAsset
+ *  @brief Part of a Reel's description which refers to a closed caption XML/MXF file.
+ */
+class ReelClosedCaptionAsset : public ReelAsset, public ReelMXF
+{
+public:
+       ReelClosedCaptionAsset (boost::shared_ptr<SubtitleAsset> asset, Fraction edit_rate, int64_t instrinsic_duration, int64_t entry_point);
+       explicit ReelClosedCaptionAsset (boost::shared_ptr<const cxml::Node>);
+
+       void write_to_cpl (xmlpp::Node* node, Standard standard) const;
+
+       boost::shared_ptr<SubtitleAsset> asset () const {
+               return asset_of_type<SubtitleAsset> ();
+       }
+
+private:
+       std::string key_type () const;
+       std::string cpl_node_name (Standard standard) const;
+       std::pair<std::string, std::string> cpl_node_namespace (Standard standard) const;
+};
+
+}
+
+#endif
index fd863bd629464fdb9a8346d40680010f7f90cb1a..e894764eea5a0b4008a7af8c0a51f730d387bf9c 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of libdcp.
 
@@ -61,7 +61,7 @@ ReelMonoPictureAsset::ReelMonoPictureAsset (boost::shared_ptr<const cxml::Node>
 }
 
 string
-ReelMonoPictureAsset::cpl_node_name () const
+ReelMonoPictureAsset::cpl_node_name (Standard) const
 {
        return "MainPicture";
 }
index b0a75f8492d370661b23cd1171a1aa949d5054b8..4c5eaa083ae469a1a580659926f2f48d1493a1a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of libdcp.
 
@@ -66,7 +66,7 @@ public:
        }
 
 private:
-       std::string cpl_node_name () const;
+       std::string cpl_node_name (Standard standard) const;
 };
 
 }
index de106c794befacb78ef475958aa3b3b858f60eff..644024ec08501a9c6937f868ad81382da6da1e7e 100644 (file)
@@ -92,7 +92,7 @@ ReelPictureAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
        ReelAsset::write_to_cpl (node, standard);
 
        /* Find <MainPicture> */
-       xmlpp::Node* mp = find_child (node, cpl_node_name ());
+       xmlpp::Node* mp = find_child (node, cpl_node_name (standard));
 
        mp->add_child ("FrameRate")->add_child_text (String::compose ("%1 %2", _frame_rate.numerator, _frame_rate.denominator));
        if (standard == INTEROP) {
index 1b582535ea2cfb354a0d58a88508cc940ef53d59..178b0a08ed72062e90ec548b9d2b595917356d35 100644 (file)
@@ -60,7 +60,7 @@ ReelSoundAsset::ReelSoundAsset (shared_ptr<const cxml::Node> node)
 }
 
 string
-ReelSoundAsset::cpl_node_name () const
+ReelSoundAsset::cpl_node_name (Standard) const
 {
        return "MainSound";
 }
@@ -78,7 +78,7 @@ ReelSoundAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
 
         if (key_id ()) {
                /* Find <MainSound> */
-               xmlpp::Node* ms = find_child (node, cpl_node_name ());
+               xmlpp::Node* ms = find_child (node, cpl_node_name (standard));
                /* Find <Hash> */
                xmlpp::Node* hash = find_child (ms, "Hash");
                ms->add_child_before (hash, "KeyId")->add_child_text ("urn:uuid:" + key_id().get ());
index da15011190853125ea6896766f2a13470f77fe68..d95b83dcd41ededcd9d3bcb038d8fe0049feafa6 100644 (file)
@@ -66,7 +66,7 @@ public:
 
 private:
        std::string key_type () const;
-       std::string cpl_node_name () const;
+       std::string cpl_node_name (Standard standard) const;
 };
 
 }
index 53419667856e08555cec34b761bc2c819c057a3c..f194cca097a0659594e2ba9fc294ea59c5e8ffd4 100644 (file)
@@ -63,7 +63,7 @@ ReelStereoPictureAsset::ReelStereoPictureAsset (boost::shared_ptr<const cxml::No
 }
 
 string
-ReelStereoPictureAsset::cpl_node_name () const
+ReelStereoPictureAsset::cpl_node_name (Standard) const
 {
        return "msp-cpl:MainStereoscopicPicture";
 }
@@ -71,11 +71,12 @@ ReelStereoPictureAsset::cpl_node_name () const
 pair<string, string>
 ReelStereoPictureAsset::cpl_node_attribute (Standard standard) const
 {
-       if (standard == INTEROP) {
+       switch (standard) {
+       case INTEROP:
                return make_pair ("xmlns:msp-cpl", "http://www.digicine.com/schemas/437-Y/2007/Main-Stereo-Picture-CPL");
-       } else {
+       case SMPTE:
                return make_pair ("xmlns:msp-cpl", "http://www.smpte-ra.org/schemas/429-10/2008/Main-Stereo-Picture-CPL");
        }
 
-       return make_pair ("", "");
+       DCP_ASSERT (false);
 }
index 9cf0ead2feffcb3a3ffa62e3064be3b1ade9ffce..c7223495bbc48d9fd2fb56efde09250cfe0e32c0 100644 (file)
@@ -66,7 +66,7 @@ public:
        }
 
 private:
-       std::string cpl_node_name () const;
+       std::string cpl_node_name (Standard standard) const;
        std::pair<std::string, std::string> cpl_node_attribute (Standard standard) const;
 };
 
index c7e4042065230ce791cb940182cbf12bb5e99df7..ddb1b9726fa5856e6e8452b3205e9f9a3e8166a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of libdcp.
 
@@ -62,7 +62,7 @@ ReelSubtitleAsset::ReelSubtitleAsset (boost::shared_ptr<const cxml::Node> node)
 }
 
 string
-ReelSubtitleAsset::cpl_node_name () const
+ReelSubtitleAsset::cpl_node_name (Standard) const
 {
        return "MainSubtitle";
 }
@@ -80,7 +80,7 @@ ReelSubtitleAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const
 
         if (key_id ()) {
                /* Find <MainSubtitle> */
-               xmlpp::Node* ms = find_child (node, cpl_node_name ());
+               xmlpp::Node* ms = find_child (node, cpl_node_name (standard));
                /* Find <Hash> */
                xmlpp::Node* hash = find_child (ms, "Hash");
                ms->add_child_before (hash, "KeyId")->add_child_text ("urn:uuid:" + key_id().get ());
index 1d76ba9e32eafeecadd2cab95427814784dcfbeb..1642a46ef023067d471bdf788a58c7649b0ffd61 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of libdcp.
 
@@ -63,7 +63,7 @@ public:
 
 private:
        std::string key_type () const;
-       std::string cpl_node_name () const;
+       std::string cpl_node_name (Standard standard) const;
 };
 
 }
index 759d66dc79fd1cc819ce22b2d52991a3bd70da43..a76ca6a145a415b28b07a1984b619389b8f5002b 100644 (file)
@@ -77,6 +77,7 @@ def build(bld):
              reel.cc
              reel_asset.cc
              reel_atmos_asset.cc
+             reel_closed_caption_asset.cc
              reel_mono_picture_asset.cc
              reel_mxf.cc
              reel_picture_asset.cc
@@ -153,6 +154,7 @@ def build(bld):
               reel.h
               reel_asset.h
               reel_atmos_asset.h
+              reel_closed_caption_asset.h
               reel_mono_picture_asset.h
               reel_mxf.h
               reel_picture_asset.h