changeset 12:a3d35e11c3fe

* Avoid repeated malloc/free for returned feature lists -- reuse static feature lists where possible. Need to document the host behaviour that permits this (i.e. a returned feature list is only valid until the next call to process, getRemainingFeatures or releaseFeatureSet)
author cannam
date Thu, 06 Apr 2006 15:12:25 +0000
parents 6616075ec7b6
children 85801331454c
files Makefile vamp-sdk/PluginAdapter.cpp vamp-sdk/PluginAdapter.h vamp-sdk/PluginHostAdapter.cpp vamp-sdk/PluginHostAdapter.h vamp/vamp.h
diffstat 6 files changed, 172 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu Apr 06 12:26:44 2006 +0000
+++ b/Makefile	Thu Apr 06 15:12:25 2006 +0000
@@ -67,10 +67,10 @@
 $(SDK_TARGET):	$(SDK_OBJECTS)
 		$(AR) r $@ $^
 
-$(PLUGIN_TARGET):	$(PLUGIN_OBJECTS)
+$(PLUGIN_TARGET):	$(PLUGIN_OBJECTS) $(SDK_TARGET)
 		$(CXX) $(LDFLAGS) $(PLUGIN_LDFLAGS) -o $@ $^ $(PLUGIN_LIBS)
 
-$(HOST_TARGET):	$(HOST_OBJECTS)
+$(HOST_TARGET):	$(HOST_OBJECTS) $(SDK_TARGET)
 		$(CXX) $(LDFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(HOST_LIBS)
 
 test:		$(HOST_TARGET) $(PLUGIN_TARGET)
--- a/vamp-sdk/PluginAdapter.cpp	Thu Apr 06 12:26:44 2006 +0000
+++ b/vamp-sdk/PluginAdapter.cpp	Thu Apr 06 15:12:25 2006 +0000
@@ -309,7 +309,7 @@
     free((void *)desc);
 }
 
-VampFeatureList **
+VampFeatureList *
 PluginAdapterBase::vampProcess(VampPluginHandle handle,
                                float **inputBuffers,
                                int sec,
@@ -321,7 +321,7 @@
                             inputBuffers, sec, nsec);
 }
 
-VampFeatureList **
+VampFeatureList *
 PluginAdapterBase::vampGetRemainingFeatures(VampPluginHandle handle)
 {
     PluginAdapterBase *adapter = lookupAdapter(handle);
@@ -330,28 +330,35 @@
 }
 
 void
-PluginAdapterBase::vampReleaseFeatureSet(VampFeatureList **fs)
+PluginAdapterBase::vampReleaseFeatureSet(VampFeatureList *fs)
 {
-    if (!fs) return;
-
-    for (unsigned int i = 0; fs[i]; ++i) {
-
-        for (unsigned int j = 0; j < fs[i]->featureCount; ++j) {
-            VampFeature *feature = &fs[i]->features[j];
-            if (feature->values) free((void *)feature->values);
-            if (feature->label) free((void *)feature->label);
-        }
-
-        if (fs[i]->features) free((void *)fs[i]->features);
-        free((void *)fs[i]);
-    }
-
-    free((void *)fs);
 }
 
 void 
 PluginAdapterBase::cleanup(Plugin *plugin)
 {
+    if (m_fs.find(plugin) != m_fs.end()) {
+        size_t outputCount = 0;
+        if (m_pluginOutputs[plugin]) {
+            outputCount = m_pluginOutputs[plugin]->size();
+        }
+        VampFeatureList *list = m_fs[plugin];
+        for (unsigned int i = 0; i < outputCount; ++i) {
+            for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) {
+                if (list[i].features[j].label) {
+                    free(list[i].features[j].label);
+                }
+                if (list[i].features[j].values) {
+                    free(list[i].features[j].values);
+                }
+            }
+            if (list[i].features) free(list[i].features);
+        }
+        m_fs.erase(plugin);
+        m_fsizes.erase(plugin);
+        m_fvsizes.erase(plugin);
+    }
+
     if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) {
         delete m_pluginOutputs[plugin];
         m_pluginOutputs.erase(plugin);
@@ -428,89 +435,167 @@
     return desc;
 }
     
-VampFeatureList **
+VampFeatureList *
 PluginAdapterBase::process(Plugin *plugin,
                            float **inputBuffers,
                            int sec, int nsec)
 {
+//    std::cerr << "PluginAdapterBase::process" << std::endl;
     RealTime rt(sec, nsec);
-    return convertFeatures(plugin->process(inputBuffers, rt));
+    checkOutputMap(plugin);
+    return convertFeatures(plugin, plugin->process(inputBuffers, rt));
 }
     
-VampFeatureList **
+VampFeatureList *
 PluginAdapterBase::getRemainingFeatures(Plugin *plugin)
 {
-    return convertFeatures(plugin->getRemainingFeatures());
+//    std::cerr << "PluginAdapterBase::getRemainingFeatures" << std::endl;
+    checkOutputMap(plugin);
+    return convertFeatures(plugin, plugin->getRemainingFeatures());
 }
 
-VampFeatureList **
-PluginAdapterBase::convertFeatures(const Plugin::FeatureSet &features)
+VampFeatureList *
+PluginAdapterBase::convertFeatures(Plugin *plugin,
+                                   const Plugin::FeatureSet &features)
 {
-    unsigned int n = 0;
-    if (features.begin() != features.end()) {
-        Plugin::FeatureSet::const_iterator i = features.end();
-        --i;
-        n = i->first + 1;
-    }
+    int lastN = -1;
 
-    if (!n) return 0;
+    int outputCount = 0;
+    if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size();
+    
+    resizeFS(plugin, outputCount);
+    VampFeatureList *fs = m_fs[plugin];
 
-    VampFeatureList **fs = (VampFeatureList **)
-        malloc((n + 1) * sizeof(VampFeatureList *));
+    for (Plugin::FeatureSet::const_iterator fi = features.begin();
+         fi != features.end(); ++fi) {
 
-    for (unsigned int i = 0; i < n; ++i) {
+        int n = fi->first;
+        
+//        std::cerr << "PluginAdapterBase::convertFeatures: n = " << n << std::endl;
 
-        fs[i] = (VampFeatureList *)malloc(sizeof(VampFeatureList));
-
-        if (features.find(i) == features.end()) {
-
-            fs[i]->featureCount = 0;
-            fs[i]->features = 0;
+        if (n >= int(outputCount)) {
+            std::cerr << "WARNING: PluginAdapterBase::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl;
             continue;
         }
 
-        Plugin::FeatureSet::const_iterator fi = features.find(i);
+        if (n > lastN + 1) {
+            for (int i = lastN + 1; i < n; ++i) {
+                fs[i].featureCount = 0;
+            }
+        }
 
         const Plugin::FeatureList &fl = fi->second;
 
-        fs[i]->featureCount = fl.size();
+        size_t sz = fl.size();
+        if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz);
+        fs[n].featureCount = sz;
+        
+        for (size_t j = 0; j < sz; ++j) {
 
-        if (fs[i]->featureCount == 0) {
-            fs[i]->features = 0;
-            continue;
-        }
+//            std::cerr << "PluginAdapterBase::convertFeatures: j = " << j << std::endl;
 
-        fs[i]->features = (VampFeature *)malloc(fl.size() * sizeof(VampFeature));
-
-        for (unsigned int j = 0; j < fl.size(); ++j) {
-
-            VampFeature *feature = &fs[i]->features[j];
+            VampFeature *feature = &fs[n].features[j];
 
             feature->hasTimestamp = fl[j].hasTimestamp;
             feature->sec = fl[j].timestamp.sec;
             feature->nsec = fl[j].timestamp.nsec;
             feature->valueCount = fl[j].values.size();
-            feature->label = strdup(fl[j].label.c_str());
 
-            if (feature->valueCount == 0) {
-                feature->values = 0;
-                continue;
+            if (feature->label) free(feature->label);
+
+            if (fl[j].label.empty()) {
+                feature->label = 0;
+            } else {
+                feature->label = strdup(fl[j].label.c_str());
             }
 
-            feature->values = (float *)malloc
-                (feature->valueCount * sizeof(float));
+            if (feature->valueCount > m_fvsizes[plugin][n][j]) {
+                resizeFV(plugin, n, j, feature->valueCount);
+            }
 
             for (unsigned int k = 0; k < feature->valueCount; ++k) {
+//                std::cerr << "PluginAdapterBase::convertFeatures: k = " << k << std::endl;
                 feature->values[k] = fl[j].values[k];
             }
         }
+
+        lastN = n;
     }
 
-    fs[n] = 0;
+    if (lastN == -1) return 0;
+
+    if (int(outputCount) > lastN + 1) {
+        for (int i = lastN + 1; i < int(outputCount); ++i) {
+            fs[i].featureCount = 0;
+        }
+    }
 
     return fs;
 }
 
+void
+PluginAdapterBase::resizeFS(Plugin *plugin, int n)
+{
+//    std::cerr << "PluginAdapterBase::resizeFS(" << plugin << ", " << n << ")" << std::endl;
+
+    int i = m_fsizes[plugin].size();
+    if (i >= n) return;
+
+    std::cerr << "resizing from " << i << std::endl;
+
+    m_fs[plugin] = (VampFeatureList *)realloc
+        (m_fs[plugin], n * sizeof(VampFeatureList));
+
+    while (i < n) {
+        m_fs[plugin][i].featureCount = 0;
+        m_fs[plugin][i].features = 0;
+        m_fsizes[plugin].push_back(0);
+        m_fvsizes[plugin].push_back(std::vector<size_t>());
+        i++;
+    }
+}
+
+void
+PluginAdapterBase::resizeFL(Plugin *plugin, int n, size_t sz)
+{
+    std::cerr << "PluginAdapterBase::resizeFL(" << plugin << ", " << n << ", "
+              << sz << ")" << std::endl;
+
+    size_t i = m_fsizes[plugin][n];
+    if (i >= sz) return;
+
+    std::cerr << "resizing from " << i << std::endl;
+
+    m_fs[plugin][n].features = (VampFeature *)realloc
+        (m_fs[plugin][n].features, sz * sizeof(VampFeature));
+
+    while (m_fsizes[plugin][n] < sz) {
+        m_fs[plugin][n].features[m_fsizes[plugin][n]].valueCount = 0;
+        m_fs[plugin][n].features[m_fsizes[plugin][n]].values = 0;
+        m_fs[plugin][n].features[m_fsizes[plugin][n]].label = 0;
+        m_fvsizes[plugin][n].push_back(0);
+        m_fsizes[plugin][n]++;
+    }
+}
+
+void
+PluginAdapterBase::resizeFV(Plugin *plugin, int n, int j, size_t sz)
+{
+
+    std::cerr << "PluginAdapterBase::resizeFV(" << plugin << ", " << n << ", "
+              << j << ", " << sz << ")" << std::endl;
+
+    size_t i = m_fvsizes[plugin][n][j];
+    if (i >= sz) return;
+
+    std::cerr << "resizing from " << i << std::endl;
+
+    m_fs[plugin][n].features[j].values = (float *)realloc
+        (m_fs[plugin][n].features[j].values, sz * sizeof(float));
+
+    m_fvsizes[plugin][n][j] = sz;
+}
+  
 PluginAdapterBase::AdapterMap 
 PluginAdapterBase::m_adapterMap;
 
--- a/vamp-sdk/PluginAdapter.h	Thu Apr 06 12:26:44 2006 +0000
+++ b/vamp-sdk/PluginAdapter.h	Thu Apr 06 15:12:25 2006 +0000
@@ -84,25 +84,26 @@
 
     static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc);
 
-    static VampFeatureList **vampProcess(VampPluginHandle handle,
-                                       float **inputBuffers,
-                                       int sec,
-                                       int nsec);
+    static VampFeatureList *vampProcess(VampPluginHandle handle,
+                                        float **inputBuffers,
+                                        int sec,
+                                        int nsec);
 
-    static VampFeatureList **vampGetRemainingFeatures(VampPluginHandle handle);
+    static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle);
 
-    static void vampReleaseFeatureSet(VampFeatureList **fs);
+    static void vampReleaseFeatureSet(VampFeatureList *fs);
 
     void cleanup(Plugin *plugin);
     void checkOutputMap(Plugin *plugin);
     unsigned int getOutputCount(Plugin *plugin);
     VampOutputDescriptor *getOutputDescriptor(Plugin *plugin,
                                              unsigned int i);
-    VampFeatureList **process(Plugin *plugin,
+    VampFeatureList *process(Plugin *plugin,
                               float **inputBuffers,
                               int sec, int nsec);
-    VampFeatureList **getRemainingFeatures(Plugin *plugin);
-    VampFeatureList **convertFeatures(const Plugin::FeatureSet &features);
+    VampFeatureList *getRemainingFeatures(Plugin *plugin);
+    VampFeatureList *convertFeatures(Plugin *plugin,
+                                     const Plugin::FeatureSet &features);
     
     typedef std::map<const void *, PluginAdapterBase *> AdapterMap;
     static AdapterMap m_adapterMap;
@@ -116,8 +117,12 @@
     typedef std::map<Plugin *, Plugin::OutputList *> OutputMap;
     OutputMap m_pluginOutputs;
 
-    typedef std::map<Plugin *, VampFeature ***> FeatureBufferMap;
-    FeatureBufferMap m_pluginFeatures;
+    std::map<Plugin *, VampFeatureList *> m_fs;
+    std::map<Plugin *, std::vector<size_t> > m_fsizes;
+    std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes;
+    void resizeFS(Plugin *plugin, int n);
+    void resizeFL(Plugin *plugin, int n, size_t sz);
+    void resizeFV(Plugin *plugin, int n, int j, size_t sz);
 };
 
 template <typename P>
--- a/vamp-sdk/PluginHostAdapter.cpp	Thu Apr 06 12:26:44 2006 +0000
+++ b/vamp-sdk/PluginHostAdapter.cpp	Thu Apr 06 15:12:25 2006 +0000
@@ -267,7 +267,7 @@
     int sec = timestamp.sec;
     int nsec = timestamp.nsec;
     
-    VampFeatureList **features = m_descriptor->process(m_handle,
+    VampFeatureList *features = m_descriptor->process(m_handle,
                                                       inputBuffers,
                                                       sec, nsec);
     
@@ -282,7 +282,7 @@
     FeatureSet fs;
     if (!m_handle) return fs;
     
-    VampFeatureList **features = m_descriptor->getRemainingFeatures(m_handle); 
+    VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle); 
 
     convertFeatures(features, fs);
     m_descriptor->releaseFeatureSet(features);
@@ -290,14 +290,16 @@
 }
 
 void
-PluginHostAdapter::convertFeatures(VampFeatureList **features,
+PluginHostAdapter::convertFeatures(VampFeatureList *features,
                                    FeatureSet &fs)
 {
     if (!features) return;
 
-    for (unsigned int i = 0; features[i]; ++i) {
+    unsigned int outputs = m_descriptor->getOutputCount(m_handle);
+
+    for (unsigned int i = 0; i < outputs; ++i) {
         
-        VampFeatureList &list = *features[i];
+        VampFeatureList &list = features[i];
 
         if (list.featureCount > 0) {
 
--- a/vamp-sdk/PluginHostAdapter.h	Thu Apr 06 12:26:44 2006 +0000
+++ b/vamp-sdk/PluginHostAdapter.h	Thu Apr 06 15:12:25 2006 +0000
@@ -79,7 +79,7 @@
     FeatureSet getRemainingFeatures();
 
 protected:
-    void convertFeatures(VampFeatureList **, FeatureSet &);
+    void convertFeatures(VampFeatureList *, FeatureSet &);
 
     const VampPluginDescriptor *m_descriptor;
     VampPluginHandle m_handle;
--- a/vamp/vamp.h	Thu Apr 06 12:26:44 2006 +0000
+++ b/vamp/vamp.h	Thu Apr 06 15:12:25 2006 +0000
@@ -159,12 +159,12 @@
                                                 unsigned int);
     void (*releaseOutputDescriptor)(VampOutputDescriptor *);
 
-    VampFeatureList **(*process)(VampPluginHandle,
+    VampFeatureList *(*process)(VampPluginHandle,
                                 float **inputBuffers,
                                 int sec,
                                 int nsec);
-    VampFeatureList **(*getRemainingFeatures)(VampPluginHandle);
-    void (*releaseFeatureSet)(VampFeatureList **);
+    VampFeatureList *(*getRemainingFeatures)(VampPluginHandle);
+    void (*releaseFeatureSet)(VampFeatureList *);
 
 } VampPluginDescriptor;