Mercurial > hg > svcore
comparison plugin/FeatureExtractionPluginFactory.cpp @ 1206:659372323b45 tony-2.0-integration
Merge latest SV 3.0 branch code
author | Chris Cannam |
---|---|
date | Fri, 19 Aug 2016 15:58:57 +0100 |
parents | 98664afd518b |
children | 385deb828b4a |
comparison
equal
deleted
inserted
replaced
1136:e94719f941ba | 1206:659372323b45 |
---|---|
19 #include <vamp-hostsdk/PluginHostAdapter.h> | 19 #include <vamp-hostsdk/PluginHostAdapter.h> |
20 #include <vamp-hostsdk/PluginWrapper.h> | 20 #include <vamp-hostsdk/PluginWrapper.h> |
21 | 21 |
22 #include "system/System.h" | 22 #include "system/System.h" |
23 | 23 |
24 #include "PluginScan.h" | |
25 | |
24 #include <QDir> | 26 #include <QDir> |
25 #include <QFile> | 27 #include <QFile> |
26 #include <QFileInfo> | 28 #include <QFileInfo> |
27 #include <QTextStream> | 29 #include <QTextStream> |
28 | 30 |
29 #include <iostream> | 31 #include <iostream> |
30 | 32 |
31 #include "base/Profiler.h" | 33 #include "base/Profiler.h" |
34 | |
35 using namespace std; | |
32 | 36 |
33 //#define DEBUG_PLUGIN_SCAN_AND_INSTANTIATE 1 | 37 //#define DEBUG_PLUGIN_SCAN_AND_INSTANTIATE 1 |
34 | 38 |
35 class PluginDeletionNotifyAdapter : public Vamp::HostExt::PluginWrapper { | 39 class PluginDeletionNotifyAdapter : public Vamp::HostExt::PluginWrapper { |
36 public: | 40 public: |
75 QString type, soName, label; | 79 QString type, soName, label; |
76 PluginIdentifier::parseIdentifier(identifier, type, soName, label); | 80 PluginIdentifier::parseIdentifier(identifier, type, soName, label); |
77 return instance(type); | 81 return instance(type); |
78 } | 82 } |
79 | 83 |
80 std::vector<QString> | 84 vector<QString> |
81 FeatureExtractionPluginFactory::getPluginPath() | 85 FeatureExtractionPluginFactory::getPluginPath() |
82 { | 86 { |
83 if (!m_pluginPath.empty()) return m_pluginPath; | 87 if (!m_pluginPath.empty()) return m_pluginPath; |
84 | 88 |
85 std::vector<std::string> p = Vamp::PluginHostAdapter::getPluginPath(); | 89 vector<string> p = Vamp::PluginHostAdapter::getPluginPath(); |
86 for (size_t i = 0; i < p.size(); ++i) m_pluginPath.push_back(p[i].c_str()); | 90 for (size_t i = 0; i < p.size(); ++i) m_pluginPath.push_back(p[i].c_str()); |
87 return m_pluginPath; | 91 return m_pluginPath; |
88 } | 92 } |
89 | 93 |
90 std::vector<QString> | 94 vector<QString> |
91 FeatureExtractionPluginFactory::getAllPluginIdentifiers() | 95 FeatureExtractionPluginFactory::getAllPluginIdentifiers() |
92 { | 96 { |
93 FeatureExtractionPluginFactory *factory; | 97 FeatureExtractionPluginFactory *factory; |
94 std::vector<QString> rv; | 98 vector<QString> rv; |
95 | 99 |
96 factory = instance("vamp"); | 100 factory = instance("vamp"); |
97 if (factory) { | 101 if (factory) { |
98 std::vector<QString> tmp = factory->getPluginIdentifiers(); | 102 vector<QString> tmp = factory->getPluginIdentifiers(); |
99 for (size_t i = 0; i < tmp.size(); ++i) { | 103 for (size_t i = 0; i < tmp.size(); ++i) { |
100 // cerr << "identifier: " << tmp[i] << endl; | 104 // cerr << "identifier: " << tmp[i] << endl; |
101 rv.push_back(tmp[i]); | 105 rv.push_back(tmp[i]); |
102 } | 106 } |
103 } | 107 } |
106 RestoreStartupLocale(); | 110 RestoreStartupLocale(); |
107 | 111 |
108 return rv; | 112 return rv; |
109 } | 113 } |
110 | 114 |
111 std::vector<QString> | 115 vector<QString> |
112 FeatureExtractionPluginFactory::getPluginIdentifiers() | 116 FeatureExtractionPluginFactory::getPluginIdentifiers() |
113 { | 117 { |
114 Profiler profiler("FeatureExtractionPluginFactory::getPluginIdentifiers"); | 118 Profiler profiler("FeatureExtractionPluginFactory::getPluginIdentifiers"); |
115 | 119 |
116 std::vector<QString> rv; | 120 vector<QString> rv; |
117 std::vector<QString> path = getPluginPath(); | 121 |
122 QStringList candidates = PluginScan::getInstance()->getCandidateLibrariesFor | |
123 (PluginScan::VampPlugin); | |
118 | 124 |
119 for (std::vector<QString>::iterator i = path.begin(); i != path.end(); ++i) { | 125 for (QString soname : candidates) { |
120 | 126 |
121 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 127 void *libraryHandle = DLOPEN(soname, RTLD_LAZY | RTLD_LOCAL); |
122 SVDEBUG << "FeatureExtractionPluginFactory::getPluginIdentifiers: scanning directory " << i-<< endl; | |
123 #endif | |
124 | |
125 QDir pluginDir(*i, PLUGIN_GLOB, | |
126 QDir::Name | QDir::IgnoreCase, | |
127 QDir::Files | QDir::Readable); | |
128 | |
129 for (unsigned int j = 0; j < pluginDir.count(); ++j) { | |
130 | |
131 QString soname = pluginDir.filePath(pluginDir[j]); | |
132 | |
133 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
134 SVDEBUG << "FeatureExtractionPluginFactory::getPluginIdentifiers: trying potential library " << soname << endl; | |
135 #endif | |
136 | |
137 void *libraryHandle = DLOPEN(soname, RTLD_LAZY | RTLD_LOCAL); | |
138 | 128 |
139 if (!libraryHandle) { | 129 if (!libraryHandle) { |
140 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to load library " << soname << ": " << DLERROR() << endl; | 130 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to load library " << soname << ": " << DLERROR() << endl; |
141 continue; | 131 continue; |
142 } | 132 } |
143 | 133 |
144 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 134 VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) |
145 SVDEBUG << "FeatureExtractionPluginFactory::getPluginIdentifiers: It's a library all right, checking for descriptor" << endl; | 135 DLSYM(libraryHandle, "vampGetPluginDescriptor"); |
146 #endif | 136 |
147 | 137 if (!fn) { |
148 VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) | 138 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: No descriptor function in " << soname << endl; |
149 DLSYM(libraryHandle, "vampGetPluginDescriptor"); | |
150 | |
151 if (!fn) { | |
152 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: No descriptor function in " << soname << endl; | |
153 if (DLCLOSE(libraryHandle) != 0) { | |
154 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname << endl; | |
155 } | |
156 continue; | |
157 } | |
158 | |
159 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
160 SVDEBUG << "FeatureExtractionPluginFactory::getPluginIdentifiers: Vamp descriptor found" << endl; | |
161 #endif | |
162 | |
163 const VampPluginDescriptor *descriptor = 0; | |
164 int index = 0; | |
165 | |
166 std::map<std::string, int> known; | |
167 bool ok = true; | |
168 | |
169 while ((descriptor = fn(VAMP_API_VERSION, index))) { | |
170 | |
171 if (known.find(descriptor->identifier) != known.end()) { | |
172 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Plugin library " | |
173 << soname | |
174 << " returns the same plugin identifier \"" | |
175 << descriptor->identifier << "\" at indices " | |
176 << known[descriptor->identifier] << " and " | |
177 << index << endl; | |
178 SVDEBUG << "FeatureExtractionPluginFactory::getPluginIdentifiers: Avoiding this library (obsolete API?)" << endl; | |
179 ok = false; | |
180 break; | |
181 } else { | |
182 known[descriptor->identifier] = index; | |
183 } | |
184 | |
185 ++index; | |
186 } | |
187 | |
188 if (ok) { | |
189 | |
190 index = 0; | |
191 | |
192 while ((descriptor = fn(VAMP_API_VERSION, index))) { | |
193 | |
194 QString id = PluginIdentifier::createIdentifier | |
195 ("vamp", soname, descriptor->identifier); | |
196 rv.push_back(id); | |
197 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
198 SVDEBUG << "FeatureExtractionPluginFactory::getPluginIdentifiers: Found plugin id " << id << " at index " << index << endl; | |
199 #endif | |
200 ++index; | |
201 } | |
202 } | |
203 | |
204 if (DLCLOSE(libraryHandle) != 0) { | 139 if (DLCLOSE(libraryHandle) != 0) { |
205 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname << endl; | 140 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname << endl; |
206 } | 141 } |
207 } | 142 continue; |
143 } | |
144 | |
145 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
146 cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Vamp descriptor found" << endl; | |
147 #endif | |
148 | |
149 const VampPluginDescriptor *descriptor = 0; | |
150 int index = 0; | |
151 | |
152 map<string, int> known; | |
153 bool ok = true; | |
154 | |
155 while ((descriptor = fn(VAMP_API_VERSION, index))) { | |
156 | |
157 if (known.find(descriptor->identifier) != known.end()) { | |
158 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Plugin library " | |
159 << soname | |
160 << " returns the same plugin identifier \"" | |
161 << descriptor->identifier << "\" at indices " | |
162 << known[descriptor->identifier] << " and " | |
163 << index << endl; | |
164 cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Avoiding this library (obsolete API?)" << endl; | |
165 ok = false; | |
166 break; | |
167 } else { | |
168 known[descriptor->identifier] = index; | |
169 } | |
170 | |
171 ++index; | |
172 } | |
173 | |
174 if (ok) { | |
175 | |
176 index = 0; | |
177 | |
178 while ((descriptor = fn(VAMP_API_VERSION, index))) { | |
179 | |
180 QString id = PluginIdentifier::createIdentifier | |
181 ("vamp", soname, descriptor->identifier); | |
182 rv.push_back(id); | |
183 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
184 cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Found plugin id " << id << " at index " << index << endl; | |
185 #endif | |
186 ++index; | |
187 } | |
188 } | |
189 | |
190 if (DLCLOSE(libraryHandle) != 0) { | |
191 cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname << endl; | |
192 } | |
208 } | 193 } |
209 | 194 |
210 generateTaxonomy(); | 195 generateTaxonomy(); |
211 | 196 |
212 return rv; | 197 return rv; |
216 FeatureExtractionPluginFactory::findPluginFile(QString soname, QString inDir) | 201 FeatureExtractionPluginFactory::findPluginFile(QString soname, QString inDir) |
217 { | 202 { |
218 QString file = ""; | 203 QString file = ""; |
219 | 204 |
220 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 205 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
221 SVDEBUG << "FeatureExtractionPluginFactory::findPluginFile(\"" | 206 cerr << "FeatureExtractionPluginFactory::findPluginFile(\"" |
222 << soname << "\", \"" << inDir << "\")" | 207 << soname << "\", \"" << inDir << "\")" |
223 << endl; | 208 << endl; |
224 #endif | 209 #endif |
225 | 210 |
226 if (inDir != "") { | 211 if (inDir != "") { |
233 file = dir.filePath(QFileInfo(soname).fileName()); | 218 file = dir.filePath(QFileInfo(soname).fileName()); |
234 | 219 |
235 if (QFileInfo(file).exists() && QFileInfo(file).isFile()) { | 220 if (QFileInfo(file).exists() && QFileInfo(file).isFile()) { |
236 | 221 |
237 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 222 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
238 SVDEBUG << "FeatureExtractionPluginFactory::findPluginFile: " | 223 cerr << "FeatureExtractionPluginFactory::findPluginFile: " |
239 << "found trivially at " << file << endl; | 224 << "found trivially at " << file << endl; |
240 #endif | 225 #endif |
241 | 226 |
242 return file; | 227 return file; |
243 } | 228 } |
245 for (unsigned int j = 0; j < dir.count(); ++j) { | 230 for (unsigned int j = 0; j < dir.count(); ++j) { |
246 file = dir.filePath(dir[j]); | 231 file = dir.filePath(dir[j]); |
247 if (QFileInfo(file).baseName() == QFileInfo(soname).baseName()) { | 232 if (QFileInfo(file).baseName() == QFileInfo(soname).baseName()) { |
248 | 233 |
249 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 234 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
250 SVDEBUG << "FeatureExtractionPluginFactory::findPluginFile: " | 235 cerr << "FeatureExtractionPluginFactory::findPluginFile: " |
251 << "found \"" << soname << "\" at " << file << endl; | 236 << "found \"" << soname << "\" at " << file << endl; |
252 #endif | 237 #endif |
253 | 238 |
254 return file; | 239 return file; |
255 } | 240 } |
256 } | 241 } |
257 | 242 |
258 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 243 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
259 SVDEBUG << "FeatureExtractionPluginFactory::findPluginFile (with dir): " | 244 cerr << "FeatureExtractionPluginFactory::findPluginFile (with dir): " |
260 << "not found" << endl; | 245 << "not found" << endl; |
261 #endif | 246 #endif |
262 | 247 |
263 return ""; | 248 return ""; |
264 | 249 |
266 | 251 |
267 QFileInfo fi(soname); | 252 QFileInfo fi(soname); |
268 | 253 |
269 if (fi.isAbsolute() && fi.exists() && fi.isFile()) { | 254 if (fi.isAbsolute() && fi.exists() && fi.isFile()) { |
270 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 255 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
271 SVDEBUG << "FeatureExtractionPluginFactory::findPluginFile: " | 256 cerr << "FeatureExtractionPluginFactory::findPluginFile: " |
272 << "found trivially at " << soname << endl; | 257 << "found trivially at " << soname << endl; |
273 #endif | 258 #endif |
274 return soname; | 259 return soname; |
275 } | 260 } |
276 | 261 |
277 if (fi.isAbsolute() && fi.absolutePath() != "") { | 262 if (fi.isAbsolute() && fi.absolutePath() != "") { |
278 file = findPluginFile(soname, fi.absolutePath()); | 263 file = findPluginFile(soname, fi.absolutePath()); |
279 if (file != "") return file; | 264 if (file != "") return file; |
280 } | 265 } |
281 | 266 |
282 std::vector<QString> path = getPluginPath(); | 267 vector<QString> path = getPluginPath(); |
283 for (std::vector<QString>::iterator i = path.begin(); | 268 for (vector<QString>::iterator i = path.begin(); |
284 i != path.end(); ++i) { | 269 i != path.end(); ++i) { |
285 if (*i != "") { | 270 if (*i != "") { |
286 file = findPluginFile(soname, *i); | 271 file = findPluginFile(soname, *i); |
287 if (file != "") return file; | 272 if (file != "") return file; |
288 } | 273 } |
289 } | 274 } |
290 | 275 |
291 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 276 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
292 SVDEBUG << "FeatureExtractionPluginFactory::findPluginFile: " | 277 cerr << "FeatureExtractionPluginFactory::findPluginFile: " |
293 << "not found" << endl; | 278 << "not found" << endl; |
294 #endif | 279 #endif |
295 | 280 |
296 return ""; | 281 return ""; |
297 } | 282 } |
310 int index = 0; | 295 int index = 0; |
311 | 296 |
312 QString type, soname, label; | 297 QString type, soname, label; |
313 PluginIdentifier::parseIdentifier(identifier, type, soname, label); | 298 PluginIdentifier::parseIdentifier(identifier, type, soname, label); |
314 if (type != "vamp") { | 299 if (type != "vamp") { |
315 SVDEBUG << "FeatureExtractionPluginFactory::instantiatePlugin: Wrong factory for plugin type " << type << endl; | 300 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
301 cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Wrong factory for plugin type " << type << endl; | |
302 #endif | |
316 return 0; | 303 return 0; |
317 } | 304 } |
318 | 305 |
319 QString found = findPluginFile(soname); | 306 QString found = findPluginFile(soname); |
320 | 307 |
322 cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find library file " << soname << endl; | 309 cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find library file " << soname << endl; |
323 return 0; | 310 return 0; |
324 } else if (found != soname) { | 311 } else if (found != soname) { |
325 | 312 |
326 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 313 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
327 SVDEBUG << "FeatureExtractionPluginFactory::instantiatePlugin: Given library name was " << soname << ", found at " << found << endl; | 314 cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Given library name was " << soname << ", found at " << found << endl; |
328 cerr << soname << " -> " << found << endl; | 315 cerr << soname << " -> " << found << endl; |
329 #endif | 316 #endif |
330 | 317 |
331 } | 318 } |
332 | 319 |
341 | 328 |
342 VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) | 329 VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) |
343 DLSYM(libraryHandle, "vampGetPluginDescriptor"); | 330 DLSYM(libraryHandle, "vampGetPluginDescriptor"); |
344 | 331 |
345 if (!fn) { | 332 if (!fn) { |
346 SVDEBUG << "FeatureExtractionPluginFactory::instantiatePlugin: No descriptor function in " << soname << endl; | 333 cerr << "FeatureExtractionPluginFactory::instantiatePlugin: No descriptor function in " << soname << endl; |
347 goto done; | 334 goto done; |
348 } | 335 } |
349 | 336 |
350 while ((descriptor = fn(VAMP_API_VERSION, index))) { | 337 while ((descriptor = fn(VAMP_API_VERSION, index))) { |
351 if (label == descriptor->identifier) break; | 338 if (label == descriptor->identifier) break; |
373 if (DLCLOSE(libraryHandle) != 0) { | 360 if (DLCLOSE(libraryHandle) != 0) { |
374 cerr << "WARNING: FeatureExtractionPluginFactory::instantiatePlugin: Failed to unload library " << soname << endl; | 361 cerr << "WARNING: FeatureExtractionPluginFactory::instantiatePlugin: Failed to unload library " << soname << endl; |
375 } | 362 } |
376 } | 363 } |
377 | 364 |
378 // SVDEBUG << "FeatureExtractionPluginFactory::instantiatePlugin: Instantiated plugin " << label << " from library " << soname << ": descriptor " << descriptor << ", rv "<< rv << ", label " << rv->getName() << ", outputs " << rv->getOutputDescriptors().size() << endl; | 365 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
366 cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Instantiated plugin " << label << " from library " << soname << ": descriptor " << descriptor << ", rv "<< rv << ", label " << rv->getName() << ", outputs " << rv->getOutputDescriptors().size() << endl; | |
367 #endif | |
379 | 368 |
380 return rv; | 369 return rv; |
381 } | 370 } |
382 | 371 |
383 void | 372 void |
384 FeatureExtractionPluginFactory::pluginDeleted(Vamp::Plugin *plugin) | 373 FeatureExtractionPluginFactory::pluginDeleted(Vamp::Plugin *plugin) |
385 { | 374 { |
386 void *handle = m_handleMap[plugin]; | 375 void *handle = m_handleMap[plugin]; |
387 if (handle) { | 376 if (handle) { |
388 // SVDEBUG << "unloading library " << handle << " for plugin " << plugin << endl; | 377 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
378 cerr << "unloading library " << handle << " for plugin " << plugin << endl; | |
379 #endif | |
389 DLCLOSE(handle); | 380 DLCLOSE(handle); |
390 } | 381 } |
391 m_handleMap.erase(plugin); | 382 m_handleMap.erase(plugin); |
392 } | 383 } |
393 | 384 |
398 } | 389 } |
399 | 390 |
400 void | 391 void |
401 FeatureExtractionPluginFactory::generateTaxonomy() | 392 FeatureExtractionPluginFactory::generateTaxonomy() |
402 { | 393 { |
403 std::vector<QString> pluginPath = getPluginPath(); | 394 vector<QString> pluginPath = getPluginPath(); |
404 std::vector<QString> path; | 395 vector<QString> path; |
405 | 396 |
406 for (size_t i = 0; i < pluginPath.size(); ++i) { | 397 for (size_t i = 0; i < pluginPath.size(); ++i) { |
407 if (pluginPath[i].contains("/lib/")) { | 398 if (pluginPath[i].contains("/lib/")) { |
408 QString p(pluginPath[i]); | 399 QString p(pluginPath[i]); |
409 path.push_back(p); | 400 path.push_back(p); |