5 #include "edlsession.h"
6 #include "mainsession.h"
9 #include "mwindowgui.h"
10 #include "preferences.h"
11 #include "renderfarm.h"
12 #include "packagedispatcher.h"
26 #define _(String) gettext(String)
27 #define gettext_noop(String) String
28 #define N_(String) gettext_noop (String)
32 #include <uuid/uuid.h>
40 BRender::BRender(MWindow *mwindow)
43 this->mwindow = mwindow;
45 completion_lock = new Mutex;
47 completion_lock->lock();
51 arguments[0] = arguments[1] = arguments[2] = 0;
63 //printf("BRender::~BRender 1\n");
65 //printf("BRender::~BRender 2\n");
69 //printf("BRender::~BRender 3\n");
73 kill(master_pid, SIGKILL);
77 //printf("BRender::~BRender 2\n");
79 //printf("BRender::~BRender 2\n");
80 delete completion_lock;
81 //printf("BRender::~BRender 2\n");
83 //printf("BRender::~BRender 2\n");
84 if(arguments[0]) delete [] arguments[0];
85 //printf("BRender::~BRender 2\n");
86 if(arguments[1]) delete [] arguments[1];
87 //printf("BRender::~BRender 2\n");
88 if(arguments[2]) delete [] arguments[2];
89 if(map) delete [] map;
91 //printf("BRender::~BRender 3\n");
94 void BRender::initialize()
97 // Create socket for background process.
99 sprintf(socket_path, "/tmp/cinelerra.");
100 uuid_generate(socket_temp);
101 uuid_unparse(socket_temp, socket_path + strlen(socket_path));
103 // Start background instance of executable since codecs aren't reentrant
106 // Wait for local node to start
107 thread = new BRenderThread(mwindow, this);
108 thread->initialize();
113 char string[BCTEXTLEN];
119 // Construct executable command with the designated filesystem port
120 fd = fopen("/proc/self/cmdline", "r");
123 fread(string, 1, BCTEXTLEN, fd);
127 perror(_("BRender::fork_background: can't open /proc/self/cmdline.\n"));
129 arguments[0] = new char[strlen(string) + 1];
130 strcpy(arguments[0], string);
132 strcpy(string, "-b");
133 arguments[1] = new char[strlen(string) + 1];
134 strcpy(arguments[1], string);
136 arguments[2] = new char[strlen(socket_path) + 1];
137 strcpy(arguments[2], socket_path);
138 //printf("BRender::fork_background 1 %s\n", socket_path);
145 execvp(arguments[0], arguments);
146 perror("BRender::fork_background");
151 //printf("BRender::fork_background 1 %d\n", master_pid);
156 if(waitpid(master_pid, &return_value, WUNTRACED) < 0)
158 perror("BRender::run waitpid");
162 // Give the last position of the EDL which hasn't changed.
163 // We copy the EDL and restart rendering at the lesser of position and
165 void BRender::restart(EDL *edl)
167 //printf("BRender::restart 1\n");
168 BRenderCommand *new_command = new BRenderCommand;
170 new_command->copy_edl(edl);
171 new_command->command = BRenderCommand::BRENDER_RESTART;
172 //printf("BRender::restart 2\n");
173 thread->send_command(new_command);
174 //printf("BRender::restart 3\n");
175 // Map should be reallocated before this returns.
180 //printf("BRender::stop 1\n");
181 BRenderCommand *new_command = new BRenderCommand;
182 //printf("BRender::stop 1\n");
183 new_command->command = BRenderCommand::BRENDER_STOP;
184 //printf("BRender::stop 1\n");
185 thread->send_command(new_command);
186 //printf("BRender::stop 1\n");
187 completion_lock->lock();
188 //printf("BRender::stop 2\n");
193 int BRender::get_last_contiguous(int64_t brender_start)
198 result = last_contiguous;
200 result = brender_start;
205 void BRender::allocate_map(int64_t brender_start, int64_t start, int64_t end)
208 unsigned char *old_map = map;
209 map = new unsigned char[end];
212 memcpy(map, old_map, start);
216 // Zero all before brender start
217 bzero(map, brender_start);
218 // Zero all after current start
219 bzero(map + start, end - start);
223 last_contiguous = start;
224 mwindow->session->brender_end = (double)last_contiguous /
225 mwindow->edl->session->frame_rate;
229 void BRender::set_video_map(int64_t position, int value)
234 //printf("BRender::set_video_map 1 %d %d\n", position, value);
236 if(value == BRender::NOT_SCANNED)
238 printf(_("BRender::set_video_map called to set NOT_SCANNED\n"));
248 if(position < map_size)
250 map[position] = value;
255 printf(_("BRender::set_video_map %d: attempt to set beyond end of map %d.\n"),
260 // Maintain last contiguous here to reduce search time
261 //printf("BRender::set_video_map 1 %d %d\n", position, last_contiguous + 1);
262 if(position == last_contiguous)
265 for(i = position + 1; i < map_size && map[i]; i++)
270 mwindow->session->brender_end = (double)last_contiguous /
271 mwindow->edl->session->frame_rate;
273 if(timer->get_difference() > 1000 || last_contiguous >= map_size)
275 //printf("BRender::set_video_map 2\n");
285 mwindow->gui->lock_window();
286 mwindow->gui->timebar->update(1, 0);
287 mwindow->gui->timebar->flush();
288 mwindow->gui->unlock_window();
305 BRenderCommand::BRenderCommand()
308 command = BRENDER_NONE;
312 BRenderCommand::~BRenderCommand()
314 // EDL should be zeroed if copied
318 void BRenderCommand::copy_from(BRenderCommand *src)
320 this->edl = src->edl;
322 this->position = src->position;
323 this->command = src->command;
327 void BRenderCommand::copy_edl(EDL *edl)
330 this->edl->create_objects();
331 this->edl->copy_all(edl);
346 BRenderThread::BRenderThread(MWindow *mwindow, BRender *brender)
349 this->mwindow = mwindow;
350 this->brender = brender;
351 input_lock = new Mutex;
352 thread_lock = new Mutex;
353 total_frames_lock = new Mutex;
363 BRenderThread::~BRenderThread()
367 input_lock->unlock();
368 thread_lock->unlock();
372 delete total_frames_lock;
373 if(command) delete command;
374 if(command_queue) delete command_queue;
375 if(preferences) delete preferences;
379 void BRenderThread::initialize()
384 void BRenderThread::send_command(BRenderCommand *command)
388 if(this->command_queue)
390 delete this->command_queue;
391 this->command_queue = 0;
393 this->command_queue = command;
396 input_lock->unlock();
397 thread_lock->unlock();
400 int BRenderThread::is_done(int do_lock)
402 if(do_lock) thread_lock->lock();
404 if(do_lock) thread_lock->unlock();
408 void BRenderThread::run()
412 BRenderCommand *new_command = 0;
421 // Wait for new command
423 thread_lock->unlock();
428 // Pull the command off
431 new_command = command_queue;
435 thread_lock->unlock();
440 // Process the command here to avoid delay.
447 if(new_command->command == BRenderCommand::BRENDER_STOP)
452 // if(command) delete command;
453 // command = new_command;
456 if(new_command->command == BRenderCommand::BRENDER_RESTART)
458 // Compare EDL's and get last equivalent position in new EDL
459 if(command && command->edl)
460 new_command->position =
461 new_command->edl->equivalent_output(command->edl);
463 new_command->position = 0;
467 //printf("BRenderThread::run 4\n");
468 brender->completion_lock->lock();
469 //printf("BRenderThread::run 5\n");
471 if(new_command->edl->tracks->total_playable_vtracks())
473 if(command) delete command;
474 command = new_command;
475 //printf("BRenderThread::run 6\n");
477 //printf("BRenderThread::run 7\n");
481 //printf("BRenderThread::run 8 %p\n", farm_server);
489 void BRenderThread::stop()
494 farm_server->wait_clients();
502 brender->completion_lock->unlock();
505 void BRenderThread::start()
507 // Reset return parameters
513 // Allocate render farm.
516 //printf("BRenderThread::start 1\n");
517 preferences = new Preferences;
518 *preferences = *mwindow->preferences;
519 packages = new PackageDispatcher;
521 // Fix preferences to use local node
522 if(!preferences->use_renderfarm)
524 preferences->use_renderfarm = 1;
525 preferences->delete_nodes();
527 preferences->add_node(brender->socket_path,
530 preferences->local_rate);
531 //printf("BRenderThread::start 1 %s\n", brender->socket_path);
532 preferences->brender_asset->use_header = 0;
533 preferences->brender_asset->frame_rate = command->edl->session->frame_rate;
534 preferences->brender_asset->width = command->edl->session->output_w;
535 preferences->brender_asset->height = command->edl->session->output_h;
537 // Get last contiguous and reset map.
538 // If the framerate changes, last good should be 0 from the user.
539 int brender_start = (int)(command->edl->session->brender_start *
540 command->edl->session->frame_rate);
541 int last_contiguous = brender->last_contiguous;
542 int last_good = (int)(command->edl->session->frame_rate *
544 if(last_good < 0) last_good = last_contiguous;
545 int start_frame = MIN(last_contiguous, last_good);
546 start_frame = MAX(start_frame, brender_start);
547 int64_t end_frame = Units::round(command->edl->tracks->total_video_length() *
548 command->edl->session->frame_rate);
549 if(end_frame < start_frame) end_frame = start_frame;
550 printf("BRenderThread::start 1 map=%d equivalent=%d brender_start=%d result=%d end=%d\n",
559 brender->allocate_map(brender_start, start_frame, end_frame);
561 //printf("BRenderThread::start 2\n");
563 result = packages->create_packages(mwindow,
567 preferences->brender_asset,
568 (double)start_frame / command->edl->session->frame_rate,
569 (double)end_frame / command->edl->session->frame_rate);
572 //printf("BRenderThread::start 3 %d\n", result);
573 farm_server = new RenderFarmServer(mwindow,
580 preferences->brender_asset,
585 //printf("BRenderThread::start 4\n");
586 result = farm_server->start_clients();
589 // No local rendering because of codec problems.
595 // No-one must be retrieving a package when packages are deleted.
596 //printf("BRenderThread::start 7 %p\n", farm_server);
599 //printf("BRenderThread::start 8 %p\n", preferences);
601 //printf("BRenderThread::start 9\n");
607 //printf("BRenderThread::start 10\n");