+2017-10-05 Carl Hetherington <cth@carlh.net>
+
+ * Add config option to control writer's
+ maximum_frames_in_memory.
+
2017-10-04 Carl Hetherington <cth@carlh.net>
* Updated da_DK translation from Anders Uhl Pedersen.
_sound = false;
_sound_output = optional<string> ();
+ /* 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);
_allowed_dcp_frame_rates.push_back (25);
_cover_sheet = f.optional_string_child("CoverSheet").get();
}
_last_player_load_directory = f.optional_string_child("LastPlayerLoadDirectory");
+ _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)) {
if (_last_player_load_directory) {
root->add_child("LastPlayerLoadDirectory")->add_child_text(_last_player_load_directory->string());
}
+ /* [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());
return _last_player_load_directory;
}
+ int frames_in_memory_multiplier () const {
+ return _frames_in_memory_multiplier;
+ }
+
void set_master_encoding_threads (int n) {
maybe_set (_master_encoding_threads, n);
}
maybe_set (_dcp_asset_filename_format, n);
}
+ void set_frames_in_memory_multiplier (int m) {
+ maybe_set (_frames_in_memory_multiplier, m);
+ }
+
void clear_history () {
_history.clear ();
changed ();
boost::optional<std::string> _sound_output;
std::string _cover_sheet;
boost::optional<boost::filesystem::path> _last_player_load_directory;
+ int _frames_in_memory_multiplier;
/** Singleton instance, or 0 */
static Config* _instance;
void
Writer::set_encoder_threads (int threads)
{
- /* 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.
- */
- _maximum_frames_in_memory = lrint (threads * 3);
+ _maximum_frames_in_memory = lrint (threads * Config::instance()->frames_in_memory_multiplier());
}
void
table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
table->AddSpacer (0);
+ {
+ add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
+ wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
+ _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
+ s->Add (_frames_in_memory_multiplier, 1);
+ table->Add (s, 1);
+ }
+
{
add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
dcp::NameFormat::Map titles;
_maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
_allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
_only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
+ _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
_dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
_dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
_log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
+ checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
#ifdef DCPOMATIC_WINDOWS
checked_set (_win32_console, config->win32_console());
#endif
Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
}
+ void frames_in_memory_multiplier_changed ()
+ {
+ Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
+ }
+
void allow_any_dcp_frame_rate_changed ()
{
Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
#endif
wxSpinCtrl* _maximum_j2k_bandwidth;
+ wxSpinCtrl* _frames_in_memory_multiplier;
wxCheckBox* _allow_any_dcp_frame_rate;
wxCheckBox* _only_servers_encode;
NameFormatEditor* _dcp_metadata_filename_format;