# HG changeset patch # User Chris Cannam # Date 1476452023 -3600 # Node ID 385deb828b4acf330d57ee237e707cf2e4e3c105 # Parent fef49844b3f8184b64e289352b3eca7b6642a8df Bodge in piper-cpp client (not yet working) diff -r fef49844b3f8 -r 385deb828b4a plugin/FeatureExtractionPluginFactory.cpp --- a/plugin/FeatureExtractionPluginFactory.cpp Tue Sep 20 09:16:13 2016 +0100 +++ b/plugin/FeatureExtractionPluginFactory.cpp Fri Oct 14 14:33:43 2016 +0100 @@ -36,27 +36,6 @@ //#define DEBUG_PLUGIN_SCAN_AND_INSTANTIATE 1 -class PluginDeletionNotifyAdapter : public Vamp::HostExt::PluginWrapper { -public: - PluginDeletionNotifyAdapter(Vamp::Plugin *plugin, - FeatureExtractionPluginFactory *factory) : - PluginWrapper(plugin), m_factory(factory) { } - virtual ~PluginDeletionNotifyAdapter(); -protected: - FeatureExtractionPluginFactory *m_factory; -}; - -PluginDeletionNotifyAdapter::~PluginDeletionNotifyAdapter() -{ - // see notes in vamp-sdk/hostext/PluginLoader.cpp from which this is drawn - Vamp::Plugin *p = m_plugin; - delete m_plugin; - m_plugin = 0; - // acceptable use after free here, as pluginDeleted uses p only as - // pointer key and does not deref it - if (m_factory) m_factory->pluginDeleted(p); -} - static FeatureExtractionPluginFactory *_nativeInstance = 0; FeatureExtractionPluginFactory * @@ -81,14 +60,10 @@ return instance(type); } -vector -FeatureExtractionPluginFactory::getPluginPath() +FeatureExtractionPluginFactory::FeatureExtractionPluginFactory() : + m_transport("piper-cpp/bin/piper-vamp-server"), + m_client(&m_transport) { - if (!m_pluginPath.empty()) return m_pluginPath; - - vector p = Vamp::PluginHostAdapter::getPluginPath(); - for (size_t i = 0; i < p.size(); ++i) m_pluginPath.push_back(p[i].c_str()); - return m_pluginPath; } vector @@ -117,319 +92,51 @@ { Profiler profiler("FeatureExtractionPluginFactory::getPluginIdentifiers"); + QMutexLocker locker(&m_mutex); + + if (m_pluginData.empty()) { + populate(); + } + vector rv; - QStringList candidates = PluginScan::getInstance()->getCandidateLibrariesFor - (PluginScan::VampPlugin); - - for (QString soname : candidates) { - - void *libraryHandle = DLOPEN(soname, RTLD_LAZY | RTLD_LOCAL); - - if (!libraryHandle) { - cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to load library " << soname << ": " << DLERROR() << endl; - continue; - } - - VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) - DLSYM(libraryHandle, "vampGetPluginDescriptor"); - - if (!fn) { - cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: No descriptor function in " << soname << endl; - if (DLCLOSE(libraryHandle) != 0) { - cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname << endl; - } - continue; - } - -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Vamp descriptor found" << endl; -#endif - - const VampPluginDescriptor *descriptor = 0; - int index = 0; - - map known; - bool ok = true; - - while ((descriptor = fn(VAMP_API_VERSION, index))) { - - if (known.find(descriptor->identifier) != known.end()) { - cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Plugin library " - << soname - << " returns the same plugin identifier \"" - << descriptor->identifier << "\" at indices " - << known[descriptor->identifier] << " and " - << index << endl; - cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Avoiding this library (obsolete API?)" << endl; - ok = false; - break; - } else { - known[descriptor->identifier] = index; - } - - ++index; - } - - if (ok) { - - index = 0; - - while ((descriptor = fn(VAMP_API_VERSION, index))) { - - QString id = PluginIdentifier::createIdentifier - ("vamp", soname, descriptor->identifier); - rv.push_back(id); -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Found plugin id " << id << " at index " << index << endl; -#endif - ++index; - } - } - - if (DLCLOSE(libraryHandle) != 0) { - cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname << endl; - } + for (const auto &d: m_pluginData) { + rv.push_back(QString("vamp:") + QString::fromStdString(d.pluginKey)); } - generateTaxonomy(); - return rv; } -QString -FeatureExtractionPluginFactory::findPluginFile(QString soname, QString inDir) -{ - QString file = ""; - -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::findPluginFile(\"" - << soname << "\", \"" << inDir << "\")" - << endl; -#endif - - if (inDir != "") { - - QDir dir(inDir, PLUGIN_GLOB, - QDir::Name | QDir::IgnoreCase, - QDir::Files | QDir::Readable); - if (!dir.exists()) return ""; - - file = dir.filePath(QFileInfo(soname).fileName()); - - if (QFileInfo(file).exists() && QFileInfo(file).isFile()) { - -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::findPluginFile: " - << "found trivially at " << file << endl; -#endif - - return file; - } - - for (unsigned int j = 0; j < dir.count(); ++j) { - file = dir.filePath(dir[j]); - if (QFileInfo(file).baseName() == QFileInfo(soname).baseName()) { - -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::findPluginFile: " - << "found \"" << soname << "\" at " << file << endl; -#endif - - return file; - } - } - -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::findPluginFile (with dir): " - << "not found" << endl; -#endif - - return ""; - - } else { - - QFileInfo fi(soname); - - if (fi.isAbsolute() && fi.exists() && fi.isFile()) { -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::findPluginFile: " - << "found trivially at " << soname << endl; -#endif - return soname; - } - - if (fi.isAbsolute() && fi.absolutePath() != "") { - file = findPluginFile(soname, fi.absolutePath()); - if (file != "") return file; - } - - vector path = getPluginPath(); - for (vector::iterator i = path.begin(); - i != path.end(); ++i) { - if (*i != "") { - file = findPluginFile(soname, *i); - if (file != "") return file; - } - } - -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::findPluginFile: " - << "not found" << endl; -#endif - - return ""; - } -} - Vamp::Plugin * FeatureExtractionPluginFactory::instantiatePlugin(QString identifier, sv_samplerate_t inputSampleRate) { Profiler profiler("FeatureExtractionPluginFactory::instantiatePlugin"); - Vamp::Plugin *rv = 0; - Vamp::PluginHostAdapter *plugin = 0; - - const VampPluginDescriptor *descriptor = 0; - int index = 0; - QString type, soname, label; PluginIdentifier::parseIdentifier(identifier, type, soname, label); - if (type != "vamp") { -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Wrong factory for plugin type " << type << endl; -#endif - return 0; - } - QString found = findPluginFile(soname); + piper_vamp::LoadRequest request; + request.pluginKey = (soname + ":" + label).toStdString(); + request.inputSampleRate = inputSampleRate; + request.adapterFlags = 0; + piper_vamp::LoadResponse response = m_client.loadPlugin(request); - if (found == "") { - cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find library file " << soname << endl; - return 0; - } else if (found != soname) { - -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Given library name was " << soname << ", found at " << found << endl; - cerr << soname << " -> " << found << endl; -#endif - - } - - soname = found; - - void *libraryHandle = DLOPEN(soname, RTLD_LAZY | RTLD_LOCAL); - - if (!libraryHandle) { - cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to load library " << soname << ": " << DLERROR() << endl; - return 0; - } - - VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) - DLSYM(libraryHandle, "vampGetPluginDescriptor"); - - if (!fn) { - cerr << "FeatureExtractionPluginFactory::instantiatePlugin: No descriptor function in " << soname << endl; - goto done; - } - - while ((descriptor = fn(VAMP_API_VERSION, index))) { - if (label == descriptor->identifier) break; - ++index; - } - - if (!descriptor) { - cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find plugin \"" << label << "\" in library " << soname << endl; - goto done; - } - - plugin = new Vamp::PluginHostAdapter(descriptor, float(inputSampleRate)); - - if (plugin) { - m_handleMap[plugin] = libraryHandle; - rv = new PluginDeletionNotifyAdapter(plugin, this); - } - -// SVDEBUG << "FeatureExtractionPluginFactory::instantiatePlugin: Constructed Vamp plugin, rv is " << rv << endl; - - //!!! need to dlclose() when plugins from a given library are unloaded - -done: - if (!rv) { - if (DLCLOSE(libraryHandle) != 0) { - cerr << "WARNING: FeatureExtractionPluginFactory::instantiatePlugin: Failed to unload library " << soname << endl; - } - } - -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Instantiated plugin " << label << " from library " << soname << ": descriptor " << descriptor << ", rv "<< rv << ", label " << rv->getName() << ", outputs " << rv->getOutputDescriptors().size() << endl; -#endif - - return rv; -} - -void -FeatureExtractionPluginFactory::pluginDeleted(Vamp::Plugin *plugin) -{ - void *handle = m_handleMap[plugin]; - if (handle) { -#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE - cerr << "unloading library " << handle << " for plugin " << plugin << endl; -#endif - DLCLOSE(handle); - } - m_handleMap.erase(plugin); + return response.plugin; } QString FeatureExtractionPluginFactory::getPluginCategory(QString identifier) { - return m_taxonomy[identifier]; + //!!! (re)implement +// return m_taxonomy[identifier]; + return QString(); } void -FeatureExtractionPluginFactory::generateTaxonomy() +FeatureExtractionPluginFactory::populate() { - vector pluginPath = getPluginPath(); - vector path; + piper_vamp::ListResponse lr = m_client.listPluginData(); + m_pluginData = lr.available; +} - for (size_t i = 0; i < pluginPath.size(); ++i) { - if (pluginPath[i].contains("/lib/")) { - QString p(pluginPath[i]); - path.push_back(p); - p.replace("/lib/", "/share/"); - path.push_back(p); - } - path.push_back(pluginPath[i]); - } - - for (size_t i = 0; i < path.size(); ++i) { - - QDir dir(path[i], "*.cat"); - -// SVDEBUG << "LADSPAPluginFactory::generateFallbackCategories: directory " << path[i] << " has " << dir.count() << " .cat files" << endl; - for (unsigned int j = 0; j < dir.count(); ++j) { - - QFile file(path[i] + "/" + dir[j]); - -// SVDEBUG << "LADSPAPluginFactory::generateFallbackCategories: about to open " << (path[i]+ "/" + dir[j]) << endl; - - if (file.open(QIODevice::ReadOnly)) { -// cerr << "...opened" << endl; - QTextStream stream(&file); - QString line; - - while (!stream.atEnd()) { - line = stream.readLine(); -// cerr << "line is: \"" << line << "\"" << endl; - QString id = PluginIdentifier::canonicalise - (line.section("::", 0, 0)); - QString cat = line.section("::", 1, 1); - m_taxonomy[id] = cat; -// cerr << "FeatureExtractionPluginFactory: set id \"" << id << "\" to cat \"" << cat << "\"" << endl; - } - } - } - } -} diff -r fef49844b3f8 -r 385deb828b4a plugin/FeatureExtractionPluginFactory.h --- a/plugin/FeatureExtractionPluginFactory.h Tue Sep 20 09:16:13 2016 +0100 +++ b/plugin/FeatureExtractionPluginFactory.h Fri Oct 14 14:33:43 2016 +0100 @@ -17,6 +17,7 @@ #define _FEATURE_EXTRACTION_PLUGIN_FACTORY_H_ #include +#include #include #include @@ -25,20 +26,20 @@ #include "base/Debug.h" #include "base/BaseTypes.h" +#include "vamp-client/ProcessQtTransport.h" +#include "vamp-client/CapnpRRClient.h" + class FeatureExtractionPluginFactory { public: + FeatureExtractionPluginFactory(); virtual ~FeatureExtractionPluginFactory() { } static FeatureExtractionPluginFactory *instance(QString pluginType); static FeatureExtractionPluginFactory *instanceFor(QString identifier); static std::vector getAllPluginIdentifiers(); - virtual std::vector getPluginPath(); - virtual std::vector getPluginIdentifiers(); - - virtual QString findPluginFile(QString soname, QString inDir = ""); // We don't set blockSize or channels on this -- they're // negotiated and handled via initialize() on the plugin @@ -51,14 +52,12 @@ virtual QString getPluginCategory(QString identifier); protected: - std::vector m_pluginPath; - std::map m_taxonomy; + piper_vamp::client::ProcessQtTransport m_transport; + piper_vamp::client::CapnpRRClient m_client; - friend class PluginDeletionNotifyAdapter; - void pluginDeleted(Vamp::Plugin *); - std::map m_handleMap; - - void generateTaxonomy(); + QMutex m_mutex; + std::vector m_pluginData; + void populate(); }; #endif diff -r fef49844b3f8 -r 385deb828b4a svcore.pro --- a/svcore.pro Tue Sep 20 09:16:13 2016 +0100 +++ b/svcore.pro Fri Oct 14 14:33:43 2016 +0100 @@ -38,8 +38,8 @@ TARGET = svcore -DEPENDPATH += . data plugin plugin/api/alsa -INCLUDEPATH += . data plugin plugin/api/alsa ../dataquay ../checker +DEPENDPATH += . data plugin plugin/api/alsa ../dataquay ../checker ../piper-cpp +INCLUDEPATH += . data plugin plugin/api/alsa ../dataquay ../checker ../piper-cpp OBJECTS_DIR = o MOC_DIR = o