2 #include "automation.h"
8 #include "edlsession.h"
9 #include "fadeengine.h"
10 #include "floatauto.h"
11 #include "floatautos.h"
14 #include "maskengine.h"
17 #include "overlayframe.h"
18 #include "playabletracks.h"
20 #include "preferences.h"
21 #include "renderengine.h"
22 #include "transition.h"
23 #include "transportque.h"
24 #include "vattachmentpoint.h"
27 #include "virtualvconsole.h"
28 #include "virtualvnode.h"
36 VirtualVNode::VirtualVNode(RenderEngine *renderengine,
37 VirtualConsole *vconsole,
41 VirtualNode *parent_node)
42 : VirtualNode(renderengine,
49 VRender *vrender = ((VirtualVConsole*)vconsole)->vrender;
50 fader = new FadeEngine(renderengine->preferences->processors);
53 VirtualVNode::~VirtualVNode()
58 VirtualNode* VirtualVNode::create_module(Plugin *real_plugin,
62 return new VirtualVNode(renderengine,
71 VirtualNode* VirtualVNode::create_plugin(Plugin *real_plugin)
73 return new VirtualVNode(renderengine,
81 int VirtualVNode::read_data(VFrame *output_temp,
82 int64_t start_position,
85 VirtualNode *previous_plugin = 0;
88 if(!output_temp) printf("VirtualVNode::read_data output_temp=%p\n", output_temp);
91 if(vconsole->debug_tree)
92 printf(" VirtualVNode::read_data position=%lld rate=%f title=%s\n",
97 // This is a plugin on parent module with a preceeding effect.
98 // Get data from preceeding effect on parent module.
99 if(parent_node && (previous_plugin = parent_node->get_previous_plugin(this)))
101 return ((VirtualVNode*)previous_plugin)->render(output_temp,
106 // First plugin on parent module.
107 // Read data from parent module
110 return ((VirtualVNode*)parent_node)->read_data(output_temp,
116 // This is the first node in the tree
117 return ((VModule*)real_module)->render(output_temp,
119 renderengine->command->get_direction(),
122 vconsole->debug_tree);
130 int VirtualVNode::render(VFrame *output_temp,
131 int64_t start_position,
134 VRender *vrender = ((VirtualVConsole*)vconsole)->vrender;
138 render_as_module(vrender->video_out,
147 render_as_plugin(output_temp,
154 void VirtualVNode::render_as_plugin(VFrame *output_temp,
155 int64_t start_position,
160 !real_plugin->on) return;
163 if(vconsole->debug_tree)
164 printf(" VirtualVNode::render_as_plugin title=%s\n", track->title);
166 ((VAttachmentPoint*)attachment)->render(
168 plugin_buffer_number,
171 vconsole->debug_tree);
175 int VirtualVNode::render_as_module(VFrame **video_out,
177 int64_t start_position,
181 int direction = renderengine->command->get_direction();
182 double edl_rate = renderengine->edl->session->frame_rate;
184 if(vconsole->debug_tree)
185 printf(" VirtualVNode::render_as_module title=%s\n", track->title);
188 // Process last subnode. This propogates up the chain of subnodes and finishes
192 VirtualVNode *node = (VirtualVNode*)subnodes.values[subnodes.total - 1];
193 node->render(output_temp,
198 // Read data from previous entity
200 read_data(output_temp,
206 render_fade(output_temp,
209 track->automation->autos[AUTOMATION_FADE],
213 // Apply mask to output
214 ((VModule *)real_module)->masker->do_mask(output_temp,
218 (MaskAutos*)track->automation->autos[AUTOMATION_MASK],
220 0); // we are not before plugins
224 // overlay on the final output
227 int mute_fragment = 1;
228 int64_t mute_position = 0;
232 get_mute_fragment(start_position,
235 (Autos*)((VTrack*)track)->automation->autos[AUTOMATION_MUTE],
242 // Fragment is playable
243 render_projector(output_temp,
251 if(renderengine->show_tc)
252 renderengine->vrender->insert_timecode(edit,
259 int VirtualVNode::render_fade(VFrame *output,
260 // start of input fragment in project if forward / end of input fragment if reverse
261 // relative to requested frame rate
262 int64_t start_position,
267 double slope, intercept;
268 int64_t slope_len = 1;
269 FloatAuto *previous = 0;
271 double edl_rate = renderengine->edl->session->frame_rate;
272 int64_t start_position_project = (int64_t)(start_position *
276 if(vconsole->debug_tree)
277 printf(" VirtualVNode::render_fade title=%s\n", track->title);
279 intercept = ((FloatAutos*)autos)->get_value(start_position_project,
285 // CLAMP(intercept, 0, 100);
288 // Can't use overlay here because overlayer blends the frame with itself.
289 // The fade engine can compensate for lack of alpha channels by reducing the
291 if(!EQUIV(intercept / 100, 1))
293 fader->do_fade(output, output, intercept / 100);
299 // Start of input fragment in project if forward. End of input fragment if reverse.
300 int VirtualVNode::render_projector(VFrame *input,
302 int64_t start_position,
305 float in_x1, in_y1, in_x2, in_y2;
306 float out_x1, out_y1, out_x2, out_y2;
307 double edl_rate = renderengine->edl->session->frame_rate;
308 int64_t start_position_project = (int64_t)(start_position *
311 VRender *vrender = ((VirtualVConsole*)vconsole)->vrender;
312 if(vconsole->debug_tree)
313 printf(" VirtualVNode::render_projector title=%s\n", track->title);
315 for(int i = 0; i < MAX_CHANNELS; i++)
319 ((VTrack*)track)->calculate_output_transfer(i,
320 start_position_project,
321 renderengine->command->get_direction(),
336 //for(int j = 0; j < input->get_w() * 3 * 5; j++)
337 // input->get_rows()[0][j] = 255;
339 if(out_x2 > out_x1 &&
344 int direction = renderengine->command->get_direction();
345 IntAuto *mode_keyframe = 0;
347 (IntAuto*)track->automation->autos[AUTOMATION_MODE]->get_prev_auto(
348 start_position_project,
350 (Auto* &)mode_keyframe);
352 int mode = mode_keyframe->value;
354 // Fade is performed in render_fade so as to allow this module
355 // to be chained in another module, thus only 4 component colormodels
356 // can do dissolves, although a blend equation is still required for 3 component
357 // colormodels since fractional translation requires blending.
359 // If this is the only playable video track and the mode_keyframe is "normal"
360 // the mode keyframe may be overridden with "replace". Replace is faster.
361 if(mode == TRANSFER_NORMAL &&
362 vconsole->total_entry_nodes == 1)
363 mode = TRANSFER_REPLACE;
366 vrender->overlayer->overlay(output[i],
378 renderengine->edl->session->interpolation_type);
380 // for(int j = 0; j < output[i]->get_w() * 3 * 5; j++)
381 // output[i]->get_rows()[0][j] = 255;