r602: Fix baver's code... don't insert timecode when show_tc is not set
[cinelerra_cv/mob.git] / cinelerra / renderfarmclient.C
blob6e63d6354308dc24d5b7107dfadc2fe35192ebe0
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 %02x%02x%02x%02x%02x\n",
230 //      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         return RenderFarmServerThread::write_socket(socket_fd, 
240                 data, 
241                 len, 
242                 timeout);
245 int RenderFarmClientThread::read_socket(char *data, int len, int timeout)
247         return RenderFarmServerThread::read_socket(socket_fd, 
248                 data, 
249                 len, 
250                 timeout);
253 void RenderFarmClientThread::lock(char *location)
255 //printf("RenderFarmClientThread::lock 1 %p %p\n", this, mutex_lock);
256         mutex_lock->lock(location);
259 void RenderFarmClientThread::unlock()
261 //printf("RenderFarmClientThread::unlock 1\n");
262         mutex_lock->unlock();
265 void RenderFarmClientThread::read_string(int socket_fd, char* &string)
267         unsigned char header[4];
268         if(read_socket((char*)header, 4, RENDERFARM_TIMEOUT) != 4)
269         {
270                 string = 0;
271                 return;
272         }
274         int64_t len = (((u_int32_t)header[0]) << 24) | 
275                                 (((u_int32_t)header[1]) << 16) | 
276                                 (((u_int32_t)header[2]) << 8) | 
277                                 ((u_int32_t)header[3]);
278 //printf("RenderFarmClientThread::read_string %d %02x%02x%02x%02x\n",
279 //len, header[0], header[1], header[2], header[3]);
281         if(len)
282         {
283                 string = new char[len];
284                 if(read_socket(string, len, RENDERFARM_TIMEOUT) != len)
285                 {
286                         delete [] string;
287                         string = 0;
288                 }
289         }
290         else
291                 string = 0;
293 //printf("RenderFarmClientThread::read_string \n%s\n", string);
297 void RenderFarmClientThread::read_preferences(int socket_fd, 
298         Preferences *preferences)
300 //printf("RenderFarmClientThread::read_preferences 1\n");
301         send_request_header(RENDERFARM_PREFERENCES, 
302                 0);
304 //printf("RenderFarmClientThread::read_preferences 2\n");
305         char *string;
306         read_string(socket_fd, string);
307 //printf("RenderFarmClientThread::read_preferences 3\n%s\n", string);
309         Defaults defaults;
310         defaults.load_string((char*)string);
311         preferences->load_defaults(&defaults);
312 //printf("RenderFarmClientThread::read_preferences 4\n");
314         delete [] string;
319 void RenderFarmClientThread::read_asset(int socket_fd, Asset *asset)
321         send_request_header(RENDERFARM_ASSET, 
322                 0);
324         char *string;
325         read_string(socket_fd, string);
326 //printf("RenderFarmClientThread::read_asset\n%s\n", string);
328         FileXML file;
329         file.read_from_string((char*)string);
330         asset->read(client->plugindb, &file);
332         delete [] string;
335 void RenderFarmClientThread::read_edl(int socket_fd, 
336         EDL *edl, 
337         Preferences *preferences)
339         send_request_header(RENDERFARM_EDL, 
340                 0);
342         char *string;
343         read_string(socket_fd, string);
345 //printf("RenderFarmClientThread::read_edl 1\n");
347         FileXML file;
348         file.read_from_string((char*)string);
349         delete [] string;
358         edl->load_xml(client->plugindb,
359                 &file, 
360                 LOAD_ALL);
364 // Tag input paths for VFS here.
365 // Create VFS object.
366         FileSystem fs;
367         if(preferences->renderfarm_vfs)
368         {
369                 fs_client = new RenderFarmFSClient(this);
370                 fs_client->initialize();
372                 for(Asset *asset = edl->assets->first;
373                         asset;
374                         asset = asset->next)
375                 {
376                         char string2[BCTEXTLEN];
377                         strcpy(string2, asset->path);
378                         sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", string2);
379                 }
380         }
382 //      for(Asset *asset = edl->assets->first;
383 //              asset;
384 //              asset = asset->next)
385 //      {
386 //              char string2[BCTEXTLEN];
387 //              strcpy(string2, asset->path);
388 //              fs.join_names(asset->path, preferences->renderfarm_mountpoint, string2);
389 //      }
392 //edl->dump();
395 int RenderFarmClientThread::read_package(int socket_fd, RenderPackage *package)
397         send_request_header(RENDERFARM_PACKAGE, 
398                 4);
400         unsigned char datagram[5];
401         int i = 0;
404 // Fails if -ieee isn't set.
405         int64_t fixed = !EQUIV(frames_per_second, 0.0) ? 
406                 (int64_t)(frames_per_second * 65536.0) : 0;
407         STORE_INT32(fixed);
408         write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
411 //printf("RenderFarmClientThread::read_package 1 %f %ld\n", frames_per_second, fixed);
412         char *data;
413         unsigned char *data_ptr;
414         read_string(socket_fd, data);
415 //printf("RenderFarmClientThread::read_package 2 %p\n", data);
416 // Signifies end of session.
417         if(!data) 
418         {
419 //              printf(_("RenderFarmClientThread::read_package no output path recieved.\n"));
420                 return 1;
421         }
423 //printf("RenderFarmClientThread::read_package 2\n");
426         data_ptr = (unsigned char*)data;
427         strcpy(package->path, data);
428         data_ptr += strlen(package->path);
429         data_ptr++;
430         package->audio_start = READ_INT32(data_ptr);
431         data_ptr += 4;
432         package->audio_end = READ_INT32(data_ptr);
433         data_ptr += 4;
434         package->video_start = READ_INT32(data_ptr);
435         data_ptr += 4;
436         package->video_end = READ_INT32(data_ptr);
437         data_ptr += 4;
438         package->use_brender = READ_INT32(data_ptr);
440         delete [] data;
442         return 0;
445 int RenderFarmClientThread::send_completion(int socket_fd)
447         return send_request_header(RENDERFARM_DONE, 
448                 0);
454 void RenderFarmClientThread::main_loop(int socket_fd)
456          this->socket_fd = socket_fd;
457          Thread::start();
460 void RenderFarmClientThread::run()
462 // Create new memory space
463         int pid = fork();
464         if(pid != 0)
465         {
466                 int return_value;
467                 waitpid(pid, &return_value, 0);
468                 return;
469         }
476         int socket_fd = this->socket_fd;
477 //printf("RenderFarmClientThread::run 1\n");
478         EDL *edl;
479         RenderPackage *package;
480         Asset *default_asset;
481         Preferences *preferences;
482         FarmPackageRenderer package_renderer(this, socket_fd);
483         int result = 0;
485 //printf("RenderFarmClientThread::run 2\n");
486 // Read settings
487         preferences = new Preferences;
488         default_asset = new Asset;
489         package = new RenderPackage;
490         edl = new EDL;
491         edl->create_objects();
493 //printf("RenderFarmClientThread::run 3\n");
501         read_preferences(socket_fd, preferences);
502 //printf("RenderFarmClientThread::run 3\n");
503         read_asset(socket_fd, default_asset);
504 //printf("RenderFarmClientThread::run 3\n");
505         read_edl(socket_fd, edl, preferences);
506 //edl->dump();
514 //printf("RenderFarmClientThread::run 4\n");
516         package_renderer.initialize(0,
517                         edl, 
518                         preferences, 
519                         default_asset,
520                         client->plugindb);
521 //printf("RenderFarmClientThread::run 5\n");
523 // Read packages
524         while(1)
525         {
526                 result = read_package(socket_fd, package);
527 //printf("RenderFarmClientThread::run 6 %d\n", result);
530 // Finished list
531                 if(result)
532                 {
533 //printf("RenderFarmClientThread::run 7 %d\n", result);
535                         result = send_completion(socket_fd);
536                         break;
537                 }
539                 Timer timer;
540                 timer.update();
542 // Error
543                 if(package_renderer.render_package(package))
544                 {
545 //printf("RenderFarmClientThread::run 8\n");
546                         result = send_completion(socket_fd);
547                         break;
548                 }
550                 frames_per_second = (double)(package->video_end - package->video_start) / 
551                         ((double)timer.get_difference() / 1000);
553 //printf("RenderFarmClientThread::run 9\n");
557         }
560 //printf("RenderFarmClientThread::run 9\n");
561         delete default_asset;
562 //printf("RenderFarmClientThread::run 10\n");
563         delete edl;
564 //printf("RenderFarmClientThread::run 11\n");
565         delete preferences;
566 //printf("RenderFarmClientThread::run 12\n");
567 printf(_("RenderFarmClientThread::run: Session finished.\n"));
569 // Socket error should be the only cause of this
570         if(result)
571         {
572                 ;
573         }
575         _exit(0);
585 FarmPackageRenderer::FarmPackageRenderer(RenderFarmClientThread *thread,
586                 int socket_fd)
587  : PackageRenderer()
589         this->thread = thread;
590         this->socket_fd = socket_fd;
595 FarmPackageRenderer::~FarmPackageRenderer()
600 int FarmPackageRenderer::get_result()
602         thread->lock("FarmPackageRenderer::get_result");
603         thread->send_request_header(RENDERFARM_GET_RESULT, 
604                 0);
605         unsigned char data[1];
606         data[0] = 1;
607         if(thread->read_socket((char*)data, 1, RENDERFARM_TIMEOUT) != 1)
608         {
609                 thread->unlock();
610                 return 1;
611         }
612         thread->unlock();
613         return data[0];
616 void FarmPackageRenderer::set_result(int value)
618         thread->lock("FarmPackageRenderer::set_result");
619         thread->send_request_header(RENDERFARM_SET_RESULT, 
620                 1);
621         unsigned char data[1];
622         data[0] = value;
623         thread->write_socket((char*)data, 1, RENDERFARM_TIMEOUT);
624         thread->unlock();
627 void FarmPackageRenderer::set_progress(int64_t total_samples)
629         thread->lock("FarmPackageRenderer::set_progress");
630         thread->send_request_header(RENDERFARM_PROGRESS, 
631                 4);
632         unsigned char datagram[4];
633         int i = 0;
634         STORE_INT32(total_samples);
635         thread->write_socket((char*)datagram, 4, RENDERFARM_TIMEOUT);
636         thread->unlock();
639 void FarmPackageRenderer::set_video_map(int64_t position, int value)
641         thread->lock("FarmPackageRenderer::set_video_map");
642         thread->send_request_header(RENDERFARM_SET_VMAP, 
643                 8);
644         unsigned char datagram[8];
645         int i = 0;
646         STORE_INT32(position);
647         STORE_INT32(value);
648         thread->write_socket((char*)datagram, 8, RENDERFARM_TIMEOUT);
649         thread->unlock();