LADSPA_PATH env var processing
authorGood Guy <good1.2guy@gmail.com>
Tue, 16 Feb 2016 17:20:42 +0000 (10:20 -0700)
committerGood Guy <good1.2guy@gmail.com>
Tue, 16 Feb 2016 17:20:42 +0000 (10:20 -0700)
cinelerra-5.0/cinelerra/mwindow.C
cinelerra-5.0/cinelerra/mwindow.h
cinelerra-5.0/cinelerra/mwindow.inc
cinelerra-5.0/cinelerra/pluginfclient.C
cinelerra-5.0/cinelerra/pluginserver.C
cinelerra-5.0/cinelerra/pluginserver.h
cinelerra-5.0/plugins/Makefile

index 0410e39bbb4d97dc66156a66bf0128eb75ec71a0..7c619b798341ce4c4e84945e3f68093c5aae13e0 100644 (file)
@@ -378,56 +378,197 @@ void MWindow::init_defaults(BC_Hash* &defaults, char *config_path)
        defaults->load();
 }
 
-int MWindow::load_plugin_index(MWindow *mwindow, char *path)
+void MWindow::get_plugin_path(char *path, const char *plug_dir, const char *fs_path)
+{
+       char *base_path = FileSystem::basepath(fs_path), *bp = base_path;
+       if( plug_dir ) {
+               const char *dp = plug_dir;
+               while( *bp && *dp && *bp == *dp ) { ++bp; ++dp; }
+               bp = !*dp && *bp == '/' ? bp+1 : base_path;
+       }
+       strcpy(path, bp);
+       delete [] base_path;
+}
+
+int MWindow::load_plugin_index(MWindow *mwindow, const char *index_path, const char *plugin_dir)
 {
 // load index
-       FILE *fp = fopen(path, "r");
-       if( !fp ) return 1;
+       FILE *fp = fopen(index_path, "r");
+       if( !fp ) return -1;
+
+       int ret = 0;
        char index_line[BCTEXTLEN];
-       int index_version = -1, ret = 0;
+       int index_version = -1, len = strlen(plugin_dir);
        if( !fgets(index_line, BCTEXTLEN, fp) ||
            sscanf(index_line, "%d", &index_version) != 1 ||
-           index_version != PLUGIN_FILE_VERSION ) ret = 1;
+           index_version != PLUGIN_FILE_VERSION ||
+           !fgets(index_line, BCTEXTLEN, fp) ||
+           (int)strlen(index_line)-1 != len || index_line[len] != '\n' ||
+           strncmp(index_line, plugin_dir, len) != 0 ) ret = 1;
 
-       while( !ret && !feof(fp)) {
-               if( !fgets(index_line, BCTEXTLEN, fp) ) break;
+       ArrayList<PluginServer*> plugins;
+       while( !ret && !feof(fp) && fgets(index_line, BCTEXTLEN, fp) ) {
                if( index_line[0] == ';' ) continue;
                if( index_line[0] == '#' ) continue;
                int type = PLUGIN_TYPE_UNKNOWN;
                char path[BCTEXTLEN], title[BCTEXTLEN];
-               if( PluginServer::scan_table(index_line, type, path, title) ) continue;
+               int64_t mtime = 0;
+               if( PluginServer::scan_table(index_line, type, path, title, mtime) ) {
+                       ret = 1; continue;
+               }
                PluginServer *server = 0;
                switch( type ) {
                case PLUGIN_TYPE_BUILTIN:
-               case PLUGIN_TYPE_LADSPA:
-                       server = new PluginServer(mwindow, path, type);
-                       break;
-               case PLUGIN_TYPE_FFMPEG: // skip "ff_..."
-                       server = new_ffmpeg_server(mwindow, path+3);
-                       break;
+               case PLUGIN_TYPE_EXECUTABLE:
+               case PLUGIN_TYPE_LADSPA: {
+                       char plugin_path[BCTEXTLEN];  struct stat st;
+                       sprintf(plugin_path, "%s/%s", plugin_dir, path);
+                       if( stat(plugin_path, &st) || st.st_mtime != mtime ) {
+                               ret = 1; continue;
+                       }
+                       server = new PluginServer(mwindow, plugin_path, type);
+                       break; }
+               case PLUGIN_TYPE_FFMPEG: {
+                       server = new_ffmpeg_server(mwindow, path);
+                       break; }
                }
                if( !server ) continue;
+               plugins.append(server);
 // Create plugin server from index entry
                server->set_title(title);
                if( server->read_table(index_line) ) {
-                       delete server;
-                       ret = 1;  break;
+                       ret = 1;  continue;
                }
-               plugindb->append(server);
        }
-
        fclose(fp);
+
+       if( !ret )
+               ret = check_plugin_index(plugins, plugin_dir, ".");
+
+       if( !ret )
+               add_plugins(plugins);
+       else
+               plugins.remove_all_objects();
+
        return ret;
 }
 
-void MWindow::init_plugin_index(MWindow *mwindow, Preferences *preferences, FILE *fp,
+int MWindow::check_plugin_index(ArrayList<PluginServer*> &plugins,
+       const char *plug_dir, const char *plug_path)
+{
+       char plugin_path[BCTEXTLEN];
+       sprintf(plugin_path, "%s/%s", plug_dir, plug_path);
+       FileSystem fs;
+       fs.set_filter( "[*.plugin][*.so]" );
+       if( fs.update(plugin_path) )
+               return 1;
+
+       for( int i=0; i<fs.dir_list.total; ++i ) {
+               char fs_path[BCTEXTLEN];
+               get_plugin_path(fs_path, 0, fs.dir_list[i]->path);
+               if( fs.is_dir(fs_path) ) {
+                       get_plugin_path(plugin_path, plug_dir, fs_path);
+                       if( check_plugin_index(plugins, plug_dir, plugin_path) )
+                               return 1;
+               }
+               else if( !plugin_exists(fs_path, plugins) )
+                       return 1;
+       }
+       return 0;
+}
+
+
+int MWindow::init_plugins(MWindow *mwindow, Preferences *preferences)
+{
+       if( !plugindb )
+               plugindb = new ArrayList<PluginServer*>;
+       init_ffmpeg();
+       char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN];
+       create_defaults_path(index_path, PLUGIN_FILE);
+       char *plugin_dir = FileSystem::basepath(preferences->plugin_dir);
+       strcpy(plugin_path, plugin_dir);  delete [] plugin_dir;
+       if( !load_plugin_index(mwindow, index_path, plugin_path) ) return 1;
+       printf("init plugin index: %s\n", plugin_path);
+       FILE *fp = fopen(index_path,"w");
+       if( !fp ) {
+               fprintf(stderr,_("MWindow::init_plugins: "
+                       "can't create plugin index: %s\n"), index_path);
+               return 1;
+       }
+       fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
+       fprintf(fp, "%s\n", plugin_path);
+       init_plugin_index(mwindow, preferences, fp, plugin_path);
+       init_ffmpeg_index(mwindow, preferences, fp);
+       fclose(fp);
+       return load_plugin_index(mwindow, index_path, plugin_path);
+}
+
+int MWindow::init_ladspa_plugins(MWindow *mwindow, Preferences *preferences)
+{
+       char *path = getenv("LADSPA_PATH");
+       char ladspa_path[BCTEXTLEN];
+       if( !path ) {
+               get_exe_path(ladspa_path);
+               strcat(ladspa_path, "/ladspa");
+               path = ladspa_path;
+       }
+       for( int len=0; *path; path+=len ) {
+               char *cp = strchr(path,':');
+               len = !cp ? strlen(path) : cp-path;
+               char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN];
+               memcpy(plugin_path, path, len);  plugin_path[len] = 0;
+               char *plugin_dir = FileSystem::basepath(plugin_path);
+               strcpy(plugin_path, plugin_dir);  delete [] plugin_dir;
+               create_defaults_path(index_path, LADSPA_FILE);
+               cp = index_path + strlen(index_path);
+               for( char *bp=plugin_path; *bp!=0; ++bp )
+                       *cp++ = *bp=='/' ? '_' : *bp;
+               *cp = 0;
+               if( !load_plugin_index(mwindow, index_path, plugin_path) ) continue;
+               if( init_ladspa_index(mwindow, preferences, index_path, plugin_path) ) continue;
+               load_plugin_index(mwindow, index_path, plugin_path);
+       }
+       return 1;
+}
+
+void MWindow::init_plugin_index(MWindow *mwindow, Preferences *preferences,
+       FILE *fp, const char *plugin_dir)
+{
+       int idx = PLUGIN_IDS;
+       if( plugindb ) {
+               for( int i=0; i<plugindb->size(); ++i ) {
+                       PluginServer *server = plugindb->get(i);
+                       if( server->dir_idx >= idx )
+                               idx = server->dir_idx+1;
+               }
+       }
+       scan_plugin_index(mwindow, preferences, fp, plugin_dir, ".", idx);
+}
+
+int MWindow::init_ladspa_index(MWindow *mwindow, Preferences *preferences,
+       const char *index_path, const char *plugin_dir)
+{
+       char plugin_path[BCTEXTLEN], *path = FileSystem::basepath(plugin_dir);
+       strcpy(plugin_path, path);  delete [] path;
+       printf("init ladspa index: %s\n", plugin_dir);
+       FILE *fp = fopen(index_path,"w");
+        if( !fp ) {
+               fprintf(stderr,_("MWindow::init_ladspa_index: "
+                       "can't create plugin index: %s\n"), index_path);
+               return 1;
+       }
+       fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
+       fprintf(fp, "%s\n", plugin_dir);
+        init_plugin_index(mwindow, preferences, fp, plugin_path);
+       fclose(fp);
+       return 0;
+}
+
+void MWindow::scan_plugin_index(MWindow *mwindow, Preferences *preferences, FILE *fp,
        const char *plug_dir, const char *plug_path, int &idx)
 {
        char plugin_path[BCTEXTLEN];
-       if( *plug_path != '/' )
-               sprintf(plugin_path, "%s/%s", plug_dir, plug_path);
-       else
-               strcpy(plugin_path, plug_path);
+       sprintf(plugin_path, "%s/%s", plug_dir, plug_path);
        FileSystem fs;
        fs.set_filter( "[*.plugin][*.so]" );
        int result = fs.update(plugin_path);
@@ -435,58 +576,42 @@ void MWindow::init_plugin_index(MWindow *mwindow, Preferences *preferences, FILE
        int vis_id = idx++;
 
        for( int i=0; i<fs.dir_list.total; ++i ) {
-               char *fs_path = fs.dir_list[i]->path;
-               char *base_path = FileSystem::basepath(fs_path), *bp = base_path;
-               const char *dp = plug_dir;
-               while( *bp && *dp && *bp == *dp ) { ++bp; ++dp; }
-               strcpy(plugin_path, !*dp && *bp == '/' ? bp+1 : base_path);
-               delete [] base_path;
+               char fs_path[BCTEXTLEN], path[BCTEXTLEN];
+               get_plugin_path(fs_path, 0, fs.dir_list[i]->path);
+               get_plugin_path(path, plug_dir, fs_path);
                if( fs.is_dir(fs_path) ) {
-                       init_plugin_index(mwindow, preferences, fp, plug_dir, plugin_path, idx);
+                       scan_plugin_index(mwindow, preferences, fp, plug_dir, path, idx);
                        continue;
                }
-               if( plugin_exists(plugin_path) ) continue;
-               PluginServer server(mwindow, plugin_path, PLUGIN_TYPE_UNKNOWN);
+               if( plugin_exists(path) ) continue;
+               struct stat st;
+               if( stat(fs_path, &st) ) continue;
+               int64_t mtime = st.st_mtime;
+               PluginServer server(mwindow, fs_path, PLUGIN_TYPE_UNKNOWN);
                result = server.open_plugin(1, preferences, 0, 0);
                if( !result ) {
-                       server.write_table(fp,vis_id);
+                       server.write_table(fp, path, vis_id, mtime);
                        server.close_plugin();
                }
                else if( result == PLUGINSERVER_IS_LAD ) {
                        int lad_index = 0;
                        for(;;) {
-                               PluginServer ladspa(mwindow, plugin_path, PLUGIN_TYPE_LADSPA);
+                               PluginServer ladspa(mwindow, fs_path, PLUGIN_TYPE_LADSPA);
                                ladspa.set_lad_index(lad_index++);
                                result = ladspa.open_plugin(1, preferences, 0, 0);
                                if( result ) break;
-                               ladspa.write_table(fp, PLUGIN_LADSPA_ID);
+                               ladspa.write_table(fp, path, PLUGIN_LADSPA_ID, mtime);
                                ladspa.close_plugin();
                        }
                }
        }
 }
 
-int MWindow::init_plugins(MWindow *mwindow, Preferences *preferences)
+void MWindow::add_plugins(ArrayList<PluginServer*> &plugins)
 {
-       init_ffmpeg();
-       if( !plugindb ) plugindb = new ArrayList<PluginServer*>;
-       char index_path[BCTEXTLEN];
-       sprintf(index_path, "%s/%s", preferences->plugin_dir, PLUGIN_FILE);
-       if( !load_plugin_index(mwindow, index_path) ) return 1;
-       FILE *fp = fopen(index_path,"w");
-       if( !fp ) {
-               fprintf(stderr,_("MWindow::init_plugins: "
-                       "can't create plugin index: %s\n"), index_path);
-               return 1;
-       }
-       fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
-       char *plug_path = FileSystem::basepath(preferences->plugin_dir);
-       int dir_id = PLUGIN_IDS;
-       init_plugin_index(mwindow, preferences, fp, plug_path, ".", dir_id);
-       init_ffmpeg_index(mwindow, preferences, fp);
-       fclose(fp);
-       delete [] plug_path;
-       return load_plugin_index(mwindow, index_path);
+       for( int i=0; i<plugins.size(); ++i )
+               plugindb->append(plugins[i]);
+       plugins.remove_all();
 }
 
 void MWindow::delete_plugins()
@@ -558,15 +683,18 @@ PluginServer* MWindow::scan_plugindb(char *title,
        return 0;
 }
 
-int MWindow::plugin_exists(char *plugin_path)
+int MWindow::plugin_exists(const char *plugin_path, ArrayList<PluginServer*> &plugins)
 {
-       for( int i=0; i<plugindb->total; ++i ) {
-               PluginServer *server = plugindb->get(i);
-               if( !strcmp(plugin_path, server->get_path()) ) return 1;
-       }
+       for( int i=0; i<plugins.size(); ++i )
+               if( !strcmp(plugin_path, plugins[i]->get_path()) ) return 1;
        return 0;
 }
 
+int MWindow::plugin_exists(char *plugin_path)
+{
+       return !plugindb ? 0 : plugin_exists(plugin_path, *plugindb);
+}
+
 void MWindow::init_preferences()
 {
        preferences = new Preferences;
@@ -1624,14 +1752,21 @@ void MWindow::create_objects(int want_gui,
        if(debug) PRINT_TRACE
        init_defaults(defaults, config_path);
        init_preferences();
+       if(splash_window)
+               splash_window->operation->update(_("Initializing Plugins"));
        init_plugins(this, preferences);
        if(debug) PRINT_TRACE
-       if(splash_window) splash_window->operation->update(_("Initializing GUI"));
+       init_ladspa_plugins(this, preferences);
+       if(debug) PRINT_TRACE
+       if(splash_window)
+               splash_window->operation->update(_("Initializing GUI"));
        if(debug) PRINT_TRACE
        init_theme();
        if(debug) PRINT_TRACE
        init_error();
 
+       if(splash_window)
+               splash_window->operation->update(_("Initializing Fonts"));
        char string[BCTEXTLEN];
        strcpy(string, preferences->plugin_dir);
        strcat(string, "/fonts");
index 97581ca8b6a5a03e741684fc1345823a5bfa4827..006b68fb81f99adc1379ede32c7255a67d1e3be1 100644 (file)
@@ -188,6 +188,7 @@ public:
 // Find the plugin whose title matches title and return it
        static PluginServer* scan_plugindb(char *title,
                int data_type);
+       static int plugin_exists(const char *plugin_path, ArrayList<PluginServer*> &plugins);
        static int plugin_exists(char *plugin_path);
        void dump_plugindb(FILE *fp);
        void stop_playback(int wait=0);
@@ -602,12 +603,21 @@ public:
        void init_gwindow();
        void init_tipwindow();
 // Used by MWindow and RenderFarmClient
+       static void get_plugin_path(char *path, const char *plug_dir, const char *fs_path);
        static int init_plugins(MWindow *mwindow, Preferences *preferences);
+       static int init_ladspa_plugins(MWindow *mwindow, Preferences *preferences);
+       static int check_plugin_index(ArrayList<PluginServer*> &plugins,
+               const char *plug_dir, const char *plug_path);
        static void init_plugin_index(MWindow *mwindow, Preferences *preferences,
-               FILE *fp, const char *plug_dir, const char *plug_path, int &dir_id);
+               FILE *fp, const char *plugin_dir);
+       static int init_ladspa_index(MWindow *mwindow, Preferences *preferences,
+               const char *index_path, const char *plugin_dir);
+       static void scan_plugin_index(MWindow *mwindow, Preferences *preferences,
+               FILE *fp, const char *plug_dir, const char *plug_path, int &idx);
        static void init_ffmpeg();
        static void init_ffmpeg_index(MWindow *mwindow, Preferences *preferences, FILE *fp);
-       static int load_plugin_index(MWindow *mwindow, char *path);
+       static int load_plugin_index(MWindow *mwindow, const char *index_path,
+               const char *plugin_dir);
        static PluginServer* new_ffmpeg_server(MWindow *mwindow, const char *name);
        void init_preferences();
        void init_signals();
@@ -623,7 +633,8 @@ public:
        void init_3d();
        void init_playbackcursor();
        void init_commercials();
-       void delete_plugins();
+       static void add_plugins(ArrayList<PluginServer*> &plugins);
+       static void delete_plugins();
 // 
        void clean_indexes();
 //     TimeBomb timebomb;
index b1ec4d5e1504b86227c91a9a35af33cfe9c804ff..ba5a67d74e2acb0351a496272e40242231617c34 100644 (file)
@@ -30,7 +30,8 @@
 #define PRESETS_FILE "Cinelerra_presets"
 #define PICTURE_FILE "Cinelerra_picture"
 #define PLUGIN_FILE "Cinelerra_plugins"
-#define PLUGIN_FILE_VERSION 2
+#define LADSPA_FILE "ladspa_plugins."
+#define PLUGIN_FILE_VERSION 3
 
 // Behavior of region selections
 #define SELECTION_SAMPLES 0
index bb483e2cd358313c6d6cfca64dcf7e9711688bb4..2a222cbe0b3a380308b00604b885de3866c8cb99 100644 (file)
@@ -1133,7 +1133,7 @@ void MWindow::init_ffmpeg_index(MWindow *mwindow, Preferences *preferences, FILE
                if( server ) {
                        int result = server->open_plugin(1, preferences, 0, 0);
                        if( !result ) {
-                               server->write_table(fp, PLUGIN_FFMPEG_ID);
+                               server->write_table(fp, filter->name, PLUGIN_FFMPEG_ID, 0);
                                server->close_plugin();
                        }
                        delete server;
index b9e7eeffb237ec79bb54ee4d99f15341db5cb4e9..6602f1eb70b0c6b9deac7420e0d2ed6e7529ff41 100644 (file)
@@ -30,6 +30,7 @@
 #include "edl.h"
 #include "edlsession.h"
 #include "floatautos.h"
+#include "format.inc"
 #include "keyframes.h"
 #include "localsession.h"
 #include "mainerror.h"
@@ -347,6 +348,8 @@ int PluginServer::open_plugin(int master,
                return PLUGINSERVER_NOT_RECOGNIZED;
        }
        switch( plugin_type ) {
+       case PLUGIN_TYPE_EXECUTABLE:
+               return PLUGINSERVER_OK;
        case PLUGIN_TYPE_BUILTIN:
                client = new_plugin(this);
                break;
@@ -424,28 +427,28 @@ void PluginServer::render_stop()
                client->render_stop();
 }
 
-void PluginServer::write_table(FILE *fp, int idx)
+void PluginServer::write_table(FILE *fp, const char *path, int idx, int64_t mtime)
 {
        if(!fp) return;
-       fprintf(fp, "%d \"%s\" \"%s\" %d %d %d %d %d %d %d %d %d %d %d\n",
-               plugin_type, path, title, idx, audio, video, theme, realtime,
+       fprintf(fp, "%d \"%s\" \"%s\" " _LD " %d %d %d %d %d %d %d %d %d %d %d\n",
+               plugin_type, path, title, mtime, idx, audio, video, theme, realtime,
                fileio, uses_gui, multichannel, synthesis, transition, lad_index);
 }
 
-int PluginServer::scan_table(char *text, int &type, char *path, char *title)
+int PluginServer::scan_table(char *text, int &type, char *path, char *title, int64_t &mtime)
 {
-       int n = sscanf(text, "%d \"%[^\"]\" \"%[^\"]\"", &type, path, title);
-       return n < 3 ? 1 : 0;
+       int n = sscanf(text, "%d \"%[^\"]\" \"%[^\"]\" " _LD "", &type, path, title, &mtime);
+       return n < 4 ? 1 : 0;
 }
 
 int PluginServer::read_table(char *text)
 {
        char path[BCTEXTLEN], title[BCTEXTLEN];
-       int n = sscanf(text, "%d \"%[^\"]\" \"%[^\"]\" %d %d %d %d %d %d %d %d %d %d %d",
-               &plugin_type, path, title, &dir_idx, &audio, &video, &theme, &realtime,
+       int64_t mtime;
+       int n = sscanf(text, "%d \"%[^\"]\" \"%[^\"]\" " _LD " %d %d %d %d %d %d %d %d %d %d %d",
+               &plugin_type, path, title, &mtime, &dir_idx, &audio, &video, &theme, &realtime,
                &fileio, &uses_gui, &multichannel, &synthesis, &transition, &lad_index);
-       if( n != 14 ) return 1;
-       set_path(path);
+       if( n != 15 ) return 1;
        set_title(title);
        return 0;
 }
index a67e32e195c78caddfea49b3fc9d4f3cde8299fe..03e9d924198d5dbca7823e4ec8e541f2f3b6f7e1 100644 (file)
@@ -132,8 +132,8 @@ public:
 // Release any objects which are required after playback stops.
        void render_stop();
 // Write entry into plugin table
-       void write_table(FILE *fp, int idx);
-       static int scan_table(char *text, int &type, char *path, char *title);
+       void write_table(FILE *fp, const char *path, int idx, int64_t mtime);
+       static int scan_table(char *text, int &type, char *path, char *title, int64_t &mtime);
        int read_table(char *text);
 // queries
        void set_title(const char *string);
index 175356397a5d53669ac76cf8bf860926c339ada7..19064e0a90218eefca98650e31ca4bcdbd569182 100644 (file)
@@ -140,7 +140,7 @@ DIRS = \
 DATA = $(PLUGIN_DIR)/fonts $(PLUGIN_DIR)/shapes
 MPEG2ENC = $(PLUGIN_DIR)/mpeg2enc.plugin
 HVEG2ENC = $(PLUGIN_DIR)/hveg2enc.plugin
-LADSPA = $(PLUGIN_DIR)/ladspa
+LADSPA = $(BINDIR)/ladspa
 
 all:   $(DIRS) $(DATA) $(MPEG2ENC) $(HVEG2ENC) $(LADSPA)