Make Atmos content work more like other content. Now its MXFs
[dcpomatic.git] / src / lib / util.cc
index c1ef4245f16b18713dd008bbb9d212ab858b1674..74951fc64e1ef9bb076e5959cdd43dddd140e25f 100644 (file)
 #include "image.h"
 #include "text_decoder.h"
 #include "job_manager.h"
+#include <dcp/decrypted_kdm.h>
 #include <dcp/locale_convert.h>
 #include <dcp/util.h>
 #include <dcp/raw_convert.h>
 #include <dcp/picture_asset.h>
 #include <dcp/sound_asset.h>
 #include <dcp/subtitle_asset.h>
+#include <dcp/atmos_asset.h>
 extern "C" {
 #include <libavfilter/avfilter.h>
 #include <libavformat/avformat.h>
@@ -361,7 +363,7 @@ dcpomatic_setup ()
        /* Add our library directory to the libltdl search path so that
           xmlsec can find xmlsec1-openssl.
        */
-       boost::filesystem::path lib = app_contents ();
+       boost::filesystem::path lib = directory_containing_executable().parent_path();
        lib /= "Frameworks";
        setenv ("LTDL_LIBRARY_PATH", lib.c_str (), 1);
 #endif
@@ -726,6 +728,21 @@ audio_asset_filename (shared_ptr<dcp::SoundAsset> asset, int reel_index, int ree
        return Config::instance()->dcp_asset_filename_format().get(values, "_" + asset->id() + ".mxf");
 }
 
+
+string
+atmos_asset_filename (shared_ptr<dcp::AtmosAsset> asset, int reel_index, int reel_count, optional<string> summary)
+{
+       dcp::NameFormat::Map values;
+       values['t'] = "atmos";
+       values['r'] = raw_convert<string> (reel_index + 1);
+       values['n'] = raw_convert<string> (reel_count);
+       if (summary) {
+               values['c'] = careful_string_filter (summary.get());
+       }
+       return Config::instance()->dcp_asset_filename_format().get(values, "_" + asset->id() + ".mxf");
+}
+
+
 float
 relaxed_string_to_float (string s)
 {
@@ -822,7 +839,9 @@ remap (shared_ptr<const AudioBuffers> input, int output_channels, AudioMapping m
        shared_ptr<AudioBuffers> mapped (new AudioBuffers (output_channels, input->frames()));
        mapped->make_silent ();
 
-       for (int i = 0; i < map.input_channels(); ++i) {
+       int to_do = min (map.input_channels(), input->channels());
+
+       for (int i = 0; i < to_do; ++i) {
                for (int j = 0; j < mapped->channels(); ++j) {
                        if (map.get (i, static_cast<dcp::Channel> (j)) > 0) {
                                mapped->accumulate_channel (
@@ -1201,3 +1220,29 @@ scale_for_display (dcp::Size s, dcp::Size display_container, dcp::Size film_cont
        return s;
 }
 
+
+dcp::DecryptedKDM
+decrypt_kdm_with_helpful_error (dcp::EncryptedKDM kdm)
+{
+       try {
+               return dcp::DecryptedKDM (kdm, Config::instance()->decryption_chain()->key().get());
+       } catch (dcp::KDMDecryptionError& e) {
+               /* Try to flesh out the error a bit */
+               string const kdm_subject_name = kdm.recipient_x509_subject_name();
+               bool on_chain = false;
+               shared_ptr<const dcp::CertificateChain> dc = Config::instance()->decryption_chain();
+               BOOST_FOREACH (dcp::Certificate i, dc->root_to_leaf()) {
+                       if (i.subject() == kdm_subject_name) {
+                               on_chain = true;
+                       }
+               }
+               if (!on_chain) {
+                       throw KDMError (_("This KDM was not made for DCP-o-matic's decryption certificate."), e.what());
+               } else if (on_chain && kdm_subject_name != dc->leaf().subject()) {
+                       throw KDMError (_("This KDM was made for DCP-o-matic but not for its leaf certificate."), e.what());
+               } else {
+                       throw;
+               }
+       }
+}
+