r863: Merge 2.1:
[cinelerra_cv/ct.git] / cinelerra / module.C
blob1006de25a569e01c7b5a12b738f8debcaad80163
1 #include "attachmentpoint.h"
2 #include "bcsignals.h"
3 #include "commonrender.h"
4 #include "edl.h"
5 #include "edlsession.h"
6 #include "filexml.h"
7 #include "module.h"
8 #include "mwindow.h"
9 #include "patch.h"
10 #include "patchbay.h"
11 #include "plugin.h"
12 #include "pluginarray.h"
13 #include "pluginserver.h"
14 #include "renderengine.h"
15 #include "sharedlocation.h"
16 #include "track.h"
17 #include "tracks.h"
18 #include "transportque.h"
21 Module::Module(RenderEngine *renderengine, 
22         CommonRender *commonrender, 
23         PluginArray *plugin_array,
24         Track *track)
26         this->renderengine = renderengine;
27         this->commonrender = commonrender;
28         this->plugin_array = plugin_array;
29         this->track = track;
30         transition = 0;
31         transition_server = 0;
32         attachments = 0;
33         total_attachments = 0;
34         new_total_attachments = 0;
35         new_attachments = 0;
38 Module::~Module()
40         if(attachments)
41         {
42                 for(int i = 0; i < track->plugin_set.total; i++)
43                 {
44                         if(attachments[i])
45                         {
46 // For some reason it isn't used here.
47 //                              attachments[i]->render_stop(0);
48                                 delete attachments[i];
49                         }
50                 }
51                 delete [] attachments;
52         }
53         if(transition_server)
54         {
55                 transition_server->close_plugin();
56                 delete transition_server;
57         }
60 void Module::create_objects()
62         create_new_attachments();
63         swap_attachments();
66 EDL* Module::get_edl()
68         if(renderengine) 
69                 return renderengine->edl;
70         else
71                 return edl;
74 void Module::create_new_attachments()
76 // Not used in pluginarray
77         if(commonrender)
78         {
79                 new_total_attachments = track->plugin_set.total;
80                 if(new_total_attachments)
81                 {
82                         new_attachments = new AttachmentPoint*[new_total_attachments];
83                         for(int i = 0; i < new_total_attachments; i++)
84                         {
85                                 Plugin *plugin = 
86                                         track->get_current_plugin(commonrender->current_position, 
87                                                 i, 
88                                                 renderengine->command->get_direction(),
89                                                 0,
90                                                 1);
92                                 if(plugin && plugin->plugin_type != PLUGIN_NONE && plugin->on)
93                                         new_attachments[i] = new_attachment(plugin);
94                                 else
95                                         new_attachments[i] = 0;
96                         }
97                 }
98                 else
99                         new_attachments = 0;
101 // Create plugin servers in virtual console expansion
102         }
105 void Module::swap_attachments()
107 // None of this is used in a pluginarray
108         for(int i = 0; 
109                 i < new_total_attachments &&
110                 i < total_attachments; 
111                 i++)
112         {
113 // Delete new attachment which is identical to the old one and copy
114 // old attachment.
115                 if(new_attachments[i] &&
116                         attachments[i] &&
117                         new_attachments[i]->identical(attachments[i]))
118                 {
119                         delete new_attachments[i];
120                         new_attachments[i] = attachments[i];
121                         attachments[i] = 0;
122                 }
123         }
125 // Delete old attachments which weren't identical to new ones
126         for(int i = 0; i < total_attachments; i++)
127         {
128                 if(attachments[i]) delete attachments[i];
129         }
131         if(attachments)
132         {
133                 delete [] attachments;
134         }
136         attachments = new_attachments;
137         total_attachments = new_total_attachments;
140 int Module::render_init()
142         for(int i = 0; i < total_attachments; i++)
143         {
144                 if(attachments[i])
145                         attachments[i]->render_init();
146         }
148         return 0;
151 void Module::render_stop()
153         for(int i = 0; i < total_attachments; i++)
154         {
155                 if(attachments[i])
156                         attachments[i]->render_stop();
157         }
160 AttachmentPoint* Module::attachment_of(Plugin *plugin)
162 //printf("Module::attachment_of 1 %d\n", total_attachments);
163         for(int i = 0; i < total_attachments; i++)
164         {
165 //printf("Module::attachment_of 2 %p\n", attachments[i]);
166                 if(attachments[i] && 
167                         attachments[i]->plugin == plugin) return attachments[i];
168         }
169         return 0;
172 AttachmentPoint* Module::get_attachment(int number)
174         if(number < total_attachments)
175                 return attachments[number];
176         else
177                 return 0;
180 void Module::reset_attachments()
182 //printf("Module::reset_attachments 1 %d\n", total_attachments);
183         for(int i = 0; i < total_attachments; i++)
184         {
185 //printf("Module::reset_attachments 2 %p\n", attachments[i]);
186                 AttachmentPoint *attachment = attachments[i];
187                 if(attachment) attachment->reset_status();
188         }
191 // Test plugins for reconfiguration.
192 // Used in playback
193 int Module::test_plugins()
195         if(total_attachments != track->plugin_set.total) return 1;
197         for(int i = 0; i < total_attachments; i++)
198         {
199                 AttachmentPoint *attachment = attachments[i];
200                 Plugin *plugin = track->get_current_plugin(
201                         commonrender->current_position, 
202                         i, 
203                         renderengine->command->get_direction(),
204                         0,
205                         1);
206 // One exists and one doesn't
207                 int use_plugin = plugin &&
208                         plugin->plugin_type != PLUGIN_NONE &&
209                         plugin->on;
211                 if((attachment && !use_plugin) || 
212                         (!attachment && use_plugin)) return 1;
214 // Plugin not the same
215                 if(plugin && 
216                         attachment &&
217                         attachment->plugin && 
218                         !plugin->identical(attachment->plugin)) return 1;
219         }
221         return 0;
224 void Module::update_transition(int64_t current_position, 
225         int direction)
227         transition = track->get_current_transition(current_position,
228                 direction,
229                 0,
230                 0); // position is already nudged in amodule.C and vmodule.C before calling update_transition!
232 // For situations where we had a transition but not anymore, 
233 // keep the server open.
234 // Maybe the same transition will follow and we won't need to reinit.
235 // (happens a lot while scrubbing over transitions left and right)
238 // If the current transition differs from the previous transition, delete the
239 // server.
240         if ((transition && 
241                 transition_server && 
242                 strcmp(transition->title, transition_server->plugin->title)))
243         {
244                 transition_server->close_plugin();
245                 delete transition_server;
246                 transition_server = 0;
247         }
249         if(transition && !transition_server)
250         {
251                 if(renderengine)
252                 {
253                         PluginServer *plugin_server = renderengine->scan_plugindb(transition->title,
254                                 track->data_type);
255                         transition_server = new PluginServer(*plugin_server);
256                         transition_server->open_plugin(0, 
257                                 renderengine->preferences, 
258                                 get_edl(), 
259                                 transition,
260                                 -1);
261                         transition_server->init_realtime(
262                                 get_edl()->session->real_time_playback &&
263                                 renderengine->command->realtime,
264                                 1,
265                                 get_buffer_size());
266                 }
267                 else
268                 if(plugin_array)
269                 {
270                         PluginServer *plugin_server = plugin_array->scan_plugindb(transition->title);
271                         transition_server = new PluginServer(*plugin_server);
272                         transition_server->open_plugin(0, 
273                                 plugin_array->mwindow->preferences,
274                                 get_edl(), 
275                                 transition,
276                                 -1);
277                         transition_server->init_realtime(
278                                 0,
279                                 1,
280                                 get_buffer_size());
281                 }
282         }
286 void Module::dump()
288         printf("  Module title=%s\n", track->title);
289         printf("   Plugins total_attachments=%d\n", total_attachments);
290         for(int i = 0; i < total_attachments; i++)
291         {
292                 attachments[i]->dump();
293         }