4 * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "confirmsave.h"
26 #include "edlsession.h"
31 #include "packagedispatcher.h"
32 #include "packagerenderer.h"
33 #include "preferences.h"
39 PackageDispatcher::PackageDispatcher()
42 package_lock = new Mutex("PackageDispatcher::package_lock");
45 PackageDispatcher::~PackageDispatcher()
49 for(int i = 0; i < total_packages; i++)
56 int PackageDispatcher::create_packages(MWindow *mwindow,
58 Preferences *preferences,
67 this->mwindow = mwindow;
69 this->preferences = preferences;
70 this->strategy = strategy;
71 this->default_asset = default_asset;
72 this->total_start = total_start;
73 this->total_end = total_end;
75 nodes = preferences->get_enabled_nodes();
76 audio_position = Units::to_int64(total_start * default_asset->sample_rate);
77 video_position = Units::to_int64(total_start * default_asset->frame_rate);
78 audio_end = Units::to_int64(total_end * default_asset->sample_rate);
79 video_end = Units::to_int64(total_end * default_asset->frame_rate);
83 // printf("PackageDispatcher::create_packages 1 %d %f %f\n",
86 // default_asset->frame_rate);
90 if(strategy == SINGLE_PASS)
92 total_len = this->total_end - this->total_start;
93 package_len = total_len;
94 min_package_len = total_len;
97 packages = new RenderPackage*[total_allocated];
98 packages[0] = new RenderPackage;
99 packages[0]->audio_start = audio_position;
100 packages[0]->audio_end = audio_end;
101 packages[0]->video_start = video_position;
102 packages[0]->video_end = video_end;
103 strcpy(packages[0]->path, default_asset->path);
106 if(strategy == SINGLE_PASS_FARM)
108 total_len = this->total_end - this->total_start;
109 total_packages = preferences->renderfarm_job_count;
110 total_allocated = total_packages + nodes;
111 packages = new RenderPackage*[total_allocated];
112 package_len = total_len / total_packages;
113 min_package_len = 2.0 / edl->session->frame_rate;
116 //printf("PackageDispatcher::create_packages: %f / %d = %f\n", total_len, total_packages, package_len);
117 Render::get_starting_number(default_asset->path,
123 for(int i = 0; i < total_allocated; i++)
125 RenderPackage *package = packages[i] = new RenderPackage;
127 // Create file number differently if image file sequence
128 Render::create_filename(package->path,
137 if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM)
139 Label *label = edl->labels->first;
141 packages = new RenderPackage*[edl->labels->total() + 2];
143 Render::get_starting_number(default_asset->path,
149 while(audio_position < audio_end)
151 RenderPackage *package =
152 packages[total_packages] =
154 package->audio_start = audio_position;
155 package->video_start = video_position;
159 (label->position < (double)audio_position / default_asset->sample_rate ||
160 EQUIV(label->position, (double)audio_position / default_asset->sample_rate)))
167 package->audio_end = Units::to_int64(total_end * default_asset->sample_rate);
168 package->video_end = Units::to_int64(total_end * default_asset->frame_rate);
172 package->audio_end = Units::to_int64(label->position * default_asset->sample_rate);
173 package->video_end = Units::to_int64(label->position * default_asset->frame_rate);
176 if(package->audio_end > audio_end)
178 package->audio_end = audio_end;
181 if(package->video_end > video_end)
183 package->video_end = video_end;
186 audio_position = package->audio_end;
187 video_position = package->video_end;
188 // Create file number differently if image file sequence
189 Render::create_filename(package->path,
199 total_allocated = total_packages;
202 if(strategy == BRENDER_FARM)
204 total_len = this->total_end - this->total_start;
206 // Create packages as they're requested.
211 Render::get_starting_number(default_asset->path,
218 if(preferences->renderfarm_nodes.total == 1)
220 package_len = total_len;
221 min_package_len = total_len;
225 package_len = preferences->brender_fragment /
226 edl->session->frame_rate;
227 min_package_len = 1.0 / edl->session->frame_rate;
231 // Test existence of every output file.
232 // Only if this isn't a background render or non interactive.
233 if(strategy != BRENDER_FARM &&
237 ArrayList<char*> paths;
238 for(int i = 0; i < total_allocated; i++)
240 paths.append(packages[i]->path);
242 result = ConfirmSave::test_files(mwindow, &paths);
248 RenderPackage* PackageDispatcher::get_package(double frames_per_second,
253 package_lock->lock("PackageDispatcher::get_package");
255 if(debug) printf("PackageDispatcher::get_package %d %f %d %d\n",
261 // Store new frames per second for the node
262 if(!EQUIV(frames_per_second, 0))
264 preferences->set_rate(frames_per_second, client_number);
265 if(mwindow) mwindow->preferences->copy_rates_from(preferences);
268 // Use previous frames per second
270 frames_per_second = preferences->get_rate(client_number);
273 if(debug) printf("PackageDispatcher::get_package %d %f %d %d\n",
279 float avg_frames_per_second = preferences->get_avg_rate(use_local_rate);
281 RenderPackage *result = 0;
282 //printf("PackageDispatcher::get_package 1 %d\n", strategy);
283 if(strategy == SINGLE_PASS ||
284 strategy == FILE_PER_LABEL ||
285 strategy == FILE_PER_LABEL_FARM)
287 if(current_package < total_packages)
289 result = packages[current_package];
294 if(strategy == SINGLE_PASS_FARM)
297 //printf("PackageDispatcher::get_package %ld %ld %ld %ld\n", audio_position, video_position, audio_end, video_end);
299 if(audio_position < audio_end ||
300 video_position < video_end)
304 result = packages[current_package];
305 result->audio_start = audio_position;
306 result->video_start = video_position;
308 if(current_package >= total_allocated - 1)
310 result->audio_end = audio_end;
311 result->video_end = video_end;
312 audio_position = result->audio_end;
313 video_position = result->video_end;
316 // No useful speed data. May get infinity for real fast jobs.
317 if(frames_per_second > 0x7fffff || frames_per_second < 0 ||
318 EQUIV(frames_per_second, 0) ||
319 EQUIV(avg_frames_per_second, 0))
321 scaled_len = MAX(package_len, min_package_len);
323 result->audio_end = audio_position +
324 Units::round(scaled_len * default_asset->sample_rate);
325 result->video_end = video_position +
326 Units::round(scaled_len * default_asset->frame_rate);
328 // If we get here without any useful speed data, render the whole thing.
329 if(current_package >= total_packages - 1)
331 result->audio_end = audio_end;
332 result->video_end = video_end;
336 result->audio_end = MIN(audio_end, result->audio_end);
337 result->video_end = MIN(video_end, result->video_end);
340 audio_position = result->audio_end;
341 video_position = result->video_end;
344 // Useful speed data and future packages exist. Scale the
345 // package size to fit the requestor.
347 scaled_len = package_len *
349 avg_frames_per_second;
350 scaled_len = MAX(scaled_len, min_package_len);
352 result->audio_end = result->audio_start +
353 Units::to_int64(scaled_len * default_asset->sample_rate);
354 result->video_end = result->video_start +
355 Units::to_int64(scaled_len * default_asset->frame_rate);
357 result->audio_end = MIN(audio_end, result->audio_end);
358 result->video_end = MIN(video_end, result->video_end);
360 audio_position = result->audio_end;
361 video_position = result->video_end;
363 // Package size is no longer touched between total_packages and total_allocated
364 if(current_package < total_packages - 1)
366 package_len = (double)(audio_end - audio_position) /
367 (double)default_asset->sample_rate /
368 (double)(total_packages - current_package);
374 //printf("Dispatcher::get_package 50 %d " _LD " " _LD " " _LD " " _LD "\n",
376 // result->audio_start,
377 // result->video_start,
378 // result->audio_end,
379 // result->video_end);
383 if(strategy == BRENDER_FARM)
385 //printf("Dispatcher::get_package 1 %d %d\n", video_position, video_end);
386 if(video_position < video_end)
388 // Allocate new packages
389 if(total_packages == 0)
391 total_allocated = 256;
392 packages = new RenderPackage*[total_allocated];
395 if(total_packages >= total_allocated)
397 RenderPackage **old_packages = packages;
398 total_allocated *= 2;
399 packages = new RenderPackage*[total_allocated];
402 total_packages * sizeof(RenderPackage*));
403 delete [] old_packages;
406 // Calculate package.
407 result = packages[total_packages] = new RenderPackage;
410 // No load balancing data exists
411 if(EQUIV(frames_per_second, 0) ||
412 EQUIV(avg_frames_per_second, 0))
414 scaled_len = package_len;
417 // Load balancing data exists
419 scaled_len = package_len *
421 avg_frames_per_second;
424 scaled_len = MAX(scaled_len, min_package_len);
426 // Always an image file sequence
427 result->audio_start = audio_position;
428 result->video_start = video_position;
429 result->audio_end = result->audio_start +
430 Units::to_int64(scaled_len * default_asset->sample_rate);
431 result->video_end = result->video_start +
432 Units::to_int64(scaled_len * default_asset->frame_rate);
433 if(result->video_end == result->video_start) result->video_end++;
434 audio_position = result->audio_end;
435 video_position = result->video_end;
436 // The frame numbers are read from the vframe objects themselves.
437 Render::create_filename(result->path,
442 //printf("PackageDispatcher::get_package 2 %s\n", result->path);
450 package_lock->unlock();
452 if(debug && result) printf("PackageDispatcher::get_package %d %ld\n", __LINE__, (long)(result->video_end - result->video_start));
457 ArrayList<Indexable*>* PackageDispatcher::get_asset_list()
459 ArrayList<Indexable*> *assets = new ArrayList<Indexable*>;
462 if(debug) printf("PackageDispatcher::get_asset_list %d\n", __LINE__);
463 if(debug) default_asset->dump();
464 for(int i = 0; i < current_package; i++)
466 Asset *asset = new Asset;
467 asset->copy_from(default_asset, 1);
468 strcpy(asset->path, packages[i]->path);
469 asset->video_length = packages[i]->video_end - packages[i]->video_start;
470 asset->audio_length = packages[i]->audio_end - packages[i]->audio_start;
471 assets->append(asset);
472 if(debug) printf("PackageDispatcher::get_asset_list %d\n", __LINE__);
473 if(debug) asset->dump();
479 RenderPackage* PackageDispatcher::get_package(int number)
481 return packages[number];
484 int PackageDispatcher::get_total_packages()
486 return total_allocated;