Add wrappers around boost::filesystem methods that handle the
[libdcp.git] / src / cpl.cc
index 33a690f3cbbe513aaf6c00be4d453e7b6785aa00..5467fef3b1db0b38ebf859e5d4adf623e7342dd7 100644 (file)
@@ -41,6 +41,8 @@
 #include "compose.hpp"
 #include "cpl.h"
 #include "dcp_assert.h"
+#include "equality_options.h"
+#include "filesystem.h"
 #include "local_time.h"
 #include "metadata.h"
 #include "raw_convert.h"
@@ -107,7 +109,7 @@ CPL::CPL (boost::filesystem::path file)
        , _content_kind (ContentKind::FEATURE)
 {
        cxml::Document f ("CompositionPlaylist");
-       f.read_file (file);
+       f.read_file(dcp::filesystem::fix_long_path(file));
 
        if (f.namespace_uri() == cpl_interop_ns) {
                _standard = Standard::INTEROP;
@@ -238,7 +240,7 @@ CPL::write_xml(boost::filesystem::path file, shared_ptr<const CertificateChain>
                signer->sign (root, _standard);
        }
 
-       doc.write_to_file_formatted (file.string(), "UTF-8");
+       doc.write_to_file_formatted(dcp::filesystem::fix_long_path(file).string(), "UTF-8");
 
        set_file (file);
 }
@@ -288,7 +290,16 @@ CPL::read_composition_metadata_asset (cxml::ConstNodePtr node)
                _luminance = Luminance (lum);
        }
 
-       _main_sound_configuration = node->optional_string_child("MainSoundConfiguration");
+       if (auto msc = node->optional_string_child("MainSoundConfiguration")) {
+               try {
+                       _main_sound_configuration = MainSoundConfiguration(*msc);
+               } catch (MainSoundConfigurationError& e) {
+                       /* With Interop DCPs this node may not make any sense, but that's OK */
+                       if (_standard == dcp::Standard::SMPTE) {
+                               throw e;
+                       }
+               }
+       }
 
        auto sr = node->optional_string_child("MainSoundSampleRate");
        if (sr) {
@@ -385,6 +396,7 @@ CPL::write_mca_subdescriptors(xmlpp::Element* parent, shared_ptr<const SoundAsse
                        sf->add_child("RFC5646SpokenLanguage", "r1")->add_child_text(buffer);
                }
 
+               /* Find the MCA subdescriptors in the MXF so that we can also write them here */
                list<ASDCP::MXF::InterchangeObject*> channels;
                auto r = reader->reader()->OP1aHeader().GetMDObjectsByType(
                        asdcp_smpte_dict->ul(ASDCP::MDD_AudioChannelLabelSubDescriptor),
@@ -393,9 +405,6 @@ CPL::write_mca_subdescriptors(xmlpp::Element* parent, shared_ptr<const SoundAsse
 
                for (auto i: channels) {
                        auto channel = reinterpret_cast<ASDCP::MXF::AudioChannelLabelSubDescriptor*>(i);
-                       if (static_cast<int>(channel->MCAChannelID) > asset->channels()) {
-                               continue;
-                       }
                        auto ch = mca_subs->add_child("AudioChannelLabelSubDescriptor", "r0");
                        channel->InstanceUID.EncodeString(buffer, sizeof(buffer));
                        ch->add_child("InstanceID", "r1")->add_child_text("urn:uuid:" + string(buffer));
@@ -494,7 +503,9 @@ CPL::maybe_write_composition_metadata_asset(xmlpp::Element* node, bool include_m
                _luminance->as_xml (meta, "meta");
        }
 
-       meta->add_child("MainSoundConfiguration", "meta")->add_child_text(*_main_sound_configuration);
+       if (_main_sound_configuration) {
+               meta->add_child("MainSoundConfiguration", "meta")->add_child_text(_main_sound_configuration->to_string());
+       }
        meta->add_child("MainSoundSampleRate", "meta")->add_child_text(raw_convert<string>(*_main_sound_sample_rate) + " 1");
 
        auto stored = meta->add_child("MainPictureStoredArea", "meta");
@@ -599,7 +610,7 @@ CPL::reel_file_assets () const
 
 
 bool
-CPL::equals (shared_ptr<const Asset> other, EqualityOptions opt, NoteHandler note) const
+CPL::equals(shared_ptr<const Asset> other, EqualityOptions const& opt, NoteHandler note) const
 {
        auto other_cpl = dynamic_pointer_cast<const CPL>(other);
        if (!other_cpl) {