00001 #include "asset.h"
00002 #include "assets.h"
00003 #include "clip.h"
00004 #include "bchash.h"
00005 #include "dvbtune.h"
00006 #include "edl.h"
00007 #include "filesystem.h"
00008 #include "filexml.h"
00009 #include "language.h"
00010 #include "mutex.h"
00011 #include "mwindow.h"
00012 #include "pluginserver.h"
00013 #include "preferences.h"
00014 #include "renderfarm.h"
00015 #include "renderfarmclient.h"
00016
00017 #include "sighandler.h"
00018
00019 #include <arpa/inet.h>
00020 #include <errno.h>
00021 #include <fcntl.h>
00022 #include <netdb.h>
00023 #include <netinet/in.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <sys/socket.h>
00027 #include <sys/types.h>
00028 #include <sys/un.h>
00029 #include <sys/wait.h>
00030 #include <unistd.h>
00031
00032
00033
00034
00035
00036
00037 RenderFarmClient::RenderFarmClient(int port,
00038 char *deamon_path,
00039 int nice_value,
00040 char *config_path)
00041 {
00042 this->port = port;
00043 this->deamon_path = deamon_path;
00044 SigHandler *signals = new SigHandler;
00045 signals->initialize();
00046
00047 this_pid = getpid();
00048 nice(nice_value);
00049
00050
00051 MWindow::init_defaults(boot_defaults, config_path);
00052 boot_preferences = new Preferences;
00053 boot_preferences->load_defaults(boot_defaults);
00054 MWindow::init_plugins(boot_preferences, plugindb, 0);
00055 }
00056
00057
00058
00059
00060 RenderFarmClient::~RenderFarmClient()
00061 {
00062
00063 delete boot_defaults;
00064 delete boot_preferences;
00065 plugindb->remove_all_objects();
00066 delete plugindb;
00067 }
00068
00069
00070 void RenderFarmClient::main_loop()
00071 {
00072 int socket_fd;
00073
00074
00075
00076
00077
00078 if(!deamon_path)
00079 {
00080 struct sockaddr_in addr;
00081
00082 addr.sin_family = AF_INET;
00083 addr.sin_port = htons((unsigned short)port);
00084 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00085
00086 if((socket_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
00087 {
00088 perror(_("RenderFarmClient::main_loop: socket"));
00089 return;
00090 }
00091
00092 if(bind(socket_fd,
00093 (struct sockaddr*)&addr,
00094 sizeof(addr)) < 0)
00095 {
00096 fprintf(stderr,
00097 _("RenderFarmClient::main_loop: bind port %d: %s"),
00098 port,
00099 strerror(errno));
00100 return;
00101 }
00102 }
00103 else
00104 {
00105 struct sockaddr_un addr;
00106 addr.sun_family = AF_FILE;
00107 strcpy(addr.sun_path, deamon_path);
00108 int size = (offsetof(struct sockaddr_un, sun_path) +
00109 strlen(deamon_path) + 1);
00110
00111 if((socket_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
00112 {
00113 perror(_("RenderFarmClient::main_loop: socket"));
00114 return;
00115 }
00116
00117 if(bind(socket_fd,
00118 (struct sockaddr*)&addr,
00119 size) < 0)
00120 {
00121 fprintf(stderr,
00122 _("RenderFarmClient::main_loop: bind path %s: %s\n"),
00123 deamon_path,
00124 strerror(errno));
00125 return;
00126 }
00127 }
00128
00129
00130 printf("RenderFarmClient::main_loop: client started\n");
00131 while(1)
00132 {
00133 if(listen(socket_fd, 256) < 0)
00134 {
00135 perror(_("RenderFarmClient::main_loop: listen"));
00136 return;
00137 }
00138
00139 int new_socket_fd;
00140
00141
00142
00143 if(!deamon_path)
00144 {
00145 struct sockaddr_in clientname;
00146 socklen_t size = sizeof(clientname);
00147 if((new_socket_fd = accept(socket_fd,
00148 (struct sockaddr*)&clientname,
00149 &size)) < 0)
00150 {
00151 perror(_("RenderFarmClient::main_loop: accept"));
00152 return;
00153 }
00154 else
00155 {
00156
00157 RenderFarmClientThread *thread =
00158 new RenderFarmClientThread(this);
00159 thread->main_loop(new_socket_fd);
00160 }
00161 }
00162 else
00163 {
00164 struct sockaddr_un clientname;
00165 socklen_t size = sizeof(clientname);
00166 if((new_socket_fd = accept(socket_fd,
00167 (struct sockaddr*)&clientname,
00168 &size)) < 0)
00169 {
00170 perror(_("RenderFarmClient::main_loop: accept"));
00171 return;
00172 }
00173 else
00174 {
00175
00176 RenderFarmClientThread *thread =
00177 new RenderFarmClientThread(this);
00178 thread->main_loop(new_socket_fd);
00179 }
00180 }
00181 }
00182 }
00183
00184 void RenderFarmClient::kill_client()
00185 {
00186 printf("RenderFarmClient::kill_client 1\n");
00187 if(deamon_path)
00188 {
00189 printf("RenderFarmClient::kill_client 2\n");
00190 remove(deamon_path);
00191 kill(this_pid, SIGKILL);
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 RenderFarmClientThread::RenderFarmClientThread(RenderFarmClient *client)
00210 : Thread(0, 0, 1)
00211 {
00212 this->client = client;
00213 frames_per_second = 0;
00214 Thread::set_synchronous(0);
00215
00216 mutex_lock = new Mutex("RenderFarmClientThread::mutex_lock");
00217 watchdog = 0;
00218 keep_alive = 0;
00219 }
00220
00221 RenderFarmClientThread::~RenderFarmClientThread()
00222 {
00223
00224 delete mutex_lock;
00225 delete watchdog;
00226 delete keep_alive;
00227 }
00228
00229
00230 int RenderFarmClientThread::send_request_header(int request,
00231 int len)
00232 {
00233 unsigned char datagram[5];
00234 datagram[0] = request;
00235
00236 int i = 1;
00237 STORE_INT32(len);
00238
00239
00240
00241 return (write_socket((char*)datagram, 5) != 5);
00242 }
00243
00244 int RenderFarmClientThread::write_socket(char *data, int len)
00245 {
00246 return write(socket_fd, data, len);
00247 }
00248
00249 int RenderFarmClientThread::read_socket(char *data, int len)
00250 {
00251 int bytes_read = 0;
00252 int offset = 0;
00253 watchdog->begin_request();
00254 while(len > 0 && bytes_read >= 0)
00255 {
00256 bytes_read = read(socket_fd, data + offset, len);
00257 if(bytes_read > 0)
00258 {
00259 len -= bytes_read;
00260 offset += bytes_read;
00261 }
00262 else
00263 if(bytes_read < 0)
00264 {
00265 break;
00266 }
00267 }
00268 watchdog->end_request();
00269
00270 return offset;
00271 }
00272
00273 int RenderFarmClientThread::write_int64(int64_t value)
00274 {
00275 unsigned char data[sizeof(int64_t)];
00276 data[0] = (value >> 56) & 0xff;
00277 data[1] = (value >> 48) & 0xff;
00278 data[2] = (value >> 40) & 0xff;
00279 data[3] = (value >> 32) & 0xff;
00280 data[4] = (value >> 24) & 0xff;
00281 data[5] = (value >> 16) & 0xff;
00282 data[6] = (value >> 8) & 0xff;
00283 data[7] = value & 0xff;
00284 return (write_socket((char*)data, sizeof(int64_t)) != sizeof(int64_t));
00285 }
00286
00287 int64_t RenderFarmClientThread::read_int64(int *error)
00288 {
00289 int temp = 0;
00290 if(!error) error = &temp;
00291
00292 unsigned char data[sizeof(int64_t)];
00293 *error = (read_socket((char*)data, sizeof(int64_t)) != sizeof(int64_t));
00294
00295
00296
00297 int64_t result = 1;
00298 if(!*error)
00299 {
00300 result = (((int64_t)data[0]) << 56) |
00301 (((uint64_t)data[1]) << 48) |
00302 (((uint64_t)data[2]) << 40) |
00303 (((uint64_t)data[3]) << 32) |
00304 (((uint64_t)data[4]) << 24) |
00305 (((uint64_t)data[5]) << 16) |
00306 (((uint64_t)data[6]) << 8) |
00307 data[7];
00308 }
00309 return result;
00310 }
00311
00312 void RenderFarmClientThread::read_string(char* &string)
00313 {
00314 unsigned char header[4];
00315 if(read_socket((char*)header, 4) != 4)
00316 {
00317 string = 0;
00318 return;
00319 }
00320
00321 int64_t len = (((u_int32_t)header[0]) << 24) |
00322 (((u_int32_t)header[1]) << 16) |
00323 (((u_int32_t)header[2]) << 8) |
00324 ((u_int32_t)header[3]);
00325
00326 if(len)
00327 {
00328 string = new char[len];
00329 if(read_socket(string, len) != len)
00330 {
00331 delete [] string;
00332 string = 0;
00333 }
00334 }
00335 else
00336 string = 0;
00337
00338 }
00339
00340 void RenderFarmClientThread::abort()
00341 {
00342 send_completion(socket_fd);
00343 close(socket_fd);
00344 exit(1);
00345 }
00346
00347 void RenderFarmClientThread::lock(char *location)
00348 {
00349 mutex_lock->lock(location);
00350 }
00351
00352 void RenderFarmClientThread::unlock()
00353 {
00354 mutex_lock->unlock();
00355 }
00356
00357 void RenderFarmClientThread::get_command(int socket_fd, int *command)
00358 {
00359 unsigned char data[4];
00360 int error;
00361 *command = read_int64(&error);
00362 if(error)
00363 {
00364 *command = 0;
00365 return;
00366 }
00367 }
00368
00369
00370 void RenderFarmClientThread::read_preferences(int socket_fd,
00371 Preferences *preferences)
00372 {
00373 lock("RenderFarmClientThread::read_preferences");
00374 send_request_header(RENDERFARM_PREFERENCES,
00375 0);
00376
00377 char *string;
00378 read_string(string);
00379
00380 BC_Hash defaults;
00381 defaults.load_string((char*)string);
00382 preferences->load_defaults(&defaults);
00383
00384 delete [] string;
00385 unlock();
00386 }
00387
00388
00389
00390 void RenderFarmClientThread::read_asset(int socket_fd, Asset *asset)
00391 {
00392 lock("RenderFarmClientThread::read_asset");
00393 send_request_header(RENDERFARM_ASSET,
00394 0);
00395
00396 char *string1;
00397 char *string2;
00398 read_string(string1);
00399 read_string(string2);
00400
00401
00402
00403 FileXML file;
00404 file.read_from_string((char*)string2);
00405 asset->read(&file);
00406
00407
00408
00409 BC_Hash defaults;
00410 defaults.load_string((char*)string1);
00411 asset->load_defaults(&defaults,
00412 0,
00413 1,
00414 1,
00415 1,
00416 1,
00417 1);
00418
00419 delete [] string1;
00420 delete [] string2;
00421 unlock();
00422 }
00423
00424 void RenderFarmClientThread::read_edl(int socket_fd,
00425 EDL *edl,
00426 Preferences *preferences)
00427 {
00428 lock("RenderFarmClientThread::read_edl");
00429 send_request_header(RENDERFARM_EDL,
00430 0);
00431
00432 char *string;
00433 read_string(string);
00434
00435
00436 FileXML file;
00437 file.read_from_string((char*)string);
00438 delete [] string;
00439
00440
00441
00442
00443
00444
00445
00446
00447 edl->load_xml(client->plugindb,
00448 &file,
00449 LOAD_ALL);
00450
00451
00452 unlock();
00453 }
00454
00455 int RenderFarmClientThread::read_package(int socket_fd, RenderPackage *package)
00456 {
00457 lock("RenderFarmClientThread::read_package");
00458 send_request_header(RENDERFARM_PACKAGE,
00459 4);
00460
00461 unsigned char datagram[5];
00462 int i = 0;
00463
00464
00465
00466 int64_t fixed = !EQUIV(frames_per_second, 0.0) ?
00467 (int64_t)(frames_per_second * 65536.0) : 0;
00468 STORE_INT32(fixed);
00469 write_socket((char*)datagram, 4);
00470
00471
00472
00473 char *data;
00474 unsigned char *data_ptr;
00475 read_string(data);
00476
00477
00478 if(!data)
00479 {
00480
00481 unlock();
00482 return 1;
00483 }
00484
00485
00486
00487
00488 data_ptr = (unsigned char*)data;
00489 strcpy(package->path, data);
00490 data_ptr += strlen(package->path);
00491 data_ptr++;
00492 package->audio_start = READ_INT32(data_ptr);
00493 data_ptr += 4;
00494 package->audio_end = READ_INT32(data_ptr);
00495 data_ptr += 4;
00496 package->video_start = READ_INT32(data_ptr);
00497 data_ptr += 4;
00498 package->video_end = READ_INT32(data_ptr);
00499 data_ptr += 4;
00500 package->use_brender = READ_INT32(data_ptr);
00501 data_ptr += 4;
00502 package->audio_do = READ_INT32(data_ptr);
00503 data_ptr += 4;
00504 package->video_do = READ_INT32(data_ptr);
00505
00506 delete [] data;
00507 unlock();
00508
00509 return 0;
00510 }
00511
00512 int RenderFarmClientThread::send_completion(int socket_fd)
00513 {
00514 lock("RenderFarmClientThread::send_completion");
00515 int result = send_request_header(RENDERFARM_DONE, 0);
00516 unlock();
00517 return result;
00518 }
00519
00520
00521 void RenderFarmClientThread::ping_server()
00522 {
00523 lock("RenderFarmClientThread::ping_server");
00524 send_request_header(RENDERFARM_KEEPALIVE, 0);
00525 unlock();
00526 }
00527
00528
00529
00530 void RenderFarmClientThread::main_loop(int socket_fd)
00531 {
00532 this->socket_fd = socket_fd;
00533
00534 Thread::start();
00535 }
00536
00537 void RenderFarmClientThread::run()
00538 {
00539
00540 pid = fork();
00541 if(pid != 0)
00542 {
00543 int return_value;
00544 waitpid(pid, &return_value, 0);
00545 return;
00546 }
00547
00548
00549 pid = getpid();
00550
00551
00552
00553 int socket_fd = this->socket_fd;
00554
00555 init_client_keepalive();
00556
00557
00558 int command;
00559 SET_TRACE
00560 lock("RenderFarmClientThread::run");
00561 SET_TRACE
00562 get_command(socket_fd, &command);
00563 SET_TRACE
00564 unlock();
00565
00566
00567
00568 SET_TRACE
00569 switch(command)
00570 {
00571 case RENDERFARM_TUNER:
00572 do_tuner(socket_fd);
00573 break;
00574 case RENDERFARM_PACKAGES:
00575 do_packages(socket_fd);
00576 break;
00577 }
00578
00579 _exit(0);
00580 }
00581
00582
00583 void RenderFarmClientThread::init_client_keepalive()
00584 {
00585 keep_alive = new RenderFarmKeepalive(this);
00586 keep_alive->start();
00587 watchdog = new RenderFarmWatchdog(0, this);
00588 watchdog->start();
00589 }
00590
00591
00592
00593 void RenderFarmClientThread::do_tuner(int socket_fd)
00594 {
00595
00596 DVBTune server(this);
00597 server.main_loop();
00598 ::close(socket_fd);
00599 }
00600
00601
00602 void RenderFarmClientThread::do_packages(int socket_fd)
00603 {
00604
00605 EDL *edl;
00606 RenderPackage *package;
00607 Asset *default_asset;
00608 Preferences *preferences;
00609
00610
00611
00612 FarmPackageRenderer package_renderer(this, socket_fd);
00613 int result = 0;
00614
00615
00616
00617
00618
00619 preferences = new Preferences;
00620 default_asset = new Asset;
00621 package = new RenderPackage;
00622 edl = new EDL;
00623 edl->create_objects();
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 read_preferences(socket_fd, preferences);
00634
00635 read_asset(socket_fd, default_asset);
00636
00637 read_edl(socket_fd, edl, preferences);
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 package_renderer.initialize(0,
00649 edl,
00650 preferences,
00651 default_asset,
00652 client->plugindb);
00653
00654
00655
00656 while(1)
00657 {
00658 result = read_package(socket_fd, package);
00659
00660
00661
00662
00663 if(result)
00664 {
00665
00666
00667 result = send_completion(socket_fd);
00668 break;
00669 }
00670
00671 Timer timer;
00672 timer.update();
00673
00674
00675 if(package_renderer.render_package(package))
00676 {
00677
00678 result = send_completion(socket_fd);
00679 break;
00680 }
00681
00682 frames_per_second = (double)(package->video_end - package->video_start) /
00683 ((double)timer.get_difference() / 1000);
00684
00685
00686
00687
00688
00689 }
00690
00691
00692
00693 Garbage::delete_object(default_asset);
00694
00695 delete edl;
00696
00697 delete preferences;
00698 printf(_("RenderFarmClientThread::run: Session finished.\n"));
00699 }
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 RenderFarmKeepalive::RenderFarmKeepalive(
00710 RenderFarmClientThread *client_thread)
00711 : Thread(1, 0, 0)
00712 {
00713 this->client_thread = client_thread;
00714 done = 0;
00715 }
00716
00717 RenderFarmKeepalive::~RenderFarmKeepalive()
00718 {
00719 done = 1;
00720 cancel();
00721 join();
00722 }
00723
00724
00725 void RenderFarmKeepalive::run()
00726 {
00727 while(!done)
00728 {
00729 enable_cancel();
00730 sleep(5);
00731 disable_cancel();
00732 if(!done)
00733 {
00734
00735 client_thread->ping_server();
00736 }
00737 }
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 FarmPackageRenderer::FarmPackageRenderer(RenderFarmClientThread *thread,
00755 int socket_fd)
00756 : PackageRenderer()
00757 {
00758 this->thread = thread;
00759 this->socket_fd = socket_fd;
00760 }
00761
00762
00763
00764 FarmPackageRenderer::~FarmPackageRenderer()
00765 {
00766 }
00767
00768
00769 int FarmPackageRenderer::get_result()
00770 {
00771 thread->lock("FarmPackageRenderer::get_result");
00772 thread->send_request_header(RENDERFARM_GET_RESULT,
00773 0);
00774 unsigned char data[1];
00775 data[0] = 1;
00776 if(thread->read_socket((char*)data, 1) != 1)
00777 {
00778 thread->unlock();
00779 return 1;
00780 }
00781 thread->unlock();
00782 return data[0];
00783 }
00784
00785 void FarmPackageRenderer::set_result(int value)
00786 {
00787 thread->lock("FarmPackageRenderer::set_result");
00788 thread->send_request_header(RENDERFARM_SET_RESULT,
00789 1);
00790 unsigned char data[1];
00791 data[0] = value;
00792 thread->write_socket((char*)data, 1);
00793 thread->unlock();
00794 }
00795
00796 void FarmPackageRenderer::set_progress(int64_t total_samples)
00797 {
00798 thread->lock("FarmPackageRenderer::set_progress");
00799 thread->send_request_header(RENDERFARM_PROGRESS,
00800 4);
00801 unsigned char datagram[4];
00802 int i = 0;
00803 STORE_INT32(total_samples);
00804 thread->write_socket((char*)datagram, 4);
00805 thread->unlock();
00806 }
00807
00808 int FarmPackageRenderer::set_video_map(int64_t position, int value)
00809 {
00810 int result = 0;
00811 unsigned char datagram[8];
00812 char return_value[1];
00813 int i = 0;
00814
00815 thread->lock("FarmPackageRenderer::set_video_map");
00816 thread->send_request_header(RENDERFARM_SET_VMAP,
00817 8);
00818 STORE_INT32(position);
00819 STORE_INT32(value);
00820 thread->write_socket((char*)datagram, 8);
00821
00822
00823 if(!thread->read_socket(return_value, 1))
00824 {
00825 result = 1;
00826 }
00827
00828 thread->unlock();
00829 return result;
00830 }
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840