r802: Remove renderframfsclient and renderfarmfsserver .h and .C from Makefile.am...
[cinelerra_cv/mob.git] / cinelerra / virtualnode.C
blob75dc98443a04965701215bf811ccb6a308d73a6f
1 #include "attachmentpoint.h"
2 #include "auto.h"
3 #include "automation.h"
4 #include "autos.h"
5 #include "floatauto.h"
6 #include "floatautos.h"
7 #include "intauto.h"
8 #include "intautos.h"
9 #include "mwindow.h"
10 #include "module.h"
11 #include "panauto.h"
12 #include "panautos.h"
13 #include "patchbay.h"
14 #include "plugin.h"
15 #include "pluginserver.h"
16 #include "renderengine.h"
17 #include "tracks.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, 
25                 Module *real_module, 
26                 Plugin *real_plugin,
27                 Track *track, 
28                 VirtualNode *parent_node)
30         this->renderengine = renderengine;
31         this->vconsole = vconsole;
32         this->real_module = real_module;
33         this->real_plugin = real_plugin;
34         this->track = track;
35         this->parent_node = parent_node;
36         render_count = 0;
37         plugin_type = 0;
38         waiting_real_plugin = 0;
39         plugin_buffer_number = 0;
40         plugin_autos = 0;
41         plugin_auto_before = plugin_auto_after = 0;
42         attachment = 0;
43         is_exit = 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)
57         PRINT_INDENT
58         printf("VirtualNode %p title=%s %s\n", 
59                 this, 
60                 track->title,
61                 is_exit ? "*" : " ");
62         if(real_module)
63         {
64                 PRINT_INDENT
65                 printf(" Plugins total=%d\n", subnodes.total);
66                 for(int i = 0; i < subnodes.total; i++)
67                 {
68                         subnodes.values[i]->dump(indent + 2);
69                 }
70         }
71         else
72         if(real_plugin)
73         {
74                 printf("    Plugin %s\n", real_plugin->title);
75         }
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
81         if(real_module)
82         {
83                 expand_as_module(persistent_plugins, current_position);
84         }
85         else
86         if(real_plugin)
87         {
88 // attach to a real plugin for a plugin
89 // plugin always takes data from input to output
90                 expand_as_plugin(persistent_plugins);
91         }
93         return 0;
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++)
102         {
103                 Plugin *plugin = track->get_current_plugin(current_position, 
104                         i, 
105                         renderengine->command->get_direction(),
106                         0,
107                         1);
109 // Switch off if circular reference.  This happens if a plugin set or a track is deleted.
110                 if(plugin == real_plugin) continue;
113                 if(plugin && plugin->on)
114                 {
115                         int plugin_type = plugin->plugin_type;
116                         if(plugin_type == PLUGIN_SHAREDMODULE)
117                         {
118 // plugin is a module
119                                 attach_virtual_module(plugin,
120                                         i, 
121                                         duplicate, 
122                                         current_position);
123                         }
124                         else
125                         if(plugin_type == PLUGIN_SHAREDPLUGIN ||
126                                 plugin_type == PLUGIN_STANDALONE)
127                         {
128 // plugin is a plugin
129                                 attach_virtual_plugin(plugin, 
130                                         i, 
131                                         duplicate, 
132                                         current_position);
133                         }
134                 }
135         }
138         if(!parent_node) vconsole->append_exit_node(this);
140         return 0;
143 int VirtualNode::expand_as_plugin(int duplicate)
145         plugin_type = real_plugin->plugin_type;
147         if(plugin_type == PLUGIN_SHAREDPLUGIN)
148         {
149 // Attached to a shared plugin.
150 // Get the real real plugin it's attached to.
152 // Redirect the real_plugin to the shared plugin.
153                 int real_module_number = real_plugin->shared_location.module;
154                 int real_plugin_number = real_plugin->shared_location.plugin;
155                 Module *real_module = vconsole->module_number(real_module_number);
156                 real_plugin = 0;
157 // module references are absolute so may get the wrong data type track.
158                 if(real_module)
159                 {
160                         attachment = real_module->get_attachment(real_plugin_number);
161 // Attachment is NULL if off
162                         if(attachment)
163                         {
164                                 real_plugin = attachment->plugin;
166 // Real plugin not on then null it.
167                                 if(!real_plugin || !real_plugin->on) real_plugin = 0;
168                         }
169                 }
170         }
177         if(plugin_type == PLUGIN_STANDALONE)
178         {
179 // Get plugin server
180                 Module *module = vconsole->module_of(track);
182                 attachment = module->attachment_of(real_plugin);
183         }
189 // Add to real plugin's list of virtual plugins for configuration updates
190 // and plugin_server initializations.
191 // Input and output are taken care of when the parent module creates this plugin.
192 // Get number for passing to render.
193 // real_plugin may become NULL after shared plugin test.
194         if(real_plugin && attachment)
195         {
196                 if(attachment)
197                         plugin_buffer_number = attachment->attach_virtual_plugin(this);
198         }
203         return 0;
206 int VirtualNode::attach_virtual_module(Plugin *plugin, 
207         int plugin_number, 
208         int duplicate, 
209         int64_t current_position)
211         if(plugin->on)
212         {
213                 int real_module_number = plugin->shared_location.module;
214                 Module *real_module = vconsole->module_number(real_module_number);
215 // If a track is deleted real_module is not found
216                 if(!real_module) return 1;
218                 Track *track = real_module->track;
220 // Switch off if circular reference.  This happens if a track is deleted.
221                 if(track == this->real_module->track) return 1;
226                 VirtualNode *virtual_module = create_module(plugin,
227                         real_module,
228                         track);
230                 subnodes.append(virtual_module);
231                 virtual_module->expand(duplicate, current_position);
232         }
234         return 0;
237 int VirtualNode::attach_virtual_plugin(Plugin *plugin, 
238         int plugin_number, 
239         int duplicate, 
240         int64_t current_position)
242 // Get real plugin and test if it is on.
243         int is_on = 1;
244         if(plugin->plugin_type == PLUGIN_SHAREDPLUGIN)
245         {
246                 int real_module_number = plugin->shared_location.module;
247                 int real_plugin_number = plugin->shared_location.plugin;
248                 Module *real_module = vconsole->module_number(real_module_number);
249                 if(real_module)
250                 {
251                         AttachmentPoint *attachment = real_module->get_attachment(real_plugin_number);
252                         if(attachment)
253                         {
254                                 Plugin *real_plugin = attachment->plugin;
255                                 if(!real_plugin || !real_plugin->on)
256                                         is_on = 0;
257                         }
258                         else
259                                 is_on = 0;
260                 }
261                 else
262                         is_on = 0;
263         }
265         if(is_on)
266         {
267                 VirtualNode *virtual_plugin = create_plugin(plugin);
268                 subnodes.append(virtual_plugin);
269                 virtual_plugin->expand(duplicate, current_position);
270         }
271         return 0;
274 VirtualNode* VirtualNode::get_previous_plugin(VirtualNode *current_node)
276         for(int i = 0; i < subnodes.total; i++)
277         {
278 // Assume plugin is on
279                 if(subnodes.values[i] == current_node)
280                 {
281                         if(i > 0) 
282                                 return subnodes.values[i - 1];
283                         else
284                                 return 0;
285                 }
286         }
287         return 0;
292 void VirtualNode::get_mute_fragment(int64_t input_position,
293                                 int &mute_constant, 
294                                 int &fragment_len, 
295                                 Autos *autos,
296                                 int direction,
297                                 int use_nudge)
299         if(use_nudge) input_position += track->nudge;
301         IntAuto *prev_keyframe = 0;
302         IntAuto *next_keyframe = 0;
303         prev_keyframe = (IntAuto*)autos->get_prev_auto(input_position, 
304                 direction, 
305                 (Auto* &)prev_keyframe);
306         next_keyframe = (IntAuto*)autos->get_next_auto(input_position, 
307                 direction, 
308                 (Auto* &)next_keyframe);
310         if(direction == PLAY_FORWARD)
311         {
312 // Two distinct keyframes within range
313                 if(next_keyframe->position > prev_keyframe->position)
314                 {
315                         mute_constant = prev_keyframe->value;
317                         if(next_keyframe->position < input_position + fragment_len)
318                                 fragment_len = next_keyframe->position - input_position;
319                 }
320                 else
321 // One keyframe within range
322                 {
323                         mute_constant = prev_keyframe->value;
324                 }
325         }
326         else
327         {
328 // Two distinct keyframes within range
329                 if(next_keyframe->position < prev_keyframe->position)
330                 {
331                         mute_constant = next_keyframe->value;
333                         if(next_keyframe->position > input_position - fragment_len)
334                                 fragment_len = input_position - next_keyframe->position;
335                 }
336                 else
337 // One keyframe within range
338                 {
339                         mute_constant = next_keyframe->value;
340                 }
341         }