r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / virtualvnode.C
bloba3e068190d9240c84de43b59ebfe63a04f899e1d
1 #include "automation.h"
2 #include "clip.h"
3 #include "edl.h"
4 #include "edlsession.h"
5 #include "fadeengine.h"
6 #include "floatauto.h"
7 #include "floatautos.h"
8 #include "intauto.h"
9 #include "intautos.h"
10 #include "maskengine.h"
11 #include "mwindow.h"
12 #include "module.h"
13 #include "overlayframe.h"
14 #include "plugin.h"
15 #include "preferences.h"
16 #include "renderengine.h"
17 #include "transition.h"
18 #include "transportque.h"
19 #include "vattachmentpoint.h"
20 #include "vframe.h"
21 #include "virtualvconsole.h"
22 #include "virtualvnode.h"
23 #include "vmodule.h"
24 #include "vtrack.h"
26 #include <string.h>
29 VirtualVNode::VirtualVNode(RenderEngine *renderengine, 
30                 VirtualConsole *vconsole, 
31                 Module *real_module, 
32                 Plugin *real_plugin,
33                 Track *track, 
34                 VirtualNode *parent_module, 
35                 VFrame *buffer_in,
36                 VFrame *buffer_out,
37                 int input_is_master,
38                 int output_is_master,
39                 int in,
40                 int out)
41  : VirtualNode(renderengine, 
42                 vconsole, 
43                 real_module, 
44                 real_plugin,
45                 track, 
46                 parent_module, 
47                 input_is_master,
48                 output_is_master,
49                 in,
50                 out)
52         this->buffer_in = buffer_in;
53         this->buffer_out = buffer_out;
54 //printf("VirtualVNode::VirtualVNode 1\n");
55         overlayer = new OverlayFrame(renderengine->edl->session->smp + 1);
56         fader = new FadeEngine(renderengine->edl->session->smp + 1);
57         masker = new MaskEngine(renderengine->edl->session->smp + 1);
60 VirtualVNode::~VirtualVNode()
62 //printf("VirtualVNode::~VirtualVNode 1\n");
63         if(!shared_output) delete buffer_out;
64         if(!shared_input) delete buffer_in;
65         delete overlayer;
66         delete fader;
67         delete masker;
70 VirtualNode* VirtualVNode::create_module(Plugin *real_plugin, 
71                                                         Module *real_module, 
72                                                         Track *track)
74         return new VirtualVNode(renderengine, 
75                 vconsole, 
76                 real_module,
77                 0,
78                 track,
79                 this,
80                 data_in_input ? buffer_in : buffer_out,
81                 buffer_out,
82                 data_in_input ? input_is_master : output_is_master,
83                 output_is_master,
84                 real_plugin->in,
85                 real_plugin->out);
89 VirtualNode* VirtualVNode::create_plugin(Plugin *real_plugin)
91         return new VirtualVNode(renderengine, 
92                 vconsole, 
93                 0,
94                 real_plugin,
95                 track,
96                 this,
97                 data_in_input ? buffer_in : buffer_out,
98                 buffer_out,
99                 data_in_input ? input_is_master : output_is_master,
100                 output_is_master,
101                 real_plugin->in,
102                 real_plugin->out);
106 void VirtualVNode::new_output_buffer()
108 printf("VirtualVNode::new_input_buffer 1 %p\n", track);
109         buffer_out = new VFrame(0,
110                         track->track_w,
111                         track->track_h,
112                         renderengine->edl->session->color_model,
113                         -1);
116 void VirtualVNode::new_input_buffer()
118 printf("VirtualVNode::new_input_buffer 1 %p\n", track);
119         buffer_in = new VFrame(0,
120                         track->track_w,
121                         track->track_h,
122                         renderengine->edl->session->color_model,
123                         -1);
126 VFrame* VirtualVNode::get_module_input()
128         VFrame* result;
129         if(data_in_input)
130         {
131                 result = buffer_in;
132         }
133         else
134         {
135                 result = buffer_out;
136         }
137         return result;
140 VFrame* VirtualVNode::get_module_output()
142         VFrame* result;
143         result = buffer_out;
144         return result;
147 int VirtualVNode::render(VFrame **video_out, int64_t input_position)
149 //printf("VirtualVNode::render 1\n");
150         if(real_module)
151         {
152 //printf("VirtualVNode::render 2\n");
153                 render_as_module(video_out, input_position);
154         }
155         else
156         if(real_plugin)
157         {
158 //printf("VirtualVNode::render 3\n");
159                 render_as_plugin(input_position);
160         }
161 //printf("VirtualVNode::render 4\n");
162         return 0;
165 void VirtualVNode::render_as_plugin(int64_t input_position)
167         if(!attachment ||
168                 !real_plugin ||
169                 !real_plugin->on) return;
171         ((VAttachmentPoint*)attachment)->render(buffer_in,
172                 buffer_out,
173                 input_position);
177 int VirtualVNode::render_as_module(VFrame **video_out, int64_t input_position)
179         this->reverse = reverse;
180         VFrame *buffer_in = get_module_input();
181         VFrame *buffer_out = get_module_output();
183 //printf("VirtualVNode::render_as_module 1 %d\n", buffer_out->get_color_model());
184         render_fade(buffer_in, 
185                                 buffer_out,
186                                 input_position,
187                                 track->automation->fade_autos);
189 //printf("VirtualVNode::render_as_module 2\n");
191 // video is definitely in output buffer now
193 // Render mask
194         masker->do_mask(buffer_out, 
195                 track->automation->mask_autos, 
196                 input_position, 
197                 renderengine->command->get_direction());
207 // overlay on the final output
208 // Get mute status
209         int mute_constant;
210         int64_t mute_fragment = 1;
211         int64_t mute_position = 0;
213 //printf("VirtualVNode::render_as_module 3\n");
214 // Is frame muted?
215         get_mute_fragment(input_position,
216                         mute_constant, 
217                         mute_fragment, 
218                         (Autos*)((VTrack*)track)->automation->mute_autos);
220 //printf("VirtualVNode::render_as_module 4 %d\n", mute_constant);
221         if(!mute_constant)
222         {
223 // Fragment is playable
224                 render_projector(buffer_out,
225                         video_out,
226                         input_position);
227         }
229 //printf("VirtualVNode::render_as_module 5\n");
230         return 0;
233 int VirtualVNode::render_fade(VFrame *input,         // start of input fragment
234                         VFrame *output,        // start of output fragment
235                         int64_t input_position,  // start of input fragment in project if forward / end of input fragment if reverse
236                         Autos *autos)
238         double slope, intercept;
239         int64_t slope_len = 1;
240         int direction = renderengine->command->get_direction();
241         FloatAuto *previous = 0;
242         FloatAuto *next = 0;
244         intercept = ((FloatAutos*)autos)->get_value(input_position, 
245                 direction,
246                 previous,
247                 next);
250 //printf("VirtualVNode::render_fade %d %f\n", input_position, intercept);
251         CLAMP(intercept, 0, 100);
254 // Can't use overlay here because overlayer blends the frame with itself.
255 // The fade engine can compensate for lack of alpha channels by reducing the 
256 // color components.
257         if(!EQUIV(intercept / 100, 1))
258         {
259                 fader->do_fade(output, input, intercept / 100);
260         }
261         else
262         {
263                 if(output->get_rows()[0] != input->get_rows()[0])
264                 {
265                         output->copy_from(input);
266                 }
267         }
269         return 0;
272 // Start of input fragment in project if forward.  End of input fragment if reverse.
273 int VirtualVNode::render_projector(VFrame *input,
274                         VFrame **output,
275                         int64_t input_position)
277         float in_x1, in_y1, in_x2, in_y2;
278         float out_x1, out_y1, out_x2, out_y2;
279         float float_input_position = input_position;
281         for(int i = 0; i < MAX_CHANNELS; i++)
282         {
283                 if(output[i])
284                 {
285                         ((VTrack*)track)->calculate_output_transfer(i,
286                                 (int64_t)float_input_position,
287                                 renderengine->command->get_direction(),
288                                 in_x1, 
289                                 in_y1, 
290                                 in_x2, 
291                                 in_y2,
292                                 out_x1, 
293                                 out_y1, 
294                                 out_x2, 
295                                 out_y2);
297                         in_x2 += in_x1;
298                         in_y2 += in_y1;
299                         out_x2 += out_x1;
300                         out_y2 += out_y1;
302 //for(int j = 0; j < input->get_w() * 3 * 5; j++)
303 //      input->get_rows()[0][j] = 255;
304 // 
305                         if(out_x2 > out_x1 && 
306                                 out_y2 > out_y1 && 
307                                 in_x2 > in_x1 && 
308                                 in_y2 > in_y1)
309                         {
310                                 int direction = renderengine->command->get_direction();
311                                 IntAuto *mode_keyframe = 0;
312                                 mode_keyframe = 
313                                         (IntAuto*)track->automation->mode_autos->get_prev_auto(
314                                                 input_position, 
315                                                 direction,
316                                                 (Auto*)mode_keyframe);
318                                 int mode = mode_keyframe->value;
320 // Fade is performed in render_fade so as to allow this module
321 // to be chained in another module, thus only 4 component colormodels
322 // can do dissolves, although a blend equation is still required for 3 component
323 // colormodels since fractional translation requires blending.
325 // If this is the only playable video track and the mode_keyframe is "normal"
326 // the mode keyframe may be overridden with "replace".  Replace is faster.
327                                 if(mode == TRANSFER_NORMAL &&
328                                         vconsole->total_tracks == 1)
329                                         mode = TRANSFER_REPLACE;
332                                 overlayer->overlay(output[i], 
333                                         input,
334                                         in_x1, 
335                                         in_y1, 
336                                         in_x2, 
337                                         in_y2,
338                                         out_x1, 
339                                         out_y1, 
340                                         out_x2, 
341                                         out_y2, 
342                                         1,
343                                         mode, 
344                                         renderengine->edl->session->interpolation_type);
345                         }
346 // for(int j = 0; j < output[i]->get_w() * 3 * 5; j++)
347 //      output[i]->get_rows()[0][j] = 255;
348                 }
349         }
350         return 0;
353 int VirtualVNode::transfer_from(VFrame *frame_out, 
354         VFrame *frame_in, 
355         float in_x1, 
356         float in_y1, 
357         float in_x2, 
358         float in_y2, 
359         float out_x1, 
360         float out_y1, 
361         float out_x2, 
362         float out_y2, 
363         float alpha, 
364         int mode)
366 printf("VirtualVNode::transfer_from Depreciated\n", mode, alpha);
367 //      overlayer->overlay(frame_out, 
368 //              frame_in,
369 //              in_x1, 
370 //              in_y1, 
371 //              in_x2, 
372 //              in_y2,
373 //              out_x1, 
374 //              out_y1, 
375 //              out_x2, 
376 //              out_y2, 
377 //              1,
378 //              mode, 
379 //              renderengine->edl->session->interpolation_type);
380         return 0;