4 * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
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.
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.
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
24 #include "attachmentpoint.h"
26 #include "bcsignals.h"
27 #include "cplayback.h"
31 #include "edlsession.h"
33 #include "floatautos.h"
34 #include "keyframes.h"
35 #include "localsession.h"
36 #include "mainerror.h"
37 #include "mainprogress.h"
38 #include "menueffects.h"
40 #include "mwindowgui.h"
41 #include "playbackengine.h"
43 #include "pluginaclient.h"
44 #include "pluginaclientlad.h"
45 #include "pluginfclient.h"
46 #include "pluginclient.h"
47 #include "plugincommands.h"
48 #include "pluginserver.h"
49 #include "pluginvclient.h"
50 #include "preferences.h"
53 #include "mainsession.h"
55 #include "trackcanvas.h"
56 #include "transportque.h"
57 #include "vdevicex11.h"
59 #include "videodevice.h"
60 #include "virtualanode.h"
61 #include "virtualvnode.h"
69 #include <sys/types.h>
75 void PluginServer::init()
78 this->plugin_type = PLUGIN_TYPE_UNKNOWN;
79 plugin_obj = new PluginObj();
80 modules = new ArrayList<Module*>;
81 nodes = new ArrayList<VirtualNode*>;
85 PluginServer::PluginServer()
90 PluginServer::PluginServer(MWindow *mwindow, char *path, int type)
92 char fpath[BCTEXTLEN];
94 this->plugin_type = type;
95 this->mwindow = mwindow;
96 if( type == PLUGIN_TYPE_FFMPEG ) {
97 ff_name = cstrdup(path);
98 sprintf(fpath, "ff_%s", path);
104 PluginServer::PluginServer(PluginServer &that)
107 plugin_type = that.plugin_type;
108 plugin_obj = that.plugin_obj;
109 plugin_obj->add_user();
110 title = !that.title ? 0 : cstrdup(that.title);
111 tip = !that.tip ? 0 : cstrdup(that.tip);
112 path = !that.path ? 0 : cstrdup(that.path);
113 ff_name = !that.ff_name ? 0 : cstrdup(that.ff_name);
114 modules = new ArrayList<Module*>;
115 nodes = new ArrayList<VirtualNode*>;
117 attachment = that.attachment;
118 realtime = that.realtime;
119 multichannel = that.multichannel;
120 preferences = that.preferences;
121 synthesis = that.synthesis;
125 fileio = that.fileio;
126 uses_gui = that.uses_gui;
127 mwindow = that.mwindow;
128 keyframe = that.keyframe;
129 new_plugin = that.new_plugin;
131 lad_descriptor = that.lad_descriptor;
132 lad_descriptor_function = that.lad_descriptor_function;
133 lad_index = that.lad_index;
136 PluginServer::~PluginServer()
146 plugin_obj->remove_user();
149 // Done only once at creation
150 int PluginServer::reset_parameters()
158 lad_descriptor_function = 0;
165 lad_descriptor_function = 0;
171 start_auto = end_auto = 0;
175 realtime = multichannel = fileio = 0;
177 audio = video = theme = 0;
184 for( int i=sizeof(args)/sizeof(args[0]); --i>=0; ) args[i] = 0;
199 // Done every time the plugin is opened or closed
200 int PluginServer::cleanup_plugin()
202 in_buffer_size = out_buffer_size = 0;
203 total_in_buffers = total_out_buffers = 0;
208 written_samples = written_frames = 0;
215 void PluginServer::set_mwindow(MWindow *mwindow)
217 this->mwindow = mwindow;
220 void PluginServer::set_attachmentpoint(AttachmentPoint *attachmentpoint)
222 this->attachmentpoint = attachmentpoint;
225 void PluginServer::set_keyframe(KeyFrame *keyframe)
227 this->keyframe = keyframe;
230 void PluginServer::set_prompt(MenuEffectPrompt *prompt)
232 this->prompt = prompt;
235 void PluginServer::set_lad_index(int i)
240 int PluginServer::get_lad_index()
242 return this->lad_index;
245 int PluginServer::is_ladspa()
247 return plugin_type == PLUGIN_TYPE_LADSPA ? 1 : 0;
250 int PluginServer::is_ffmpeg()
252 return plugin_type == PLUGIN_TYPE_FFMPEG ? 1 : 0;
255 void PluginServer::set_path(const char *path)
257 delete [] this->path;
258 this->path = cstrdup(path);
261 char* PluginServer::get_path()
266 int PluginServer::get_synthesis()
272 void PluginServer::set_title(const char *string)
274 if(title) delete [] title;
275 title = cstrdup(string);
278 void PluginServer::generate_display_title(char *string)
280 char ltitle[BCTEXTLEN];
281 if(BC_Resources::locale_utf8)
282 strcpy(ltitle, _(title));
284 BC_Resources::encode(BC_Resources::encoding, 0,
285 _(title),strlen(title)+1, ltitle,BCTEXTLEN);
286 if(plugin && plugin->track)
287 sprintf(string, "%s: %s", plugin->track->title, ltitle);
289 strcpy(string, ltitle);
292 void *PluginObj::load(const char *plugin_dir, const char *path)
294 char dlpath[BCTEXTLEN], *dp = dlpath;
295 const char *cp = path;
297 const char *bp = plugin_dir;
298 while( *bp ) *dp++ = *bp++;
301 while( *cp ) *dp++ = *cp++;
303 return dlobj = load(dlpath);
306 int PluginServer::load_obj()
308 void *obj = plugin_obj->obj();
309 if( !obj ) obj =plugin_obj->load(preferences->plugin_dir, path);
313 const char *PluginServer::load_error()
315 return plugin_obj->load_error();
318 void *PluginServer::get_sym(const char *sym)
320 if( !plugin_obj->obj() ) return 0;
321 return plugin_obj->load_sym(sym);
324 // Open plugin for signal processing
325 int PluginServer::open_plugin(int master,
326 Preferences *preferences,
330 if(plugin_open) return 0;
332 this->preferences = preferences;
333 this->plugin = plugin;
335 if( plugin_type != PLUGIN_TYPE_FFMPEG && plugin_type != PLUGIN_TYPE_EXECUTABLE && !load_obj() ) {
336 // If the load failed, can't use error to detect executable
337 // because locale and language selection change the load_error()
338 // if( !strstr(string, "executable") ) { set_title(path); plugin_type = PLUGIN_TYPE_EXECUTABLE; }
339 eprintf("PluginServer::open_plugin: load_obj %s = %s\n", path, load_error());
340 return PLUGINSERVER_NOT_RECOGNIZED;
342 if( plugin_type == PLUGIN_TYPE_UNKNOWN || plugin_type == PLUGIN_TYPE_BUILTIN ) {
344 (PluginClient* (*)(PluginServer*)) get_sym("new_plugin");
346 plugin_type = PLUGIN_TYPE_BUILTIN;
348 if( plugin_type == PLUGIN_TYPE_UNKNOWN || plugin_type == PLUGIN_TYPE_LADSPA ) {
349 lad_descriptor_function =
350 (LADSPA_Descriptor_Function) get_sym("ladspa_descriptor");
351 if( lad_descriptor_function ) {
352 if( lad_index < 0 ) return PLUGINSERVER_IS_LAD;
353 lad_descriptor = lad_descriptor_function(lad_index);
354 if( !lad_descriptor )
355 return PLUGINSERVER_NOT_RECOGNIZED;
356 plugin_type = PLUGIN_TYPE_LADSPA;
359 if( plugin_type == PLUGIN_TYPE_UNKNOWN ) {
360 fprintf(stderr, "PluginServer::open_plugin "
361 " %d: plugin undefined in %s\n", __LINE__, path);
362 return PLUGINSERVER_NOT_RECOGNIZED;
364 switch( plugin_type ) {
365 case PLUGIN_TYPE_EXECUTABLE:
366 return PLUGINSERVER_OK;
367 case PLUGIN_TYPE_BUILTIN:
368 client = new_plugin(this);
370 case PLUGIN_TYPE_LADSPA:
371 client = new PluginAClientLAD(this);
373 case PLUGIN_TYPE_FFMPEG:
374 client = new_ffmpeg_plugin();
381 return PLUGINSERVER_NOT_RECOGNIZED;
383 // Run initialization functions
384 realtime = client->is_realtime();
385 // Don't load defaults when probing the directory.
388 client->load_defaults_xml();
390 client->load_defaults();
392 audio = client->is_audio();
393 video = client->is_video();
394 theme = client->is_theme();
395 fileio = client->is_fileio();
396 uses_gui = client->uses_gui();
397 multichannel = client->is_multichannel();
398 synthesis = client->is_synthesis();
399 transition = client->is_transition();
400 set_title(client->plugin_title());
402 //printf("PluginServer::open_plugin 2\n");
404 return PLUGINSERVER_OK;
407 int PluginServer::close_plugin()
409 if(!plugin_open) return 0;
413 // Defaults are saved in the thread.
414 // if(client->defaults) client->save_defaults();
418 // shared object is persistent since plugin deletion would unlink its own object
424 void PluginServer::client_side_close()
426 // Last command executed in client thread
428 mwindow->hide_plugin(plugin, 1);
432 prompt->lock_window();
434 prompt->unlock_window();
438 void PluginServer::render_stop()
441 client->render_stop();
444 void PluginServer::write_table(FILE *fp, const char *path, int idx, int64_t mtime)
447 fprintf(fp, "%d \"%s\" \"%s\" %jd %d %d %d %d %d %d %d %d %d %d %d\n",
448 plugin_type, path, title, mtime, idx, audio, video, theme, realtime,
449 fileio, uses_gui, multichannel, synthesis, transition, lad_index);
452 int PluginServer::scan_table(char *text, int &type, char *path, char *title, int64_t &mtime)
454 int n = sscanf(text, "%d \"%[^\"]\" \"%[^\"]\" %jd", &type, path, title, &mtime);
455 return n < 4 ? 1 : 0;
458 int PluginServer::read_table(char *text)
460 char path[BCTEXTLEN], title[BCTEXTLEN];
462 int n = sscanf(text, "%d \"%[^\"]\" \"%[^\"]\" %jd %d %d %d %d %d %d %d %d %d %d %d",
463 &plugin_type, path, title, &mtime, &dir_idx, &audio, &video, &theme, &realtime,
464 &fileio, &uses_gui, &multichannel, &synthesis, &transition, &lad_index);
465 if( n != 15 ) return 1;
470 int PluginServer::init_realtime(int realtime_sched,
471 int total_in_buffers,
475 if(!plugin_open) return 0;
477 // set for realtime priority
479 // Call start_realtime
480 this->total_in_buffers = this->total_out_buffers = total_in_buffers;
481 client->plugin_init_realtime(realtime_sched,
489 // Replaced by pull method but still needed for transitions
490 void PluginServer::process_transition(VFrame *input,
492 int64_t current_position,
495 if(!plugin_open) return;
496 PluginVClient *vclient = (PluginVClient*)client;
498 vclient->source_position = current_position;
499 vclient->source_start = 0;
500 vclient->total_len = total_len;
502 vclient->input = new VFrame*[1];
503 vclient->output = new VFrame*[1];
505 vclient->input[0] = input;
506 vclient->output[0] = output;
508 vclient->process_realtime(input, output);
510 delete [] vclient->input;
511 delete [] vclient->output;
515 void PluginServer::process_transition(Samples *input,
517 int64_t current_position,
518 int64_t fragment_size,
521 if(!plugin_open) return;
522 PluginAClient *aclient = (PluginAClient*)client;
524 aclient->source_position = current_position;
525 aclient->total_len = total_len;
526 aclient->source_start = 0;
527 aclient->process_realtime(fragment_size,
533 void PluginServer::process_buffer(VFrame **frame,
534 int64_t current_position,
539 if(!plugin_open) return;
540 PluginVClient *vclient = (PluginVClient*)client;
542 vclient->source_position = current_position;
543 vclient->total_len = total_len;
544 vclient->frame_rate = frame_rate;
545 vclient->input = new VFrame*[total_in_buffers];
546 vclient->output = new VFrame*[total_in_buffers];
547 for(int i = 0; i < total_in_buffers; i++)
549 vclient->input[i] = frame[i];
550 vclient->output[i] = frame[i];
555 vclient->source_start = (int64_t)plugin->startproject *
557 vclient->project_frame_rate;
559 vclient->direction = direction;
563 //printf("plugin=%p source_start=%ld\n", plugin, vclient->source_start);
565 vclient->begin_process_buffer();
568 vclient->process_buffer(frame, current_position, frame_rate);
572 vclient->process_buffer(frame[0], current_position, frame_rate);
574 vclient->end_process_buffer();
576 for(int i = 0; i < total_in_buffers; i++)
577 frame[i]->push_prev_effect(title);
579 delete [] vclient->input;
580 delete [] vclient->output;
586 void PluginServer::process_buffer(Samples **buffer,
587 int64_t current_position,
588 int64_t fragment_size,
593 if(!plugin_open) return;
594 PluginAClient *aclient = (PluginAClient*)client;
596 aclient->source_position = current_position;
597 aclient->total_len = total_len;
598 aclient->sample_rate = sample_rate;
601 aclient->source_start = plugin->startproject *
603 aclient->project_sample_rate;
605 aclient->direction = direction;
606 aclient->begin_process_buffer();
609 aclient->process_buffer(fragment_size,
616 aclient->process_buffer(fragment_size,
621 aclient->end_process_buffer();
625 void PluginServer::send_render_gui(void *data)
627 //printf("PluginServer::send_render_gui 1 %p\n", attachmentpoint);
628 if(attachmentpoint) attachmentpoint->render_gui(data, this);
631 void PluginServer::send_render_gui(void *data, int size)
633 //printf("PluginServer::send_render_gui 1 %p\n", attachmentpoint);
634 if(attachmentpoint) attachmentpoint->render_gui(data, size, this);
637 void PluginServer::render_gui(void *data)
639 if(client) client->plugin_render_gui(data);
642 void PluginServer::render_gui(void *data, int size)
644 if(client) client->plugin_render_gui(data, size);
647 MainProgressBar* PluginServer::start_progress(char *string, int64_t length)
649 mwindow->gui->lock_window();
650 MainProgressBar *result = mwindow->mainprogress->start_progress(string, length);
651 mwindow->gui->unlock_window();
655 int64_t PluginServer::get_written_samples()
657 if(!plugin_open) return 0;
658 return written_samples;
661 int64_t PluginServer::get_written_frames()
663 if(!plugin_open) return 0;
664 return written_frames;
676 // ======================= Non-realtime plugin
678 int PluginServer::get_parameters(int64_t start, int64_t end, int channels)
680 if(!plugin_open) return 0;
682 client->start = start;
684 client->source_start = start;
685 client->total_len = end - start;
686 client->total_in_buffers = channels;
689 //printf(" source_start=%ld total_len=%ld\n", client->source_start, client->total_len);
691 return client->plugin_get_parameters();
694 int PluginServer::set_interactive()
696 if(!plugin_open) return 0;
697 client->set_interactive();
701 void PluginServer::append_module(Module *module)
703 modules->append(module);
706 void PluginServer::append_node(VirtualNode *node)
711 void PluginServer::reset_nodes()
716 int PluginServer::set_error()
722 int PluginServer::set_realtime_sched()
724 //struct sched_param params;
725 //params.sched_priority = 1;
726 //sched_setscheduler(0, SCHED_RR, ¶m);
731 int PluginServer::process_loop(VFrame **buffers, int64_t &write_length)
733 if(!plugin_open) return 1;
734 return client->plugin_process_loop(buffers, write_length);
737 int PluginServer::process_loop(Samples **buffers, int64_t &write_length)
739 if(!plugin_open) return 1;
740 return client->plugin_process_loop(buffers, write_length);
744 int PluginServer::start_loop(int64_t start,
749 if(!plugin_open) return 0;
750 client->plugin_start_loop(start, end, buffer_size, total_buffers);
754 int PluginServer::stop_loop()
756 if(!plugin_open) return 0;
757 return client->plugin_stop_loop();
760 int PluginServer::read_frame(VFrame *buffer,
762 int64_t start_position)
764 ((VModule*)modules->values[channel])->render(buffer,
767 mwindow->edl->session->frame_rate,
773 int PluginServer::read_samples(Samples *buffer,
776 int64_t start_position,
779 // len is now in buffer
780 if(!multichannel) channel = 0;
782 if(nodes->total > channel)
783 return ((VirtualANode*)nodes->values[channel])->read_data(buffer,
788 if(modules->total > channel)
789 return ((AModule*)modules->values[channel])->render(buffer,
797 printf("PluginServer::read_samples no object available for channel=%d\n",
805 int PluginServer::read_samples(Samples *buffer,
807 int64_t start_position,
810 // total_samples is now set in buffer
811 ((AModule*)modules->values[channel])->render(buffer,
815 mwindow->edl->session->sample_rate,
820 int PluginServer::read_frame(VFrame *buffer,
822 int64_t start_position,
826 // Data source depends on whether we're part of a virtual console or a
830 // If we're a VirtualNode, read_data in the virtual plugin node handles
831 // backward propogation and produces the data.
832 // If we're a Module, render in the module produces the data.
836 if(!multichannel) channel = 0;
838 // Push our name on the next effect stack
839 buffer->push_next_effect(title);
840 //printf("PluginServer::read_frame %p\n", buffer);
841 //buffer->dump_stacks();
843 if(nodes->total > channel)
845 //printf("PluginServer::read_frame %d\n", __LINE__);
846 result = ((VirtualVNode*)nodes->values[channel])->read_data(buffer,
852 if(modules->total > channel)
854 //printf("PluginServer::read_frame %d\n", __LINE__);
855 result = ((VModule*)modules->values[channel])->render(buffer,
866 printf("PluginServer::read_frame no object available for channel=%d\n",
870 // Pop our name from the next effect stack
871 buffer->pop_next_effect();
896 int PluginServer::get_gui_status()
899 return plugin->show ? GUI_ON : GUI_OFF;
904 void PluginServer::raise_window()
906 if(!plugin_open) return;
907 client->raise_window();
910 void PluginServer::show_gui()
912 if(!plugin_open) return;
913 if(plugin) client->total_len = plugin->length;
914 if(plugin) client->source_start = plugin->startproject;
917 client->source_position = Units::to_int64(
918 mwindow->edl->local_session->get_selectionstart(1) *
919 mwindow->edl->session->frame_rate);
924 client->source_position = Units::to_int64(
925 mwindow->edl->local_session->get_selectionstart(1) *
926 mwindow->edl->session->sample_rate);
929 client->update_display_title();
933 void PluginServer::hide_gui()
935 if(!plugin_open) return;
936 if(client->defaults) client->save_defaults();
940 void PluginServer::update_gui()
942 if(!plugin_open || !plugin) return;
944 client->total_len = plugin->length;
945 client->source_start = plugin->startproject;
949 client->source_position = Units::to_int64(
950 mwindow->edl->local_session->get_selectionstart(1) *
951 mwindow->edl->session->frame_rate);
956 client->source_position = Units::to_int64(
957 mwindow->edl->local_session->get_selectionstart(1) *
958 mwindow->edl->session->sample_rate);
961 client->plugin_update_gui();
964 void PluginServer::update_title()
966 if(!plugin_open) return;
968 client->update_display_title();
972 int PluginServer::set_string(char *string)
974 if(!plugin_open) return 0;
976 client->set_string_client(string);
980 int PluginServer::gui_open()
982 if(attachmentpoint) return attachmentpoint->gui_open();
986 void PluginServer::set_use_opengl(int value, VideoDevice *vdevice)
988 this->use_opengl = value;
989 this->vdevice = vdevice;
992 int PluginServer::get_use_opengl()
998 void PluginServer::run_opengl(PluginClient *plugin_client)
1001 ((VDeviceX11*)vdevice->get_output_base())->run_plugin(plugin_client);
1004 // ============================= queries
1006 void PluginServer::get_defaults_path(char *path)
1008 // Get plugin name from path
1009 char *ptr1 = strrchr(get_path(), '/');
1010 char *ptr2 = strrchr(get_path(), '.');
1011 if(!ptr1) ptr1 = get_path();
1012 if(!ptr2) ptr2 = get_path() + strlen(get_path());
1013 char string2[BCTEXTLEN], *ptr3 = string2;
1014 while( ptr1 < ptr2 ) *ptr3++ = *ptr1++;
1016 sprintf(path, "%s/%s.xml", File::get_config_path(), string2);
1019 void PluginServer::save_defaults()
1021 if(client) client->save_defaults();
1024 int PluginServer::get_samplerate()
1026 if(!plugin_open) return 0;
1029 return client->get_samplerate();
1033 return mwindow->edl->session->sample_rate;
1036 printf("PluginServer::get_samplerate audio and mwindow == NULL\n");
1042 double PluginServer::get_framerate()
1044 if(!plugin_open) return 0;
1047 return client->get_framerate();
1051 return mwindow->edl->session->frame_rate;
1054 printf("PluginServer::get_framerate video and mwindow == NULL\n");
1059 int PluginServer::get_project_samplerate()
1062 return mwindow->edl->session->sample_rate;
1065 return edl->session->sample_rate;
1068 printf("PluginServer::get_project_samplerate mwindow and edl are NULL.\n");
1073 double PluginServer::get_project_framerate()
1076 return mwindow->edl->session->frame_rate;
1079 return edl->session->frame_rate;
1082 printf("PluginServer::get_project_framerate mwindow and edl are NULL.\n");
1089 int PluginServer::detach_buffers()
1091 ring_buffers_out.remove_all();
1092 offset_out_render.remove_all();
1093 double_buffer_out_render.remove_all();
1094 realtime_out_size.remove_all();
1096 ring_buffers_in.remove_all();
1097 offset_in_render.remove_all();
1098 double_buffer_in_render.remove_all();
1099 realtime_in_size.remove_all();
1101 out_buffer_size = 0;
1103 total_out_buffers = 0;
1105 total_in_buffers = 0;
1109 int PluginServer::arm_buffer(int buffer_number,
1112 int double_buffer_in,
1113 int double_buffer_out)
1115 offset_in_render.values[buffer_number] = offset_in;
1116 offset_out_render.values[buffer_number] = offset_out;
1117 double_buffer_in_render.values[buffer_number] = double_buffer_in;
1118 double_buffer_out_render.values[buffer_number] = double_buffer_out;
1123 int PluginServer::set_automation(FloatAutos *autos, FloatAuto **start_auto, FloatAuto **end_auto, int reverse)
1125 this->autos = autos;
1126 this->start_auto = start_auto;
1127 this->end_auto = end_auto;
1128 this->reverse = reverse;
1134 void PluginServer::save_data(KeyFrame *keyframe)
1136 if(!plugin_open) return;
1137 client->save_data(keyframe);
1140 KeyFrame* PluginServer::get_prev_keyframe(int64_t position)
1142 KeyFrame *result = 0;
1144 result = plugin->get_prev_keyframe(position, client->direction);
1150 KeyFrame* PluginServer::get_next_keyframe(int64_t position)
1152 KeyFrame *result = 0;
1154 result = plugin->get_next_keyframe(position, client->direction);
1161 KeyFrame* PluginServer::get_keyframe()
1164 // Realtime plugin case
1165 return plugin->get_keyframe();
1167 // Rendered plugin case
1172 void PluginServer::apply_keyframe(KeyFrame *src)
1176 keyframe->copy_data(src);
1181 plugin->keyframes->update_parameter(src);
1189 void PluginServer::get_camera(float *x, float *y, float *z,
1190 int64_t position, int direction)
1192 plugin->track->automation->get_camera(x, y, z, position, direction);
1195 void PluginServer::get_projector(float *x, float *y, float *z,
1196 int64_t position, int direction)
1198 plugin->track->automation->get_projector(x, y, z, position, direction);
1202 int PluginServer::get_interpolation_type()
1204 return plugin->edl->session->interpolation_type;
1207 Theme* PluginServer::new_theme()
1211 return client->new_theme();
1217 Theme* PluginServer::get_theme()
1219 if(mwindow) return mwindow->theme;
1220 printf("PluginServer::get_theme mwindow not set\n");
1225 int PluginServer::get_plugin_png_path(char *png_path, const char *plugin_icons)
1227 char *pp = png_path, *ep = pp + BCTEXTLEN-1;
1228 pp += snprintf(pp, ep-pp, "%s/picon", File::get_plugin_path());
1229 if( strcmp(DEFAULT_PICON, plugin_icons) )
1230 pp += snprintf(pp, ep-pp, "_%s", plugin_icons);
1231 if( pp < ep ) *pp++ = '/';
1232 char *cp = strrchr(path, '/');
1233 cp = !cp ? path : cp+1;
1234 char *sp = strrchr(cp, '.');
1235 if( !sp ) sp = cp+strlen(cp);
1236 while( pp < ep && cp < sp ) *pp++ = *cp++;
1237 pp += snprintf(pp, ep-pp, ".png");
1240 if( stat(png_path, &st) ) return 0;
1241 if( !S_ISREG(st.st_mode) ) return 0;
1242 if( st.st_size == 0 ) return 0;
1246 int PluginServer::get_plugin_png_path(char *png_path)
1248 int len = get_plugin_png_path(png_path, mwindow->preferences->plugin_icons);
1249 if( !len ) len = get_plugin_png_path(png_path, DEFAULT_PICON);
1253 VFrame *PluginServer::get_plugin_images()
1255 char png_path[BCTEXTLEN];
1256 if( !get_plugin_png_path(png_path) ) return 0;
1257 return VFramePng::vframe_png(png_path,0,0);
1260 VFrame *PluginServer::get_picon()
1263 picon = get_plugin_images();
1267 // Called when plugin interface is tweeked
1268 void PluginServer::sync_parameters()
1270 if(video) mwindow->restart_brender();
1271 mwindow->sync_parameters();
1272 mwindow->update_keyframe_guis();
1273 if(mwindow->edl->session->auto_conf->plugins)
1275 mwindow->gui->lock_window("PluginServer::sync_parameters");
1276 mwindow->gui->draw_overlays(1);
1277 mwindow->gui->unlock_window();
1283 void PluginServer::dump(FILE *fp)
1285 fprintf(fp," PluginServer %d %p %s %s %d\n",
1286 __LINE__, this, path, title, realtime);