r802: Remove renderframfsclient and renderfarmfsserver .h and .C from Makefile.am...
[cinelerra_cv/mob.git] / cinelerra / packagedispatcher.C
blob622dfdc9aba47d6a67a4b59f97fc05ded5eae2a2
1 #include "asset.h"
2 #include "clip.h"
3 #include "confirmsave.h"
4 #include "edl.h"
5 #include "edlsession.h"
6 #include "labels.h"
7 #include "mutex.h"
8 #include "mwindow.h"
9 #include "packagedispatcher.h"
10 #include "packagerenderer.h"
11 #include "preferences.h"
12 #include "render.h"
17 PackageDispatcher::PackageDispatcher()
19         packages = 0;
20         package_lock = new Mutex("PackageDispatcher::package_lock");
23 PackageDispatcher::~PackageDispatcher()
25         if(packages)
26         {
27                 for(int i = 0; i < total_packages; i++)
28                         delete packages[i];
29                 delete [] packages;
30         }
31         delete package_lock;
34 int PackageDispatcher::create_packages(MWindow *mwindow,
35         EDL *edl,
36         Preferences *preferences,
37         int strategy, 
38         Asset *default_asset, 
39         double total_start, 
40         double total_end,
41         int test_overwrite)
43         int result = 0;
45         this->mwindow = mwindow;
46         this->edl = edl;
47         this->preferences = preferences;
48         this->strategy = strategy;
49         this->default_asset = default_asset;
50         this->total_start = total_start;
51         this->total_end = total_end;
53         nodes = preferences->get_enabled_nodes();
54         audio_position = Units::to_int64(total_start * default_asset->sample_rate);
55         video_position = Units::to_int64(total_start * default_asset->frame_rate);
56         audio_end = Units::to_int64(total_end * default_asset->sample_rate);
57         video_end = Units::to_int64(total_end * default_asset->frame_rate);
58         current_package = 0;
60 // sleep(1);
61 // printf("PackageDispatcher::create_packages 1 %d %f %f\n", 
62 // video_end, 
63 // total_end, 
64 // default_asset->frame_rate);
68         if(strategy == SINGLE_PASS)
69         {
70                 total_len = this->total_end - this->total_start;
71                 package_len = total_len;
72                 min_package_len = total_len;
73                 total_packages = 1;
74                 total_allocated = 1;
75                 packages = new RenderPackage*[total_allocated];
76                 packages[0] = new RenderPackage;
77                 packages[0]->audio_start = audio_position;
78                 packages[0]->audio_end = audio_end;
79                 packages[0]->video_start = video_position;
80                 packages[0]->video_end = video_end;
81                 strcpy(packages[0]->path, default_asset->path);
82         }
83         else
84         if(strategy == SINGLE_PASS_FARM)
85         {
86                 total_len = this->total_end - this->total_start;
87                 total_packages = preferences->renderfarm_job_count;
88                 total_allocated = total_packages + nodes;
89                 packages = new RenderPackage*[total_allocated];
90                 package_len = total_len / total_packages;
91                 min_package_len = 2.0 / edl->session->frame_rate;
94 //printf("PackageDispatcher::create_packages: %f / %d = %f\n", total_len, total_packages, package_len);
95                 Render::get_starting_number(default_asset->path, 
96                         current_number,
97                         number_start, 
98                         total_digits,
99                         3);
101                 for(int i = 0; i < total_allocated; i++)
102                 {
103                         RenderPackage *package = packages[i] = new RenderPackage;
105 // Create file number differently if image file sequence
106                         Render::create_filename(package->path, 
107                                 default_asset->path, 
108                                 current_number,
109                                 total_digits,
110                                 number_start);
111                         current_number++;
112                 }
113         }
114         else
115         if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM)
116         {
117                 Label *label = edl->labels->first;
118                 total_packages = 0;
119                 packages = new RenderPackage*[edl->labels->total() + 2];
121                 Render::get_starting_number(default_asset->path, 
122                         current_number,
123                         number_start, 
124                         total_digits,
125                         2);
127                 while(audio_position < audio_end)
128                 {
129                         RenderPackage *package = 
130                                 packages[total_packages] = 
131                                 new RenderPackage;
132                         package->audio_start = audio_position;
133                         package->video_start = video_position;
136                         while(label && 
137                                 (label->position < (double)audio_position / default_asset->sample_rate ||
138                                 EQUIV(label->position, (double)audio_position / default_asset->sample_rate)))
139                         {
140                                 label = label->next;
141                         }
143                         if(!label)
144                         {
145                                 package->audio_end = Units::to_int64(total_end * default_asset->sample_rate);
146                                 package->video_end = Units::to_int64(total_end * default_asset->frame_rate);
147                         }
148                         else
149                         {
150                                 package->audio_end = Units::to_int64(label->position * default_asset->sample_rate);
151                                 package->video_end = Units::to_int64(label->position * default_asset->frame_rate);
152                         }
154                         if(package->audio_end > audio_end)
155                         {
156                                 package->audio_end = audio_end;
157                         }
159                         if(package->video_end > video_end)
160                         {
161                                 package->video_end = video_end;
162                         }
164                         audio_position = package->audio_end;
165                         video_position = package->video_end;
166 // Create file number differently if image file sequence
167                         Render::create_filename(package->path, 
168                                 default_asset->path, 
169                                 current_number,
170                                 total_digits,
171                                 number_start);
172                         current_number++;
174                         total_packages++;
175                 }
176                 
177                 total_allocated = total_packages;
178         }
179         else
180         if(strategy == BRENDER_FARM)
181         {
182                 total_len = this->total_end - this->total_start;
184 // Create packages as they're requested.
185                 total_packages = 0;
186                 total_allocated = 0;
187                 packages = 0;
189                 Render::get_starting_number(default_asset->path, 
190                         current_number,
191                         number_start, 
192                         total_digits,
193                         6);
195 // Master node only
196                 if(preferences->renderfarm_nodes.total == 1)
197                 {
198                         package_len = total_len;
199                         min_package_len = total_len;
200                 }
201                 else
202                 {
203                         package_len = preferences->brender_fragment / 
204                                 edl->session->frame_rate;
205                         min_package_len = 1.0 / edl->session->frame_rate;
206                 }
207         }
209 // Test existence of every output file.
210 // Only if this isn't a background render or non interactive.
211         if(strategy != BRENDER_FARM && 
212                 test_overwrite &&
213                 mwindow)
214         {
215                 ArrayList<char*> paths;
216                 for(int i = 0; i < total_allocated; i++)
217                 {
218                         paths.append(packages[i]->path);
219                 }
220                 result = ConfirmSave::test_files(mwindow, &paths);
221         }
222         
223         return result;
226 RenderPackage* PackageDispatcher::get_package(double frames_per_second, 
227         int client_number,
228         int use_local_rate)
230         package_lock->lock("PackageDispatcher::get_package");
231 // printf("PackageDispatcher::get_package 1 %f\n", 
232 // frames_per_second);
234         preferences->set_rate(frames_per_second, client_number);
235         if(mwindow) mwindow->preferences->copy_rates_from(preferences);
236         float avg_frames_per_second = preferences->get_avg_rate(use_local_rate);
238         RenderPackage *result = 0;
239 //printf("PackageDispatcher::get_package 1 %d\n", strategy);
240         if(strategy == SINGLE_PASS || 
241                 strategy == FILE_PER_LABEL || 
242                 strategy == FILE_PER_LABEL_FARM)
243         {
244                 if(current_package < total_packages)
245                 {
246                         result = packages[current_package];
247                         current_package++;
248                 }
249         }
250         else
251         if(strategy == SINGLE_PASS_FARM)
252         {
254 //printf("PackageDispatcher::get_package %ld %ld %ld %ld\n", audio_position, video_position, audio_end, video_end);
256                 if(audio_position < audio_end ||
257                         video_position < video_end)
258                 {
259 // Last package
260                         double scaled_len;
261                         result = packages[current_package];
262                         result->audio_start = audio_position;
263                         result->video_start = video_position;
265                         if(current_package >= total_allocated - 1)
266                         {
267                                 result->audio_end = audio_end;
268                                 result->video_end = video_end;
269                                 audio_position = result->audio_end;
270                                 video_position = result->video_end;
271                         }
272                         else
273 // No useful speed data.  May get infinity for real fast jobs.
274                         if(frames_per_second > 0x7fffff || frames_per_second < 0 ||
275                                 EQUIV(frames_per_second, 0) || 
276                                 EQUIV(avg_frames_per_second, 0))
277                         {
278                                 scaled_len = MAX(package_len, min_package_len);
280                                 result->audio_end = audio_position + 
281                                         Units::round(scaled_len * default_asset->sample_rate);
282                                 result->video_end = video_position + 
283                                         Units::round(scaled_len * default_asset->frame_rate);
285 // If we get here without any useful speed data render the whole thing.
286                                 if(current_package >= total_packages - 1)
287                                 {
288                                         result->audio_end = audio_end;
289                                         result->video_end = video_end;
290                                 }
291                                 else
292                                 {
293                                         result->audio_end = MIN(audio_end, result->audio_end);
294                                         result->video_end = MIN(video_end, result->video_end);
295                                 }
297                                 audio_position = result->audio_end;
298                                 video_position = result->video_end;
299                         }
300                         else
301 // Useful speed data and future packages exist.  Scale the 
302 // package size to fit the requestor.
303                         {
304                                 scaled_len = package_len * 
305                                         frames_per_second / 
306                                         avg_frames_per_second;
307                                 scaled_len = MAX(scaled_len, min_package_len);
309                                 result->audio_end = result->audio_start + 
310                                         Units::to_int64(scaled_len * default_asset->sample_rate);
311                                 result->video_end = result->video_start +
312                                         Units::to_int64(scaled_len * default_asset->frame_rate);
314                                 result->audio_end = MIN(audio_end, result->audio_end);
315                                 result->video_end = MIN(video_end, result->video_end);
317                                 audio_position = result->audio_end;
318                                 video_position = result->video_end;
320 // Package size is no longer touched between total_packages and total_allocated
321                                 if(current_package < total_packages - 1)
322                                 {
323                                         package_len = (double)(audio_end - audio_position) / 
324                                                 (double)default_asset->sample_rate /
325                                                 (double)(total_packages - current_package);
326                                 }
328                         }
330                         current_package++;
331 //printf("Dispatcher::get_package 50 %lld %lld %lld %lld\n", 
332 //result->audio_start, 
333 //result->video_start, 
334 //result->audio_end, 
335 //result->video_end);
336                 }
337         }
338         else
339         if(strategy == BRENDER_FARM)
340         {
341 //printf("Dispatcher::get_package 1 %d %d\n", video_position, video_end);
342                 if(video_position < video_end)
343                 {
344 // Allocate new packages
345                         if(total_packages == 0)
346                         {
347                                 total_allocated = 256;
348                                 packages = new RenderPackage*[total_allocated];
349                         }
350                         else
351                         if(total_packages >= total_allocated)
352                         {
353                                 RenderPackage **old_packages = packages;
354                                 total_allocated *= 2;
355                                 packages = new RenderPackage*[total_allocated];
356                                 memcpy(packages, 
357                                         old_packages, 
358                                         total_packages * sizeof(RenderPackage*));
359                                 delete [] old_packages;
360                         }
362 // Calculate package.
363                         result = packages[total_packages] = new RenderPackage;
364                         double scaled_len;
366 // No load balancing data exists
367                         if(EQUIV(frames_per_second, 0) || 
368                                 EQUIV(avg_frames_per_second, 0))
369                         {
370                                 scaled_len = package_len;
371                         }
372                         else
373 // Load balancing data exists
374                         {
375                                 scaled_len = package_len * 
376                                         frames_per_second / 
377                                         avg_frames_per_second;
378                         }
380                         scaled_len = MAX(scaled_len, min_package_len);
382 // Always an image file sequence
383                         result->audio_start = audio_position;
384                         result->video_start = video_position;
385                         result->audio_end = result->audio_start + 
386                                 Units::to_int64(scaled_len * default_asset->sample_rate);
387                         result->video_end = result->video_start + 
388                                 Units::to_int64(scaled_len * default_asset->frame_rate);
389                         if(result->video_end == result->video_start) result->video_end++;
390                         audio_position = result->audio_end;
391                         video_position = result->video_end;
392 // The frame numbers are read from the vframe objects themselves.
393                         Render::create_filename(result->path,
394                                 default_asset->path,
395                                 0,
396                                 total_digits,
397                                 number_start);
398 //printf("PackageDispatcher::get_package 2 %s\n", result->path);
400                         current_number++;
401                         total_packages++;
402                         current_package++;
403                 }
404         }
406         package_lock->unlock();
408 //printf("PackageDispatcher::get_package %p\n", result);
409         return result;
413 ArrayList<Asset*>* PackageDispatcher::get_asset_list()
415         ArrayList<Asset*> *assets = new ArrayList<Asset*>;
417         for(int i = 0; i < current_package; i++)
418         {
419                 Asset *asset = new Asset;
420                 *asset = *default_asset;
421                 strcpy(asset->path, packages[i]->path);
422                 asset->video_length = packages[i]->video_end - packages[i]->video_start;
423                 asset->audio_length = packages[i]->audio_end - packages[i]->audio_start;
424                 assets->append(asset);
425         }
427         return assets;
430 RenderPackage* PackageDispatcher::get_package(int number)
432         return packages[number];
435 int PackageDispatcher::get_total_packages()
437         return total_allocated;