5 #include "filesystem.h"
8 #include "pluginserver.h"
9 #include "preferences.h"
10 #include "renderfarm.h"
11 #include "renderfarmclient.h"
12 #include "renderfarmfsclient.h"
13 #include "sighandler.h"
15 #include <arpa/inet.h>
19 #include <netinet/in.h>
22 #include <sys/socket.h>
23 #include <sys/types.h>
30 #define _(String) gettext(String)
31 #define gettext_noop(String) String
32 #define N_(String) gettext_noop (String)
35 // The render client waits for connections from the server.
36 // Then it starts a thread for each connection.
37 RenderFarmClient::RenderFarmClient(int port, char *deamon_path)
40 this->deamon_path = deamon_path;
46 thread = new RenderFarmClientThread(this);
48 MWindow::init_defaults(boot_defaults);
49 boot_preferences = new Preferences;
50 boot_preferences->load_defaults(boot_defaults);
51 MWindow::init_plugins(boot_preferences, plugindb, 0);
57 RenderFarmClient::~RenderFarmClient()
61 delete boot_preferences;
62 plugindb->remove_all_objects();
67 void RenderFarmClient::main_loop()
73 // Open listening port
77 struct sockaddr_in addr;
79 addr.sin_family = AF_INET;
80 addr.sin_port = htons((unsigned short)port);
81 addr.sin_addr.s_addr = htonl(INADDR_ANY);
83 if((socket_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
85 perror(_("RenderFarmClient::main_loop: socket"));
90 (struct sockaddr*)&addr,
94 _("RenderFarmClient::main_loop: bind port %d: %s"),
102 struct sockaddr_un addr;
103 addr.sun_family = AF_FILE;
104 strcpy(addr.sun_path, deamon_path);
105 int size = (offsetof(struct sockaddr_un, sun_path) +
106 strlen(deamon_path) + 1);
108 if((socket_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
110 perror(_("RenderFarmClient::main_loop: socket"));
115 (struct sockaddr*)&addr,
119 _("RenderFarmClient::main_loop: bind path %s: %s\n"),
126 // Wait for connections
129 if(listen(socket_fd, 256) < 0)
131 perror(_("RenderFarmClient::main_loop: listen"));
141 struct sockaddr_in clientname;
142 socklen_t size = sizeof(clientname);
143 if((new_socket_fd = accept(socket_fd,
144 (struct sockaddr*)&clientname,
147 perror(_("RenderFarmClient::main_loop: accept"));
152 printf("RenderFarmClient::main_loop: Session started from %s\n", inet_ntoa(clientname.sin_addr));
153 thread->main_loop(new_socket_fd);
158 struct sockaddr_un clientname;
159 socklen_t size = sizeof(clientname);
160 if((new_socket_fd = accept(socket_fd,
161 (struct sockaddr*)&clientname,
164 perror(_("RenderFarmClient::main_loop: accept"));
169 printf("RenderFarmClient::main_loop: Session started from %s\n", clientname.sun_path);
170 thread->main_loop(new_socket_fd);
176 void RenderFarmClient::kill_client()
178 printf("RenderFarmClient::kill_client 1\n");
181 printf("RenderFarmClient::kill_client 2\n");
183 kill(this_pid, SIGKILL);
197 // The thread requests jobs from the server until the job table is empty
198 // or the server reports an error. This thread must poll the server
199 // after every frame for the error status.
200 // Detaches when finished.
201 RenderFarmClientThread::RenderFarmClientThread(RenderFarmClient *client)
204 this->client = client;
205 frames_per_second = 0;
206 Thread::set_synchronous(0);
208 mutex_lock = new Mutex;
211 RenderFarmClientThread::~RenderFarmClientThread()
213 if(fs_client) delete fs_client;
218 int RenderFarmClientThread::send_request_header(int request,
221 unsigned char datagram[5];
222 datagram[0] = request;
226 //printf("RenderFarmClientThread::send_request_header %02x%02x%02x%02x%02x\n",
227 // datagram[0], datagram[1], datagram[2], datagram[3], datagram[4]);
229 return (write_socket((char*)datagram,
231 RENDERFARM_TIMEOUT) != 5);
234 int RenderFarmClientThread::write_socket(char *data, int len, int timeout)
236 return RenderFarmServerThread::write_socket(socket_fd,
242 int RenderFarmClientThread::read_socket(char *data, int len, int timeout)
244 return RenderFarmServerThread::read_socket(socket_fd,
250 void RenderFarmClientThread::lock()
252 //printf("RenderFarmClientThread::lock 1 %p %p\n", this, mutex_lock);
256 void RenderFarmClientThread::unlock()
258 //printf("RenderFarmClientThread::unlock 1\n");
259 mutex_lock->unlock();
262 void RenderFarmClientThread::read_string(int socket_fd, char* &string)
264 unsigned char header[4];
265 if(read_socket((char*)header, 4, RENDERFARM_TIMEOUT) != 4)
271 int64_t len = (((u_int32_t)header[0]) << 24) |
272 (((u_int32_t)header[1]) << 16) |
273 (((u_int32_t)header[2]) << 8) |
274 ((u_int32_t)header[3]);
275 //printf("RenderFarmClientThread::read_string %d %02x%02x%02x%02x\n",
276 // len, header[0], header[1], header[2], header[3]);
280 string = new char[len];
281 if(read_socket(string, len, RENDERFARM_TIMEOUT) != len)
290 //printf("RenderFarmClientThread::read_string \n%s\n", string);
294 void RenderFarmClientThread::read_preferences(int socket_fd,
295 Preferences *preferences)
297 //printf("RenderFarmClientThread::read_preferences 1\n");
298 send_request_header(RENDERFARM_PREFERENCES,
301 //printf("RenderFarmClientThread::read_preferences 2\n");
303 read_string(socket_fd, string);
304 //printf("RenderFarmClientThread::read_preferences 3\n%s\n", string);
307 defaults.load_string((char*)string);
308 preferences->load_defaults(&defaults);
309 //printf("RenderFarmClientThread::read_preferences 4\n");
316 void RenderFarmClientThread::read_asset(int socket_fd, Asset *asset)
318 send_request_header(RENDERFARM_ASSET,
322 read_string(socket_fd, string);
323 //printf("RenderFarmClientThread::read_asset\n%s\n", string);
326 file.read_from_string((char*)string);
327 asset->read(client->plugindb, &file);
332 void RenderFarmClientThread::read_edl(int socket_fd,
334 Preferences *preferences)
336 send_request_header(RENDERFARM_EDL,
340 read_string(socket_fd, string);
342 //printf("RenderFarmClientThread::read_edl 1\n");
345 file.read_from_string((char*)string);
355 edl->load_xml(client->plugindb,
361 // Tag input paths for VFS here.
362 // Create VFS object.
364 if(preferences->renderfarm_vfs)
366 fs_client = new RenderFarmFSClient(this);
367 fs_client->initialize();
369 for(Asset *asset = edl->assets->first;
373 char string2[BCTEXTLEN];
374 strcpy(string2, asset->path);
375 sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", string2);
379 // for(Asset *asset = edl->assets->first;
381 // asset = asset->next)
383 // char string2[BCTEXTLEN];
384 // strcpy(string2, asset->path);
385 // fs.join_names(asset->path, preferences->renderfarm_mountpoint, string2);
392 int RenderFarmClientThread::read_package(int socket_fd, RenderPackage *package)
394 send_request_header(RENDERFARM_PACKAGE,
397 unsigned char datagram[5];
401 // Fails if -ieee isn't set.
402 int64_t fixed = !EQUIV(frames_per_second, 0.0) ?
403 (int64_t)(frames_per_second * 65536.0) : 0;
405 write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
409 unsigned char *data_ptr;
410 read_string(socket_fd, data);
412 // Signifies end of session.
415 // printf(_("RenderFarmClientThread::read_package no output path recieved.\n"));
421 data_ptr = (unsigned char*)data;
422 strcpy(package->path, data);
423 data_ptr += strlen(package->path);
425 package->audio_start = READ_INT32(data_ptr);
427 package->audio_end = READ_INT32(data_ptr);
429 package->video_start = READ_INT32(data_ptr);
431 package->video_end = READ_INT32(data_ptr);
433 package->use_brender = READ_INT32(data_ptr);
440 int RenderFarmClientThread::send_completion(int socket_fd)
442 return send_request_header(RENDERFARM_DONE,
449 void RenderFarmClientThread::main_loop(int socket_fd)
451 this->socket_fd = socket_fd;
455 void RenderFarmClientThread::run()
457 // Create new memory space
462 waitpid(pid, &return_value, 0);
471 int socket_fd = this->socket_fd;
472 //printf("RenderFarmClientThread::run 1\n");
474 RenderPackage *package;
475 Asset *default_asset;
476 Preferences *preferences;
477 FarmPackageRenderer package_renderer(this, socket_fd);
480 //printf("RenderFarmClientThread::run 2\n");
482 preferences = new Preferences;
483 default_asset = new Asset;
484 package = new RenderPackage;
486 edl->create_objects();
488 //printf("RenderFarmClientThread::run 3\n");
496 read_preferences(socket_fd, preferences);
497 //printf("RenderFarmClientThread::run 3\n");
498 read_asset(socket_fd, default_asset);
499 //printf("RenderFarmClientThread::run 3\n");
500 read_edl(socket_fd, edl, preferences);
509 //printf("RenderFarmClientThread::run 4\n");
511 package_renderer.initialize(0,
516 //printf("RenderFarmClientThread::run 5\n");
521 result = read_package(socket_fd, package);
522 //printf("RenderFarmClientThread::run 6 %d\n", result);
528 //printf("RenderFarmClientThread::run 7 %d\n", result);
530 result = send_completion(socket_fd);
538 if(package_renderer.render_package(package))
540 //printf("RenderFarmClientThread::run 8\n");
541 result = send_completion(socket_fd);
545 frames_per_second = (double)(package->video_end - package->video_start) /
546 ((double)timer.get_difference() / 1000);
548 //printf("RenderFarmClientThread::run 9\n");
555 //printf("RenderFarmClientThread::run 9\n");
556 delete default_asset;
557 //printf("RenderFarmClientThread::run 10\n");
559 //printf("RenderFarmClientThread::run 11\n");
561 //printf("RenderFarmClientThread::run 12\n");
562 printf(_("RenderFarmClientThread::run: Session finished.\n"));
564 // Socket error should be the only cause of this
580 FarmPackageRenderer::FarmPackageRenderer(RenderFarmClientThread *thread,
584 this->thread = thread;
585 this->socket_fd = socket_fd;
590 FarmPackageRenderer::~FarmPackageRenderer()
595 int FarmPackageRenderer::get_result()
598 thread->send_request_header(RENDERFARM_GET_RESULT,
600 unsigned char data[1];
602 if(thread->read_socket((char*)data, 1, RENDERFARM_TIMEOUT) != 1)
611 void FarmPackageRenderer::set_result(int value)
614 thread->send_request_header(RENDERFARM_SET_RESULT,
616 unsigned char data[1];
618 thread->write_socket((char*)data, 1, RENDERFARM_TIMEOUT);
622 void FarmPackageRenderer::set_progress(int64_t total_samples)
625 thread->send_request_header(RENDERFARM_PROGRESS,
627 unsigned char datagram[4];
629 STORE_INT32(total_samples);
630 thread->write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
634 void FarmPackageRenderer::set_video_map(int64_t position, int value)
637 thread->send_request_header(RENDERFARM_SET_VMAP,
639 unsigned char datagram[8];
641 STORE_INT32(position);
643 thread->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT);