Make a backup of configuration when we load in a Version 2 file, and bump our config...
[dcpomatic.git] / src / lib / config.cc
index e5fd9d17ad105578791594989ab96b63dac41cea..ec5b05afaa0a49ec41c84b732b7f1abea08105d2 100644 (file)
@@ -64,6 +64,7 @@ using boost::algorithm::trim;
 using dcp::raw_convert;
 
 Config* Config::_instance = 0;
+int const Config::_current_version = 3;
 boost::signals2::signal<void ()> Config::FailedToLoad;
 boost::signals2::signal<void (string)> Config::Warning;
 boost::optional<boost::filesystem::path> Config::test_path;
@@ -129,9 +130,10 @@ Config::set_defaults ()
        for (int i = 0; i < NAG_COUNT; ++i) {
                _nagged[i] = false;
        }
-       _sound = false;
+       _sound = true;
        _sound_output = optional<string> ();
        _last_kdm_write_type = KDM_WRITE_FLAT;
+       _last_dkdm_write_type = DKDM_WRITE_INTERNAL;
 
        /* 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
@@ -143,6 +145,7 @@ Config::set_defaults ()
           use about 240Mb with 72 encoding threads.
        */
        _frames_in_memory_multiplier = 3;
+       _decode_reduction = optional<int>();
 
        _allowed_dcp_frame_rates.clear ();
        _allowed_dcp_frame_rates.push_back (24);
@@ -178,6 +181,21 @@ Config::create_certificate_chain ()
                );
 }
 
+void
+Config::backup ()
+{
+       /* Make a copy of the configuration */
+       try {
+               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 (...) {}
+}
+
 void
 Config::read ()
 try
@@ -186,6 +204,10 @@ try
        f.read_file (config_file ());
 
        optional<int> version = f.optional_number_child<int> ("Version");
+       if (version && *version < _current_version) {
+               /* Back up the old config before we re-write it in a back-incompatible way */
+               backup ();
+       }
 
        if (f.optional_number_child<int>("NumLocalEncodingThreads")) {
                _master_encoding_threads = _server_encoding_threads = f.optional_number_child<int>("NumLocalEncodingThreads").get();
@@ -251,11 +273,7 @@ try
                _default_scale_to = Ratio::from_id (c.get ());
        }
 
-       c = f.optional_string_child ("DefaultDCPContentType");
-       if (c) {
-               _default_dcp_content_type = DCPContentType::from_isdcf_name (c.get ());
-       }
-
+       _default_dcp_content_type = DCPContentType::from_isdcf_name(f.optional_string_child("DefaultDCPContentType").get_value_or("FTR"));
        _default_dcp_audio_channels = f.optional_number_child<int>("DefaultDCPAudioChannels").get_value_or (6);
 
        if (f.optional_string_child ("DCPMetadataIssuer")) {
@@ -368,7 +386,7 @@ try
                }
        }
        /* The variable was renamed but not the XML tag */
-       _sound = f.optional_bool_child("PreviewSound").get_value_or (false);
+       _sound = f.optional_bool_child("PreviewSound").get_value_or (true);
        _sound_output = f.optional_string_child("PreviewSoundOutput");
        if (f.optional_string_child("CoverSheet")) {
                _cover_sheet = f.optional_string_child("CoverSheet").get();
@@ -383,7 +401,15 @@ try
                        _last_kdm_write_type = KDM_WRITE_ZIP;
                }
        }
+       if (f.optional_string_child("LastDKDMWriteType")) {
+               if (f.optional_string_child("LastDKDMWriteType").get() == "internal") {
+                       _last_dkdm_write_type = DKDM_WRITE_INTERNAL;
+               } else if (f.optional_string_child("LastDKDMWriteType").get() == "file") {
+                       _last_dkdm_write_type = DKDM_WRITE_FILE;
+               }
+       }
        _frames_in_memory_multiplier = f.optional_number_child<int>("FramesInMemoryMultiplier").get_value_or(3);
+       _decode_reduction = f.optional_number_child<int>("DecodeReduction");
 
        /* Replace any cinemas from config.xml with those from the configured file */
        if (boost::filesystem::exists (_cinemas_file)) {
@@ -394,18 +420,7 @@ try
 }
 catch (...) {
        if (have_existing ("config.xml")) {
-
-               /* Make a copy of the configuration */
-               try {
-                       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 (...) {}
-
+               backup ();
                /* We have a config file but it didn't load */
                FailedToLoad ();
        }
@@ -470,8 +485,8 @@ Config::write_config () const
        xmlpp::Document doc;
        xmlpp::Element* root = doc.create_root_node ("Config");
 
-       /* [XML] Version The version number of the configuration file format; currently 2. */
-       root->add_child("Version")->add_child_text ("2");
+       /* [XML] Version The version number of the configuration file format */
+       root->add_child("Version")->add_child_text (String::compose ("%1", _current_version));
        /* [XML] MasterEncodingThreads Number of encoding threads to use when running as master. */
        root->add_child("MasterEncodingThreads")->add_child_text (raw_convert<string> (_master_encoding_threads));
        /* [XML] ServerEncodingThreads Number of encoding threads to use when running as server. */
@@ -691,11 +706,26 @@ Config::write_config () const
                        break;
                }
        }
+       if (_last_dkdm_write_type) {
+               switch (_last_dkdm_write_type.get()) {
+               case DKDM_WRITE_INTERNAL:
+                       root->add_child("LastDKDMWriteType")->add_child_text("internal");
+                       break;
+               case DKDM_WRITE_FILE:
+                       root->add_child("LastDKDMWriteType")->add_child_text("file");
+                       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));
 
+       /* [XML] DecodeReduction power of 2 to reduce DCP images by before decoding in the player */
+       if (_decode_reduction) {
+               root->add_child("DecodeReduction")->add_child_text(raw_convert<string>(_decode_reduction.get()));
+       }
+
        try {
                doc.write_to_file_formatted(config_file().string());
        } catch (xmlpp::exception& e) {