• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef HISTREAMER_PLUGIN_INTF_PLUGIN_DEFINITION_H
17 #define HISTREAMER_PLUGIN_INTF_PLUGIN_DEFINITION_H
18 
19 #include <functional>
20 #include <string>
21 #include <memory>
22 #include "plugin_caps.h"
23 #include "plugin_base.h"
24 #include "plugin/plugin_buffer.h"
25 
26 namespace OHOS {
27 namespace Media {
28 namespace Plugins {
29 /**
30  * @brief Macro definition, creating the version information.
31  *
32  * @details The versioning is the process of assigning a unique version number to a unique state
33  * of plugin interface. Within a given version number category (major, minor), these numbers are
34  * usually assigned in ascending order and correspond to new developments in the plugin.
35  *
36  * Given a version number MAJOR.MINOR:
37  *  - MAJOR: When you make incompatible API changes.
38  *  - MINOR: When you add features in a backwards-compatible manner or do backwards-compatible bug fixes.
39  */
40 #define MAKE_VERSION(MAJOR, MINOR) ((((MAJOR)&0xFFFF) << 16) | ((MINOR)&0xFFFF))
41 
42 /// Plugin interface major number
43 #define PLUGIN_INTERFACE_VERSION_MAJOR (1)
44 
45 /// Plugin interface minor number
46 #define PLUGIN_INTERFACE_VERSION_MINOR (0)
47 
48 /// Plugin interface version
49 #define PLUGIN_INTERFACE_VERSION MAKE_VERSION(PLUGIN_INTERFACE_VERSION_MAJOR, PLUGIN_INTERFACE_VERSION_MINOR)
50 
51 /**
52  * @enum License Type.
53  * an official permission or permit.
54  *
55  * @since 1.0
56  * @version 1.0
57  */
58 enum struct LicenseType : uint8_t {
59     APACHE_V2, ///< The Apache License 2.0
60     LGPL,      ///< The GNU Lesser General Public License
61     GPL,       ///< The GNU General Public License
62     CC0,       ///< The Creative Commons Zero v1.0 Universal
63     UNKNOWN,   ///< Unknown License
64 };
65 
66 /**
67  * @brief Definition of plugin packaging information.
68  *
69  * @since 1.0
70  * @version 1.0
71  */
72 struct PackageDef {
73     uint32_t pkgVersion;    ///< Package information version, which indicates the latest plug-in interface version
74                             ///< used by the plugin in the package. The default value is PLUGIN_INTERFACE_VERSION.
75 
76     std::string name;   ///< Package name. The plugin framework registers the plugin using this name.
77                         ///< If the plugins are packaged as a dynamic library, the name of library
78                         ///< must be in the format of "libplugin_<name>.so".
79 
80     LicenseType
81         licenseType;    ///< The License information of the plugin in the package.
82                         ///< The different plugins must be the same.
83                         ///< The plugin framework processing in the plugin running state based on different license.
84 };
85 
86 /**
87  * @brief Data source operation interface.
88  *
89  * @since 1.0
90  * @version 1.0
91  */
92 struct DataSource {
93     /// Destructor
94     virtual ~DataSource() = default;
95 
96     /**
97      * @brief Read data from data source.
98      *
99      * @param offset    Offset of read position
100      * @param buffer    Storage of the read data
101      * @param expectedLen   Expected data size to be read
102      * @return  Execution status return
103      *  @retval OK: Plugin ReadAt succeeded.
104      *  @retval ERROR_NOT_ENOUGH_DATA: Data not enough
105      *  @retval END_OF_STREAM: End of stream
106      */
107     virtual Status ReadAt(int64_t offset, std::shared_ptr<Buffer>& buffer, size_t expectedLen) = 0;
108 
109     /**
110      * @brief Get data source size.
111      *
112      * @param size data source size.
113      * @return  Execution status return.
114      *  @retval OK: Plugin GetSize succeeded.
115      */
116     virtual Status GetSize(uint64_t& size) = 0;
117 
118     /**
119      * @brief Indicates that the current data source seekable or not.
120      *
121      * The function is valid only after INITIALIZED state.
122      *
123      * @return  Seekable status
124      */
125     virtual Seekable GetSeekable() = 0;
126 };
127 
128 /// Plugin create function. All plugins must implement this function.
129 template <typename T>
130 using PluginCreatorFunc = std::function<std::shared_ptr<T>(const std::string& name)>;
131 
132 /// Sniff function
133 using PluginSnifferFunc = int (*)(const std::string& name, std::shared_ptr<DataSource> dataSource);
134 
135 /**
136  * @brief Describes the basic information about the plugin.
137  *
138  * @since 1.0
139  * @version 1.0
140  */
141 struct PluginDefBase {
142     uint32_t apiVersion{0}; ///< Versions of different plugins. Different types of plugin have their own versions.
143 
144     PluginType pluginType = PluginType::INVALID_TYPE; ///< Describe the plugin type, e.g. 'source', 'codec'.
145 
146     std::string name;   ///< Indicates the name of a plugin. The name of the same type plugins must be unique.
147                         ///< Plugins with the same name may fail to be registered.
148 
149     std::string description; ///< Detailed description of the plugin.
150 
151     uint32_t rank{0};  ///< Plugin score. The plugin with a high score may be preferred. You can evaluate the
152                     ///< plugin score in terms of performance, version support, and license. Range: 0 to 100.
153 
PluginDefBasePluginDefBase154     PluginDefBase()
155     {
156         pluginType = PluginType::INVALID_TYPE;
157     }
158 
~PluginDefBasePluginDefBase159     virtual ~PluginDefBase() {}
160 
AddInCapsPluginDefBase161     virtual void AddInCaps(Capability& capability)
162     {
163         inCaps.emplace_back(capability);
164     }
165 
AddOutCapsPluginDefBase166     virtual void AddOutCaps(Capability& capability)
167     {
168         outCaps.emplace_back(capability);
169     }
170 
AddExtensionsPluginDefBase171     virtual void AddExtensions(std::vector<std::string> ex)
172     {
173         auto iter = ex.begin();
174         while (iter != ex.end()) {
175             extensions.emplace_back(*iter);
176             iter++;
177         }
178     }
179 
GetExtensionsPluginDefBase180     virtual std::vector<std::string> GetExtensions() const
181     {
182         return extensions;
183     }
184 
GetInCapsPluginDefBase185     virtual CapabilitySet GetInCaps() const
186     {
187         return inCaps;
188     }
189 
GetOutCapsPluginDefBase190     virtual CapabilitySet GetOutCaps() const
191     {
192         return outCaps;
193     }
194 
GetCreatorPluginDefBase195     virtual PluginCreatorFunc<PluginBase> GetCreator() const
196     {
197         return creator;
198     }
199 
SetCreatorPluginDefBase200     virtual void SetCreator(PluginCreatorFunc<PluginBase> creatorFunc)
201     {
202         creator = creatorFunc;
203     }
204 
GetSnifferPluginDefBase205     virtual PluginSnifferFunc GetSniffer() const
206     {
207         return sniffer;
208     }
209 
SetSnifferPluginDefBase210     virtual void SetSniffer(PluginSnifferFunc sniffFunc)
211     {
212         sniffer = sniffFunc;
213     }
214 
215 private:
216     std::vector<std::string> extensions;      ///< File extensions
217     CapabilitySet inCaps;                     ///< Plug-in input capability, For details, @see Capability.
218     CapabilitySet outCaps;                    ///< Plug-in output capability, For details, @see Capability.
219     PluginCreatorFunc<PluginBase> creator {nullptr}; ///< plugin create function.
220     PluginSnifferFunc sniffer {nullptr};         ///< plugin sniff function.
221 };
222 
223 /**
224  * @brief The plugin registration interface.
225  * The plugin framework will provide the implementation.
226  * Developers only need to invoke the API to register the plugin.
227  *
228  * @since 1.0
229  * @version 1.0
230  */
231 struct Register {
232     virtual ~Register() = default;
233     /**
234      * @brief Register the plugin.
235      *
236      * @param def   Basic information about the plugin
237      * @return  Registration status return
238      *  @retval OK: The plugin is registered succeed.
239      *  @retval ERROR_PLUGIN_ALREADY_EXISTS: The plugin already exists in plugin registered.
240      *  @retval ERROR_INCOMPATIBLE_VERSION: Incompatible version during plugin registration.
241      */
242     virtual Status AddPlugin(const PluginDefBase& def) = 0;
243 };
244 
245 /**
246  * @brief The package registration interface.
247  * The plugin framework will provide the implementation and auto invoke the API to
248  * finish the package registration when plugin framework first time be initialized.
249  *
250  * @since 1.0
251  * @version 1.0
252  */
253 struct PackageRegister : Register {
254     ~PackageRegister() override = default;
255 
256     /**
257      * @brief Register the package.
258      * During package registration, all plugins in the package are automatically registered.
259      *
260      * @param def   plugin packaging information.
261      * @return  Registration status return
262      *  @retval OK: The package is registered succeed without any errors.
263      *  @retval ERROR_PLUGIN_ALREADY_EXISTS: The package or plugins already exists.
264      *  @retval ERROR_INCOMPATIBLE_VERSION: Incompatible plugin interface version or api version.
265      */
266     virtual Status AddPackage(const PackageDef& def) = 0;
267 };
268 
269 /// Plugin registration function, all plugins must be implemented.
270 using RegisterFunc = Status (*)(const std::shared_ptr<PackageRegister>& reg);
271 
272 /// Plugin deregister function, all plugins must be implemented.
273 using UnregisterFunc = void (*)();
274 
275 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
276 #define PLUGIN_EXPORT extern "C" __declspec(dllexport)
277 #else
278 #if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
279 #define PLUGIN_EXPORT extern "C" __attribute__((visibility("default")))
280 #else
281 #define PLUGIN_EXPORT
282 #endif
283 #endif
284 
285 /// Macro definition, string concatenation
286 #define PLUGIN_PASTE_ARGS(str1, str2) str1##str2
287 
288 /// Macro definition, string concatenation
289 #define PLUGIN_PASTE(str1, str2) PLUGIN_PASTE_ARGS(str1, str2)
290 
291 /// Macro definition, stringify
292 #define PLUGIN_STRINGIFY_ARG(str) #str
293 
294 /// Macro definition, stringify
295 #define PLUGIN_STRINGIFY(str) PLUGIN_STRINGIFY_ARG(str)
296 
297 /**
298  * @brief Macro definition, Defines basic plugin information.
299  * Which is invoked during plugin package registration. All plugin packages must be implemented.
300  *
301  * @param name              Package name. For details, @see PackageDef::name
302  * @param license           Package License, For details, @see PackageDef::licenseType
303  * @param registerFunc      Plugin registration function, MUST NOT be NULL.
304  * @param unregisterFunc    Plugin deregister function,MUST NOT be NULL.
305  */
306 #define PLUGIN_DEFINITION(name, license, registerFunc, unregisterFunc)                                          \
307     PLUGIN_EXPORT OHOS::Media::Status PLUGIN_PASTE(register_, name)(                                            \
308         const std::shared_ptr<OHOS::Media::Plugins::PackageRegister>& pkgReg)                                   \
309     {                                                                                                           \
310         pkgReg->AddPackage({PLUGIN_INTERFACE_VERSION, PLUGIN_STRINGIFY(name), license});                        \
311         std::shared_ptr<OHOS::Media::Plugins::Register> pluginReg = pkgReg;                                     \
312         return registerFunc(pluginReg);                                                                         \
313     }                                                                                                           \
314     PLUGIN_EXPORT void PLUGIN_PASTE(unregister_, name)()                                                        \
315     {                                                                                                           \
316         unregisterFunc();                                                                                       \
317     }
318 } // namespace Plugins
319 } // namespace Media
320 } // namespace OHOS
321 #endif // HISTREAMER_PLUGIN_INTF_PLUGIN_DEFINITION_H
322