Add comment.
[dcpomatic.git] / src / lib / config.cc
index f7456e2699ea9af7944586cb772542e024372c58..983fb69d8d8af2725c5bec70b28a32c298a202e2 100644 (file)
@@ -31,6 +31,7 @@
 #include "cross.h"
 #include "film.h"
 #include "dkdm_wrapper.h"
+#include "compose.hpp"
 #include <dcp/raw_convert.h>
 #include <dcp/name_format.h>
 #include <dcp/certificate_chain.h>
@@ -64,6 +65,8 @@ using dcp::raw_convert;
 
 Config* Config::_instance = 0;
 boost::signals2::signal<void ()> Config::FailedToLoad;
+boost::signals2::signal<void (string)> Config::Warning;
+boost::optional<boost::filesystem::path> Config::test_path;
 
 /** Construct default configuration */
 Config::Config ()
@@ -127,6 +130,18 @@ Config::set_defaults ()
        }
        _sound = false;
        _sound_output = optional<string> ();
+       _last_kdm_write_type = KDM_WRITE_FLAT;
+
+       /* I think the scaling factor here should be the ratio of the longest frame
+          encode time to the shortest; if the thread count is T, longest time is L
+          and the shortest time S we could encode L/S frames per thread whilst waiting
+          for the L frame to encode so we might have to store LT/S frames.
+
+          However we don't want to use too much memory, so keep it a bit lower than we'd
+          perhaps like.  A J2K frame is typically about 1Mb so 3 here will mean we could
+          use about 240Mb with 72 encoding threads.
+       */
+       _frames_in_memory_multiplier = 3;
 
        _allowed_dcp_frame_rates.clear ();
        _allowed_dcp_frame_rates.push_back (24);
@@ -225,6 +240,11 @@ try
                _default_container = Ratio::from_id (c.get ());
        }
 
+       if (_default_container && !_default_container->used_for_container()) {
+               Warning (_("Your default container is not valid and has been changed to Flat (1.85:1)"));
+               _default_container = Ratio::from_id ("185");
+       }
+
        c = f.optional_string_child ("DefaultScaleTo");
        if (c) {
                _default_scale_to = Ratio::from_id (c.get ());
@@ -348,6 +368,17 @@ try
        if (f.optional_string_child("CoverSheet")) {
                _cover_sheet = f.optional_string_child("CoverSheet").get();
        }
+       _last_player_load_directory = f.optional_string_child("LastPlayerLoadDirectory");
+       if (f.optional_string_child("LastKDMWriteType")) {
+               if (f.optional_string_child("LastKDMWriteType").get() == "flat") {
+                       _last_kdm_write_type = KDM_WRITE_FLAT;
+               } else if (f.optional_string_child("LastKDMWriteType").get() == "folder") {
+                       _last_kdm_write_type = KDM_WRITE_FOLDER;
+               } else if (f.optional_string_child("LastKDMWriteType").get() == "zip") {
+                       _last_kdm_write_type = KDM_WRITE_ZIP;
+               }
+       }
+       _frames_in_memory_multiplier = f.optional_number_child<int>("FramesInMemoryMultiplier").get_value_or(3);
 
        /* Replace any cinemas from config.xml with those from the configured file */
        if (boost::filesystem::exists (_cinemas_file)) {
@@ -361,8 +392,13 @@ catch (...) {
 
                /* Make a copy of the configuration */
                try {
-                       boost::filesystem::copy_file (path ("config.xml", false), path ("config.xml.backup", false));
-                       boost::filesystem::copy_file (path ("cinemas.xml", false), path ("cinemas.xml.backup", false));
+                       int n = 1;
+                       while (n < 100 && boost::filesystem::exists(path(String::compose("config.xml.%1", n)))) {
+                               ++n;
+                       }
+
+                       boost::filesystem::copy_file(path("config.xml", false), path(String::compose("config.xml.%1", n), false));
+                       boost::filesystem::copy_file(path("cinemas.xml", false), path(String::compose("cinemas.xml.%1", n), false));
                } catch (...) {}
 
                /* We have a config file but it didn't load */
@@ -381,16 +417,20 @@ boost::filesystem::path
 Config::path (string file, bool create_directories)
 {
        boost::filesystem::path p;
+       if (test_path) {
+               p = test_path.get();
+       } else {
 #ifdef DCPOMATIC_OSX
-       p /= g_get_home_dir ();
-       p /= "Library";
-       p /= "Preferences";
-       p /= "com.dcpomatic";
-       p /= "2";
+               p /= g_get_home_dir ();
+               p /= "Library";
+               p /= "Preferences";
+               p /= "com.dcpomatic";
+               p /= "2";
 #else
-       p /= g_get_user_config_dir ();
-       p /= "dcpomatic2";
+               p /= g_get_user_config_dir ();
+               p /= "dcpomatic2";
 #endif
+       }
        boost::system::error_code ec;
        if (create_directories) {
                boost::filesystem::create_directories (p, ec);
@@ -475,9 +515,9 @@ Config::write_config () const
                root->add_child("Language")->add_child_text (_language.get());
        }
        if (_default_container) {
-               /* [XML:opt] DefaultContainer ID of default container to use when creating new films (<code>119</code>, <code>133</code>,
-                  <code>138</code>, <code>143</code>, <code>166</code>, <code>178</code>, <code>185</code>, <code>235</code>,
-                  <code>239</code> or <code>full-frame</code>).
+               /* [XML:opt] DefaultContainer ID of default container
+                * to use when creating new films (<code>185</code>,<code>239</code> or
+                * <code>190</code>).
                */
                root->add_child("DefaultContainer")->add_child_text (_default_container->id ());
        }
@@ -625,6 +665,26 @@ Config::write_config () const
        }
        /* [XML] CoverSheet Text of the cover sheet to write when making DCPs */
        root->add_child("CoverSheet")->add_child_text (_cover_sheet);
+       if (_last_player_load_directory) {
+               root->add_child("LastPlayerLoadDirectory")->add_child_text(_last_player_load_directory->string());
+       }
+       if (_last_kdm_write_type) {
+               switch (_last_kdm_write_type.get()) {
+               case KDM_WRITE_FLAT:
+                       root->add_child("LastKDMWriteType")->add_child_text("flat");
+                       break;
+               case KDM_WRITE_FOLDER:
+                       root->add_child("LastKDMWriteType")->add_child_text("folder");
+                       break;
+               case KDM_WRITE_ZIP:
+                       root->add_child("LastKDMWriteType")->add_child_text("zip");
+                       break;
+               }
+       }
+       /* [XML] FramesInMemoryMultiplier value to multiply the encoding threads count by to get the maximum number of
+          frames to be held in memory at once.
+       */
+       root->add_child("FramesInMemoryMultiplier")->add_child_text(raw_convert<string>(_frames_in_memory_multiplier));
 
        try {
                doc.write_to_file_formatted(config_file().string());