r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / pluginserver.C
blob55c0950df1754f34be6fcb6894f8dd0973bd08a8
1 #include "amodule.h"
2 #include "atrack.h"
3 #include "attachmentpoint.h"
4 #include "autoconf.h"
5 #include "cplayback.h"
6 #include "cwindow.h"
7 #include "edl.h"
8 #include "edlsession.h"
9 #include "floatautos.h"
10 #include "localsession.h"
11 #include "mainprogress.h"
12 #include "menueffects.h"
13 #include "mwindow.h"
14 #include "mwindowgui.h"
15 #include "neworappend.h"
16 #include "playbackengine.h"
17 #include "plugin.h"
18 #include "pluginaclientlad.h"
19 #include "pluginclient.h"
20 #include "plugincommands.h"
21 #include "pluginserver.h"
22 #include "preferences.h"
23 #include "sema.h"
24 #include "mainsession.h"
25 #include "trackcanvas.h"
26 #include "transportque.h"
27 #include "vframe.h"
28 #include "vmodule.h"
29 #include "vtrack.h"
32 #include <sys/types.h>
33 #include <sys/wait.h>
34 #include <dlfcn.h>
37 PluginServer::PluginServer()
39         reset_parameters();
40         modules = new ArrayList<Module*>;
43 PluginServer::PluginServer(char *path)
45         reset_parameters();
46         set_path(path);
47         modules = new ArrayList<Module*>;
48 //if(path) printf("PluginServer::PluginServer %s\n", path);
51 PluginServer::PluginServer(PluginServer &that)
53         reset_parameters();
55         if(that.title)
56         {
57                 title = new char[strlen(that.title) + 1];
58                 strcpy(title, that.title);
59         }
61         if(that.path)
62         {
63                 path = new char[strlen(that.path) + 1];
64                 strcpy(path, that.path);
65         }
67         modules = new ArrayList<Module*>;
69         attachment = that.attachment;   
70         realtime = that.realtime;
71         multichannel = that.multichannel;
72         synthesis = that.synthesis;
73         audio = that.audio;
74         video = that.video;
75         theme = that.theme;
76         fileio = that.fileio;
77         uses_gui = that.uses_gui;
78         mwindow = that.mwindow;
79         keyframe = that.keyframe;
80         plugin_fd = that.plugin_fd;
81         new_plugin = that.new_plugin;
83         is_lad = that.is_lad;
84         lad_descriptor = that.lad_descriptor;
85         lad_descriptor_function = that.lad_descriptor_function;
88 PluginServer::~PluginServer()
90         close_plugin();
91         if(path) delete [] path;
92         if(title) delete [] title;
93         if(modules) delete modules;
94         if(picon) delete picon;
97 // Done only once at creation
98 int PluginServer::reset_parameters()
100         mwindow = 0;
101         keyframe = 0;
102         prompt = 0;
103         cleanup_plugin();
104         plugin_fd = 0;
105         autos = 0;
106         plugin = 0;
107         edl = 0;
108         title = 0;
109         path = 0;
110         audio = video = theme = 0;
111         uses_gui = 0;
112         realtime = multichannel = fileio = 0;
113         synthesis = 0;
114         start_auto = end_auto = 0;
115         picon = 0;
116         transition = 0;
117         new_plugin = 0;
118         client = 0;
120         is_lad = 0;
121         lad_descriptor_function = 0;
122         lad_descriptor = 0;
126 // Done every time the plugin is opened or closed
127 int PluginServer::cleanup_plugin()
129         in_buffer_size = out_buffer_size = 0;
130         total_in_buffers = total_out_buffers = 0;
131         error_flag = 0;
132         written_samples = 0;
133         shared_buffers = 0;
134         new_buffers = 0;
135         written_samples = written_frames = 0;
136         gui_on = 0;
137         plugin = 0;
138         plugin_open = 0;
141 void PluginServer::set_mwindow(MWindow *mwindow)
143         this->mwindow = mwindow;
146 void PluginServer::set_attachmentpoint(AttachmentPoint *attachmentpoint)
148         this->attachmentpoint = attachmentpoint;
151 void PluginServer::set_keyframe(KeyFrame *keyframe)
153         this->keyframe = keyframe;
156 void PluginServer::set_prompt(MenuEffectPrompt *prompt)
158         this->prompt = prompt;
162 int PluginServer::set_path(char *path)
164         if(this->path) delete [] this->path;
165         this->path = new char[strlen(path) + 1];
166         strcpy(this->path, path);
169 void PluginServer::set_title(char *string)
171         if(title) delete [] title;
172         title = new char[strlen(string) + 1];
173         strcpy(title, string);
176 void PluginServer::generate_display_title(char *string)
178 //printf("PluginServer::generate_display_title %s %s\n", plugin->track->title, title);
179         if(plugin) 
180                 sprintf(string, "%s: %s", plugin->track->title, title);
181         else
182                 strcpy(string, title);
185 // Open plugin for signal processing
186 int PluginServer::open_plugin(int master, 
187         EDL *edl, 
188         Plugin *plugin,
189         int lad_index)
191         if(plugin_open) return 0;
193         if(!plugin_fd) plugin_fd = dlopen(path, RTLD_NOW);
194         this->plugin = plugin;
195         this->edl = edl;
196 //printf("PluginServer::open_plugin %s %p %p\n", path, this->plugin, plugin_fd);
201         if(!plugin_fd)
202         {
203 // If the dlopen failed it may still be an executable tool for a specific
204 // file format, in which case we just store the path.
205                 set_title(path);
206                 char string[BCTEXTLEN];
207                 strcpy(string, dlerror());
209                 if(!strstr(string, "executable"))
210                         printf("PluginServer::open_plugin: %s\n", string);
211                 
212                 return 0;
213         }
216         if(!new_plugin && !lad_descriptor)
217         {
218 //printf("%p %p\n", dlsym(RTLD_NEXT, "open"), dlsym(RTLD_NEXT, "open64"));
219                 new_plugin = (PluginClient* (*)(PluginServer*))dlsym(plugin_fd, "new_plugin");
221 // Probably a LAD plugin but we're not going to instantiate it here anyway.
222                 if(!new_plugin)
223                 {
224                         lad_descriptor_function = (LADSPA_Descriptor_Function)dlsym(
225                                 plugin_fd,
226                                 "ladspa_descriptor");
227 //printf("PluginServer::open_plugin 2 %p\n", lad_descriptor_function);
229                         if(!lad_descriptor_function)
230                         {
231 // Not a recognized plugin
232                                 fprintf(stderr, "PluginServer::open_plugin: new_plugin undefined in %s\n", path);
233                                 dlclose(plugin_fd);
234                                 plugin_fd = 0;
235                                 return PLUGINSERVER_NOT_RECOGNIZED;
236                         }
237                         else
238                         {
239 // LAD plugin,  Load the descriptor and get parameters.
240                                 is_lad = 1;
241                                 if(lad_index >= 0)
242                                 {
243                                         lad_descriptor = lad_descriptor_function(lad_index);
244                                 }
246 // make plugin initializer handle the subplugins in the LAD plugin or stop
247 // trying subplugins.
248                                 if(!lad_descriptor)
249                                 {
250                                         dlclose(plugin_fd);
251                                         plugin_fd = 0;
252 //printf("PluginServer::open_plugin 1 %s\n", path);
253                                         return PLUGINSERVER_IS_LAD;
254                                 }
255                         }
256                 }
257         }
260         if(is_lad)
261         {
262                 client = new PluginAClientLAD(this);
263         }
264         else
265         {
266                 client = new_plugin(this);
267         }
269         realtime = client->is_realtime();
270         audio = client->is_audio();
271         video = client->is_video();
272         theme = client->is_theme();
273         fileio = client->is_fileio();
274         uses_gui = client->uses_gui();
275         multichannel = client->is_multichannel();
276         synthesis = client->is_synthesis();
277         transition = client->is_transition();
278         set_title(client->plugin_title());
280         if(master)
281         {
282                 picon = client->new_picon();
283         }
285 //printf("PluginServer::open_plugin 2\n");
286         plugin_open = 1;
287         return PLUGINSERVER_OK;
290 int PluginServer::close_plugin()
292         if(!plugin_open) return 0;
294         int plugin_status, result;
295         if(client) delete client;
297 // shared object is persistent since plugin deletion would unlink its own object
298 //      dlclose(plugin_fd);
299 //printf("PluginServer::close_plugin 1\n");
300         plugin_open = 0;
302         cleanup_plugin();
303 //printf("PluginServer::close_plugin 2\n");
305         return 0;
308 void PluginServer::client_side_close()
310 // Last command executed in client thread
311         if(plugin)
312                 mwindow->hide_plugin(plugin, 1);
313         else
314         if(prompt)
315         {
316                 prompt->lock_window();
317                 prompt->set_done(1);
318                 prompt->unlock_window();
319         }
322 int PluginServer::init_realtime(int realtime_sched,
323                 int total_in_buffers, 
324                 int buffer_size)
326         if(!plugin_open) return 0;
327 // set for realtime priority
328 // initialize plugin
329 // Call start_realtime
330         client->plugin_init_realtime(realtime_sched, total_in_buffers, buffer_size);
334 void PluginServer::process_realtime(VFrame **input, 
335                 VFrame **output, 
336                 int64_t current_position,
337                 int64_t total_len)
339 //printf("PluginServer::process_realtime 1 %d\n", plugin_open);
340         if(!plugin_open) return;
342         client->plugin_process_realtime(input, 
343                 output, 
344                 current_position,
345                 total_len);
346 //printf("PluginServer::process_realtime 2 %d\n", plugin_open);
349 void PluginServer::process_realtime(double **input, 
350                 double **output,
351                 int64_t current_position, 
352                 int64_t fragment_size,
353                 int64_t total_len)
355         if(!plugin_open) return;
357         client->plugin_process_realtime(input, 
358                 output, 
359                 current_position, 
360                 fragment_size,
361                 total_len);
364 void PluginServer::send_render_gui(void *data)
366 //printf("PluginServer::send_render_gui 1 %p\n", attachmentpoint);
367         if(attachmentpoint) attachmentpoint->render_gui(data);
370 void PluginServer::send_render_gui(void *data, int size)
372 //printf("PluginServer::send_render_gui 1 %p\n", attachmentpoint);
373         if(attachmentpoint) attachmentpoint->render_gui(data, size);
376 void PluginServer::render_gui(void *data)
378         if(client) client->plugin_render_gui(data);
381 void PluginServer::render_gui(void *data, int size)
383         if(client) client->plugin_render_gui(data, size);
386 MainProgressBar* PluginServer::start_progress(char *string, int64_t length)
388         mwindow->gui->lock_window();
389         MainProgressBar *result = mwindow->mainprogress->start_progress(string, length);
390         mwindow->gui->unlock_window();
391         return result;
394 int64_t PluginServer::get_written_samples()
396         if(!plugin_open) return 0;
397         return written_samples;
400 int64_t PluginServer::get_written_frames()
402         if(!plugin_open) return 0;
403         return written_frames;
411 int PluginServer::get_parameters()      // waits for plugin to finish and returns a result
413         if(!plugin_open) return 0;
414         return client->plugin_get_parameters();
421 // ======================= Non-realtime plugin
423 int PluginServer::set_interactive()
425         if(!plugin_open) return 0;
426         client->set_interactive();
427         return 0;
430 int PluginServer::set_module(Module *module)
432         modules->append(module);
433         return 0;
436 int PluginServer::set_error()
438         error_flag = 1;
439         return 0;
442 int PluginServer::set_realtime_sched()
444         struct sched_param params;
445         params.sched_priority = 1;
446         return 0;
450 int PluginServer::process_loop(VFrame **buffers, int64_t &write_length)
452         if(!plugin_open) return 1;
453         return client->plugin_process_loop(buffers, write_length);
456 int PluginServer::process_loop(double **buffers, int64_t &write_length)
458         if(!plugin_open) return 1;
459         return client->plugin_process_loop(buffers, write_length);
462 int PluginServer::start_loop(int64_t start, int64_t end, int64_t buffer_size, int total_buffers)
464         if(!plugin_open) return 0;
465         client->plugin_start_loop(start, end, buffer_size, total_buffers);
466         return 0;
469 int PluginServer::stop_loop()
471         if(!plugin_open) return 0;
472         return client->plugin_stop_loop();
475 int PluginServer::read_frame(VFrame *buffer, int channel, int64_t start_position)
477 //printf("PluginServer::read_frame 1 %p\n", modules);
478 //printf("PluginServer::read_frame 1 %p\n", modules->values[channel]);
479 //printf("PluginServer::read_frame 1 %d %d\n", buffer->get_w(), buffer->get_h());
480         ((VModule*)modules->values[channel])->render(buffer,
481                 start_position,
482                 PLAY_FORWARD);
483 //printf("PluginServer::read_frame 2\n");
484         return 0;
487 int PluginServer::read_samples(double *buffer, int channel, int64_t start_position, int64_t total_samples)
489 //printf("PluginServer::read_samples 1\n");
490         ((AModule*)modules->values[channel])->render(buffer, 
491                 total_samples, 
492                 start_position,
493                 PLAY_FORWARD);
494 //printf("PluginServer::read_samples 2\n");
495         return 0;
498 int PluginServer::read_samples(double *buffer, int64_t start_position, int64_t total_samples)
500         ((AModule*)modules->values[0])->render(buffer, 
501                 total_samples, 
502                 start_position,
503                 PLAY_FORWARD);
504         return 0;
509 // Called by client
510 int PluginServer::get_gui_status()
512 //printf("PluginServer::get_gui_status %p %p\n", this, plugin);
513         if(plugin)
514                 return plugin->show ? GUI_ON : GUI_OFF;
515         else
516                 return GUI_OFF;
519 void PluginServer::raise_window()
521         if(!plugin_open) return;
522         client->raise_window();
525 void PluginServer::show_gui()
527 //printf("PluginServer::show_gui 1\n");
528         if(!plugin_open) return;
529         client->smp = mwindow->edl->session->smp;
530 //printf("PluginServer::show_gui 1\n");
531         client->update_display_title();
532 //printf("PluginServer::show_gui 1\n");
533         client->show_gui();
534 //printf("PluginServer::show_gui 2\n");
537 void PluginServer::update_gui()
539 //printf("PluginServer::update_gui 1\n");
540         if(!plugin_open) return;
541 //printf("PluginServer::update_gui 2\n");
543         if(video)
544                 client->source_position = Units::to_int64(
545                         mwindow->edl->local_session->selectionstart * mwindow->edl->session->frame_rate);
546         else
547         if(audio)
548                 client->source_position = Units::to_int64(
549                         mwindow->edl->local_session->selectionstart * mwindow->edl->session->sample_rate);
550         client->update_gui();
553 void PluginServer::update_title()
555         if(!plugin_open) return;
556         
557         client->update_display_title();
561 int PluginServer::set_string(char *string)
563         if(!plugin_open) return 0;
565         client->set_string_client(string);
566         return 0;
570 // ============================= queries
572 int PluginServer::get_samplerate()
574         if(!plugin_open) return 0;
575         if(audio)
576         {
577                 return client->get_samplerate();
578         }
579         else
580         if(mwindow)
581                 return mwindow->edl->session->sample_rate;
582         else
583         {
584                 printf("PluginServer::get_samplerate audio and mwindow == NULL\n");
585                 return 1;
586         }
590 double PluginServer::get_framerate()
592         if(!plugin_open) return 0;
593         if(video)
594         {
595                 return client->get_framerate();
596         }
597         else
598         if(mwindow)
599                 return mwindow->edl->session->frame_rate;
600         else 
601         {
602                 printf("PluginServer::get_framerate video and mwindow == NULL\n");
603                 return 1;
604         }
607 int PluginServer::get_project_samplerate()
609         return mwindow->edl->session->sample_rate;
612 double PluginServer::get_project_framerate()
614         return  mwindow->edl->session->frame_rate;
619 int PluginServer::detach_buffers()
621         ring_buffers_out.remove_all();
622         offset_out_render.remove_all();
623         double_buffer_out_render.remove_all();
624         realtime_out_size.remove_all();
626         ring_buffers_in.remove_all();
627         offset_in_render.remove_all();
628         double_buffer_in_render.remove_all();
629         realtime_in_size.remove_all();
630         
631         out_buffer_size = 0;
632         shared_buffers = 0;
633         total_out_buffers = 0;
634         in_buffer_size = 0;
635         total_in_buffers = 0;
636         return 0;
639 int PluginServer::arm_buffer(int buffer_number, 
640                 int64_t offset_in, 
641                 int64_t offset_out,
642                 int double_buffer_in,
643                 int double_buffer_out)
645         offset_in_render.values[buffer_number] = offset_in;
646         offset_out_render.values[buffer_number] = offset_out;
647         double_buffer_in_render.values[buffer_number] = double_buffer_in;
648         double_buffer_out_render.values[buffer_number] = double_buffer_out;
652 int PluginServer::set_automation(FloatAutos *autos, FloatAuto **start_auto, FloatAuto **end_auto, int reverse)
654         this->autos = autos;
655         this->start_auto = start_auto;
656         this->end_auto = end_auto;
657         this->reverse = reverse;
662 void PluginServer::save_data(KeyFrame *keyframe)
664         if(!plugin_open) return;
665         client->save_data(keyframe);
668 KeyFrame* PluginServer::get_prev_keyframe(int64_t position)
670         KeyFrame *result = 0;
671         if(plugin)
672                 result = plugin->get_prev_keyframe(position);
673         else
674                 result = keyframe;
675         return result;
678 KeyFrame* PluginServer::get_next_keyframe(int64_t position)
680         KeyFrame *result = 0;
681         if(plugin)
682                 result = plugin->get_next_keyframe(position);
683         else
684                 result = keyframe;
685         return result;
688 int64_t PluginServer::get_source_start()
690         if(plugin)
691                 return plugin->startproject;
692         else
693                 return 0;
696 int PluginServer::get_interpolation_type()
698         return plugin->edl->session->interpolation_type;
701 KeyFrame* PluginServer::get_keyframe()
703 //printf("PluginServer::get_keyframe %p\n", plugin);
704         if(plugin)
705                 return plugin->get_keyframe();
706         else
707                 return keyframe;
710 Theme* PluginServer::new_theme()
712         if(theme)
713         {
714                 return client->new_theme();
715         }
716         else
717                 return 0;
721 // Called when plugin interface is tweeked
722 void PluginServer::sync_parameters()
724 //printf("PluginServer::sync_parameters 1\n");
725         if(video) mwindow->restart_brender();
726 //printf("PluginServer::sync_parameters 1\n");
727         mwindow->sync_parameters();
728         if(mwindow->edl->session->auto_conf->plugins)
729         {
730 //printf("PluginServer::sync_parameters 1\n");
731                 mwindow->gui->lock_window();
732 //printf("PluginServer::sync_parameters 2\n");
733                 mwindow->gui->canvas->draw_overlays();
734                 mwindow->gui->canvas->flash();
735                 mwindow->gui->unlock_window();
736         }
737 //printf("PluginServer::sync_parameters 3\n");
742 void PluginServer::dump()
744         printf("    PluginServer %s %s\n", path, title);