1 #include "attachmentpoint.h"
3 #include "automation.h"
6 #include "floatautos.h"
15 #include "pluginserver.h"
16 #include "renderengine.h"
18 #include "transition.h"
19 #include "transportque.h"
20 #include "virtualconsole.h"
21 #include "virtualnode.h"
23 VirtualNode::VirtualNode(RenderEngine *renderengine,
24 VirtualConsole *vconsole,
28 VirtualNode *parent_node)
30 this->renderengine = renderengine;
31 this->vconsole = vconsole;
32 this->real_module = real_module;
33 this->real_plugin = real_plugin;
35 this->parent_node = parent_node;
38 waiting_real_plugin = 0;
39 plugin_buffer_number = 0;
41 plugin_auto_before = plugin_auto_after = 0;
44 //printf("VirtualNode::VirtualNode 1\n");
47 VirtualNode::~VirtualNode()
49 subnodes.remove_all_objects();
50 //printf("VirtualNode::VirtualNode 2\n");
53 #define PRINT_INDENT for(int j = 0; j < indent; j++) printf(" ");
55 void VirtualNode::dump(int indent)
58 printf("VirtualNode %p title=%s %s\n",
65 printf(" Plugins total=%d\n", subnodes.total);
66 for(int i = 0; i < subnodes.total; i++)
68 subnodes.values[i]->dump(indent + 2);
74 printf(" Plugin %s\n", real_plugin->title);
78 int VirtualNode::expand(int persistent_plugins, int64_t current_position)
80 // module needs to know where the input data for the next process is
83 expand_as_module(persistent_plugins, current_position);
88 // attach to a real plugin for a plugin
89 // plugin always takes data from input to output
90 expand_as_plugin(persistent_plugins);
96 int VirtualNode::expand_as_module(int duplicate, int64_t current_position)
98 Transition *transition = 0;
100 // create the plugins for this module
101 for(int i = 0; i < track->plugin_set.total; i++)
103 Plugin *plugin = track->get_current_plugin(current_position,
105 renderengine->command->get_direction(),
109 // Switch off if circular reference. This happens if a plugin set or a track is deleted.
110 if(plugin == real_plugin) continue;
117 int plugin_type = plugin->plugin_type;
118 if(plugin_type == PLUGIN_SHAREDMODULE)
120 // plugin is a module
121 attach_virtual_module(plugin,
127 if(plugin_type == PLUGIN_SHAREDPLUGIN ||
128 plugin_type == PLUGIN_STANDALONE)
130 // plugin is a plugin
131 attach_virtual_plugin(plugin,
141 if(!parent_node) vconsole->append_exit_node(this);
146 int VirtualNode::expand_as_plugin(int duplicate)
148 plugin_type = real_plugin->plugin_type;
150 if(plugin_type == PLUGIN_SHAREDPLUGIN)
152 // Attached to a shared plugin.
153 // Get the real real plugin it's attached to.
155 // Redirect the real_plugin to the shared plugin.
156 int real_module_number = real_plugin->shared_location.module;
157 int real_plugin_number = real_plugin->shared_location.plugin;
158 Module *real_module = 0;
161 real_module = vconsole->module_number(real_module_number);
162 // module references are absolute so may get the wrong data type track.
164 real_plugin_number < real_module->total_attachments)
166 attachment = real_module->attachments[real_plugin_number];
167 // Attachment is NULL if off
170 real_plugin = attachment->plugin;
172 // Real plugin not on then null it.
173 if(!real_plugin || !real_plugin->on) real_plugin = 0;
187 if(plugin_type == PLUGIN_STANDALONE)
190 Module *module = vconsole->module_of(track);
192 attachment = module->attachment_of(real_plugin);
199 // Add to real plugin's list of virtual plugins for configuration updates
200 // and plugin_server initializations.
201 // Input and output are taken care of when the parent module creates this plugin.
202 // Get number for passing to render.
203 // real_plugin may become NULL after shared plugin test.
204 if(real_plugin && attachment)
207 plugin_buffer_number = attachment->attach_virtual_plugin(this);
216 int VirtualNode::attach_virtual_module(Plugin *plugin,
219 int64_t current_position)
223 //printf("VirtualNode::attach_virtual_module 1 %p\n", plugin);
224 int real_module_number = plugin->shared_location.module;
225 //printf("VirtualNode::attach_virtual_module 1\n");
226 Module *real_module = vconsole->module_number(real_module_number);
227 //printf("VirtualNode::attach_virtual_module 1\n");
229 // If a track is deleted real_module is not found
230 if(!real_module) return 1;
232 Track *track = real_module->track;
234 // Switch off if circular reference. This happens if a track is deleted.
235 if(track == this->real_module->track) return 1;
240 VirtualNode *virtual_module = create_module(plugin,
243 //printf("VirtualNode::attach_virtual_module 1\n");
245 subnodes.append(virtual_module);
246 //printf("VirtualNode::attach_virtual_module 1\n");
247 virtual_module->expand(duplicate, current_position);
248 //printf("VirtualNode::attach_virtual_module 2\n");
254 int VirtualNode::attach_virtual_plugin(Plugin *plugin,
257 int64_t current_position)
261 VirtualNode *virtual_plugin = create_plugin(plugin);
262 subnodes.append(virtual_plugin);
263 virtual_plugin->expand(duplicate, current_position);
268 VirtualNode* VirtualNode::get_previous_plugin(VirtualNode *current_node)
270 for(int i = 0; i < subnodes.total; i++)
272 // Assume plugin is on
273 if(subnodes.values[i] == current_node)
276 return subnodes.values[i - 1];
284 // int VirtualNode::sort(ArrayList<VirtualNode*>*render_list)
286 // int result = 0, total_result = 0;
289 // //printf("VirtualNode::sort %p %p\n", real_module, real_plugin);
292 // sort_as_module(render_list, result, total_result);
297 // sort_as_plugin(render_list, result, total_result);
300 // if(!result && total_result) result = total_result;
301 // // if a plugin that wasn't patched out couldn't be rendered, try again
306 // int VirtualNode::sort_as_module(ArrayList<VirtualNode*>*render_list, int &result, int &total_result)
309 // // Render plugins first.
310 // for(int i = 0; i < subnodes.total && !result; i++)
312 // // stop when rendering can't continue without another higher level module
313 // result = subnodes.values[i]->sort(render_list);
315 // if(result && !subnodes.values[i]->out)
319 // // couldn't render the last plugin but it wasn't patched out so continue to next plugin
322 // //printf("VirtualNode::sort_as_module 3\n");
324 // // All plugins rendered.
325 // // Render this module.
326 // if(render_count == 0 && !result)
328 // render_list->append(this);
332 // //printf("VirtualNode::sort_as_module 4\n");
336 // int VirtualNode::sort_as_plugin(ArrayList<VirtualNode*>*render_list,
338 // int &total_result)
340 // // Plugin server does not exist at this point.
341 // // need to know if plugin requires all inputs to be armed before rendering
342 // //printf("VirtualNode::sort_as_plugin 1\n");
343 // int multichannel = 0, singlechannel = 0;
347 // // Referenced plugin is off
348 // if(!attachment) return 0;
350 // //printf("VirtualNode::sort_as_plugin 2 %p\n", attachment);
351 // if(plugin_type == PLUGIN_STANDALONE || plugin_type == PLUGIN_SHAREDPLUGIN)
353 // multichannel = attachment->multichannel_shared(1);
354 // singlechannel = attachment->singlechannel();
357 // //printf("VirtualNode::sort_as_plugin 3\n");
358 // if(plugin_type == PLUGIN_STANDALONE && !multichannel)
360 // // unshared single channel plugin
362 // //printf("VirtualNode::sort_as_plugin 4\n");
365 // render_list->append(this);
369 // //printf("VirtualNode::sort_as_plugin 5\n");
372 // if(plugin_type == PLUGIN_SHAREDPLUGIN || multichannel)
376 // //printf("VirtualNode::sort_as_plugin 6\n");
381 // // shared single channel plugin
383 // //printf("VirtualNode::sort_as_plugin 7\n");
384 // render_list->append(this);
385 // //printf("VirtualNode::sort_as_plugin 8\n");
391 // // shared multichannel plugin
392 // // all buffers must be armed before rendering at the same time
393 // if(!waiting_real_plugin)
395 // //printf("VirtualNode::sort_as_plugin 9 %p\n", attachment);
396 // waiting_real_plugin = 1;
398 // result = attachment->sort(this);
399 // //printf("VirtualNode::sort_as_plugin 10\n");
401 // render_list->append(this);
402 // //printf("VirtualNode::sort_as_plugin 11\n");
407 // // Assume it was rendered later in the first pass
413 // //printf("VirtualNode::sort_as_plugin 12\n");
417 // int VirtualNode::get_plugin_input(int &ring_buffer_in, int64_t &fragment_position_in,
418 // int &ring_buffer_out, int64_t &fragment_position_out,
419 // int ring_buffer, int64_t fragment_position)
421 // if(input_is_master)
423 // ring_buffer_in = ring_buffer;
424 // fragment_position_in = fragment_position;
428 // ring_buffer_in = 0;
429 // fragment_position_in = 0;
432 // if(output_is_master)
434 // ring_buffer_out = ring_buffer;
435 // fragment_position_out = fragment_position;
439 // ring_buffer_out = 0;
440 // fragment_position_out = 0;
444 // int VirtualNode::render_as_plugin(int64_t source_len,
445 // int64_t source_position,
447 // int64_t fragment_position,
448 // int64_t fragment_len)
450 // // need numbers for actual buffers
451 // int direction = renderengine->command->get_direction();
452 // int ring_buffer_in, ring_buffer_out;
453 // int64_t fragment_position_in, fragment_position_out;
454 // int multichannel = 0;
455 // //printf("VirtualNode::render_as_plugin 1 %p\n", attachment);
457 // // Abort if no plugin
460 // !real_plugin->on) return 0;
462 // //printf("VirtualNode::render_as_plugin 2\n");
467 void VirtualNode::get_mute_fragment(int64_t input_position,
474 if(use_nudge) input_position += track->nudge;
476 IntAuto *prev_keyframe = 0;
477 IntAuto *next_keyframe = 0;
478 prev_keyframe = (IntAuto*)autos->get_prev_auto(input_position, direction, (Auto*&)prev_keyframe);
479 next_keyframe = (IntAuto*)autos->get_next_auto(input_position, direction, (Auto*&)next_keyframe);
481 if(direction == PLAY_FORWARD)
483 // Two distinct keyframes within range
484 if(next_keyframe->position > prev_keyframe->position)
486 mute_constant = prev_keyframe->value;
488 if(next_keyframe->position < input_position + fragment_len)
489 fragment_len = next_keyframe->position - input_position;
492 // One keyframe within range
494 mute_constant = prev_keyframe->value;
499 // Two distinct keyframes within range
500 if(next_keyframe->position < prev_keyframe->position)
502 mute_constant = next_keyframe->value;
504 if(next_keyframe->position > input_position - fragment_len)
505 fragment_len = input_position - next_keyframe->position;
508 // One keyframe within range
510 mute_constant = next_keyframe->value;
517 // void VirtualNode::get_fade_automation(double &slope,
518 // double &intercept,
519 // int64_t input_position,
520 // int64_t &slope_len,
523 // int direction = renderengine->command->get_direction();
524 // ((FloatAutos*)autos)->get_fade_automation(slope,
532 // int VirtualNode::init_automation(int &automate,
534 // int64_t input_position,
535 // int64_t buffer_len,
540 // return autos->init_automation(buffer_position,
552 // int VirtualNode::init_slope(Autos *autos, Auto **before, Auto **after)
554 // return autos->init_slope(¤t_auto,
565 // int VirtualNode::get_slope(Autos *autos, int64_t buffer_len, int64_t buffer_position)
567 // return autos->get_slope(¤t_auto,
577 // int VirtualNode::advance_slope(Autos *autos)
579 // return autos->advance_slope(¤t_auto,