Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

packagedispatcher.C

Go to the documentation of this file.
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 // sleep(1);
00061 // printf("PackageDispatcher::create_packages 1 %d %f %f\n", 
00062 // video_end, 
00063 // total_end, 
00064 // default_asset->frame_rate);
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 //printf("PackageDispatcher::create_packages: %f / %d = %f\n", total_len, total_packages, package_len);
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 // Create file number differently if image file sequence
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 // Create file number differently if image file sequence
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 // Create packages as they're requested.
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 // Master node only
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 // Test existence of every output file.
00210 // Only if this isn't a background render or non interactive.
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 // printf("PackageDispatcher::get_package 1 %f\n", 
00232 // frames_per_second);
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 //printf("PackageDispatcher::get_package 1 %d\n", strategy);
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 //printf("PackageDispatcher::get_package %ld %ld %ld %ld\n", audio_position, video_position, audio_end, video_end);
00255 
00256                 if(audio_position < audio_end ||
00257                         video_position < video_end)
00258                 {
00259 // Last package
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 // No useful speed data.  May get infinity for real fast jobs.
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 // If we get here without any useful speed data render the whole thing.
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 // Useful speed data and future packages exist.  Scale the 
00302 // package size to fit the requestor.
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 // Package size is no longer touched between total_packages and total_allocated
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 //printf("Dispatcher::get_package 50 %lld %lld %lld %lld\n", 
00332 //result->audio_start, 
00333 //result->video_start, 
00334 //result->audio_end, 
00335 //result->video_end);
00336                 }
00337         }
00338         else
00339         if(strategy == BRENDER_FARM)
00340         {
00341 //printf("Dispatcher::get_package 1 %d %d\n", video_position, video_end);
00342                 if(video_position < video_end)
00343                 {
00344 // Allocate new packages
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 // Calculate package.
00363                         result = packages[total_packages] = new RenderPackage;
00364                         double scaled_len;
00365 
00366 // No load balancing data exists
00367                         if(EQUIV(frames_per_second, 0) || 
00368                                 EQUIV(avg_frames_per_second, 0))
00369                         {
00370                                 scaled_len = package_len;
00371                         }
00372                         else
00373 // Load balancing data exists
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 // Always an image file sequence
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 // The frame numbers are read from the vframe objects themselves.
00393                         Render::create_filename(result->path,
00394                                 default_asset->path,
00395                                 0,
00396                                 total_digits,
00397                                 number_start);
00398 //printf("PackageDispatcher::get_package 2 %s\n", result->path);
00399 
00400                         current_number++;
00401                         total_packages++;
00402                         current_package++;
00403                 }
00404         }
00405 
00406         package_lock->unlock();
00407 
00408 //printf("PackageDispatcher::get_package %p\n", result);
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 

Generated on Sun Jan 8 13:38:57 2006 for Cinelerra-svn by  doxygen 1.4.4