comparison runner/FeatureExtractionManager.h @ 366:9f7297c47850

Update plugin handling to follow the smart pointers used in the svcore library. This is awkward in our context, and the outcome isn't a very nice one - but it does look as if we had the potential for use-after-free in cases where a plugin was both used "bare" and wrapped in an auto-deleting adapter; those should be fixed now
author Chris Cannam
date Thu, 23 Apr 2020 15:51:55 +0100
parents e39307a8d22d
children
comparison
equal deleted inserted replaced
365:5e17f44b2e74 366:9f7297c47850
17 #define _FEATURE_EXTRACTION_MANAGER_H_ 17 #define _FEATURE_EXTRACTION_MANAGER_H_
18 18
19 #include <vector> 19 #include <vector>
20 #include <set> 20 #include <set>
21 #include <string> 21 #include <string>
22 #include <memory>
22 23
23 #include <QMap> 24 #include <QMap>
24 25
25 #include <vamp-hostsdk/Plugin.h> 26 #include <vamp-hostsdk/Plugin.h>
26 #include <vamp-hostsdk/PluginSummarisingAdapter.h> 27 #include <vamp-hostsdk/PluginSummarisingAdapter.h>
29 using std::vector; 30 using std::vector;
30 using std::set; 31 using std::set;
31 using std::string; 32 using std::string;
32 using std::pair; 33 using std::pair;
33 using std::map; 34 using std::map;
35 using std::shared_ptr;
34 36
35 class FeatureWriter; 37 class FeatureWriter;
36 class AudioFileReader; 38 class AudioFileReader;
37 39
38 class FeatureExtractionManager 40 class FeatureExtractionManager
74 // supplied sources. 76 // supplied sources.
75 void extractFeaturesMultiplexed(QStringList sources); 77 void extractFeaturesMultiplexed(QStringList sources);
76 78
77 private: 79 private:
78 bool m_verbose; 80 bool m_verbose;
81
82 // The plugins that we actually "run" may be wrapped versions of
83 // the originally loaded ones, depending on the adapter
84 // characteristics we need. Because the wrappers use raw pointers,
85 // we need to separately retain the originally loaded shared_ptrs
86 // so that they don't get auto-deleted. Same goes for any wrappers
87 // that may then be re-wrapped. That's what these are for.
88 set<shared_ptr<Vamp::PluginBase>> m_allLoadedPlugins;
89 set<shared_ptr<Vamp::PluginBase>> m_allAdapters;
79 90
80 // A plugin may have many outputs, so we can have more than one 91 // A plugin may have many outputs, so we can have more than one
81 // transform requested for a single plugin. The things we want to 92 // transform requested for a single plugin. The things we want to
82 // run in our process loop are plugins rather than their outputs, 93 // run in our process loop are plugins rather than their outputs,
83 // so we maintain a map from the plugins to the transforms desired 94 // so we maintain a map from the plugins to the transforms desired
84 // of them and then iterate through this map 95 // of them and then iterate through this map
85
86 typedef map<Transform, vector<FeatureWriter *> > TransformWriterMap; 96 typedef map<Transform, vector<FeatureWriter *> > TransformWriterMap;
87 typedef map<Vamp::Plugin *, TransformWriterMap> PluginMap; 97 typedef map<shared_ptr<Vamp::Plugin>, TransformWriterMap> PluginMap;
88 PluginMap m_plugins; 98 PluginMap m_plugins;
89 99
90 // When we run plugins, we want to run them in a known order so as 100 // When we run plugins, we want to run them in a known order so as
91 // to get the same results on each run of Sonic Annotator with the 101 // to get the same results on each run of Sonic Annotator with the
92 // same transforms. But if we just iterate through our PluginMap, 102 // same transforms. But if we just iterate through our PluginMap,
93 // we get them in an arbitrary order based on pointer 103 // we get them in an arbitrary order based on pointer
94 // address. This vector provides an underlying order for us. Note 104 // address. This vector provides an underlying order for us. Note
95 // that the TransformWriterMap is consistently ordered (because 105 // that the TransformWriterMap is consistently ordered (because
96 // the key is a Transform which has a proper ordering) so using 106 // the key is a Transform which has a proper ordering) so using
97 // this gives us a consistent order across the whole PluginMap 107 // this gives us a consistent order across the whole PluginMap
98 vector<Vamp::Plugin *> m_orderedPlugins; 108 vector<shared_ptr<Vamp::Plugin>> m_orderedPlugins;
99 109
100 // And a map back from transforms to their plugins. Note that 110 // And a map back from transforms to their plugins. Note that
101 // this is keyed by transform, not transform ID -- two differently 111 // this is keyed by whole transform structure, not transform ID --
102 // configured transforms with the same ID must use different 112 // two differently configured transforms with the same ID must use
103 // plugin instances. 113 // different plugin instances.
104 114 typedef map<Transform, shared_ptr<Vamp::Plugin>> TransformPluginMap;
105 typedef map<Transform, Vamp::Plugin *> TransformPluginMap;
106 TransformPluginMap m_transformPluginMap; 115 TransformPluginMap m_transformPluginMap;
107 116
108 // Cache the plugin output descriptors, mapping from plugin to a 117 // Cache the plugin output descriptors, mapping from plugin to a
109 // map from output ID to output descriptor. 118 // map from output ID to output descriptor.
110 typedef map<string, Vamp::Plugin::OutputDescriptor> OutputMap; 119 typedef map<string, Vamp::Plugin::OutputDescriptor> OutputMap;
111 typedef map<Vamp::Plugin *, OutputMap> PluginOutputMap; 120 typedef map<shared_ptr<Vamp::Plugin>, OutputMap> PluginOutputMap;
112 PluginOutputMap m_pluginOutputs; 121 PluginOutputMap m_pluginOutputs;
113 122
114 // Map from plugin output identifier to plugin output index 123 // Map from plugin output identifier to plugin output index
115 typedef map<string, int> OutputIndexMap; 124 typedef map<string, int> OutputIndexMap;
116 OutputIndexMap m_pluginOutputIndices; 125 OutputIndexMap m_pluginOutputIndices;
122 131
123 AudioFileReader *prepareReader(QString audioSource); 132 AudioFileReader *prepareReader(QString audioSource);
124 133
125 void extractFeaturesFor(AudioFileReader *reader, QString audioSource); 134 void extractFeaturesFor(AudioFileReader *reader, QString audioSource);
126 135
127 void writeSummaries(QString audioSource, Vamp::Plugin *); 136 void writeSummaries(QString audioSource,
137 std::shared_ptr<Vamp::Plugin>);
128 138
129 void writeFeatures(QString audioSource, 139 void writeFeatures(QString audioSource,
130 Vamp::Plugin *, 140 std::shared_ptr<Vamp::Plugin>,
131 const Vamp::Plugin::FeatureSet &, 141 const Vamp::Plugin::FeatureSet &,
132 Transform::SummaryType summaryType = 142 Transform::SummaryType summaryType =
133 Transform::NoSummary); 143 Transform::NoSummary);
134 144
135 void testOutputFiles(QString audioSource); 145 void testOutputFiles(QString audioSource);