Credit Andrew R for finding the direct copy mods for exr and ppm sequences
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / vtransition.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 "assets.h"
23 #include "autoconf.h"
24 #include "bezierautos.h"
25 #include "cache.h"
26 #include "edit.h"
27 #include "edits.h"
28 #include "filexml.h"
29 #include "floatautos.h"
30 #include "mwindow.h"
31 #include "patch.h"
32 #include "trackcanvas.h"
33 #include "tracks.h"
34 #include "vedit.h"
35 #include "vedits.h"
36 #include "vframe.h"
37 #include "vtrack.h"
38 #include "datatype.h"
39
40 VTrack::VTrack(MWindow *mwindow, Tracks *tracks) : Track(mwindow, tracks)
41 {
42         data_type = TRACK_VIDEO;
43 }
44
45 VTrack::~VTrack()
46 {
47         delete edits;
48         delete camera_autos;
49         delete projector_autos;
50 }
51
52 int VTrack::create_derived_objs(int flash)
53 {
54         int i;
55         edits = new VEdits(mwindow, this);
56         camera_autos = new BezierAutos(this, WHITE,
57                 0, 0, 1, mwindow->track_w, mwindow->track_h);
58
59         projector_autos = new BezierAutos(this, WHITE,
60                 0, 0, 1, mwindow->output_w, mwindow->output_h);
61
62         fade_autos = new FloatAutos(this, LTGREY, -100, 100);
63         fade_autos->create_objects();
64
65         if(mwindow->gui)
66         {
67                 if(mwindow->session->tracks_vertical)
68                         draw(pixel, data_h, 0, tracks->canvas->h, flash);
69                 else
70                         draw(0, tracks->canvas->w, pixel, data_h, flash);
71         }
72 }
73
74
75 int VTrack::save_derived(FileXML *xml)
76 {
77         edits->save(xml);
78
79         if(camera_autos->total())
80         {
81                 xml->tag.set_title("CAMERAAUTOS");
82                 xml->append_tag();
83                 xml->append_newline();
84                 camera_autos->save(xml);
85                 xml->tag.set_title("/CAMERAAUTOS");
86                 xml->append_tag();
87                 xml->append_newline();
88         }
89
90         if(projector_autos->total())
91         {
92                 xml->tag.set_title("PROJECTORAUTOS");
93                 xml->append_tag();
94                 xml->append_newline();
95                 projector_autos->save(xml);
96                 xml->tag.set_title("/PROJECTORAUTOS");
97                 xml->append_tag();
98                 xml->append_newline();
99         }
100 }
101
102 int VTrack::load_derived(FileXML *xml, int automation_only, int edits_only, int load_all, int &output_channel)
103 {
104         if(xml->tag.title_is("CAMERAAUTOS"))
105         {
106                 camera_autos->load(xml, "/CAMERAAUTOS");
107         }
108         else
109         if(xml->tag.title_is("PROJECTORAUTOS"))
110         {
111                 projector_autos->load(xml, "/PROJECTORAUTOS");
112         }
113 }
114
115 long VTrack::length()
116 {
117         return tosamples(edits->end(), mwindow->sample_rate, mwindow->frame_rate);
118 }
119
120 // int VTrack::get_dimensions(float &view_start, float &view_units, float &zoom_units)
121 // {
122 //      view_start = toframes(mwindow->view_start, mwindow->sample_rate, mwindow->frame_rate);
123 //      view_units = toframes(tracks->view_samples(), mwindow->sample_rate, mwindow->frame_rate);
124 //      zoom_units = toframes(mwindow->zoom_sample, mwindow->sample_rate, mwindow->frame_rate);
125 // }
126
127 long VTrack::samples_to_units(long &samples)
128 {
129         samples = toframes_round(samples, mwindow->sample_rate, mwindow->frame_rate);
130 }
131
132 int VTrack::copy_derived(long start, long end, FileXML *xml)
133 {
134 // automation is copied in the Track::copy
135 }
136
137 int VTrack::copy_automation_derived(AutoConf *auto_conf, long start, long end, FileXML *xml)
138 {
139 // used for copying only automation
140         if(auto_conf->camera)
141         {
142                 xml->tag.set_title("CAMERAAUTOS");
143                 xml->append_tag();
144
145                 camera_autos->copy(start, end, xml, 1);
146
147                 xml->tag.set_title("/CAMERAAUTOS");
148                 xml->append_tag();
149                 xml->append_newline();
150         }
151
152         if(auto_conf->projector)
153         {
154                 xml->tag.set_title("PROJECTORAUTOS");
155                 xml->append_tag();
156
157                 projector_autos->copy(start, end, xml, 1);
158
159                 xml->tag.set_title("/PROJECTORAUTOS");
160                 xml->append_tag();
161                 xml->append_newline();
162         }
163 }
164
165 int VTrack::paste_derived(long start, long end, long total_length, FileXML *xml, int &current_channel)
166 {
167         if(xml->tag.title_is("CAMERAAUTOS"))
168         {
169                 camera_autos->paste(start, end, total_length, xml, "/CAMERAAUTOS", 1);
170         }
171         else
172         if(xml->tag.title_is("PROJECTORAUTOS"))
173         {
174                 projector_autos->paste(start, end, total_length, xml, "/PROJECTORAUTOS", 1);
175         }
176 }
177
178 int VTrack::paste_output(long startproject, long endproject, long startsource, long endsource, int layer, Asset *asset)
179 {
180         int result = 0;
181
182 //printf("VTrack::paste_output startproject %ld endproject %ld\n", startproject, endproject);
183         //Track::samples_to_units(startproject, endproject);
184
185         result = ((VEdits*)edits)->paste_edit(startproject,
186                                                 endproject,
187                                                 startsource,
188                                                 endsource - startsource,
189                                                 layer,
190                                                 0,
191                                                 0,
192                                                 1,
193                                                 asset);
194
195         //if(!result && mwindow->autos_follow_edits)
196         //{
197         //      paste_auto_silence(startproject, endproject);
198         //}
199         return result;
200 }
201
202 int VTrack::clear_derived(long start, long end)
203 {
204         if(mwindow->autos_follow_edits)
205         {
206                 camera_autos->clear(start, end, mwindow->autos_follow_edits, 1);
207                 projector_autos->clear(start, end, mwindow->autos_follow_edits, 1);
208         }
209 }
210
211 int VTrack::paste_automation_derived(long start, long end, long total_length, FileXML *xml, int shift_autos, int &current_pan)
212 {
213 // only used for pasting automation
214         camera_autos->paste(start, end, total_length, xml, "/CAMERAUTOS", 1, shift_autos);
215         projector_autos->paste(start, end, total_length, xml, "/PROJECTORAUTOS", 1, shift_autos);
216 }
217
218 int VTrack::clear_automation_derived(AutoConf *auto_conf, long start, long end, int shift_autos)
219 {
220         if(auto_conf->camera)
221                 camera_autos->clear(start, end, mwindow->autos_follow_edits, shift_autos);
222
223         if(auto_conf->projector)
224                 projector_autos->clear(start, end, mwindow->autos_follow_edits, shift_autos);
225 }
226
227 int VTrack::paste_auto_silence_derived(long start, long end)
228 {
229         camera_autos->paste_silence(start, end);
230         projector_autos->paste_silence(start, end);
231 }
232
233 int VTrack::draw_autos_derived(float view_start, float zoom_units, AutoConf *auto_conf)
234 {
235                 if(auto_conf->camera)
236                         camera_autos->draw(tracks->canvas, pixel, data_h,
237                                 zoom_units, view_start, mwindow->session->tracks_vertical);
238
239                 if(auto_conf->projector)
240                         projector_autos->draw(tracks->canvas, pixel, data_h,
241                                 zoom_units, view_start, mwindow->session->tracks_vertical);
242 }
243
244 int VTrack::select_translation(int cursor_x, int cursor_y)
245 {
246 // cursor position is relative to time
247         int result = 0;
248         float view_start, view_units, zoom_units;
249         get_dimensions(view_start, view_units, zoom_units);
250
251         if(cursor_y > pixel && cursor_y < pixel + data_h)
252         {
253                 for(Edit* current = edits->first; current && !result; current = NEXT)
254                 {
255                         result = ((VEdit*)current)->select_translation(cursor_x, cursor_y, view_start, zoom_units);
256                 }
257         }
258         return result;
259 }
260
261 int VTrack::update_translation(int cursor_x, int cursor_y, int shift_down)
262 {
263         int result = 0;
264         float view_start, view_units, zoom_units;
265         get_dimensions(view_start, view_units, zoom_units);
266
267         for(Edit* current = edits->first; current && !result; current = NEXT)
268         {
269                 result = ((VEdit*)current)->update_translation(cursor_x, cursor_y, shift_down, view_start, zoom_units);
270         }
271         return result;
272 }
273
274 int VTrack::end_translation()
275 {
276         int result = 0;
277         for(Edit* current = edits->first; current && !result; current = NEXT)
278         {
279                 result = ((VEdit*)current)->end_translation();
280         }
281         return result;
282 }
283
284 int VTrack::reset_translation(long start, long end)
285 {
286         int result = 0;
287         Track::samples_to_units(start, end);
288         for(Edit* current = edits->first; current && !result; current = NEXT)
289         {
290                 result = ((VEdit*)current)->reset_translation(start, end);
291         }
292         return result;
293 }
294
295
296 int VTrack::select_auto_derived(float zoom_units, float view_start, AutoConf *auto_conf, int cursor_x, int cursor_y)
297 {
298         int result = 0;
299
300         if(auto_conf->camera)
301                 result = camera_autos->select_auto(tracks->canvas, pixel, data_h,
302                         zoom_units, view_start, cursor_x, cursor_y,
303                         tracks->canvas->shift_down(), tracks->canvas->ctrl_down(),
304                         tracks->canvas->get_buttonpress(), mwindow->session->tracks_vertical);
305
306         if(auto_conf->projector && !result)
307                 result = projector_autos->select_auto(tracks->canvas, pixel, data_h,
308                         zoom_units, view_start, cursor_x, cursor_y,
309                         tracks->canvas->shift_down(), tracks->canvas->ctrl_down(),
310                         tracks->canvas->get_buttonpress(), mwindow->session->tracks_vertical);
311
312         return result;
313 }
314
315
316 int VTrack::move_auto_derived(float zoom_units, float view_start, AutoConf *auto_conf, int cursor_x, int cursor_y, int shift_down)
317 {
318         int result;
319         result = 0;
320
321         if(auto_conf->camera)
322                 result = camera_autos->move_auto(tracks->canvas, pixel, data_h,
323                         zoom_units, view_start, cursor_x, cursor_y,
324                         shift_down, mwindow->session->tracks_vertical);
325
326         if(auto_conf->projector && !result)
327                 result = projector_autos->move_auto(tracks->canvas, pixel, data_h,
328                         zoom_units, view_start, cursor_x, cursor_y,
329                         shift_down, mwindow->session->tracks_vertical);
330
331         if(result)
332         {
333                 mwindow->tracks->hide_overlays(0);
334                 draw_clear(0, tracks->canvas->w, 0, tracks->canvas->h, 0);
335                 draw(0, tracks->canvas->w, 0, tracks->canvas->h, 0);
336                 mwindow->tracks->show_overlays(0);
337         }
338
339         return result;
340 }
341
342 int VTrack::draw_floating_autos_derived(float view_start, float zoom_units, AutoConf *auto_conf, int flash)
343 {
344         if(auto_conf->camera)
345                 camera_autos->draw_floating_autos(tracks->canvas, pixel, data_h,
346                         zoom_units, view_start, mwindow->session->tracks_vertical, flash);
347
348         if(auto_conf->projector)
349                 projector_autos->draw_floating_autos(tracks->canvas, pixel, data_h,
350                         zoom_units, view_start, mwindow->session->tracks_vertical, flash);
351 }
352
353 int VTrack::release_auto_derived()
354 {
355         int result;
356         result = 0;
357
358         result = camera_autos->release_auto();
359         if(!result) result = projector_autos->release_auto();
360
361         return result;
362 }
363
364 int VTrack::scale_video(float camera_scale, float projector_scale, int *offsets)
365 {
366 // Fix the camera.
367         for(VEdit *current = (VEdit*)edits->first; current; current = (VEdit*)NEXT)
368         {
369                 current->center_z *= camera_scale;
370                 current->center_x = -offsets[0];
371                 current->center_y = -offsets[1];
372         }
373
374 // Fix the projector.
375         projector_autos->scale_video(projector_scale, &offsets[2]);
376 }
377
378 int VTrack::render(VFrame **output, long input_len, long input_position, float step)
379 {
380         BezierAuto *before[4], *after[4];     // for bounding box
381         int i;
382         for(i = 0; i < 4; i++) { before[i] = 0;  after[i] = 0; }
383
384 // clear output buffer
385 //      for(i = 0; i < input_len; i++)
386 //      {
387 //              output[i]->clear_frame();
388 //      }
389         output[0]->clear_frame();
390
391 // Render from the last edit to the first edit to accomidate feathering
392         for(VEdit *current = (VEdit*)edits->last; current; current = (VEdit*)PREVIOUS)
393         {
394 //if(current == (VEdit*)edits->first || current == (VEdit*)edits->first->next)
395 //      printf("%d %d %d\n", input_position, current->startproject, current->startproject + current->length);
396                 if(input_position < current->startproject + current->length + current->feather_right &&
397                         input_position >= current->startproject)
398                         current->render(output,
399                                 input_len,
400                                 input_position,
401                                 step,
402                                 before,
403                                 after,
404                                 get_patch_of()->automate);
405         }
406 }
407
408 int VTrack::get_projection(float &in_x1, float &in_y1, float &in_x2, float &in_y2,
409                                         float &out_x1, float &out_y1, float &out_x2, float &out_y2,
410                                         int frame_w, int frame_h, long real_position,
411                                         BezierAuto **before, BezierAuto **after)
412 {
413         static float center_x, center_y, center_z;
414         static float x[4], y[4];
415
416         projector_autos->get_center(center_x, center_y, center_z, (float)real_position, 0, before, after);
417         x[0] = y[0] = 0;
418         x[1] = frame_w;
419         y[1] = frame_h;
420
421         center_x += mwindow->output_w / 2;
422         center_y += mwindow->output_h / 2;
423
424         x[2] = center_x - (frame_w / 2) * center_z;
425         y[2] = center_y - (frame_h / 2) * center_z;
426         x[3] = x[2] + frame_w * center_z;
427         y[3] = y[2] + frame_h * center_z;
428
429         if(x[2] < 0)
430         {
431                 x[0] -= x[2] / center_z;
432                 x[2] = 0;
433         }
434         if(y[2] < 0)
435         {
436                 y[0] -= y[2] / center_z;
437                 y[2] = 0;
438         }
439         if(x[3] > mwindow->output_w)
440         {
441                 x[1] -= (x[3] - mwindow->output_w) / center_z;
442                 x[3] = mwindow->output_w;
443         }
444         if(y[3] > mwindow->output_h)
445         {
446                 y[1] -= (y[3] - mwindow->output_h) / center_z;
447                 y[3] = mwindow->output_h;
448         }
449
450         in_x1 = x[0];
451         in_y1 = y[0];
452         in_x2 = x[1];
453         in_y2 = y[1];
454         out_x1 = x[2];
455         out_y1 = y[2];
456         out_x2 = x[3];
457         out_y2 = y[3];
458 }
459
460 int VTrack::scale_time_derived(float rate_scale, int scale_edits, int scale_autos, long start, long end)
461 {
462         camera_autos->scale_time(rate_scale, scale_edits, scale_autos, start, end);
463         projector_autos->scale_time(rate_scale, scale_edits, scale_autos, start, end);
464 }
465