# HG changeset patch # User cannam # Date 1144336345 0 # Node ID a3d35e11c3fe1cce0fac1e7d6bf10e844ddc0154 # Parent 6616075ec7b636861b2e3494f98092c00e2d0f37 * 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) diff -r 6616075ec7b6 -r a3d35e11c3fe Makefile --- 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) diff -r 6616075ec7b6 -r a3d35e11c3fe vamp-sdk/PluginAdapter.cpp --- 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()); + 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; diff -r 6616075ec7b6 -r a3d35e11c3fe vamp-sdk/PluginAdapter.h --- 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 AdapterMap; static AdapterMap m_adapterMap; @@ -116,8 +117,12 @@ typedef std::map OutputMap; OutputMap m_pluginOutputs; - typedef std::map FeatureBufferMap; - FeatureBufferMap m_pluginFeatures; + std::map m_fs; + std::map > m_fsizes; + std::map > > 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 diff -r 6616075ec7b6 -r a3d35e11c3fe vamp-sdk/PluginHostAdapter.cpp --- 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) { diff -r 6616075ec7b6 -r a3d35e11c3fe vamp-sdk/PluginHostAdapter.h --- 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; diff -r 6616075ec7b6 -r a3d35e11c3fe vamp/vamp.h --- 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;