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