fix ctl-x cut, reorganize track/edit popup, pack cut fixes, paste plugin new feature...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / packagingengine.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "packagingengine.h"
23 #include "preferences.h"
24 #include "edlsession.h"
25 #include "asset.h"
26 #include "render.h"
27 #include "clip.h"
28
29
30 // Default packaging engine implementation, simply split the range up, and consider client's speed
31
32 PackagingEngineDefault::PackagingEngineDefault()
33 {
34         packages = 0;
35 }
36
37 PackagingEngineDefault::~PackagingEngineDefault()
38 {
39         if(packages)
40         {
41                 for(int i = 0; i < total_packages; i++)
42                         delete packages[i];
43                 delete [] packages;
44         }
45 }
46
47
48 int PackagingEngineDefault::create_packages_single_farm(
49                 EDL *edl,
50                 Preferences *preferences,
51                 Asset *default_asset,
52                 double total_start,
53                 double total_end)
54 {
55         this->total_start = total_start;
56         this->total_end = total_end;
57
58         this->preferences = preferences;
59         this->default_asset = default_asset;
60         audio_position = Units::to_int64(total_start * default_asset->sample_rate);
61         video_position = Units::to_int64(total_start * default_asset->frame_rate);
62         audio_end = Units::to_int64(total_end * default_asset->sample_rate);
63         video_end = Units::to_int64(total_end * default_asset->frame_rate);
64         current_package = 0;
65
66         double total_len = total_end - total_start;
67         total_packages = preferences->renderfarm_job_count;
68         total_allocated = total_packages + preferences->get_enabled_nodes();
69         packages = new RenderPackage*[total_allocated];
70         package_len = total_len / total_packages;
71         min_package_len = 2.0 / edl->session->frame_rate;
72
73
74 //printf("PackageDispatcher::create_packages: %f / %d = %f\n", total_len, total_packages, package_len);
75         int current_number;    // The number being injected into the filename.
76         int number_start;      // Character in the filename path at which the number begins
77         int total_digits;      // Total number of digits including padding the user specified.
78
79         Render::get_starting_number(default_asset->path,
80                 current_number,
81                 number_start,
82                 total_digits,
83                 3);
84
85         for(int i = 0; i < total_allocated; i++)
86         {
87                 RenderPackage *package = packages[i] = new RenderPackage;
88
89 // Create file number differently if image file sequence
90                 Render::create_filename(package->path,
91                         default_asset->path,
92                         current_number,
93                         total_digits,
94                         number_start);
95                 current_number++;
96         }
97         return 0;
98 }
99
100 RenderPackage* PackagingEngineDefault::get_package_single_farm(double frames_per_second,
101                 int client_number,
102                 int use_local_rate)
103 {
104
105 //printf("PackageDispatcher::get_package %ld %ld %ld %ld\n", audio_position, video_position, audio_end, video_end);
106
107                 RenderPackage *result = 0;
108                 float avg_frames_per_second = preferences->get_avg_rate(use_local_rate);
109
110                 if(audio_position < audio_end ||
111                         video_position < video_end)
112                 {
113 // Last package
114                         double scaled_len;
115                         result = packages[current_package];
116                         result->audio_start = audio_position;
117                         result->video_start = video_position;
118                         result->video_do = default_asset->video_data;
119                         result->audio_do = default_asset->audio_data;
120
121                         if(current_package >= total_allocated - 1)
122                         {
123                                 result->audio_end = audio_end;
124                                 result->video_end = video_end;
125                                 audio_position = result->audio_end;
126                                 video_position = result->video_end;
127                         }
128                         else
129 // No useful speed data.  May get infinity for real fast jobs.
130                         if(frames_per_second > 0x7fffff || frames_per_second < 0 ||
131                                 EQUIV(frames_per_second, 0) ||
132                                 EQUIV(avg_frames_per_second, 0))
133                         {
134                                 scaled_len = MAX(package_len, min_package_len);
135
136                                 result->audio_end = audio_position +
137                                         Units::round(scaled_len * default_asset->sample_rate);
138                                 result->video_end = video_position +
139                                         Units::round(scaled_len * default_asset->frame_rate);
140
141 // If we get here without any useful speed data render the whole thing.
142                                 if(current_package >= total_packages - 1)
143                                 {
144                                         result->audio_end = audio_end;
145                                         result->video_end = video_end;
146                                 }
147                                 else
148                                 {
149                                         result->audio_end = MIN(audio_end, result->audio_end);
150                                         result->video_end = MIN(video_end, result->video_end);
151                                 }
152
153                                 audio_position = result->audio_end;
154                                 video_position = result->video_end;
155                         }
156                         else
157 // Useful speed data and future packages exist.  Scale the
158 // package size to fit the requestor.
159                         {
160                                 scaled_len = package_len *
161                                         frames_per_second /
162                                         avg_frames_per_second;
163                                 scaled_len = MAX(scaled_len, min_package_len);
164
165                                 result->audio_end = result->audio_start +
166                                         Units::to_int64(scaled_len * default_asset->sample_rate);
167                                 result->video_end = result->video_start +
168                                         Units::to_int64(scaled_len * default_asset->frame_rate);
169
170                                 result->audio_end = MIN(audio_end, result->audio_end);
171                                 result->video_end = MIN(video_end, result->video_end);
172
173                                 audio_position = result->audio_end;
174                                 video_position = result->video_end;
175
176 // Package size is no longer touched between total_packages and total_allocated
177                                 if(current_package < total_packages - 1)
178                                 {
179                                         package_len = (double)(audio_end - audio_position) /
180                                                 (double)default_asset->sample_rate /
181                                                 (double)(total_packages - current_package);
182                                 }
183
184                         }
185
186                         current_package++;
187 //printf("Dispatcher::get_package 50 %lld %lld %lld %lld\n",
188 //result->audio_start,
189 //result->video_start,
190 //result->audio_end,
191 //result->video_end);
192                 }
193                 return result;
194
195 }
196
197 void PackagingEngineDefault::get_package_paths(ArrayList<char*> *path_list)
198 {
199         for(int i = 0; i < total_allocated; i++)
200         {
201                 path_list->append(strdup(packages[i]->path));
202         }
203         path_list->set_free();
204 }
205
206 int64_t PackagingEngineDefault::get_progress_max()
207 {
208         return Units::to_int64(default_asset->sample_rate *
209                         (total_end - total_start)) +
210                 Units::to_int64(preferences->render_preroll *
211                         2 *
212                         default_asset->sample_rate);
213 }
214
215 int PackagingEngineDefault::packages_are_done()
216 {
217         return 0;
218 }
219
220
221
222