r802: Remove renderframfsclient and renderfarmfsserver .h and .C from Makefile.am...
[cinelerra_cv/mob.git] / cinelerra / renderfarmclient.C
blob980995e3c51fb049b2ec58c4d925134c947d4dd6
1 #include "asset.h"
2 #include "assets.h"
3 #include "clip.h"
4 #include "defaults.h"
5 #include "edl.h"
6 #include "filesystem.h"
7 #include "filexml.h"
8 #include "language.h"
9 #include "mwindow.h"
10 #include "pluginserver.h"
11 #include "preferences.h"
12 #include "renderfarm.h"
13 #include "renderfarmclient.h"
14 //#include "renderfarmfsclient.h"
15 #include "sighandler.h"
17 #include <arpa/inet.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <netdb.h>
21 #include <netinet/in.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <sys/socket.h>
25 #include <sys/types.h>
26 #include <sys/un.h>
27 #include <sys/wait.h>
28 #include <unistd.h>
33 // The render client waits for connections from the server.
34 // Then it starts a thread for each connection.
35 RenderFarmClient::RenderFarmClient(int port, 
36         char *deamon_path, 
37         int nice_value,
38         char *config_path)
40         this->port = port;
41         this->deamon_path = deamon_path;
42         SigHandler *signals = new SigHandler;
43         signals->initialize();
45         this_pid = getpid();
46         nice(nice_value);
48         thread = new RenderFarmClientThread(this);
50         MWindow::init_defaults(boot_defaults, config_path);
51         boot_preferences = new Preferences;
52         boot_preferences->load_defaults(boot_defaults);
53         MWindow::init_plugins(boot_preferences, plugindb, 0);
59 RenderFarmClient::~RenderFarmClient()
61         delete thread;
62         delete boot_defaults;
63         delete boot_preferences;
64         plugindb->remove_all_objects();
65         delete plugindb;
69 void RenderFarmClient::main_loop()
71         int socket_fd;
75 // Open listening port
77         if(!deamon_path)
78         {
79                 struct sockaddr_in addr;
81                 addr.sin_family = AF_INET;
82                 addr.sin_port = htons((unsigned short)port);
83                 addr.sin_addr.s_addr = htonl(INADDR_ANY);
85                 if((socket_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
86                 {
87                         perror(_("RenderFarmClient::main_loop: socket"));
88                         return;
89                 }
91                 if(bind(socket_fd, 
92                         (struct sockaddr*)&addr, 
93                         sizeof(addr)) < 0)
94                 {
95                         fprintf(stderr, 
96                                 _("RenderFarmClient::main_loop: bind port %d: %s"),
97                                 port,
98                                 strerror(errno));
99                         return;
100                 }
101         }
102         else
103         {
104                 struct sockaddr_un addr;
105                 addr.sun_family = AF_FILE;
106                 strcpy(addr.sun_path, deamon_path);
107                 int size = (offsetof(struct sockaddr_un, sun_path) + 
108                         strlen(deamon_path) + 1);
110                 if((socket_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
111                 {
112                         perror(_("RenderFarmClient::main_loop: socket"));
113                         return;
114                 }
116                 if(bind(socket_fd, 
117                         (struct sockaddr*)&addr, 
118                         size) < 0)
119                 {
120                         fprintf(stderr, 
121                                 _("RenderFarmClient::main_loop: bind path %s: %s\n"),
122                                 deamon_path,
123                                 strerror(errno));
124                         return;
125                 }
126         }
128 // Wait for connections
129         printf("RenderFarmClient::main_loop: client started\n");
130         while(1)
131         {
132                 if(listen(socket_fd, 256) < 0)
133         {
134                 perror(_("RenderFarmClient::main_loop: listen"));
135                 return;
136         }
138                 int new_socket_fd;
142                 if(!deamon_path)
143                 {
144                         struct sockaddr_in clientname;
145                         socklen_t size = sizeof(clientname);
146                 if((new_socket_fd = accept(socket_fd,
147                                 (struct sockaddr*)&clientname, 
148                                                 &size)) < 0)
149                 {
150                         perror(_("RenderFarmClient::main_loop: accept"));
151                         return;
152                 }
153                         else
154                         {
155 //printf("RenderFarmClient::main_loop: Session started from %s\n", inet_ntoa(clientname.sin_addr));
156                                 thread->main_loop(new_socket_fd);
157                         }
158                 }
159                 else
160                 {
161                         struct sockaddr_un clientname;
162                         socklen_t size = sizeof(clientname);
163                 if((new_socket_fd = accept(socket_fd,
164                                 (struct sockaddr*)&clientname, 
165                                                 &size)) < 0)
166                 {
167                         perror(_("RenderFarmClient::main_loop: accept"));
168                         return;
169                 }
170                         else
171                         {
172 //printf("RenderFarmClient::main_loop: Session started from %s\n", clientname.sun_path);
173                                 thread->main_loop(new_socket_fd);
174                         }
175                 }
176         }
179 void RenderFarmClient::kill_client()
181 printf("RenderFarmClient::kill_client 1\n");
182         if(deamon_path)
183         {
184 printf("RenderFarmClient::kill_client 2\n");
185                 remove(deamon_path);
186                 kill(this_pid, SIGKILL);
187         }
200 // The thread requests jobs from the server until the job table is empty
201 // or the server reports an error.  This thread must poll the server
202 // after every frame for the error status.
203 // Detaches when finished.
204 RenderFarmClientThread::RenderFarmClientThread(RenderFarmClient *client)
205  : Thread()
207         this->client = client;
208         frames_per_second = 0;
209         Thread::set_synchronous(0);
210 //      fs_client = 0;
211         mutex_lock = new Mutex("RenderFarmClientThread::mutex_lock");
214 RenderFarmClientThread::~RenderFarmClientThread()
216 //      if(fs_client) delete fs_client;
217         delete mutex_lock;
221 int RenderFarmClientThread::send_request_header(int request, 
222         int len)
224         unsigned char datagram[5];
225         datagram[0] = request;
227         int i = 1;
228         STORE_INT32(len);
229 // printf("RenderFarmClientThread::send_request_header %d %02x%02x%02x%02x%02x\n",
230 // request, datagram[0], datagram[1], datagram[2], datagram[3], datagram[4]);
232         return (write_socket((char*)datagram, 
233                 5, 
234                 RENDERFARM_TIMEOUT) != 5);
237 int RenderFarmClientThread::write_socket(char *data, int len, int timeout)
239         int result = RenderFarmServerThread::write_socket(socket_fd, 
240                 data, 
241                 len, 
242                 timeout);
243 // Assume the stream is offset and give up future accesses.
244         if(result <= 0) abort();
247 int RenderFarmClientThread::read_socket(char *data, int len, int timeout)
249         int result = RenderFarmServerThread::read_socket(socket_fd, 
250                 data, 
251                 len, 
252                 timeout);
253 // Assume the stream is offset and give up future accesses.
254         if(result <= 0) abort();
257 void RenderFarmClientThread::abort()
259         send_completion(socket_fd);
260         close(socket_fd);
261         exit(1);
264 void RenderFarmClientThread::lock(char *location)
266         mutex_lock->lock(location);
269 void RenderFarmClientThread::unlock()
271         mutex_lock->unlock();
274 void RenderFarmClientThread::read_string(int socket_fd, char* &string)
276         unsigned char header[4];
277         if(read_socket((char*)header, 4, RENDERFARM_TIMEOUT) != 4)
278         {
279                 string = 0;
280                 return;
281         }
283         int64_t len = (((u_int32_t)header[0]) << 24) | 
284                                 (((u_int32_t)header[1]) << 16) | 
285                                 (((u_int32_t)header[2]) << 8) | 
286                                 ((u_int32_t)header[3]);
288         if(len)
289         {
290                 string = new char[len];
291                 if(read_socket(string, len, RENDERFARM_TIMEOUT) != len)
292                 {
293                         delete [] string;
294                         string = 0;
295                 }
296         }
297         else
298                 string = 0;
303 void RenderFarmClientThread::read_preferences(int socket_fd, 
304         Preferences *preferences)
306         send_request_header(RENDERFARM_PREFERENCES, 
307                 0);
309         char *string;
310         read_string(socket_fd, string);
312         Defaults defaults;
313         defaults.load_string((char*)string);
314         preferences->load_defaults(&defaults);
316         delete [] string;
321 void RenderFarmClientThread::read_asset(int socket_fd, Asset *asset)
323         send_request_header(RENDERFARM_ASSET, 
324                 0);
326         char *string1;
327         char *string2;
328         read_string(socket_fd, string1);
329         read_string(socket_fd, string2);
333         FileXML file;
334         file.read_from_string((char*)string2);
335         asset->read(&file);
336         
339         Defaults defaults;
340         defaults.load_string((char*)string1);
341         asset->load_defaults(&defaults,
342                 0,
343                 1,
344                 1,
345                 1,
346                 1,
347                 1);
349         delete [] string1;
350         delete [] string2;
353 void RenderFarmClientThread::read_edl(int socket_fd, 
354         EDL *edl, 
355         Preferences *preferences)
357         send_request_header(RENDERFARM_EDL, 
358                 0);
360         char *string;
361         read_string(socket_fd, string);
363 //printf("RenderFarmClientThread::read_edl 1\n");
365         FileXML file;
366         file.read_from_string((char*)string);
367         delete [] string;
376         edl->load_xml(client->plugindb,
377                 &file, 
378                 LOAD_ALL);
382 // Tag input paths for VFS here.
383 // Create VFS object.
384         FileSystem fs;
385 //      if(preferences->renderfarm_vfs)
386 //      {
387 //              fs_client = new RenderFarmFSClient(this);
388 //              fs_client->initialize();
389 // 
390 //              for(Asset *asset = edl->assets->first;
391 //                      asset;
392 //                      asset = asset->next)
393 //              {
394 //                      char string2[BCTEXTLEN];
395 //                      strcpy(string2, asset->path);
396 //                      sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", string2);
397 //              }
398 //      }
400 //      for(Asset *asset = edl->assets->first;
401 //              asset;
402 //              asset = asset->next)
403 //      {
404 //              char string2[BCTEXTLEN];
405 //              strcpy(string2, asset->path);
406 //              fs.join_names(asset->path, preferences->renderfarm_mountpoint, string2);
407 //      }
410 //edl->dump();
413 int RenderFarmClientThread::read_package(int socket_fd, RenderPackage *package)
415         send_request_header(RENDERFARM_PACKAGE, 
416                 4);
418         unsigned char datagram[5];
419         int i = 0;
422 // Fails if -ieee isn't set.
423         int64_t fixed = !EQUIV(frames_per_second, 0.0) ? 
424                 (int64_t)(frames_per_second * 65536.0) : 0;
425         STORE_INT32(fixed);
426         write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
429 //printf("RenderFarmClientThread::read_package 1 %f %ld\n", frames_per_second, fixed);
430         char *data;
431         unsigned char *data_ptr;
432         read_string(socket_fd, data);
433 //printf("RenderFarmClientThread::read_package 2 %p\n", data);
434 // Signifies end of session.
435         if(!data) 
436         {
437 //              printf(_("RenderFarmClientThread::read_package no output path recieved.\n"));
438                 return 1;
439         }
441 //printf("RenderFarmClientThread::read_package 2\n");
444         data_ptr = (unsigned char*)data;
445         strcpy(package->path, data);
446         data_ptr += strlen(package->path);
447         data_ptr++;
448         package->audio_start = READ_INT32(data_ptr);
449         data_ptr += 4;
450         package->audio_end = READ_INT32(data_ptr);
451         data_ptr += 4;
452         package->video_start = READ_INT32(data_ptr);
453         data_ptr += 4;
454         package->video_end = READ_INT32(data_ptr);
455         data_ptr += 4;
456         package->use_brender = READ_INT32(data_ptr);
458         delete [] data;
460         return 0;
463 int RenderFarmClientThread::send_completion(int socket_fd)
465         return send_request_header(RENDERFARM_DONE, 
466                 0);
472 void RenderFarmClientThread::main_loop(int socket_fd)
474          this->socket_fd = socket_fd;
475          Thread::start();
478 void RenderFarmClientThread::run()
480 // Create new memory space
481         int pid = fork();
482         if(pid != 0)
483         {
484                 int return_value;
485                 waitpid(pid, &return_value, 0);
486                 return;
487         }
494         int socket_fd = this->socket_fd;
495 //printf("RenderFarmClientThread::run 1\n");
496         EDL *edl;
497         RenderPackage *package;
498         Asset *default_asset;
499         Preferences *preferences;
500         FarmPackageRenderer package_renderer(this, socket_fd);
501         int result = 0;
503 //printf("RenderFarmClientThread::run 2\n");
504 // Read settings
505         preferences = new Preferences;
506         default_asset = new Asset;
507         package = new RenderPackage;
508         edl = new EDL;
509         edl->create_objects();
511 //printf("RenderFarmClientThread::run 3\n");
519         read_preferences(socket_fd, preferences);
520 //printf("RenderFarmClientThread::run 3\n");
521         read_asset(socket_fd, default_asset);
522 //printf("RenderFarmClientThread::run 3\n");
523         read_edl(socket_fd, edl, preferences);
524 //edl->dump();
532 //printf("RenderFarmClientThread::run 4\n");
534         package_renderer.initialize(0,
535                         edl, 
536                         preferences, 
537                         default_asset,
538                         client->plugindb);
539 //printf("RenderFarmClientThread::run 5\n");
541 // Read packages
542         while(1)
543         {
544                 result = read_package(socket_fd, package);
545 //printf("RenderFarmClientThread::run 6 %d\n", result);
548 // Finished list
549                 if(result)
550                 {
551 //printf("RenderFarmClientThread::run 7 %d\n", result);
553                         result = send_completion(socket_fd);
554                         break;
555                 }
557                 Timer timer;
558                 timer.update();
560 // Error
561                 if(package_renderer.render_package(package))
562                 {
563 //printf("RenderFarmClientThread::run 8\n");
564                         result = send_completion(socket_fd);
565                         break;
566                 }
568                 frames_per_second = (double)(package->video_end - package->video_start) / 
569                         ((double)timer.get_difference() / 1000);
571 //printf("RenderFarmClientThread::run 9\n");
575         }
578 //printf("RenderFarmClientThread::run 9\n");
579         delete default_asset;
580 //printf("RenderFarmClientThread::run 10\n");
581         delete edl;
582 //printf("RenderFarmClientThread::run 11\n");
583         delete preferences;
584 //printf("RenderFarmClientThread::run 12\n");
585 printf(_("RenderFarmClientThread::run: Session finished.\n"));
587 // Socket error should be the only cause of this
588         if(result)
589         {
590                 ;
591         }
593         _exit(0);
603 FarmPackageRenderer::FarmPackageRenderer(RenderFarmClientThread *thread,
604                 int socket_fd)
605  : PackageRenderer()
607         this->thread = thread;
608         this->socket_fd = socket_fd;
613 FarmPackageRenderer::~FarmPackageRenderer()
618 int FarmPackageRenderer::get_result()
620         thread->lock("FarmPackageRenderer::get_result");
621         thread->send_request_header(RENDERFARM_GET_RESULT, 
622                 0);
623         unsigned char data[1];
624         data[0] = 1;
625         if(thread->read_socket((char*)data, 1, RENDERFARM_TIMEOUT) != 1)
626         {
627                 thread->unlock();
628                 return 1;
629         }
630         thread->unlock();
631         return data[0];
634 void FarmPackageRenderer::set_result(int value)
636         thread->lock("FarmPackageRenderer::set_result");
637         thread->send_request_header(RENDERFARM_SET_RESULT, 
638                 1);
639         unsigned char data[1];
640         data[0] = value;
641         thread->write_socket((char*)data, 1, RENDERFARM_TIMEOUT);
642         thread->unlock();
645 void FarmPackageRenderer::set_progress(int64_t total_samples)
647         thread->lock("FarmPackageRenderer::set_progress");
648         thread->send_request_header(RENDERFARM_PROGRESS, 
649                 4);
650         unsigned char datagram[4];
651         int i = 0;
652         STORE_INT32(total_samples);
653         thread->write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
654         thread->unlock();
657 int FarmPackageRenderer::set_video_map(int64_t position, int value)
659         int result = 0;
660         unsigned char datagram[8];
661         char return_value[1];
662         int i = 0;
664         thread->lock("FarmPackageRenderer::set_video_map");
665         thread->send_request_header(RENDERFARM_SET_VMAP, 
666                 8);
667         STORE_INT32(position);
668         STORE_INT32(value);
669         thread->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT);
671 // Get completion since the GUI may be locked for a long time.
672         if(!thread->read_socket(return_value, 1, RENDERFARM_TIMEOUT))
673         {
674                 result = 1;
675         }
677         thread->unlock();
678         return result;