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