7 #include "edlsession.h"
9 #include "mainsession.h"
12 #include "mwindowgui.h"
14 #include "packagedispatcher.h"
15 #include "preferences.h"
16 #include "renderfarm.h"
31 #include <uuid/uuid.h>
39 BRender::BRender(MWindow *mwindow)
42 this->mwindow = mwindow;
43 map_lock = new Mutex("BRender::map_lock");
44 completion_lock = new Condition(0, "BRender::completion_lock");
49 arguments[0] = arguments[1] = arguments[2] = 0;
59 TRACE("BRender::~BRender 1\n");
62 TRACE("BRender::~BRender 2\n");
64 TRACE("BRender::~BRender 3\n");
66 TRACE("BRender::~BRender 4\n");
70 TRACE("BRender::~BRender 5\n");
73 kill(master_pid, SIGKILL);
74 TRACE("BRender::~BRender 6\n");
76 TRACE("BRender::~BRender 7\n");
79 TRACE("BRender::~BRender 8\n");
81 TRACE("BRender::~BRender 9\n");
82 delete completion_lock;
83 TRACE("BRender::~BRender 10\n");
84 UNSET_TEMP(socket_path);
86 TRACE("BRender::~BRender 11\n");
87 if(arguments[0]) delete [] arguments[0];
88 TRACE("BRender::~BRender 12\n");
89 if(arguments[1]) delete [] arguments[1];
90 TRACE("BRender::~BRender 13\n");
91 if(arguments[2]) delete [] arguments[2];
92 TRACE("BRender::~BRender 14\n");
93 if(map) delete [] map;
94 TRACE("BRender::~BRender 15\n");
96 TRACE("BRender::~BRender 100\n");
99 void BRender::initialize()
102 // Create socket for background process.
104 sprintf(socket_path, "/tmp/cinelerra.");
105 uuid_generate(socket_temp);
106 uuid_unparse(socket_temp, socket_path + strlen(socket_path));
107 SET_TEMP(socket_path);
109 // Start background instance of executable since codecs aren't reentrant
112 // Wait for local node to start
113 thread = new BRenderThread(mwindow, this);
114 thread->initialize();
119 char string[BCTEXTLEN];
122 //printf("BRender::run 1 %d\n", getpid());
125 // Construct executable command with the designated filesystem port
126 fd = fopen("/proc/self/cmdline", "r");
129 fread(string, 1, BCTEXTLEN, fd);
133 perror(_("BRender::fork_background: can't open /proc/self/cmdline.\n"));
135 arguments[0] = new char[strlen(string) + 1];
136 strcpy(arguments[0], string);
138 strcpy(string, "-b");
139 arguments[1] = new char[strlen(string) + 1];
140 strcpy(arguments[1], string);
142 arguments[2] = new char[strlen(socket_path) + 1];
143 strcpy(arguments[2], socket_path);
144 //printf("BRender::fork_background 1 %s\n", socket_path);
151 execvp(arguments[0], arguments);
152 perror("BRender::fork_background");
157 //printf("BRender::fork_background 1 %d\n", master_pid);
162 if(waitpid(master_pid, &return_value, WUNTRACED) < 0)
164 perror("BRender::run waitpid");
168 // Give the last position of the EDL which hasn't changed.
169 // We copy the EDL and restart rendering at the lesser of position and
171 void BRender::restart(EDL *edl)
173 //printf("BRender::restart 1\n");
174 BRenderCommand *new_command = new BRenderCommand;
176 new_command->copy_edl(edl);
177 new_command->command = BRenderCommand::BRENDER_RESTART;
178 //printf("BRender::restart 2\n");
179 thread->send_command(new_command);
180 //printf("BRender::restart 3\n");
181 // Map should be reallocated before this returns.
186 //printf("BRender::stop 1\n");
187 BRenderCommand *new_command = new BRenderCommand;
188 //printf("BRender::stop 1\n");
189 new_command->command = BRenderCommand::BRENDER_STOP;
190 //printf("BRender::stop 1\n");
191 thread->send_command(new_command);
192 //printf("BRender::stop 1\n");
193 completion_lock->lock("BRender::stop");
194 //printf("BRender::stop 2\n");
199 int BRender::get_last_contiguous(int64_t brender_start)
202 map_lock->lock("BRender::get_last_contiguous");
204 result = last_contiguous;
206 result = brender_start;
211 void BRender::allocate_map(int64_t brender_start, int64_t start, int64_t end)
213 map_lock->lock("BRender::allocate_map");
214 unsigned char *old_map = map;
215 map = new unsigned char[end];
218 memcpy(map, old_map, start);
222 // Zero all before brender start
223 bzero(map, brender_start);
224 // Zero all after current start
225 bzero(map + start, end - start);
229 last_contiguous = start;
230 mwindow->session->brender_end = (double)last_contiguous /
231 mwindow->edl->session->frame_rate;
235 int BRender::set_video_map(int64_t position, int value)
238 map_lock->lock("BRender::set_video_map");
241 if(value == BRender::NOT_SCANNED)
243 printf(_("BRender::set_video_map called to set NOT_SCANNED\n"));
253 if(position < map_size)
255 map[position] = value;
260 printf(_("BRender::set_video_map %d: attempt to set beyond end of map %d.\n"),
265 // Maintain last contiguous here to reduce search time
266 if(position == last_contiguous)
269 for(i = position + 1; i < map_size && map[i]; i++)
274 mwindow->session->brender_end = (double)last_contiguous /
275 mwindow->edl->session->frame_rate;
277 if(timer->get_difference() > 1000 || last_contiguous >= map_size)
288 mwindow->gui->lock_window("BRender::set_video_map");
289 mwindow->gui->timebar->update(1, 0);
290 mwindow->gui->timebar->flush();
291 mwindow->gui->unlock_window();
309 BRenderCommand::BRenderCommand()
312 command = BRENDER_NONE;
316 BRenderCommand::~BRenderCommand()
318 // EDL should be zeroed if copied
322 void BRenderCommand::copy_from(BRenderCommand *src)
324 this->edl = src->edl;
326 this->position = src->position;
327 this->command = src->command;
331 void BRenderCommand::copy_edl(EDL *edl)
334 this->edl->create_objects();
335 this->edl->copy_all(edl);
350 BRenderThread::BRenderThread(MWindow *mwindow, BRender *brender)
353 this->mwindow = mwindow;
354 this->brender = brender;
355 input_lock = new Condition(0, "BRenderThread::input_lock");
356 thread_lock = new Mutex("BRenderThread::thread_lock");
357 total_frames_lock = new Mutex("BRenderThread::total_frames_lock");
366 BRenderThread::~BRenderThread()
368 thread_lock->lock("BRenderThread::~BRenderThread");
370 input_lock->unlock();
371 thread_lock->unlock();
375 delete total_frames_lock;
376 if(command) delete command;
377 if(command_queue) delete command_queue;
378 if(preferences) delete preferences;
382 void BRenderThread::initialize()
387 void BRenderThread::send_command(BRenderCommand *command)
389 TRACE("BRenderThread::send_command 1");
390 thread_lock->lock("BRenderThread::send_command");
391 TRACE("BRenderThread::send_command 10");
393 if(this->command_queue)
395 delete this->command_queue;
396 this->command_queue = 0;
398 this->command_queue = command;
399 TRACE("BRenderThread::send_command 20");
402 input_lock->unlock();
403 thread_lock->unlock();
406 int BRenderThread::is_done(int do_lock)
408 if(do_lock) thread_lock->lock("BRenderThread::is_done");
410 if(do_lock) thread_lock->unlock();
414 void BRenderThread::run()
418 BRenderCommand *new_command = 0;
419 thread_lock->lock("BRenderThread::run 1");
427 // Wait for new command
429 thread_lock->unlock();
430 input_lock->lock("BRenderThread::run 2");
431 thread_lock->lock("BRenderThread::run 3");
434 // Pull the command off
437 new_command = command_queue;
441 thread_lock->unlock();
446 // Process the command here to avoid delay.
453 if(new_command->command == BRenderCommand::BRENDER_STOP)
458 // if(command) delete command;
459 // command = new_command;
462 if(new_command->command == BRenderCommand::BRENDER_RESTART)
464 // Compare EDL's and get last equivalent position in new EDL
465 if(command && command->edl)
466 new_command->position =
467 new_command->edl->equivalent_output(command->edl);
469 new_command->position = 0;
473 //printf("BRenderThread::run 4\n");
474 brender->completion_lock->lock("BRenderThread::run 4");
475 //printf("BRenderThread::run 5\n");
477 if(new_command->edl->tracks->total_playable_vtracks())
479 if(command) delete command;
480 command = new_command;
481 //printf("BRenderThread::run 6\n");
483 //printf("BRenderThread::run 7\n");
487 //printf("BRenderThread::run 8 %p\n", farm_server);
495 void BRenderThread::stop()
500 farm_server->wait_clients();
508 brender->completion_lock->unlock();
511 void BRenderThread::start()
513 // Reset return parameters
519 // Allocate render farm.
522 //printf("BRenderThread::start 1\n");
523 preferences = new Preferences;
524 preferences->copy_from(mwindow->preferences);
525 packages = new PackageDispatcher;
527 // Fix preferences to use local node
528 if(!preferences->use_renderfarm)
530 preferences->use_renderfarm = 1;
531 preferences->delete_nodes();
533 preferences->add_node(brender->socket_path,
536 preferences->local_rate);
537 //printf("BRenderThread::start 1 %s\n", brender->socket_path);
538 preferences->brender_asset->use_header = 0;
539 preferences->brender_asset->frame_rate = command->edl->session->frame_rate;
540 preferences->brender_asset->width = command->edl->session->output_w;
541 preferences->brender_asset->height = command->edl->session->output_h;
542 preferences->brender_asset->interlace_mode = command->edl->session->interlace_mode;
544 // Get last contiguous and reset map.
545 // If the framerate changes, last good should be 0 from the user.
546 int brender_start = (int)(command->edl->session->brender_start *
547 command->edl->session->frame_rate);
548 int last_contiguous = brender->last_contiguous;
549 int last_good = (int)(command->edl->session->frame_rate *
551 if(last_good < 0) last_good = last_contiguous;
552 int start_frame = MIN(last_contiguous, last_good);
553 start_frame = MAX(start_frame, brender_start);
554 int64_t end_frame = Units::round(command->edl->tracks->total_video_length() *
555 command->edl->session->frame_rate);
556 if(end_frame < start_frame) end_frame = start_frame;
559 printf("BRenderThread::start 1 map=%d equivalent=%d brender_start=%d result=%d end=%d\n",
568 brender->allocate_map(brender_start, start_frame, end_frame);
570 //printf("BRenderThread::start 2\n");
572 result = packages->create_packages(mwindow,
576 preferences->brender_asset,
577 (double)start_frame / command->edl->session->frame_rate,
578 (double)end_frame / command->edl->session->frame_rate,
582 //printf("BRenderThread::start 3 %d\n", result);
583 farm_server = new RenderFarmServer(mwindow->plugindb,
590 preferences->brender_asset,
595 //printf("BRenderThread::start 4\n");
596 result = farm_server->start_clients();
599 // No local rendering because of codec problems.
605 // No-one must be retrieving a package when packages are deleted.
606 //printf("BRenderThread::start 7 %p\n", farm_server);
609 //printf("BRenderThread::start 8 %p\n", preferences);
611 //printf("BRenderThread::start 9\n");
617 //printf("BRenderThread::start 10\n");