00001 #include "asset.h"
00002 #include "audioconfig.h"
00003 #include "audiodevice.inc"
00004 #include "bcmeter.inc"
00005 #include "cache.inc"
00006 #include "clip.h"
00007 #include "bchash.h"
00008 #include "file.inc"
00009 #include "filesystem.h"
00010 #include "guicast.h"
00011 #include "mutex.h"
00012 #include "preferences.h"
00013 #include "theme.h"
00014 #include "videoconfig.h"
00015 #include "videodevice.inc"
00016 #include <string.h>
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 Preferences::Preferences()
00032 {
00033
00034 FileSystem fs;
00035
00036 preferences_lock = new Mutex("Preferences::preferences_lock");
00037 sprintf(index_directory, BCASTDIR);
00038 if(strlen(index_directory))
00039 fs.complete_path(index_directory);
00040 cache_size = 0xa00000;
00041 index_size = 0x300000;
00042 index_count = 100;
00043 use_thumbnails = 1;
00044 theme[0] = 0;
00045 use_renderfarm = 0;
00046 force_uniprocessor = 0;
00047 renderfarm_port = DEAMON_PORT;
00048 render_preroll = 0.5;
00049 brender_preroll = 0;
00050 renderfarm_mountpoint[0] = 0;
00051 renderfarm_vfs = 0;
00052 renderfarm_job_count = 20;
00053 processors = calculate_processors(0);
00054 real_processors = calculate_processors(1);
00055
00056
00057 brender_asset = new Asset;
00058 brender_asset->audio_data = 0;
00059 brender_asset->video_data = 1;
00060 sprintf(brender_asset->path, "/tmp/brender");
00061 brender_asset->format = FILE_JPEG_LIST;
00062 brender_asset->jpeg_quality = 80;
00063
00064 use_brender = 0;
00065 brender_fragment = 1;
00066 local_rate = 0.0;
00067
00068 use_tipwindow = 1;
00069
00070 for(int i = 0; i < MAXCHANNELS; i++)
00071 {
00072 for(int j = 0; j < i + 1; j++)
00073 {
00074 int position = 180 - (360 * j / (i + 1));
00075 while(position < 0) position += 360;
00076 channel_positions[i * MAXCHANNELS + j] = position;
00077 }
00078 }
00079 }
00080
00081 Preferences::~Preferences()
00082 {
00083 Garbage::delete_object(brender_asset);
00084 delete preferences_lock;
00085 }
00086
00087 void Preferences::copy_rates_from(Preferences *preferences)
00088 {
00089 preferences_lock->lock("Preferences::copy_rates_from");
00090
00091
00092 local_rate = preferences->local_rate;
00093
00094 for(int j = 0;
00095 j < preferences->renderfarm_nodes.total;
00096 j++)
00097 {
00098 double new_rate = preferences->renderfarm_rate.values[j];
00099
00100 if(preferences->renderfarm_nodes.values[j][0] == '/')
00101 {
00102 if(!EQUIV(new_rate, 0.0))
00103 local_rate = new_rate;
00104 }
00105 else
00106
00107 if(!EQUIV(new_rate, 0.0))
00108 {
00109 for(int i = 0; i < renderfarm_nodes.total; i++)
00110 {
00111 if(!strcmp(preferences->renderfarm_nodes.values[j], renderfarm_nodes.values[i]) &&
00112 preferences->renderfarm_ports.values[j] == renderfarm_ports.values[i])
00113 {
00114 renderfarm_rate.values[i] = new_rate;
00115 break;
00116 }
00117 }
00118 }
00119 }
00120
00121
00122 preferences_lock->unlock();
00123 }
00124
00125 void Preferences::copy_from(Preferences *that)
00126 {
00127
00128 strcpy(index_directory, that->index_directory);
00129 index_size = that->index_size;
00130 index_count = that->index_count;
00131 use_thumbnails = that->use_thumbnails;
00132 strcpy(global_plugin_dir, that->global_plugin_dir);
00133 strcpy(theme, that->theme);
00134
00135 use_tipwindow = that->use_tipwindow;
00136
00137 cache_size = that->cache_size;
00138 force_uniprocessor = that->force_uniprocessor;
00139 processors = that->processors;
00140 real_processors = that->real_processors;
00141 renderfarm_nodes.remove_all_objects();
00142 renderfarm_ports.remove_all();
00143 renderfarm_enabled.remove_all();
00144 renderfarm_rate.remove_all();
00145 local_rate = that->local_rate;
00146 for(int i = 0; i < that->renderfarm_nodes.total; i++)
00147 {
00148 add_node(that->renderfarm_nodes.values[i],
00149 that->renderfarm_ports.values[i],
00150 that->renderfarm_enabled.values[i],
00151 that->renderfarm_rate.values[i]);
00152 }
00153 use_renderfarm = that->use_renderfarm;
00154 renderfarm_port = that->renderfarm_port;
00155 render_preroll = that->render_preroll;
00156 brender_preroll = that->brender_preroll;
00157 renderfarm_job_count = that->renderfarm_job_count;
00158 renderfarm_vfs = that->renderfarm_vfs;
00159 strcpy(renderfarm_mountpoint, that->renderfarm_mountpoint);
00160 renderfarm_consolidate = that->renderfarm_consolidate;
00161 use_brender = that->use_brender;
00162 brender_fragment = that->brender_fragment;
00163 *brender_asset = *that->brender_asset;
00164
00165
00166
00167 FileSystem fs;
00168 if(strlen(index_directory))
00169 {
00170 fs.complete_path(index_directory);
00171 fs.add_end_slash(index_directory);
00172 }
00173
00174 if(strlen(global_plugin_dir))
00175 {
00176 fs.complete_path(global_plugin_dir);
00177 fs.add_end_slash(global_plugin_dir);
00178 }
00179
00180 boundaries();
00181 }
00182
00183 void Preferences::boundaries()
00184 {
00185 renderfarm_job_count = MAX(renderfarm_job_count, 1);
00186 CLAMP(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
00187 }
00188
00189 Preferences& Preferences::operator=(Preferences &that)
00190 {
00191 printf("Preferences::operator=\n");
00192 copy_from(&that);
00193 return *this;
00194 }
00195
00196 void Preferences::print_channels(char *string,
00197 int *channel_positions,
00198 int channels)
00199 {
00200 char string3[BCTEXTLEN];
00201 string[0] = 0;
00202 for(int j = 0; j < channels; j++)
00203 {
00204 sprintf(string3, "%d", channel_positions[j]);
00205 strcat(string, string3);
00206 if(j < channels - 1)
00207 strcat(string, ",");
00208 }
00209 }
00210
00211 void Preferences::scan_channels(char *string,
00212 int *channel_positions,
00213 int channels)
00214 {
00215 char string2[BCTEXTLEN];
00216 int len = strlen(string);
00217 int current_channel = 0;
00218 for(int i = 0; i < len; i++)
00219 {
00220 strcpy(string2, &string[i]);
00221 for(int j = 0; j < BCTEXTLEN; j++)
00222 {
00223 if(string2[j] == ',' || string2[j] == 0)
00224 {
00225 i += j;
00226 string2[j] = 0;
00227 break;
00228 }
00229 }
00230 channel_positions[current_channel++] = atoi(string2);
00231 if(current_channel >= channels) break;
00232 }
00233 }
00234
00235 int Preferences::load_defaults(BC_Hash *defaults)
00236 {
00237 char string[BCTEXTLEN];
00238
00239 use_tipwindow = defaults->get("USE_TIPWINDOW", use_tipwindow);
00240 defaults->get("INDEX_DIRECTORY", index_directory);
00241 index_size = defaults->get("INDEX_SIZE", index_size);
00242 index_count = defaults->get("INDEX_COUNT", index_count);
00243 use_thumbnails = defaults->get("USE_THUMBNAILS", use_thumbnails);
00244
00245 sprintf(global_plugin_dir, PLUGIN_DIR);
00246
00247 if(getenv("GLOBAL_PLUGIN_DIR"))
00248 {
00249 strcpy(global_plugin_dir, getenv("GLOBAL_PLUGIN_DIR"));
00250 }
00251
00252 strcpy(theme, DEFAULT_THEME);
00253 defaults->get("THEME", theme);
00254
00255 for(int i = 0; i < MAXCHANNELS; i++)
00256 {
00257 char string2[BCTEXTLEN];
00258 sprintf(string, "CHANNEL_POSITIONS%d", i);
00259 print_channels(string2,
00260 &channel_positions[i * MAXCHANNELS],
00261 i + 1);
00262
00263 defaults->get(string, string2);
00264
00265 scan_channels(string2,
00266 &channel_positions[i * MAXCHANNELS],
00267 i + 1);
00268 }
00269
00270 brender_asset->load_defaults(defaults,
00271 "BRENDER_",
00272 1,
00273 1,
00274 1,
00275 0,
00276 0);
00277
00278
00279
00280 force_uniprocessor = defaults->get("FORCE_UNIPROCESSOR", 0);
00281 use_brender = defaults->get("USE_BRENDER", use_brender);
00282 brender_fragment = defaults->get("BRENDER_FRAGMENT", brender_fragment);
00283 cache_size = defaults->get("CACHE_SIZE", cache_size);
00284 local_rate = defaults->get("LOCAL_RATE", local_rate);
00285 use_renderfarm = defaults->get("USE_RENDERFARM", use_renderfarm);
00286 renderfarm_port = defaults->get("RENDERFARM_PORT", renderfarm_port);
00287 render_preroll = defaults->get("RENDERFARM_PREROLL", render_preroll);
00288 brender_preroll = defaults->get("BRENDER_PREROLL", brender_preroll);
00289 renderfarm_job_count = defaults->get("RENDERFARM_JOBS_COUNT", renderfarm_job_count);
00290 renderfarm_consolidate = defaults->get("RENDERFARM_CONSOLIDATE", renderfarm_consolidate);
00291
00292 defaults->get("RENDERFARM_MOUNTPOINT", renderfarm_mountpoint);
00293 int renderfarm_total = defaults->get("RENDERFARM_TOTAL", 0);
00294
00295 for(int i = 0; i < renderfarm_total; i++)
00296 {
00297 sprintf(string, "RENDERFARM_NODE%d", i);
00298 char result[BCTEXTLEN];
00299 int result_port = 0;
00300 int result_enabled = 0;
00301 float result_rate = 0.0;
00302
00303 result[0] = 0;
00304 defaults->get(string, result);
00305
00306 sprintf(string, "RENDERFARM_PORT%d", i);
00307 result_port = defaults->get(string, renderfarm_port);
00308
00309 sprintf(string, "RENDERFARM_ENABLED%d", i);
00310 result_enabled = defaults->get(string, result_enabled);
00311
00312 sprintf(string, "RENDERFARM_RATE%d", i);
00313 result_rate = defaults->get(string, result_rate);
00314
00315 if(result[0] != 0)
00316 {
00317 add_node(result, result_port, result_enabled, result_rate);
00318 }
00319 }
00320
00321 boundaries();
00322
00323 return 0;
00324 }
00325
00326 int Preferences::save_defaults(BC_Hash *defaults)
00327 {
00328 char string[BCTEXTLEN];
00329
00330
00331 defaults->update("USE_TIPWINDOW", use_tipwindow);
00332
00333 defaults->update("CACHE_SIZE", cache_size);
00334 defaults->update("INDEX_DIRECTORY", index_directory);
00335 defaults->update("INDEX_SIZE", index_size);
00336 defaults->update("INDEX_COUNT", index_count);
00337 defaults->update("USE_THUMBNAILS", use_thumbnails);
00338
00339 defaults->update("THEME", theme);
00340
00341
00342 for(int i = 0; i < MAXCHANNELS; i++)
00343 {
00344 char string2[BCTEXTLEN];
00345 sprintf(string, "CHANNEL_POSITIONS%d", i);
00346 print_channels(string2, &channel_positions[i * MAXCHANNELS], i + 1);
00347 defaults->update(string, string2);
00348 }
00349
00350 defaults->update("FORCE_UNIPROCESSOR", force_uniprocessor);
00351 brender_asset->save_defaults(defaults,
00352 "BRENDER_",
00353 1,
00354 1,
00355 1,
00356 0,
00357 0);
00358 defaults->update("USE_BRENDER", use_brender);
00359 defaults->update("BRENDER_FRAGMENT", brender_fragment);
00360 defaults->update("USE_RENDERFARM", use_renderfarm);
00361 defaults->update("LOCAL_RATE", local_rate);
00362 defaults->update("RENDERFARM_PORT", renderfarm_port);
00363 defaults->update("RENDERFARM_PREROLL", render_preroll);
00364 defaults->update("BRENDER_PREROLL", brender_preroll);
00365
00366 defaults->update("RENDERFARM_MOUNTPOINT", renderfarm_mountpoint);
00367 defaults->update("RENDERFARM_JOBS_COUNT", renderfarm_job_count);
00368 defaults->update("RENDERFARM_CONSOLIDATE", renderfarm_consolidate);
00369 defaults->update("RENDERFARM_TOTAL", (int64_t)renderfarm_nodes.total);
00370 for(int i = 0; i < renderfarm_nodes.total; i++)
00371 {
00372 sprintf(string, "RENDERFARM_NODE%d", i);
00373 defaults->update(string, renderfarm_nodes.values[i]);
00374 sprintf(string, "RENDERFARM_PORT%d", i);
00375 defaults->update(string, renderfarm_ports.values[i]);
00376 sprintf(string, "RENDERFARM_ENABLED%d", i);
00377 defaults->update(string, renderfarm_enabled.values[i]);
00378 sprintf(string, "RENDERFARM_RATE%d", i);
00379 defaults->update(string, renderfarm_rate.values[i]);
00380 }
00381 return 0;
00382 }
00383
00384
00385 void Preferences::add_node(char *text, int port, int enabled, float rate)
00386 {
00387 if(text[0] == 0) return;
00388
00389 preferences_lock->lock("Preferences::add_node");
00390 char *new_item = new char[strlen(text) + 1];
00391 strcpy(new_item, text);
00392 renderfarm_nodes.append(new_item);
00393 renderfarm_nodes.set_array_delete();
00394 renderfarm_ports.append(port);
00395 renderfarm_enabled.append(enabled);
00396 renderfarm_rate.append(rate);
00397 preferences_lock->unlock();
00398 }
00399
00400 void Preferences::delete_node(int number)
00401 {
00402 preferences_lock->lock("Preferences::delete_node");
00403 if(number < renderfarm_nodes.total)
00404 {
00405 delete [] renderfarm_nodes.values[number];
00406 renderfarm_nodes.remove_number(number);
00407 renderfarm_ports.remove_number(number);
00408 renderfarm_enabled.remove_number(number);
00409 renderfarm_rate.remove_number(number);
00410 }
00411 preferences_lock->unlock();
00412 }
00413
00414 void Preferences::delete_nodes()
00415 {
00416 preferences_lock->lock("Preferences::delete_nodes");
00417 for(int i = 0; i < renderfarm_nodes.total; i++)
00418 delete [] renderfarm_nodes.values[i];
00419 renderfarm_nodes.remove_all();
00420 renderfarm_ports.remove_all();
00421 renderfarm_enabled.remove_all();
00422 renderfarm_rate.remove_all();
00423 preferences_lock->unlock();
00424 }
00425
00426 void Preferences::reset_rates()
00427 {
00428 for(int i = 0; i < renderfarm_nodes.total; i++)
00429 {
00430 renderfarm_rate.values[i] = 0.0;
00431 }
00432 local_rate = 0.0;
00433 }
00434
00435 void Preferences::set_rate(float rate, int node)
00436 {
00437
00438 if(node < 0)
00439 {
00440 local_rate = rate;
00441 }
00442 else
00443 {
00444 int total = 0;
00445 for(int i = 0; i < renderfarm_nodes.total; i++)
00446 {
00447 if(renderfarm_enabled.values[i]) total++;
00448 if(total == node + 1)
00449 {
00450 renderfarm_rate.values[i] = rate;
00451 return;
00452 }
00453 }
00454 }
00455 }
00456
00457 float Preferences::get_avg_rate(int use_master_node)
00458 {
00459 preferences_lock->lock("Preferences::get_avg_rate");
00460 float total = 0.0;
00461 if(renderfarm_rate.total)
00462 {
00463 int enabled = 0;
00464 if(use_master_node)
00465 {
00466 if(EQUIV(local_rate, 0.0))
00467 {
00468 preferences_lock->unlock();
00469 return 0.0;
00470 }
00471 else
00472 {
00473 enabled++;
00474 total += local_rate;
00475 }
00476 }
00477
00478 for(int i = 0; i < renderfarm_rate.total; i++)
00479 {
00480 if(renderfarm_enabled.values[i])
00481 {
00482 enabled++;
00483 total += renderfarm_rate.values[i];
00484 if(EQUIV(renderfarm_rate.values[i], 0.0))
00485 {
00486 preferences_lock->unlock();
00487 return 0.0;
00488 }
00489 }
00490 }
00491
00492 if(enabled)
00493 total /= enabled;
00494 else
00495 total = 0.0;
00496 }
00497 preferences_lock->unlock();
00498
00499 return total;
00500 }
00501
00502 void Preferences::sort_nodes()
00503 {
00504 int done = 0;
00505
00506 while(!done)
00507 {
00508 done = 1;
00509 for(int i = 0; i < renderfarm_nodes.total - 1; i++)
00510 {
00511 if(strcmp(renderfarm_nodes.values[i], renderfarm_nodes.values[i + 1]) > 0)
00512 {
00513 char *temp = renderfarm_nodes.values[i];
00514 int temp_port = renderfarm_ports.values[i];
00515
00516 renderfarm_nodes.values[i] = renderfarm_nodes.values[i + 1];
00517 renderfarm_nodes.values[i + 1] = temp;
00518
00519 renderfarm_ports.values[i] = renderfarm_ports.values[i + 1];
00520 renderfarm_ports.values[i + 1] = temp_port;
00521
00522 renderfarm_enabled.values[i] = renderfarm_enabled.values[i + 1];
00523 renderfarm_enabled.values[i + 1] = temp_port;
00524
00525 renderfarm_rate.values[i] = renderfarm_rate.values[i + 1];
00526 renderfarm_rate.values[i + 1] = temp_port;
00527 done = 0;
00528 }
00529 }
00530 }
00531 }
00532
00533 void Preferences::edit_node(int number,
00534 char *new_text,
00535 int new_port,
00536 int new_enabled)
00537 {
00538 char *new_item = new char[strlen(new_text) + 1];
00539 strcpy(new_item, new_text);
00540
00541 delete [] renderfarm_nodes.values[number];
00542 renderfarm_nodes.values[number] = new_item;
00543 renderfarm_ports.values[number] = new_port;
00544 renderfarm_enabled.values[number] = new_enabled;
00545 }
00546
00547 int Preferences::get_enabled_nodes()
00548 {
00549 int result = 0;
00550 for(int i = 0; i < renderfarm_enabled.total; i++)
00551 if(renderfarm_enabled.values[i]) result++;
00552 return result;
00553 }
00554
00555 char* Preferences::get_node_hostname(int number)
00556 {
00557 int total = 0;
00558 for(int i = 0; i < renderfarm_nodes.total; i++)
00559 {
00560 if(renderfarm_enabled.values[i])
00561 {
00562 if(total == number)
00563 return renderfarm_nodes.values[i];
00564 else
00565 total++;
00566 }
00567 }
00568 return "";
00569 }
00570
00571 int Preferences::get_node_port(int number)
00572 {
00573 int total = 0;
00574 for(int i = 0; i < renderfarm_ports.total; i++)
00575 {
00576 if(renderfarm_enabled.values[i])
00577 {
00578 if(total == number)
00579 return renderfarm_ports.values[i];
00580 else
00581 total++;
00582 }
00583 }
00584 return -1;
00585 }
00586
00587
00588 int Preferences::calculate_processors(int interactive)
00589 {
00590
00591 int result = 1;
00592 FILE *proc;
00593
00594 if(force_uniprocessor && !interactive) return 1;
00595
00596 if(proc = fopen("/proc/cpuinfo", "r"))
00597 {
00598 char string[BCTEXTLEN];
00599 while(!feof(proc))
00600 {
00601 fgets(string, BCTEXTLEN, proc);
00602 if(!strncasecmp(string, "processor", 9))
00603 {
00604 char *ptr = strchr(string, ':');
00605 if(ptr)
00606 {
00607 ptr++;
00608 result = atol(ptr) + 1;
00609 }
00610 }
00611 else
00612 if(!strncasecmp(string, "cpus detected", 13))
00613 {
00614 char *ptr = strchr(string, ':');
00615 if(ptr)
00616 {
00617 ptr++;
00618 result = atol(ptr);
00619 }
00620 }
00621 }
00622 fclose(proc);
00623 }
00624
00625 return result;
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640