repair default keyframe load, tweak init default histogram threshold
[goodguy/history.git] / cinelerra-5.1 / cinelerra / vtrack.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 "asset.h"
23 #include "autoconf.h"
24 #include "cache.h"
25 #include "clip.h"
26 #include "datatype.h"
27 #include "edit.h"
28 #include "edits.h"
29 #include "edl.h"
30 #include "edlsession.h"
31 #include "filexml.h"
32 #include "floatauto.h"
33 #include "floatautos.h"
34 #include "language.h"
35 #include "localsession.h"
36 #include "patch.h"
37 #include "mainsession.h"
38 #include "theme.h"
39 #include "trackcanvas.h"
40 #include "tracks.h"
41 #include "transportque.inc"
42 #include "units.h"
43 #include "vautomation.h"
44 #include "vedit.h"
45 #include "vedits.h"
46 #include "vframe.h"
47 #include "vmodule.h"
48 #include "vpluginset.h"
49 #include "vtrack.h"
50
51 VTrack::VTrack(EDL *edl, Tracks *tracks)
52  : Track(edl, tracks)
53 {
54         data_type = TRACK_VIDEO;
55         draw = 1;
56 }
57
58 VTrack::~VTrack()
59 {
60 }
61
62 void VTrack::create_objects()
63 {
64         Track::create_objects();
65         automation = new VAutomation(edl, this);
66         automation->create_objects();
67         edits = new VEdits(edl, this);
68 }
69
70 // Used by PlaybackEngine
71 void VTrack::synchronize_params(Track *track)
72 {
73         Track::synchronize_params(track);
74         //VTrack *vtrack = (VTrack*)track;
75 }
76
77 // Used by EDL::operator=
78 int VTrack::copy_settings(Track *track)
79 {
80         Track::copy_settings(track);
81         //VTrack *vtrack = (VTrack*)track;
82         return 0;
83 }
84
85 int VTrack::vertical_span(Theme *theme)
86 {
87         int track_h = Track::vertical_span(theme);
88         int patch_h = theme->title_h;
89         if( expand_view )
90                 patch_h += theme->play_h + theme->fade_h + theme->mode_h;
91         return MAX(track_h, patch_h);
92 }
93
94
95 PluginSet* VTrack::new_plugins()
96 {
97         return new VPluginSet(edl, this);
98 }
99
100 int VTrack::load_defaults(BC_Hash *defaults)
101 {
102         Track::load_defaults(defaults);
103         return 0;
104 }
105
106 void VTrack::set_default_title()
107 {
108         Track *current = ListItem<Track>::list->first;
109         int i;
110         for(i = 0; current; current = NEXT)
111         {
112                 if(current->data_type == TRACK_VIDEO) i++;
113         }
114         sprintf(title, _("Video %d"), i);
115         BC_Resources::encode_to_utf8(title, BCTEXTLEN);
116 }
117
118 int64_t VTrack::to_units(double position, int round)
119 {
120         return round ? Units::round(position * edl->session->frame_rate) :
121                 Units::to_int64(position * edl->session->frame_rate + 1e-6);
122 }
123
124 double VTrack::to_doubleunits(double position)
125 {
126         return position * edl->session->frame_rate;
127 }
128
129
130 double VTrack::from_units(int64_t position)
131 {
132         return (double)position / edl->session->frame_rate;
133 }
134
135
136
137
138 int VTrack::identical(int64_t sample1, int64_t sample2)
139 {
140 // Units of frames
141         if(labs(sample1 - sample2) <= 1) return 1; else return 0;
142 }
143
144 int VTrack::save_header(FileXML *file)
145 {
146         file->tag.set_property("TYPE", "VIDEO");
147         return 0;
148 }
149
150 int VTrack::save_derived(FileXML *file)
151 {
152         return 0;
153 }
154
155 int VTrack::load_header(FileXML *file, uint32_t load_flags)
156 {
157         return 0;
158 }
159
160 int VTrack::load_derived(FileXML *file, uint32_t load_flags)
161 {
162         return 0;
163 }
164
165
166 int VTrack::direct_copy_possible(int64_t start, int direction, int use_nudge)
167 {
168         if(use_nudge) start += nudge;
169
170 // Track size must equal output size
171         if(track_w != edl->session->output_w || track_h != edl->session->output_h)
172                 return 0;
173
174         if(has_speed()) return 0;
175
176 // No automation must be present in the track
177         if(!automation->direct_copy_possible(start, direction))
178                 return 0;
179
180 // No plugin must be present
181         if(plugin_used(start, direction))
182                 return 0;
183
184 // No transition
185         if(get_current_transition(start, direction, 0, 0))
186                 return 0;
187
188         return 1;
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 int VTrack::create_derived_objs(int flash)
208 {
209         edits = new VEdits(edl, this);
210         return 0;
211 }
212
213
214 // int VTrack::get_dimensions(double &view_start,
215 //      double &view_units,
216 //      double &zoom_units)
217 // {
218 //      view_start = edl->local_session->view_start * edl->session->frame_rate;
219 //      view_units = 0;
220 //      zoom_units = edl->local_session->zoom_sample / edl->session->sample_rate * edl->session->frame_rate;
221 //      return 0;
222 // }
223
224 int VTrack::copy_derived(int64_t start, int64_t end, FileXML *xml)
225 {
226 // automation is copied in the Track::copy
227         return 0;
228 }
229
230 int VTrack::copy_automation_derived(AutoConf *auto_conf, int64_t start, int64_t end, FileXML *file)
231 {
232         return 0;
233 }
234
235 int VTrack::paste_derived(int64_t start, int64_t end, int64_t total_length, FileXML *xml, int &current_channel)
236 {
237         return 0;
238 }
239
240 int VTrack::paste_output(int64_t startproject, int64_t endproject, int64_t startsource, int64_t endsource, int layer, Asset *asset)
241 {
242         return 0;
243 }
244
245 int VTrack::clear_derived(int64_t start, int64_t end)
246 {
247         return 0;
248 }
249
250 int VTrack::paste_automation_derived(int64_t start, int64_t end, int64_t total_length, FileXML *xml, int shift_autos, int &current_pan)
251 {
252         return 0;
253 }
254
255 int VTrack::clear_automation_derived(AutoConf *auto_conf, int64_t start, int64_t end, int shift_autos)
256 {
257         return 0;
258 }
259
260 int VTrack::draw_autos_derived(float view_start, float zoom_units, AutoConf *auto_conf)
261 {
262         return 0;
263 }
264
265
266 int VTrack::select_auto_derived(float zoom_units, float view_start, AutoConf *auto_conf, int cursor_x, int cursor_y)
267 {
268         return 0;
269 }
270
271
272 int VTrack::move_auto_derived(float zoom_units, float view_start, AutoConf *auto_conf, int cursor_x, int cursor_y, int shift_down)
273 {
274         return 0;
275 }
276
277 int VTrack::draw_floating_autos_derived(float view_start, float zoom_units, AutoConf *auto_conf, int flash)
278 {
279         return 0;
280 }
281
282 int VTrack::is_playable(int64_t position, int direction)
283 {
284         int result = 0;
285         float in_x, in_y, in_w, in_h;
286         float out_x, out_y, out_w, out_h;
287
288         calculate_output_transfer(position,
289                 direction,
290                 in_x, in_y, in_w, in_h,
291                 out_x, out_y, out_w, out_h);
292
293 //printf("VTrack::is_playable %0.0f %0.0f %0.0f %0.0f %0.0f %0.0f %0.0f %0.0f\n",
294 //in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h);
295         if(out_w > 0 && out_h > 0)
296                 result = 1;
297         return result;
298 }
299
300 void VTrack::calculate_input_transfer(int asset_w, int asset_h,
301         int64_t position, int direction,
302         float &in_x, float &in_y, float &in_w, float &in_h,
303         float &out_x, float &out_y, float &out_w, float &out_h)
304 {
305         float auto_x, auto_y, auto_z;
306         float camera_z = 1.;
307         float camera_x = asset_w / 2.;
308         float camera_y = asset_h / 2.;
309 // camera and output coords
310         float x[6], y[6];
311
312 //printf("VTrack::calculate_input_transfer %jd\n", position);
313
314 // get camera center in asset
315         automation->get_camera(&auto_x, &auto_y, &auto_z,
316                 position, direction);
317
318         camera_z *= auto_z;
319         camera_x += auto_x;
320         camera_y += auto_y;
321
322 // get camera coords on asset
323         x[0] = camera_x - (float)track_w / 2 / camera_z;
324         y[0] = camera_y - (float)track_h / 2 / camera_z;
325         x[1] = x[0] + (float)track_w / camera_z;
326         y[1] = y[0] + (float)track_h / camera_z;
327
328 // get asset coords on camera
329         x[2] = 0;
330         y[2] = 0;
331         x[3] = track_w;
332         y[3] = track_h;
333
334 // crop asset coords on camera
335         if(x[0] < 0)
336         {
337                 x[2] -= x[0] * camera_z;
338                 x[0] = 0;
339         }
340         if(y[0] < 0)
341         {
342                 y[2] -= y[0] * camera_z;
343                 y[0] = 0;
344         }
345         if(x[1] > asset_w)
346         {
347                 x[3] -= (x[1] - asset_w) * camera_z;
348                 x[1] = asset_w;
349         }
350         if(y[1] > asset_h)
351         {
352                 y[3] -= (y[1] - asset_h) * camera_z;
353                 y[1] = asset_h;
354         }
355
356 // get output bounding box
357         out_x = x[2];
358         out_y = y[2];
359         out_w = x[3] - x[2];
360         out_h = y[3] - y[2];
361
362         in_x = x[0];
363         in_y = y[0];
364         in_w = x[1] - x[0];
365         in_h = y[1] - y[0];
366 // printf("VTrack::calculate_input_transfer %f %f %f %f -> %f %f %f %f\n",
367 // in_x, in_y, in_w, in_h,
368 // out_x, out_y, out_w, out_h);
369 }
370
371 void VTrack::calculate_output_transfer(int64_t position, int direction,
372         float &in_x, float &in_y, float &in_w, float &in_h,
373         float &out_x, float &out_y, float &out_w, float &out_h)
374 {
375         float center_x, center_y, center_z;
376         float x[4], y[4];
377
378         x[0] = 0;
379         y[0] = 0;
380         x[1] = track_w;
381         y[1] = track_h;
382
383         automation->get_projector(&center_x,
384                 &center_y,
385                 &center_z,
386                 position,
387                 direction);
388
389         center_x += edl->session->output_w / 2;
390         center_y += edl->session->output_h / 2;
391
392         x[2] = center_x - (track_w / 2) * center_z;
393         y[2] = center_y - (track_h / 2) * center_z;
394         x[3] = x[2] + track_w * center_z;
395         y[3] = y[2] + track_h * center_z;
396
397 // Clip to boundaries of output
398         if(x[2] < 0)
399         {
400                 x[0] -= (x[2] - 0) / center_z;
401                 x[2] = 0;
402         }
403         if(y[2] < 0)
404         {
405                 y[0] -= (y[2] - 0) / center_z;
406                 y[2] = 0;
407         }
408         if(x[3] > edl->session->output_w)
409         {
410                 x[1] -= (x[3] - edl->session->output_w) / center_z;
411                 x[3] = edl->session->output_w;
412         }
413         if(y[3] > edl->session->output_h)
414         {
415                 y[1] -= (y[3] - edl->session->output_h) / center_z;
416                 y[3] = edl->session->output_h;
417         }
418
419         in_x = x[0];
420         in_y = y[0];
421         in_w = x[1] - x[0];
422         in_h = y[1] - y[0];
423         out_x = x[2];
424         out_y = y[2];
425         out_w = x[3] - x[2];
426         out_h = y[3] - y[2];
427 // printf("VTrack::calculate_output_transfer %f %f %f %f -> %f %f %f %f\n",
428 // in_x, in_y, in_w, in_h,
429 // out_x, out_y, out_w, out_h);
430 }
431
432
433
434 int VTrack::get_projection(float &in_x1, float &in_y1, float &in_x2, float &in_y2,
435         float &out_x1, float &out_y1, float &out_x2, float &out_y2,
436         int frame_w, int frame_h, int64_t real_position, int direction)
437 {
438         float center_x, center_y, center_z;
439         float x[4], y[4];
440
441         automation->get_projector(&center_x,
442                 &center_y,
443                 &center_z,
444                 real_position,
445                 direction);
446
447         x[0] = y[0] = 0;
448         x[1] = frame_w;
449         y[1] = frame_h;
450
451         center_x += edl->session->output_w / 2;
452         center_y += edl->session->output_h / 2;
453
454         x[2] = center_x - (frame_w / 2) * center_z;
455         y[2] = center_y - (frame_h / 2) * center_z;
456         x[3] = x[2] + frame_w * center_z;
457         y[3] = y[2] + frame_h * center_z;
458
459         if(x[2] < 0)
460         {
461                 x[0] -= x[2] / center_z;
462                 x[2] = 0;
463         }
464         if(y[2] < 0)
465         {
466                 y[0] -= y[2] / center_z;
467                 y[2] = 0;
468         }
469         if(x[3] > edl->session->output_w)
470         {
471                 x[1] -= (x[3] - edl->session->output_w) / center_z;
472                 x[3] = edl->session->output_w;
473         }
474         if(y[3] > edl->session->output_h)
475         {
476                 y[1] -= (y[3] - edl->session->output_h) / center_z;
477                 y[3] = edl->session->output_h;
478         }
479
480         in_x1 = x[0];  in_y1 = y[0];  in_x2 = x[1];  in_y2 = y[1];
481         out_x1 = x[2]; out_y1 = y[2]; out_x2 = x[3]; out_y2 = y[3];
482         return 0;
483 }
484
485
486
487 inline void addto_value(FloatAuto *fauto, float offset)
488 {
489         fauto->set_value(fauto->get_value() + offset);
490 }
491
492
493 void VTrack::translate(float offset_x, float offset_y, int do_camera)
494 {
495         int subscript;
496         if(do_camera)
497                 subscript = AUTOMATION_CAMERA_X;
498         else
499                 subscript = AUTOMATION_PROJECTOR_X;
500
501 // Translate default keyframe
502         addto_value((FloatAuto*)automation->autos[subscript]->default_auto, offset_x);
503         addto_value((FloatAuto*)automation->autos[subscript + 1]->default_auto, offset_y);
504
505 // Translate everyone else
506         for(Auto *current = automation->autos[subscript]->first;
507                 current;
508                 current = NEXT)
509         {
510                 addto_value((FloatAuto*)current, offset_x);
511         }
512
513         for(Auto *current = automation->autos[subscript + 1]->first;
514                 current;
515                 current = NEXT)
516         {
517                 addto_value((FloatAuto*)current, offset_y);
518         }
519 }
520