pluginclient cr=apply in option value textbox, add loop_mode for vwdw
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / module.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "attachmentpoint.h"
23 #include "bcsignals.h"
24 #include "cache.h"
25 #include "commonrender.h"
26 #include "edl.h"
27 #include "edlsession.h"
28 #include "filexml.h"
29 #include "module.h"
30 #include "mwindow.h"
31 #include "patch.h"
32 #include "patchbay.h"
33 #include "plugin.h"
34 #include "pluginarray.h"
35 #include "pluginserver.h"
36 #include "renderengine.h"
37 #include "sharedlocation.h"
38 #include "track.h"
39 #include "tracks.h"
40 #include "transportque.h"
41 #include "virtualconsole.h"
42
43
44 Module::Module(RenderEngine *renderengine,
45         CommonRender *commonrender,
46         PluginArray *plugin_array,
47         Track *track)
48 {
49         this->renderengine = renderengine;
50         this->commonrender = commonrender;
51         this->plugin_array = plugin_array;
52         this->track = track;
53         transition_id = -1;
54         transition_server = 0;
55         attachments = 0;
56         total_attachments = 0;
57         new_total_attachments = 0;
58         new_attachments = 0;
59         nested_edl = 0;
60         nested_renderengine = 0;
61         nested_command = 0;
62         cache = 0;
63 }
64
65 Module::~Module()
66 {
67         if(attachments)
68         {
69                 for(int i = 0; i < track->plugin_set.total; i++)
70                 {
71                         if(attachments[i])
72                         {
73 // For some reason it isn't used here.
74 //                              attachments[i]->render_stop(0);
75                                 delete attachments[i];
76                         }
77                 }
78                 delete [] attachments;
79         }
80         if(transition_server)
81         {
82                 transition_server->close_plugin();
83                 delete transition_server;
84         }
85
86         delete nested_renderengine;
87         delete nested_command;
88 }
89
90 void Module::create_objects()
91 {
92         create_new_attachments();
93         swap_attachments();
94 }
95
96 EDL* Module::get_edl()
97 {
98         return renderengine ? renderengine->get_edl() : edl;
99 }
100
101 Preferences* Module::get_preferences()
102 {
103         if( renderengine ) return renderengine->preferences;
104         if( plugin_array ) return plugin_array->mwindow->preferences;
105         return 0;
106 }
107
108
109 void Module::create_new_attachments()
110 {
111 // Not used in pluginarray
112         if(commonrender)
113         {
114                 new_total_attachments = track->plugin_set.size();
115                 if(new_total_attachments)
116                 {
117                         new_attachments = new AttachmentPoint*[new_total_attachments];
118                         for(int i = 0; i < new_total_attachments; i++)
119                         {
120                                 Plugin *plugin =
121                                         track->get_current_plugin(commonrender->current_position,
122                                                 i,
123                                                 renderengine->command->get_direction(),
124                                                 0,
125                                                 1);
126
127                                 if(plugin && plugin->plugin_type != PLUGIN_NONE && plugin->on)
128                                 {
129                                         new_attachments[i] = new_attachment(plugin);
130 // printf("Module::create_new_attachments %d new_attachment=%p\n",
131 // __LINE__,
132 // new_attachments[i]->virtual_plugins.values);
133                                 }
134                                 else
135                                 {
136                                         new_attachments[i] = 0;
137                                 }
138                         }
139                 }
140                 else
141                         new_attachments = 0;
142
143 // Create plugin servers in virtual console expansion
144         }
145 }
146
147 void Module::swap_attachments()
148 {
149 // for(int i = 0; i < total_attachments; i++)
150 // printf("Module::swap_attachments %d attachment=%p\n", __LINE__, attachments[i] ? attachments[i]->virtual_plugins.values : 0);
151 // for(int i = 0; i < new_total_attachments; i++)
152 // printf("Module::swap_attachments %d new_attachment=%p\n", __LINE__, new_attachments[i] ? new_attachments[i]->virtual_plugins.values : 0);
153
154 // None of this is used in a pluginarray
155         for(int i = 0;
156                 i < new_total_attachments &&
157                 i < total_attachments;
158                 i++)
159         {
160 // Delete new attachment which is identical to the old one and copy
161 // old attachment.
162                 if(new_attachments[i] &&
163                         attachments[i] &&
164                         new_attachments[i]->identical(attachments[i]))
165                 {
166 // printf("Module::swap_attachments %d virtual_plugins=%p new_virtual_plugins=%p\n",
167 // __LINE__,
168 // new_attachments[i]->virtual_plugins.values,
169 // new_attachments[i]->new_virtual_plugins.values);
170
171                         delete new_attachments[i];
172                         new_attachments[i] = attachments[i];
173                         attachments[i] = 0;
174                 }
175         }
176
177 // Delete old attachments which weren't identical to new ones
178         for(int i = 0; i < total_attachments; i++)
179         {
180                 if(attachments[i]) delete attachments[i];
181         }
182
183         if(attachments)
184         {
185                 delete [] attachments;
186         }
187
188         attachments = new_attachments;
189         total_attachments = new_total_attachments;
190
191         new_attachments = 0;
192         new_total_attachments = 0;
193
194 // for(int i = 0; i < total_attachments; i++)
195 // printf("Module::swap_attachments %d final_attachment=%p\n", __LINE__, attachments[i] ? attachments[i]->virtual_plugins.values : 0);
196 }
197
198 int Module::render_init()
199 {
200         for(int i = 0; i < total_attachments; i++)
201         {
202                 if(attachments[i])
203                         attachments[i]->render_init();
204         }
205
206         return 0;
207 }
208
209 void Module::render_stop()
210 {
211         for(int i = 0; i < total_attachments; i++)
212         {
213                 if(attachments[i])
214                         attachments[i]->render_stop();
215         }
216 }
217
218 AttachmentPoint* Module::attachment_of(Plugin *plugin)
219 {
220 //printf("Module::attachment_of 1 %d\n", total_attachments);
221         for(int i = 0; i < total_attachments; i++)
222         {
223 //printf("Module::attachment_of 2 %p\n", attachments[i]);
224                 if(attachments[i] &&
225                         attachments[i]->plugin == plugin) return attachments[i];
226         }
227         return 0;
228 }
229
230 AttachmentPoint* Module::get_attachment(int number)
231 {
232         if(number < total_attachments)
233                 return attachments[number];
234         else
235                 return 0;
236 }
237
238 void Module::reset_attachments()
239 {
240 //printf("Module::reset_attachments 1 %d\n", total_attachments);
241         for(int i = 0; i < total_attachments; i++)
242         {
243 //printf("Module::reset_attachments 2 %p\n", attachments[i]);
244                 AttachmentPoint *attachment = attachments[i];
245                 if(attachment) attachment->reset_status();
246         }
247 }
248
249 // Test plugins for reconfiguration.
250 // Used in playback
251 int Module::test_plugins()
252 {
253         if(total_attachments != track->plugin_set.total) return 1;
254
255         for(int i = 0; i < total_attachments; i++)
256         {
257                 AttachmentPoint *attachment = attachments[i];
258                 Plugin *plugin = track->get_current_plugin(
259                         commonrender->current_position,
260                         i,
261                         renderengine->command->get_direction(),
262                         0,
263                         1);
264 // One exists and one doesn't
265                 int use_plugin = plugin &&
266                         plugin->plugin_type != PLUGIN_NONE &&
267                         plugin->on;
268
269                 if((attachment && !use_plugin) ||
270                         (!attachment && use_plugin)) return 1;
271
272 // Plugin not the same
273                 if( plugin && attachment && attachment->plugin && (
274                         plugin->gui_id != attachment->plugin->gui_id ||
275                         !plugin->identical(attachment->plugin) ) ) return 1;
276         }
277
278         return 0;
279 }
280
281 void Module::update_transition(int64_t current_position,
282         int direction)
283 {
284         Plugin *transition = track->get_current_transition(current_position,
285                 direction, 0, 0);
286         transition_id = transition ? transition->orig_id : -1;
287
288 // For situations where we had a transition but not anymore,
289 // keep the server open.
290 // Maybe the same transition will follow and we won't need to reinit.
291 // (happens a lot while scrubbing over transitions left and right)
292
293
294 // If the current transition differs from the previous transition, delete the
295 // server.
296         if (transition && transition_server) {
297                 Plugin *plugin = transition->edl->tracks->plugin_exists(transition_server->plugin_id);
298                 if (!plugin || strcmp(transition->title, plugin->title)) {
299                         transition_server->close_plugin();
300                         delete transition_server;
301                         transition_server = 0;
302                 }
303                 else {
304                         transition_server->plugin_id = transition_id;
305                 }
306         }
307
308         if(transition && !transition_server) {
309                 if(renderengine) {
310                         PluginServer *plugin_server = MWindow::scan_plugindb(transition->title,
311                                 track->data_type);
312                         transition_server = new PluginServer(*plugin_server);
313                         transition_server->open_plugin(0,
314                                 get_preferences(),
315                                 get_edl(),
316                                 transition);
317                         transition_server->init_realtime(
318                                 get_edl()->session->real_time_playback &&
319                                 renderengine->command->realtime,
320                                 1,
321                                 get_buffer_size());
322                 }
323                 else
324                 if(plugin_array) {
325                         PluginServer *plugin_server = MWindow::scan_plugindb(transition->title,
326                                 plugin_array->data_type);
327                         transition_server = new PluginServer(*plugin_server);
328                         transition_server->open_plugin(0,
329                                 get_preferences(),
330                                 get_edl(),
331                                 transition);
332                         transition_server->init_realtime(
333                                 0,
334                                 1,
335                                 get_buffer_size());
336                 }
337         }
338 }
339
340
341 void Module::dump()
342 {
343         printf("  Module title=%s\n", track->title);
344         printf("   Plugins total_attachments=%d\n", total_attachments);
345         for(int i = 0; i < total_attachments; i++)
346         {
347                 attachments[i]->dump();
348         }
349 }
350
351
352
353
354
355