2 #include "automation.h"
7 #include "edlsession.h"
8 #include "fadeengine.h"
10 #include "floatautos.h"
14 #include "maskautos.h"
15 #include "maskengine.h"
18 #include "overlayframe.h"
19 #include "playabletracks.h"
21 #include "preferences.h"
22 #include "renderengine.h"
23 #include "transition.h"
24 #include "transportque.h"
25 #include "vattachmentpoint.h"
26 #include "vdevicex11.h"
28 #include "videodevice.h"
29 #include "virtualvconsole.h"
30 #include "virtualvnode.h"
38 VirtualVNode::VirtualVNode(RenderEngine *renderengine,
39 VirtualConsole *vconsole,
43 VirtualNode *parent_node)
44 : VirtualNode(renderengine,
51 VRender *vrender = ((VirtualVConsole*)vconsole)->vrender;
52 fader = new FadeEngine(renderengine->preferences->processors);
53 masker = new MaskEngine(renderengine->preferences->processors);
56 VirtualVNode::~VirtualVNode()
62 VirtualNode* VirtualVNode::create_module(Plugin *real_plugin,
66 return new VirtualVNode(renderengine,
75 VirtualNode* VirtualVNode::create_plugin(Plugin *real_plugin)
77 return new VirtualVNode(renderengine,
85 int VirtualVNode::read_data(VFrame *output_temp,
86 int64_t start_position,
90 VirtualNode *previous_plugin = 0;
94 printf("VirtualVNode::read_data output_temp=%p\n", output_temp);
96 if(vconsole->debug_tree)
97 printf(" VirtualVNode::read_data position=%lld rate=%f title=%s opengl=%d\n",
103 // If there is a parent module but the parent module has no data source,
104 // use our own data source.
105 // Current edit in parent track
106 VEdit *parent_edit = 0;
107 if(parent_node && parent_node->track && renderengine)
109 double edl_rate = renderengine->edl->session->frame_rate;
110 int64_t start_position_project = (int64_t)(start_position *
114 parent_edit = (VEdit*)parent_node->track->edits->editof(start_position_project,
115 renderengine->command->get_direction(),
120 // This is a plugin on parent module with a preceeding effect.
121 // Get data from preceeding effect on parent module.
122 if(parent_node && (previous_plugin = parent_node->get_previous_plugin(this)))
124 result = ((VirtualVNode*)previous_plugin)->render(output_temp,
130 // The current node is the first plugin on parent module.
131 // The parent module has an edit to read from or the current node
132 // has no source to read from.
133 // Read data from parent module
134 if(parent_node && (parent_edit || !real_module))
136 result = ((VirtualVNode*)parent_node)->read_data(output_temp,
144 // This is the first node in the tree
145 result = ((VModule*)real_module)->render(output_temp,
147 renderengine->command->get_direction(),
150 vconsole->debug_tree,
158 int VirtualVNode::render(VFrame *output_temp,
159 int64_t start_position,
163 VRender *vrender = ((VirtualVConsole*)vconsole)->vrender;
166 render_as_module(vrender->video_out,
175 render_as_plugin(output_temp,
183 void VirtualVNode::render_as_plugin(VFrame *output_temp,
184 int64_t start_position,
190 !real_plugin->on) return;
193 if(vconsole->debug_tree)
194 printf(" VirtualVNode::render_as_plugin title=%s use_opengl=%d\n",
198 ((VAttachmentPoint*)attachment)->render(
200 plugin_buffer_number,
203 vconsole->debug_tree,
208 int VirtualVNode::render_as_module(VFrame *video_out,
210 int64_t start_position,
215 int direction = renderengine->command->get_direction();
216 double edl_rate = renderengine->edl->session->frame_rate;
217 // Get position relative to project, compensated for direction
218 int64_t start_position_project = (int64_t)(start_position *
221 if(direction == PLAY_REVERSE) start_position_project--;
223 if(vconsole->debug_tree)
224 printf(" VirtualVNode::render_as_module title=%s use_opengl=%d video_out=%p output_temp=%p\n",
230 output_temp->push_next_effect("VirtualVNode::render_as_module");
232 // Process last subnode. This propogates up the chain of subnodes and finishes
236 VirtualVNode *node = (VirtualVNode*)subnodes.values[subnodes.total - 1];
237 node->render(output_temp,
243 // Read data from previous entity
245 read_data(output_temp,
251 output_temp->pop_next_effect();
253 render_fade(output_temp,
256 track->automation->autos[AUTOMATION_FADE],
259 render_mask(output_temp, start_position_project, frame_rate, use_opengl);
262 // overlay on the final output
265 int mute_fragment = 1;
266 int64_t mute_position = 0;
270 get_mute_fragment(start_position,
273 (Autos*)((VTrack*)track)->automation->autos[AUTOMATION_MUTE],
280 render_projector(output_temp,
286 output_temp->push_prev_effect("VirtualVNode::render_as_module");
287 //printf("VirtualVNode::render_as_module\n");
288 //output_temp->dump_stacks();
291 if(renderengine->show_tc)
292 renderengine->vrender->insert_timecode(edit,
299 int VirtualVNode::render_fade(VFrame *output,
300 // start of input fragment in project if forward / end of input fragment if reverse
301 // relative to requested frame rate
302 int64_t start_position,
307 double slope, intercept;
308 int64_t slope_len = 1;
309 FloatAuto *previous = 0;
311 double edl_rate = renderengine->edl->session->frame_rate;
312 int64_t start_position_project = (int64_t)(start_position *
316 if(vconsole->debug_tree)
317 printf(" VirtualVNode::render_fade title=%s\n", track->title);
319 intercept = ((FloatAutos*)autos)->get_value(start_position_project,
325 CLAMP(intercept, 0, 100);
328 // Can't use overlay here because overlayer blends the frame with itself.
329 // The fade engine can compensate for lack of alpha channels by multiplying the
330 // color components by alpha.
331 if(!EQUIV(intercept / 100, 1))
333 if(((VirtualVConsole*)vconsole)->use_opengl)
334 ((VDeviceX11*)((VirtualVConsole*)vconsole)->get_vdriver())->do_fade(
338 fader->do_fade(output, output, intercept / 100);
346 void VirtualVNode::render_mask(VFrame *output_temp,
347 int64_t start_position_project,
351 MaskAutos *keyframe_set =
352 (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
355 MaskAuto *default_auto = (MaskAuto*)keyframe_set->default_auto;
356 MaskAuto *keyframe = (MaskAuto*)keyframe_set->get_prev_auto(start_position_project,
360 int total_points = 0;
361 for(int i = 0; i < keyframe->masks.total; i++)
363 SubMask *mask = keyframe->get_submask(i);
364 int submask_points = mask->points.total;
365 if(submask_points > 1) total_points += submask_points;
368 //printf("VirtualVNode::render_mask 1 %d %d\n", total_points, keyframe->value);
369 // Ignore certain masks
370 if(total_points <= 2 ||
371 (keyframe->value == 0 && default_auto->mode == MASK_SUBTRACT_ALPHA))
376 // Fake certain masks
377 if(keyframe->value == 0 && default_auto->mode == MASK_MULTIPLY_ALPHA)
379 output_temp->clear_frame();
383 if(((VirtualVConsole*)vconsole)->use_opengl)
385 ((VDeviceX11*)((VirtualVConsole*)vconsole)->get_vdriver())->do_mask(
387 start_position_project,
394 // Revert to software
395 int direction = renderengine->command->get_direction();
396 double edl_rate = renderengine->edl->session->frame_rate;
397 masker->do_mask(output_temp,
398 start_position_project,
408 // Start of input fragment in project if forward. End of input fragment if reverse.
409 int VirtualVNode::render_projector(VFrame *input,
411 int64_t start_position,
414 float in_x1, in_y1, in_x2, in_y2;
415 float out_x1, out_y1, out_x2, out_y2;
416 double edl_rate = renderengine->edl->session->frame_rate;
417 int64_t start_position_project = (int64_t)(start_position *
420 VRender *vrender = ((VirtualVConsole*)vconsole)->vrender;
421 if(vconsole->debug_tree)
422 printf(" VirtualVNode::render_projector input=%p output=%p title=%s\n",
423 input, output, track->title);
427 ((VTrack*)track)->calculate_output_transfer(start_position_project,
428 renderengine->command->get_direction(),
443 //for(int j = 0; j < input->get_w() * 3 * 5; j++)
444 // input->get_rows()[0][j] = 255;
446 if(out_x2 > out_x1 &&
451 int direction = renderengine->command->get_direction();
452 IntAuto *mode_keyframe = 0;
454 (IntAuto*)track->automation->autos[AUTOMATION_MODE]->get_prev_auto(
455 start_position_project,
457 (Auto* &)mode_keyframe);
459 int mode = mode_keyframe->value;
461 // Fade is performed in render_fade so as to allow this module
462 // to be chained in another module, thus only 4 component colormodels
463 // can do dissolves, although a blend equation is still required for 3 component
464 // colormodels since fractional translation requires blending.
466 // If this is the first playable video track and the mode_keyframe is "normal"
467 // the mode may be overridden with "replace". Replace is faster.
468 if(mode == TRANSFER_NORMAL &&
469 vconsole->current_exit_node == vconsole->total_exit_nodes - 1)
470 mode = TRANSFER_REPLACE;
472 if(((VirtualVConsole*)vconsole)->use_opengl)
474 ((VDeviceX11*)((VirtualVConsole*)vconsole)->get_vdriver())->overlay(
491 vrender->overlayer->overlay(output,
503 renderengine->edl->session->interpolation_type);