r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / renderfarmclient.C
blobbf986d96a8f239beb96241ee0b1c1011e1e9d759
1 #include "assets.h"
2 #include "clip.h"
3 #include "defaults.h"
4 #include "edl.h"
5 #include "filesystem.h"
6 #include "filexml.h"
7 #include "mwindow.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>
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <netdb.h>
19 #include <netinet/in.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/socket.h>
23 #include <sys/types.h>
24 #include <sys/un.h>
25 #include <sys/wait.h>
26 #include <unistd.h>
29 #include <libintl.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)
39         this->port = port;
40         this->deamon_path = deamon_path;
41         new SigHandler;
43         this_pid = getpid();
44         nice(20);
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()
59         delete thread;
60         delete boot_defaults;
61         delete boot_preferences;
62         plugindb->remove_all_objects();
63         delete plugindb;
67 void RenderFarmClient::main_loop()
69         int socket_fd;
73 // Open listening port
75         if(!deamon_path)
76         {
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)
84                 {
85                         perror(_("RenderFarmClient::main_loop: socket"));
86                         return;
87                 }
89                 if(bind(socket_fd, 
90                         (struct sockaddr*)&addr, 
91                         sizeof(addr)) < 0)
92                 {
93                         fprintf(stderr, 
94                                 _("RenderFarmClient::main_loop: bind port %d: %s"),
95                                 port,
96                                 strerror(errno));
97                         return;
98                 }
99         }
100         else
101         {
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)
109                 {
110                         perror(_("RenderFarmClient::main_loop: socket"));
111                         return;
112                 }
114                 if(bind(socket_fd, 
115                         (struct sockaddr*)&addr, 
116                         size) < 0)
117                 {
118                         fprintf(stderr, 
119                                 _("RenderFarmClient::main_loop: bind path %s: %s\n"),
120                                 deamon_path,
121                                 strerror(errno));
122                         return;
123                 }
124         }
126 // Wait for connections
127         while(1)
128         {
129                 if(listen(socket_fd, 256) < 0)
130         {
131                 perror(_("RenderFarmClient::main_loop: listen"));
132                 return;
133         }
135                 int new_socket_fd;
139                 if(!deamon_path)
140                 {
141                         struct sockaddr_in clientname;
142                         socklen_t size = sizeof(clientname);
143                 if((new_socket_fd = accept(socket_fd,
144                                 (struct sockaddr*)&clientname, 
145                                                 &size)) < 0)
146                 {
147                         perror(_("RenderFarmClient::main_loop: accept"));
148                         return;
149                 }
150                         else
151                         {
152 printf("RenderFarmClient::main_loop: Session started from %s\n", inet_ntoa(clientname.sin_addr));
153                                 thread->main_loop(new_socket_fd);
154                         }
155                 }
156                 else
157                 {
158                         struct sockaddr_un clientname;
159                         socklen_t size = sizeof(clientname);
160                 if((new_socket_fd = accept(socket_fd,
161                                 (struct sockaddr*)&clientname, 
162                                                 &size)) < 0)
163                 {
164                         perror(_("RenderFarmClient::main_loop: accept"));
165                         return;
166                 }
167                         else
168                         {
169 printf("RenderFarmClient::main_loop: Session started from %s\n", clientname.sun_path);
170                                 thread->main_loop(new_socket_fd);
171                         }
172                 }
173         }
176 void RenderFarmClient::kill_client()
178 printf("RenderFarmClient::kill_client 1\n");
179         if(deamon_path)
180         {
181 printf("RenderFarmClient::kill_client 2\n");
182                 remove(deamon_path);
183                 kill(this_pid, SIGKILL);
184         }
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)
202  : Thread()
204         this->client = client;
205         frames_per_second = 0;
206         Thread::set_synchronous(0);
207         fs_client = 0;
208         mutex_lock = new Mutex;
211 RenderFarmClientThread::~RenderFarmClientThread()
213         if(fs_client) delete fs_client;
214         delete mutex_lock;
218 int RenderFarmClientThread::send_request_header(int request, 
219         int len)
221         unsigned char datagram[5];
222         datagram[0] = request;
224         int i = 1;
225         STORE_INT32(len);
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, 
230                 5, 
231                 RENDERFARM_TIMEOUT) != 5);
234 int RenderFarmClientThread::write_socket(char *data, int len, int timeout)
236         return RenderFarmServerThread::write_socket(socket_fd, 
237                 data, 
238                 len, 
239                 timeout);
242 int RenderFarmClientThread::read_socket(char *data, int len, int timeout)
244         return RenderFarmServerThread::read_socket(socket_fd, 
245                 data, 
246                 len, 
247                 timeout);
250 void RenderFarmClientThread::lock()
252 //printf("RenderFarmClientThread::lock 1 %p %p\n", this, mutex_lock);
253         mutex_lock->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)
266         {
267                 string = 0;
268                 return;
269         }
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]);
278         if(len)
279         {
280                 string = new char[len];
281                 if(read_socket(string, len, RENDERFARM_TIMEOUT) != len)
282                 {
283                         delete [] string;
284                         string = 0;
285                 }
286         }
287         else
288                 string = 0;
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, 
299                 0);
301 //printf("RenderFarmClientThread::read_preferences 2\n");
302         char *string;
303         read_string(socket_fd, string);
304 //printf("RenderFarmClientThread::read_preferences 3\n%s\n", string);
306         Defaults defaults;
307         defaults.load_string((char*)string);
308         preferences->load_defaults(&defaults);
309 //printf("RenderFarmClientThread::read_preferences 4\n");
311         delete [] string;
316 void RenderFarmClientThread::read_asset(int socket_fd, Asset *asset)
318         send_request_header(RENDERFARM_ASSET, 
319                 0);
321         char *string;
322         read_string(socket_fd, string);
323 //printf("RenderFarmClientThread::read_asset\n%s\n", string);
325         FileXML file;
326         file.read_from_string((char*)string);
327         asset->read(client->plugindb, &file);
329         delete [] string;
332 void RenderFarmClientThread::read_edl(int socket_fd, 
333         EDL *edl, 
334         Preferences *preferences)
336         send_request_header(RENDERFARM_EDL, 
337                 0);
339         char *string;
340         read_string(socket_fd, string);
342 //printf("RenderFarmClientThread::read_edl 1\n");
344         FileXML file;
345         file.read_from_string((char*)string);
346         delete [] string;
355         edl->load_xml(client->plugindb,
356                 &file, 
357                 LOAD_ALL);
361 // Tag input paths for VFS here.
362 // Create VFS object.
363         FileSystem fs;
364         if(preferences->renderfarm_vfs)
365         {
366                 fs_client = new RenderFarmFSClient(this);
367                 fs_client->initialize();
369                 for(Asset *asset = edl->assets->first;
370                         asset;
371                         asset = asset->next)
372                 {
373                         char string2[BCTEXTLEN];
374                         strcpy(string2, asset->path);
375                         sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", string2);
376                 }
377         }
379 //      for(Asset *asset = edl->assets->first;
380 //              asset;
381 //              asset = asset->next)
382 //      {
383 //              char string2[BCTEXTLEN];
384 //              strcpy(string2, asset->path);
385 //              fs.join_names(asset->path, preferences->renderfarm_mountpoint, string2);
386 //      }
389 //edl->dump();
392 int RenderFarmClientThread::read_package(int socket_fd, RenderPackage *package)
394         send_request_header(RENDERFARM_PACKAGE, 
395                 4);
397         unsigned char datagram[5];
398         int i = 0;
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;
404         STORE_INT32(fixed);
405         write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
408         char *data;
409         unsigned char *data_ptr;
410         read_string(socket_fd, data);
412 // Signifies end of session.
413         if(!data) 
414         {
415 //              printf(_("RenderFarmClientThread::read_package no output path recieved.\n"));
416                 return 1;
417         }
421         data_ptr = (unsigned char*)data;
422         strcpy(package->path, data);
423         data_ptr += strlen(package->path);
424         data_ptr++;
425         package->audio_start = READ_INT32(data_ptr);
426         data_ptr += 4;
427         package->audio_end = READ_INT32(data_ptr);
428         data_ptr += 4;
429         package->video_start = READ_INT32(data_ptr);
430         data_ptr += 4;
431         package->video_end = READ_INT32(data_ptr);
432         data_ptr += 4;
433         package->use_brender = READ_INT32(data_ptr);
435         delete [] data;
437         return 0;
440 int RenderFarmClientThread::send_completion(int socket_fd)
442         return send_request_header(RENDERFARM_DONE, 
443                 0);
449 void RenderFarmClientThread::main_loop(int socket_fd)
451          this->socket_fd = socket_fd;
452          Thread::start();
455 void RenderFarmClientThread::run()
457 // Create new memory space
458         int pid = fork();
459         if(pid != 0)
460         {
461                 int return_value;
462                 waitpid(pid, &return_value, 0);
463                 return;
464         }
471         int socket_fd = this->socket_fd;
472 //printf("RenderFarmClientThread::run 1\n");
473         EDL *edl;
474         RenderPackage *package;
475         Asset *default_asset;
476         Preferences *preferences;
477         FarmPackageRenderer package_renderer(this, socket_fd);
478         int result = 0;
480 //printf("RenderFarmClientThread::run 2\n");
481 // Read settings
482         preferences = new Preferences;
483         default_asset = new Asset;
484         package = new RenderPackage;
485         edl = new EDL;
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);
501 //edl->dump();
509 //printf("RenderFarmClientThread::run 4\n");
511         package_renderer.initialize(0,
512                         edl, 
513                         preferences, 
514                         default_asset,
515                         client->plugindb);
516 //printf("RenderFarmClientThread::run 5\n");
518 // Read packages
519         while(1)
520         {
521                 result = read_package(socket_fd, package);
522 //printf("RenderFarmClientThread::run 6 %d\n", result);
525 // Finished list
526                 if(result)
527                 {
528 //printf("RenderFarmClientThread::run 7 %d\n", result);
530                         result = send_completion(socket_fd);
531                         break;
532                 }
534                 Timer timer;
535                 timer.update();
537 // Error
538                 if(package_renderer.render_package(package))
539                 {
540 //printf("RenderFarmClientThread::run 8\n");
541                         result = send_completion(socket_fd);
542                         break;
543                 }
545                 frames_per_second = (double)(package->video_end - package->video_start) / 
546                         ((double)timer.get_difference() / 1000);
548 //printf("RenderFarmClientThread::run 9\n");
552         }
555 //printf("RenderFarmClientThread::run 9\n");
556         delete default_asset;
557 //printf("RenderFarmClientThread::run 10\n");
558         delete edl;
559 //printf("RenderFarmClientThread::run 11\n");
560         delete preferences;
561 //printf("RenderFarmClientThread::run 12\n");
562 printf(_("RenderFarmClientThread::run: Session finished.\n"));
564 // Socket error should be the only cause of this
565         if(result)
566         {
567                 ;
568         }
570         _exit(0);
580 FarmPackageRenderer::FarmPackageRenderer(RenderFarmClientThread *thread,
581                 int socket_fd)
582  : PackageRenderer()
584         this->thread = thread;
585         this->socket_fd = socket_fd;
590 FarmPackageRenderer::~FarmPackageRenderer()
595 int FarmPackageRenderer::get_result()
597         thread->lock();
598         thread->send_request_header(RENDERFARM_GET_RESULT, 
599                 0);
600         unsigned char data[1];
601         data[0] = 1;
602         if(thread->read_socket((char*)data, 1, RENDERFARM_TIMEOUT) != 1)
603         {
604                 thread->unlock();
605                 return 1;
606         }
607         thread->unlock();
608         return data[0];
611 void FarmPackageRenderer::set_result(int value)
613         thread->lock();
614         thread->send_request_header(RENDERFARM_SET_RESULT, 
615                 1);
616         unsigned char data[1];
617         data[0] = value;
618         thread->write_socket((char*)data, 1, RENDERFARM_TIMEOUT);
619         thread->unlock();
622 void FarmPackageRenderer::set_progress(int64_t total_samples)
624         thread->lock();
625         thread->send_request_header(RENDERFARM_PROGRESS, 
626                 4);
627         unsigned char datagram[4];
628         int i = 0;
629         STORE_INT32(total_samples);
630         thread->write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
631         thread->unlock();
634 void FarmPackageRenderer::set_video_map(int64_t position, int value)
636         thread->lock();
637         thread->send_request_header(RENDERFARM_SET_VMAP, 
638                 8);
639         unsigned char datagram[8];
640         int i = 0;
641         STORE_INT32(position);
642         STORE_INT32(value);
643         thread->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT);
644         thread->unlock();