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