4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "audioconfig.h"
24 #include "audiodevice.inc"
25 #include "bcmeter.inc"
26 #include "bcsignals.h"
31 #include "filesystem.h"
33 #include "indexfile.h"
35 #include "preferences.h"
37 #include "videoconfig.h"
38 #include "videodevice.inc"
42 #include <sys/types.h>
46 //#define CLAMP(x, y, z) (x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x)))
53 extern void get_exe_path(char *result);
59 Preferences::Preferences()
64 preferences_lock = new Mutex("Preferences::preferences_lock");
68 get_exe_path(plugin_dir);
69 strcat(plugin_dir,"/plugins");
71 sprintf(index_directory, BCASTDIR);
72 if(strlen(index_directory))
73 fs.complete_path(index_directory);
74 cache_size = 0xa00000;
75 index_size = 0x300000;
82 force_uniprocessor = 0;
83 renderfarm_port = DEAMON_PORT;
86 renderfarm_mountpoint[0] = 0;
88 renderfarm_job_count = 20;
89 processors = calculate_processors(0);
90 real_processors = calculate_processors(1);
92 ffmpeg_early_probe = 0;
95 // Default brender asset
96 brender_asset = new Asset;
97 brender_asset->audio_data = 0;
98 brender_asset->video_data = 1;
99 sprintf(brender_asset->path, "/tmp/brender");
100 brender_asset->format = FILE_JPEG_LIST;
101 brender_asset->jpeg_quality = 80;
104 brender_fragment = 1;
108 scan_commercials = 0;
111 android_port = 23432;
112 strcpy(android_pin, "cinelerra");
114 for(int i = 0; i < MAXCHANNELS; i++)
116 for(int j = 0; j < i + 1; j++)
118 int position = 180 - (360 * j / (i + 1));
119 while(position < 0) position += 360;
120 channel_positions[i * MAXCHANNELS + j] = position;
125 Preferences::~Preferences()
127 brender_asset->Garbage::remove_user();
128 delete preferences_lock;
131 void Preferences::copy_rates_from(Preferences *preferences)
133 preferences_lock->lock("Preferences::copy_rates_from");
134 // Need to match node titles in case the order changed and in case
135 // one of the nodes in the source is the master node.
136 local_rate = preferences->local_rate;
139 j < preferences->renderfarm_nodes.total;
142 double new_rate = preferences->renderfarm_rate.values[j];
143 // Put in the master node
144 if(preferences->renderfarm_nodes.values[j][0] == '/')
146 if(!EQUIV(new_rate, 0.0))
147 local_rate = new_rate;
150 // Search for local node and copy it to that node
151 if(!EQUIV(new_rate, 0.0))
153 for(int i = 0; i < renderfarm_nodes.total; i++)
155 if(!strcmp(preferences->renderfarm_nodes.values[j], renderfarm_nodes.values[i]) &&
156 preferences->renderfarm_ports.values[j] == renderfarm_ports.values[i])
158 renderfarm_rate.values[i] = new_rate;
165 //printf("Preferences::copy_rates_from 1 %f %f\n", local_rate, preferences->local_rate);
166 preferences_lock->unlock();
169 void Preferences::copy_from(Preferences *that)
171 // ================================= Performance ================================
172 strcpy(index_directory, that->index_directory);
173 index_size = that->index_size;
174 index_count = that->index_count;
175 use_thumbnails = that->use_thumbnails;
176 strcpy(theme, that->theme);
178 use_tipwindow = that->use_tipwindow;
179 scan_commercials = that->scan_commercials;
180 android_remote = that->android_remote;
181 android_port = that->android_port;
182 strcpy(android_pin, that->android_pin);
183 cache_size = that->cache_size;
184 force_uniprocessor = that->force_uniprocessor;
185 trap_sigsegv = that->trap_sigsegv;
186 trap_sigintr = that->trap_sigintr;
187 processors = that->processors;
188 real_processors = that->real_processors;
189 file_forking = that->file_forking;
190 ffmpeg_early_probe = that->ffmpeg_early_probe;
191 warn_indecies = that->warn_indecies;
192 renderfarm_nodes.remove_all_objects();
193 renderfarm_ports.remove_all();
194 renderfarm_enabled.remove_all();
195 renderfarm_rate.remove_all();
196 local_rate = that->local_rate;
197 for(int i = 0; i < that->renderfarm_nodes.size(); i++)
199 add_node(that->renderfarm_nodes.get(i),
200 that->renderfarm_ports.get(i),
201 that->renderfarm_enabled.get(i),
202 that->renderfarm_rate.get(i));
204 use_renderfarm = that->use_renderfarm;
205 renderfarm_port = that->renderfarm_port;
206 render_preroll = that->render_preroll;
207 brender_preroll = that->brender_preroll;
208 renderfarm_job_count = that->renderfarm_job_count;
209 renderfarm_vfs = that->renderfarm_vfs;
210 strcpy(renderfarm_mountpoint, that->renderfarm_mountpoint);
211 renderfarm_consolidate = that->renderfarm_consolidate;
212 use_brender = that->use_brender;
213 brender_fragment = that->brender_fragment;
214 brender_asset->copy_from(that->brender_asset, 0);
219 if(strlen(index_directory))
221 fs.complete_path(index_directory);
222 fs.add_end_slash(index_directory);
225 // if(strlen(global_plugin_dir))
227 // fs.complete_path(global_plugin_dir);
228 // fs.add_end_slash(global_plugin_dir);
232 // Redo with the proper value of force_uniprocessor
233 processors = calculate_processors(0);
237 void Preferences::boundaries()
239 renderfarm_job_count = MAX(renderfarm_job_count, 1);
240 CLAMP(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
243 Preferences& Preferences::operator=(Preferences &that)
245 printf("Preferences::operator=\n");
250 void Preferences::print_channels(char *string,
251 int *channel_positions,
254 char string3[BCTEXTLEN];
256 for(int j = 0; j < channels; j++)
258 sprintf(string3, "%d", channel_positions[j]);
259 strcat(string, string3);
265 void Preferences::scan_channels(char *string,
266 int *channel_positions,
269 char string2[BCTEXTLEN];
270 int len = strlen(string);
271 int current_channel = 0;
272 for(int i = 0; i < len; i++)
274 strcpy(string2, &string[i]);
275 for(int j = 0; j < BCTEXTLEN; j++)
277 if(string2[j] == ',' || string2[j] == 0)
284 channel_positions[current_channel++] = atoi(string2);
285 if(current_channel >= channels) break;
289 int Preferences::load_defaults(BC_Hash *defaults)
291 char string[BCTEXTLEN];
293 use_tipwindow = defaults->get("USE_TIPWINDOW", use_tipwindow);
294 scan_commercials = defaults->get("SCAN_COMMERCIALS", scan_commercials);
295 android_remote = defaults->get("ANDROID_REMOTE", android_remote);
296 android_port = defaults->get("ANDROID_PORT", android_port);
297 defaults->get("ANDROID_PIN", android_pin);
298 defaults->get("INDEX_DIRECTORY", index_directory);
299 index_size = defaults->get("INDEX_SIZE", index_size);
300 index_count = defaults->get("INDEX_COUNT", index_count);
301 use_thumbnails = defaults->get("USE_THUMBNAILS", use_thumbnails);
302 trap_sigsegv = defaults->get("TRAP_SIGSEGV", trap_sigsegv);
303 trap_sigintr = defaults->get("TRAP_SIGINTR", trap_sigintr);
305 // sprintf(global_plugin_dir, PLUGIN_DIR);
306 // defaults->get("GLOBAL_PLUGIN_DIR", global_plugin_dir);
307 // if(getenv("GLOBAL_PLUGIN_DIR"))
309 // strcpy(global_plugin_dir, getenv("GLOBAL_PLUGIN_DIR"));
312 strcpy(theme, DEFAULT_THEME);
313 defaults->get("THEME", theme);
315 for(int i = 0; i < MAXCHANNELS; i++)
317 char string2[BCTEXTLEN];
318 sprintf(string, "CHANNEL_POSITIONS%d", i);
319 print_channels(string2,
320 &channel_positions[i * MAXCHANNELS],
323 defaults->get(string, string2);
325 scan_channels(string2,
326 &channel_positions[i * MAXCHANNELS],
330 brender_asset->load_defaults(defaults,
340 force_uniprocessor = defaults->get("FORCE_UNIPROCESSOR", 0);
341 file_forking = defaults->get("FILE_FORKING", 1);
342 ffmpeg_early_probe = defaults->get("FFMPEG_EARLY_PROBE", 0);
343 warn_indecies = defaults->get("WARN_INDECIES", 1);
344 use_brender = defaults->get("USE_BRENDER", use_brender);
345 brender_fragment = defaults->get("BRENDER_FRAGMENT", brender_fragment);
346 cache_size = defaults->get("CACHE_SIZE", cache_size);
347 local_rate = defaults->get("LOCAL_RATE", local_rate);
348 use_renderfarm = defaults->get("USE_RENDERFARM", use_renderfarm);
349 renderfarm_port = defaults->get("RENDERFARM_PORT", renderfarm_port);
350 render_preroll = defaults->get("RENDERFARM_PREROLL", render_preroll);
351 brender_preroll = defaults->get("BRENDER_PREROLL", brender_preroll);
352 renderfarm_job_count = defaults->get("RENDERFARM_JOBS_COUNT", renderfarm_job_count);
353 renderfarm_consolidate = defaults->get("RENDERFARM_CONSOLIDATE", renderfarm_consolidate);
354 // renderfarm_vfs = defaults->get("RENDERFARM_VFS", renderfarm_vfs);
355 defaults->get("RENDERFARM_MOUNTPOINT", renderfarm_mountpoint);
356 int renderfarm_total = defaults->get("RENDERFARM_TOTAL", 0);
358 for(int i = 0; i < renderfarm_total; i++)
360 sprintf(string, "RENDERFARM_NODE%d", i);
361 char result[BCTEXTLEN];
363 int result_enabled = 0;
364 float result_rate = 0.0;
367 defaults->get(string, result);
369 sprintf(string, "RENDERFARM_PORT%d", i);
370 result_port = defaults->get(string, renderfarm_port);
372 sprintf(string, "RENDERFARM_ENABLED%d", i);
373 result_enabled = defaults->get(string, result_enabled);
375 sprintf(string, "RENDERFARM_RATE%d", i);
376 result_rate = defaults->get(string, result_rate);
380 add_node(result, result_port, result_enabled, result_rate);
384 // Redo with the proper value of force_uniprocessor
385 processors = calculate_processors(0);
390 int Preferences::save_defaults(BC_Hash *defaults)
392 char string[BCTEXTLEN];
395 defaults->update("USE_TIPWINDOW", use_tipwindow);
396 defaults->update("SCAN_COMMERCIALS", scan_commercials);
397 defaults->update("ANDROID_REMOTE", android_remote);
398 defaults->update("ANDROID_PIN", android_pin);
399 defaults->update("ANDROID_PORT", android_port);
401 defaults->update("CACHE_SIZE", cache_size);
402 defaults->update("INDEX_DIRECTORY", index_directory);
403 defaults->update("INDEX_SIZE", index_size);
404 defaults->update("INDEX_COUNT", index_count);
405 defaults->update("USE_THUMBNAILS", use_thumbnails);
406 defaults->update("TRAP_SIGSEGV", trap_sigsegv);
407 defaults->update("TRAP_SIGINTR", trap_sigintr);
408 // defaults->update("GLOBAL_PLUGIN_DIR", global_plugin_dir);
409 defaults->update("THEME", theme);
412 for(int i = 0; i < MAXCHANNELS; i++)
414 char string2[BCTEXTLEN];
415 sprintf(string, "CHANNEL_POSITIONS%d", i);
416 print_channels(string2, &channel_positions[i * MAXCHANNELS], i + 1);
417 defaults->update(string, string2);
420 defaults->update("FORCE_UNIPROCESSOR", force_uniprocessor);
421 defaults->update("FILE_FORKING", file_forking);
422 defaults->update("FFMPEG_EARLY_PROBE", ffmpeg_early_probe);
423 defaults->update("WARN_INDECIES", warn_indecies);
424 brender_asset->save_defaults(defaults,
431 defaults->update("USE_BRENDER", use_brender);
432 defaults->update("BRENDER_FRAGMENT", brender_fragment);
433 defaults->update("USE_RENDERFARM", use_renderfarm);
434 defaults->update("LOCAL_RATE", local_rate);
435 defaults->update("RENDERFARM_PORT", renderfarm_port);
436 defaults->update("RENDERFARM_PREROLL", render_preroll);
437 defaults->update("BRENDER_PREROLL", brender_preroll);
438 // defaults->update("RENDERFARM_VFS", renderfarm_vfs);
439 defaults->update("RENDERFARM_MOUNTPOINT", renderfarm_mountpoint);
440 defaults->update("RENDERFARM_JOBS_COUNT", renderfarm_job_count);
441 defaults->update("RENDERFARM_CONSOLIDATE", renderfarm_consolidate);
442 defaults->update("RENDERFARM_TOTAL", (int64_t)renderfarm_nodes.total);
443 for(int i = 0; i < renderfarm_nodes.total; i++)
445 sprintf(string, "RENDERFARM_NODE%d", i);
446 defaults->update(string, renderfarm_nodes.values[i]);
447 sprintf(string, "RENDERFARM_PORT%d", i);
448 defaults->update(string, renderfarm_ports.values[i]);
449 sprintf(string, "RENDERFARM_ENABLED%d", i);
450 defaults->update(string, renderfarm_enabled.values[i]);
451 sprintf(string, "RENDERFARM_RATE%d", i);
452 defaults->update(string, renderfarm_rate.values[i]);
458 void Preferences::add_node(const char *text, int port, int enabled, float rate)
460 if(text[0] == 0) return;
462 preferences_lock->lock("Preferences::add_node");
463 char *new_item = new char[strlen(text) + 1];
464 strcpy(new_item, text);
465 renderfarm_nodes.append(new_item);
466 renderfarm_ports.append(port);
467 renderfarm_enabled.append(enabled);
468 renderfarm_rate.append(rate);
469 preferences_lock->unlock();
472 void Preferences::delete_node(int number)
474 preferences_lock->lock("Preferences::delete_node");
475 if(number < renderfarm_nodes.total && number >= 0)
477 delete [] renderfarm_nodes.values[number];
478 renderfarm_nodes.remove_number(number);
479 renderfarm_ports.remove_number(number);
480 renderfarm_enabled.remove_number(number);
481 renderfarm_rate.remove_number(number);
483 preferences_lock->unlock();
486 void Preferences::delete_nodes()
488 preferences_lock->lock("Preferences::delete_nodes");
489 for(int i = 0; i < renderfarm_nodes.total; i++)
490 delete [] renderfarm_nodes.values[i];
491 renderfarm_nodes.remove_all();
492 renderfarm_ports.remove_all();
493 renderfarm_enabled.remove_all();
494 renderfarm_rate.remove_all();
495 preferences_lock->unlock();
498 void Preferences::reset_rates()
500 for(int i = 0; i < renderfarm_nodes.total; i++)
502 renderfarm_rate.values[i] = 0.0;
507 float Preferences::get_rate(int node)
516 for(int i = 0; i < renderfarm_nodes.size(); i++)
518 if(renderfarm_enabled.get(i)) total++;
519 if(total == node + 1)
521 return renderfarm_rate.get(i);
529 void Preferences::set_rate(float rate, int node)
531 //printf("Preferences::set_rate %f %d\n", rate, node);
539 for(int i = 0; i < renderfarm_nodes.size(); i++)
541 if(renderfarm_enabled.get(i)) total++;
542 if(total == node + 1)
544 renderfarm_rate.set(i, rate);
551 float Preferences::get_avg_rate(int use_master_node)
553 preferences_lock->lock("Preferences::get_avg_rate");
555 if(renderfarm_rate.total)
560 if(EQUIV(local_rate, 0.0))
562 preferences_lock->unlock();
572 for(int i = 0; i < renderfarm_rate.total; i++)
574 if(renderfarm_enabled.values[i])
577 total += renderfarm_rate.values[i];
578 if(EQUIV(renderfarm_rate.values[i], 0.0))
580 preferences_lock->unlock();
591 preferences_lock->unlock();
596 void Preferences::sort_nodes()
603 for(int i = 0; i < renderfarm_nodes.total - 1; i++)
605 if(strcmp(renderfarm_nodes.values[i], renderfarm_nodes.values[i + 1]) > 0)
607 char *temp = renderfarm_nodes.values[i];
608 int temp_port = renderfarm_ports.values[i];
610 renderfarm_nodes.values[i] = renderfarm_nodes.values[i + 1];
611 renderfarm_nodes.values[i + 1] = temp;
613 renderfarm_ports.values[i] = renderfarm_ports.values[i + 1];
614 renderfarm_ports.values[i + 1] = temp_port;
616 renderfarm_enabled.values[i] = renderfarm_enabled.values[i + 1];
617 renderfarm_enabled.values[i + 1] = temp_port;
619 renderfarm_rate.values[i] = renderfarm_rate.values[i + 1];
620 renderfarm_rate.values[i + 1] = temp_port;
627 void Preferences::edit_node(int number,
628 const char *new_text,
632 char *new_item = new char[strlen(new_text) + 1];
633 strcpy(new_item, new_text);
635 delete [] renderfarm_nodes.values[number];
636 renderfarm_nodes.values[number] = new_item;
637 renderfarm_ports.values[number] = new_port;
638 renderfarm_enabled.values[number] = new_enabled;
641 int Preferences::get_enabled_nodes()
644 for(int i = 0; i < renderfarm_enabled.total; i++)
645 if(renderfarm_enabled.values[i]) result++;
649 const char* Preferences::get_node_hostname(int number)
652 for(int i = 0; i < renderfarm_nodes.total; i++)
654 if(renderfarm_enabled.values[i])
657 return renderfarm_nodes.values[i];
665 int Preferences::get_node_port(int number)
668 for(int i = 0; i < renderfarm_ports.total; i++)
670 if(renderfarm_enabled.values[i])
673 return renderfarm_ports.values[i];
681 int Preferences::get_asset_file_path(Asset *asset, char *path)
683 strcpy(path, asset->path);
684 int result = access(path, R_OK);
685 if( !result && asset->format == FILE_MPEG ) {
686 char source_filename[BCTEXTLEN];
687 char index_filename[BCTEXTLEN];
688 IndexFile::get_index_filename(source_filename,
689 index_directory, index_filename,
690 asset->path, ".toc");
692 if( !access(index_filename, R_OK) &&
693 !stat(index_filename,&st) && st.st_size > 0 )
694 strcpy(path, index_filename);
700 int Preferences::calculate_processors(int interactive)
702 if(force_uniprocessor && !interactive) return 1;
703 return BC_WindowBase::get_resources()->machine_cpus;