00001 #include "asset.h"
00002 #include "clip.h"
00003 #include "confirmsave.h"
00004 #include "edl.h"
00005 #include "edlsession.h"
00006 #include "labels.h"
00007 #include "mutex.h"
00008 #include "mwindow.h"
00009 #include "packagedispatcher.h"
00010 #include "packagerenderer.h"
00011 #include "preferences.h"
00012 #include "render.h"
00013
00014
00015
00016
00017 PackageDispatcher::PackageDispatcher()
00018 {
00019 packages = 0;
00020 package_lock = new Mutex("PackageDispatcher::package_lock");
00021 }
00022
00023 PackageDispatcher::~PackageDispatcher()
00024 {
00025 if(packages)
00026 {
00027 for(int i = 0; i < total_packages; i++)
00028 delete packages[i];
00029 delete [] packages;
00030 }
00031 delete package_lock;
00032 }
00033
00034 int PackageDispatcher::create_packages(MWindow *mwindow,
00035 EDL *edl,
00036 Preferences *preferences,
00037 int strategy,
00038 Asset *default_asset,
00039 double total_start,
00040 double total_end,
00041 int test_overwrite)
00042 {
00043 int result = 0;
00044
00045 this->mwindow = mwindow;
00046 this->edl = edl;
00047 this->preferences = preferences;
00048 this->strategy = strategy;
00049 this->default_asset = default_asset;
00050 this->total_start = total_start;
00051 this->total_end = total_end;
00052
00053 nodes = preferences->get_enabled_nodes();
00054 audio_position = Units::to_int64(total_start * default_asset->sample_rate);
00055 video_position = Units::to_int64(total_start * default_asset->frame_rate);
00056 audio_end = Units::to_int64(total_end * default_asset->sample_rate);
00057 video_end = Units::to_int64(total_end * default_asset->frame_rate);
00058 current_package = 0;
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 if(strategy == SINGLE_PASS)
00069 {
00070 total_len = this->total_end - this->total_start;
00071 package_len = total_len;
00072 min_package_len = total_len;
00073 total_packages = 1;
00074 total_allocated = 1;
00075 packages = new RenderPackage*[total_allocated];
00076 packages[0] = new RenderPackage;
00077 packages[0]->audio_start = audio_position;
00078 packages[0]->audio_end = audio_end;
00079 packages[0]->video_start = video_position;
00080 packages[0]->video_end = video_end;
00081 strcpy(packages[0]->path, default_asset->path);
00082 }
00083 else
00084 if(strategy == SINGLE_PASS_FARM)
00085 {
00086 total_len = this->total_end - this->total_start;
00087 total_packages = preferences->renderfarm_job_count;
00088 total_allocated = total_packages + nodes;
00089 packages = new RenderPackage*[total_allocated];
00090 package_len = total_len / total_packages;
00091 min_package_len = 2.0 / edl->session->frame_rate;
00092
00093
00094
00095 Render::get_starting_number(default_asset->path,
00096 current_number,
00097 number_start,
00098 total_digits,
00099 3);
00100
00101 for(int i = 0; i < total_allocated; i++)
00102 {
00103 RenderPackage *package = packages[i] = new RenderPackage;
00104
00105
00106 Render::create_filename(package->path,
00107 default_asset->path,
00108 current_number,
00109 total_digits,
00110 number_start);
00111 current_number++;
00112 }
00113 }
00114 else
00115 if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM)
00116 {
00117 Label *label = edl->labels->first;
00118 total_packages = 0;
00119 packages = new RenderPackage*[edl->labels->total() + 2];
00120
00121 Render::get_starting_number(default_asset->path,
00122 current_number,
00123 number_start,
00124 total_digits,
00125 2);
00126
00127 while(audio_position < audio_end)
00128 {
00129 RenderPackage *package =
00130 packages[total_packages] =
00131 new RenderPackage;
00132 package->audio_start = audio_position;
00133 package->video_start = video_position;
00134
00135
00136 while(label &&
00137 (label->position < (double)audio_position / default_asset->sample_rate ||
00138 EQUIV(label->position, (double)audio_position / default_asset->sample_rate)))
00139 {
00140 label = label->next;
00141 }
00142
00143 if(!label)
00144 {
00145 package->audio_end = Units::to_int64(total_end * default_asset->sample_rate);
00146 package->video_end = Units::to_int64(total_end * default_asset->frame_rate);
00147 }
00148 else
00149 {
00150 package->audio_end = Units::to_int64(label->position * default_asset->sample_rate);
00151 package->video_end = Units::to_int64(label->position * default_asset->frame_rate);
00152 }
00153
00154 if(package->audio_end > audio_end)
00155 {
00156 package->audio_end = audio_end;
00157 }
00158
00159 if(package->video_end > video_end)
00160 {
00161 package->video_end = video_end;
00162 }
00163
00164 audio_position = package->audio_end;
00165 video_position = package->video_end;
00166
00167 Render::create_filename(package->path,
00168 default_asset->path,
00169 current_number,
00170 total_digits,
00171 number_start);
00172 current_number++;
00173
00174 total_packages++;
00175 }
00176
00177 total_allocated = total_packages;
00178 }
00179 else
00180 if(strategy == BRENDER_FARM)
00181 {
00182 total_len = this->total_end - this->total_start;
00183
00184
00185 total_packages = 0;
00186 total_allocated = 0;
00187 packages = 0;
00188
00189 Render::get_starting_number(default_asset->path,
00190 current_number,
00191 number_start,
00192 total_digits,
00193 6);
00194
00195
00196 if(preferences->renderfarm_nodes.total == 1)
00197 {
00198 package_len = total_len;
00199 min_package_len = total_len;
00200 }
00201 else
00202 {
00203 package_len = preferences->brender_fragment /
00204 edl->session->frame_rate;
00205 min_package_len = 1.0 / edl->session->frame_rate;
00206 }
00207 }
00208
00209
00210
00211 if(strategy != BRENDER_FARM &&
00212 test_overwrite &&
00213 mwindow)
00214 {
00215 ArrayList<char*> paths;
00216 for(int i = 0; i < total_allocated; i++)
00217 {
00218 paths.append(packages[i]->path);
00219 }
00220 result = ConfirmSave::test_files(mwindow, &paths);
00221 }
00222
00223 return result;
00224 }
00225
00226 RenderPackage* PackageDispatcher::get_package(double frames_per_second,
00227 int client_number,
00228 int use_local_rate)
00229 {
00230 package_lock->lock("PackageDispatcher::get_package");
00231
00232
00233
00234 preferences->set_rate(frames_per_second, client_number);
00235 if(mwindow) mwindow->preferences->copy_rates_from(preferences);
00236 float avg_frames_per_second = preferences->get_avg_rate(use_local_rate);
00237
00238 RenderPackage *result = 0;
00239
00240 if(strategy == SINGLE_PASS ||
00241 strategy == FILE_PER_LABEL ||
00242 strategy == FILE_PER_LABEL_FARM)
00243 {
00244 if(current_package < total_packages)
00245 {
00246 result = packages[current_package];
00247 current_package++;
00248 }
00249 }
00250 else
00251 if(strategy == SINGLE_PASS_FARM)
00252 {
00253
00254
00255
00256 if(audio_position < audio_end ||
00257 video_position < video_end)
00258 {
00259
00260 double scaled_len;
00261 result = packages[current_package];
00262 result->audio_start = audio_position;
00263 result->video_start = video_position;
00264
00265 if(current_package >= total_allocated - 1)
00266 {
00267 result->audio_end = audio_end;
00268 result->video_end = video_end;
00269 audio_position = result->audio_end;
00270 video_position = result->video_end;
00271 }
00272 else
00273
00274 if(frames_per_second > 0x7fffff || frames_per_second < 0 ||
00275 EQUIV(frames_per_second, 0) ||
00276 EQUIV(avg_frames_per_second, 0))
00277 {
00278 scaled_len = MAX(package_len, min_package_len);
00279
00280 result->audio_end = audio_position +
00281 Units::round(scaled_len * default_asset->sample_rate);
00282 result->video_end = video_position +
00283 Units::round(scaled_len * default_asset->frame_rate);
00284
00285
00286 if(current_package >= total_packages - 1)
00287 {
00288 result->audio_end = audio_end;
00289 result->video_end = video_end;
00290 }
00291 else
00292 {
00293 result->audio_end = MIN(audio_end, result->audio_end);
00294 result->video_end = MIN(video_end, result->video_end);
00295 }
00296
00297 audio_position = result->audio_end;
00298 video_position = result->video_end;
00299 }
00300 else
00301
00302
00303 {
00304 scaled_len = package_len *
00305 frames_per_second /
00306 avg_frames_per_second;
00307 scaled_len = MAX(scaled_len, min_package_len);
00308
00309 result->audio_end = result->audio_start +
00310 Units::to_int64(scaled_len * default_asset->sample_rate);
00311 result->video_end = result->video_start +
00312 Units::to_int64(scaled_len * default_asset->frame_rate);
00313
00314 result->audio_end = MIN(audio_end, result->audio_end);
00315 result->video_end = MIN(video_end, result->video_end);
00316
00317 audio_position = result->audio_end;
00318 video_position = result->video_end;
00319
00320
00321 if(current_package < total_packages - 1)
00322 {
00323 package_len = (double)(audio_end - audio_position) /
00324 (double)default_asset->sample_rate /
00325 (double)(total_packages - current_package);
00326 }
00327
00328 }
00329
00330 current_package++;
00331
00332
00333
00334
00335
00336 }
00337 }
00338 else
00339 if(strategy == BRENDER_FARM)
00340 {
00341
00342 if(video_position < video_end)
00343 {
00344
00345 if(total_packages == 0)
00346 {
00347 total_allocated = 256;
00348 packages = new RenderPackage*[total_allocated];
00349 }
00350 else
00351 if(total_packages >= total_allocated)
00352 {
00353 RenderPackage **old_packages = packages;
00354 total_allocated *= 2;
00355 packages = new RenderPackage*[total_allocated];
00356 memcpy(packages,
00357 old_packages,
00358 total_packages * sizeof(RenderPackage*));
00359 delete [] old_packages;
00360 }
00361
00362
00363 result = packages[total_packages] = new RenderPackage;
00364 double scaled_len;
00365
00366
00367 if(EQUIV(frames_per_second, 0) ||
00368 EQUIV(avg_frames_per_second, 0))
00369 {
00370 scaled_len = package_len;
00371 }
00372 else
00373
00374 {
00375 scaled_len = package_len *
00376 frames_per_second /
00377 avg_frames_per_second;
00378 }
00379
00380 scaled_len = MAX(scaled_len, min_package_len);
00381
00382
00383 result->audio_start = audio_position;
00384 result->video_start = video_position;
00385 result->audio_end = result->audio_start +
00386 Units::to_int64(scaled_len * default_asset->sample_rate);
00387 result->video_end = result->video_start +
00388 Units::to_int64(scaled_len * default_asset->frame_rate);
00389 if(result->video_end == result->video_start) result->video_end++;
00390 audio_position = result->audio_end;
00391 video_position = result->video_end;
00392
00393 Render::create_filename(result->path,
00394 default_asset->path,
00395 0,
00396 total_digits,
00397 number_start);
00398
00399
00400 current_number++;
00401 total_packages++;
00402 current_package++;
00403 }
00404 }
00405
00406 package_lock->unlock();
00407
00408
00409 return result;
00410 }
00411
00412
00413 ArrayList<Asset*>* PackageDispatcher::get_asset_list()
00414 {
00415 ArrayList<Asset*> *assets = new ArrayList<Asset*>;
00416
00417 for(int i = 0; i < current_package; i++)
00418 {
00419 Asset *asset = new Asset;
00420 *asset = *default_asset;
00421 strcpy(asset->path, packages[i]->path);
00422 asset->video_length = packages[i]->video_end - packages[i]->video_start;
00423 asset->audio_length = packages[i]->audio_end - packages[i]->audio_start;
00424 assets->append(asset);
00425 }
00426
00427 return assets;
00428 }
00429
00430 RenderPackage* PackageDispatcher::get_package(int number)
00431 {
00432 return packages[number];
00433 }
00434
00435 int PackageDispatcher::get_total_packages()
00436 {
00437 return total_allocated;
00438 }
00439