r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / packagedispatcher.C
blobbf7cdeeceb45cf6aa513a8230360beec3f910754
1 #include "assets.h"
2 #include "clip.h"
3 #include "edl.h"
4 #include "edlsession.h"
5 #include "mutex.h"
6 #include "mwindow.h"
7 #include "packagedispatcher.h"
8 #include "packagerenderer.h"
9 #include "preferences.h"
10 #include "render.h"
15 PackageDispatcher::PackageDispatcher()
17         packages = 0;
18         package_lock = new Mutex;
21 PackageDispatcher::~PackageDispatcher()
23         if(packages)
24         {
25                 for(int i = 0; i < total_packages; i++)
26                         delete packages[i];
27                 delete [] packages;
28         }
29         delete package_lock;
32 int PackageDispatcher::create_packages(MWindow *mwindow,
33         EDL *edl,
34         Preferences *preferences,
35         int strategy, 
36         Asset *default_asset, 
37         double total_start, 
38         double total_end)
40         int result = 0;
42         this->mwindow = mwindow;
43         this->edl = edl;
44         this->preferences = preferences;
45         this->strategy = strategy;
46         this->default_asset = default_asset;
47         this->total_start = total_start;
48         this->total_end = total_end;
50         nodes = preferences->get_enabled_nodes();
51         audio_position = Units::to_int64(total_start * default_asset->sample_rate);
52         video_position = Units::to_int64(total_start * default_asset->frame_rate);
53         audio_end = Units::to_int64(total_end * default_asset->sample_rate);
54         video_end = Units::to_int64(total_end * default_asset->frame_rate);
55         current_package = 0;
57 // sleep(1);
58 // printf("PackageDispatcher::create_packages 1 %d %f %f\n", 
59 // video_end, 
60 // total_end, 
61 // default_asset->frame_rate);
65         if(strategy == SINGLE_PASS)
66         {
67                 total_len = this->total_end - this->total_start;
68                 package_len = total_len;
69                 min_package_len = total_len;
70                 total_packages = 1;
71                 total_allocated = 1;
72                 packages = new RenderPackage*[total_allocated];
73                 packages[0] = new RenderPackage;
74                 packages[0]->audio_start = audio_position;
75                 packages[0]->audio_end = audio_end;
76                 packages[0]->video_start = video_position;
77                 packages[0]->video_end = video_end;
78                 strcpy(packages[0]->path, default_asset->path);
79         }
80         else
81         if(strategy == SINGLE_PASS_FARM)
82         {
83                 total_len = this->total_end - this->total_start;
84                 total_packages = preferences->renderfarm_job_count;
85                 total_allocated = total_packages + nodes;
86                 packages = new RenderPackage*[total_allocated];
87                 package_len = total_len / total_packages;
88                 min_package_len = 2.0 / edl->session->frame_rate;
91 //printf("PackageDispatcher::create_packages: %f / %d = %f\n", total_len, total_packages, package_len);
92                 Render::get_starting_number(default_asset->path, 
93                         current_number,
94                         number_start, 
95                         total_digits,
96                         3);
98                 for(int i = 0; i < total_allocated; i++)
99                 {
100                         RenderPackage *package = packages[i] = new RenderPackage;
102 // Create file number differently if image file sequence
103                         Render::create_filename(package->path, 
104                                 default_asset->path, 
105                                 current_number,
106                                 total_digits,
107                                 number_start);
108                         current_number++;
109                 }
110         }
111         else
112         if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM)
113         {
114                 Label *label = edl->labels->first;
115                 total_packages = 0;
116                 packages = new RenderPackage*[edl->labels->total() + 2];
118                 Render::get_starting_number(default_asset->path, 
119                         current_number,
120                         number_start, 
121                         total_digits,
122                         2);
124                 while(audio_position < audio_end)
125                 {
126                         RenderPackage *package = 
127                                 packages[total_packages] = 
128                                 new RenderPackage;
129                         package->audio_start = audio_position;
130                         package->video_start = video_position;
133                         while(label && 
134                                 (label->position < (double)audio_position / default_asset->sample_rate ||
135                                 EQUIV(label->position, (double)audio_position / default_asset->sample_rate)))
136                         {
137                                 label = label->next;
138                         }
140                         if(!label)
141                         {
142                                 package->audio_end = Units::to_int64(total_end * default_asset->sample_rate);
143                                 package->video_end = Units::to_int64(total_end * default_asset->frame_rate);
144                         }
145                         else
146                         {
147                                 package->audio_end = Units::to_int64(label->position * default_asset->sample_rate);
148                                 package->video_end = Units::to_int64(label->position * default_asset->frame_rate);
149                         }
151                         if(package->audio_end > audio_end)
152                         {
153                                 package->audio_end = audio_end;
154                         }
156                         if(package->video_end > video_end)
157                         {
158                                 package->video_end = video_end;
159                         }
161                         audio_position = package->audio_end;
162                         video_position = package->video_end;
163 // Create file number differently if image file sequence
164                         Render::create_filename(package->path, 
165                                 default_asset->path, 
166                                 current_number,
167                                 total_digits,
168                                 number_start);
169                         current_number++;
171                         total_packages++;
172                 }
173                 
174                 total_allocated = total_packages;
175         }
176         else
177         if(strategy == BRENDER_FARM)
178         {
179                 total_len = this->total_end - this->total_start;
181 // Create packages as they're requested.
182                 total_packages = 0;
183                 total_allocated = 0;
184                 packages = 0;
186                 Render::get_starting_number(default_asset->path, 
187                         current_number,
188                         number_start, 
189                         total_digits,
190                         6);
192 // Master node only
193                 if(preferences->renderfarm_nodes.total == 1)
194                 {
195                         package_len = total_len;
196                         min_package_len = total_len;
197                 }
198                 else
199                 {
200                         package_len = preferences->brender_fragment / 
201                                 edl->session->frame_rate;
202                         min_package_len = 1.0 / edl->session->frame_rate;
203                 }
204         }
206 // Test existence of every output file
207         if(strategy != BRENDER_FARM)
208         {
209                 for(int i = 0; i < total_allocated && !result; i++)
210                 {
211                         Asset temp_asset(packages[i]->path);
212                         result = Render::test_existence(mwindow, &temp_asset);
213                 }
214         }
215         
216         return result;
219 RenderPackage* PackageDispatcher::get_package(double frames_per_second, 
220         int client_number,
221         int use_local_rate)
223         package_lock->lock();
225         preferences->set_rate(frames_per_second, client_number);
226         mwindow->preferences->copy_rates_from(preferences);
227         float avg_frames_per_second = preferences->get_avg_rate(use_local_rate);
229         RenderPackage *result = 0;
230         if(strategy == SINGLE_PASS || 
231                 strategy == FILE_PER_LABEL || 
232                 strategy == FILE_PER_LABEL_FARM)
233         {
234                 if(current_package < total_packages)
235                 {
236                         result = packages[current_package];
237                         current_package++;
238                 }
239         }
240         else
241         if(strategy == SINGLE_PASS_FARM)
242         {
243 //printf("PackageDispatcher::get_package 1\n");
244                 if(audio_position < audio_end ||
245                         video_position < video_end)
246                 {
247 // Last package
248 //printf("PackageDispatcher::get_package 2\n");
249                         double scaled_len;
250                         result = packages[current_package];
251                         result->audio_start = audio_position;
252                         result->video_start = video_position;
254 //printf("PackageDispatcher::get_package 3\n");
255                         if(current_package >= total_allocated - 1)
256                         {
257                                 result->audio_end = audio_end;
258                                 result->video_end = video_end;
259                                 audio_position = result->audio_end;
260                                 video_position = result->video_end;
261                         }
262                         else
263 // No useful speed data
264                         if(EQUIV(frames_per_second, 0) || 
265                                 EQUIV(avg_frames_per_second, 0))
266                         {
267                                 scaled_len = MAX(package_len, min_package_len);
269 //printf("PackageDispatcher::get_package 4\n");
270                                 result->audio_end = audio_position + 
271                                         Units::round(scaled_len * default_asset->sample_rate);
272                                 result->video_end = video_position + 
273                                         Units::round(scaled_len * default_asset->frame_rate);
275 //printf("PackageDispatcher::get_package 5\n");
276 // If we get here without any useful speed data render the whole thing.
277                                 if(current_package >= total_packages - 1)
278                                 {
279                                         result->audio_end = audio_end;
280                                         result->video_end = video_end;
281                                 }
282                                 else
283                                 {
284                                         result->audio_end = MIN(audio_end, result->audio_end);
285                                         result->video_end = MIN(video_end, result->video_end);
286                                 }
288 //printf("PackageDispatcher::get_package 6\n");
289                                 audio_position = result->audio_end;
290                                 video_position = result->video_end;
291                         }
292                         else
293 // Useful speed data and future packages exist.  Scale the 
294 // package size to fit the requestor.
295                         {
296                                 scaled_len = package_len * 
297                                         frames_per_second / 
298                                         avg_frames_per_second;
299                                 scaled_len = MAX(scaled_len, min_package_len);
301 //printf("PackageDispatcher::get_package 7\n");
302                                 result->audio_end = result->audio_start + 
303                                         Units::to_int64(scaled_len * default_asset->sample_rate);
304                                 result->video_end = result->video_start +
305                                         Units::to_int64(scaled_len * default_asset->frame_rate);
307 //printf("PackageDispatcher::get_package 8\n");
308                                 result->audio_end = MIN(audio_end, result->audio_end);
309                                 result->video_end = MIN(video_end, result->video_end);
311 //printf("PackageDispatcher::get_package 9\n");
312                                 audio_position = result->audio_end;
313                                 video_position = result->video_end;
315 //printf("PackageDispatcher::get_package 10\n");
316 // Package size is no longer touched between total_packages and total_allocated
317                                 if(current_package < total_packages - 1)
318                                 {
319                                         package_len = (double)(audio_end - audio_position) / 
320                                                 (double)default_asset->sample_rate /
321                                                 (double)(total_packages - current_package);
322                                 }
324 //printf("PackageDispatcher::get_package 11\n");
325                         }
327                         current_package++;
328 //printf("Dispatcher::get_package 2 %d %d %d %d\n", 
329 //result->audio_start, result->video_start, result->audio_end, result->video_end);
330                 }
331         }
332         else
333         if(strategy == BRENDER_FARM)
334         {
335 //printf("Dispatcher::get_package 1 %d %d\n", video_position, video_end);
336                 if(video_position < video_end)
337                 {
338 // Allocate new packages
339                         if(total_packages == 0)
340                         {
341                                 total_allocated = 256;
342                                 packages = new RenderPackage*[total_allocated];
343                         }
344                         else
345                         if(total_packages >= total_allocated)
346                         {
347                                 RenderPackage **old_packages = packages;
348                                 total_allocated *= 2;
349                                 packages = new RenderPackage*[total_allocated];
350                                 memcpy(packages, 
351                                         old_packages, 
352                                         total_packages * sizeof(RenderPackage*));
353                                 delete [] old_packages;
354                         }
356 // Calculate package.
357                         result = packages[total_packages] = new RenderPackage;
358                         double scaled_len;
360 // No load balancing data exists
361                         if(EQUIV(frames_per_second, 0) || 
362                                 EQUIV(avg_frames_per_second, 0))
363                         {
364                                 scaled_len = package_len;
365                         }
366                         else
367 // Load balancing data exists
368                         {
369                                 scaled_len = package_len * 
370                                         frames_per_second / 
371                                         avg_frames_per_second;
372                         }
374                         scaled_len = MAX(scaled_len, min_package_len);
376 // Always an image file sequence
377                         result->audio_start = audio_position;
378                         result->video_start = video_position;
379                         result->audio_end = result->audio_start + 
380                                 Units::to_int64(scaled_len * default_asset->sample_rate);
381                         result->video_end = result->video_start + 
382                                 Units::to_int64(scaled_len * default_asset->frame_rate);
383                         if(result->video_end == result->video_start) result->video_end++;
384                         audio_position = result->audio_end;
385                         video_position = result->video_end;
386 // The frame numbers are read from the vframe objects themselves.
387                         Render::create_filename(result->path,
388                                 default_asset->path,
389                                 0,
390                                 total_digits,
391                                 number_start);
392 //printf("PackageDispatcher::get_package 2 %s\n", result->path);
394                         current_number++;
395                         total_packages++;
396                         current_package++;
397                 }
398         }
400         package_lock->unlock();
402         return result;
406 ArrayList<Asset*>* PackageDispatcher::get_asset_list()
408         ArrayList<Asset*> *assets = new ArrayList<Asset*>;
410         for(int i = 0; i < current_package; i++)
411         {
412                 Asset *asset = new Asset;
413                 *asset = *default_asset;
414                 strcpy(asset->path, packages[i]->path);
415                 asset->video_length = packages[i]->video_end - packages[i]->video_start;
416                 asset->audio_length = packages[i]->audio_end - packages[i]->audio_start;
417                 assets->append(asset);
418         }
420         return assets;