Mercurial > hg > sonic-annotator
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); |