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_PLUGINS_INTF_PLUGIN_DEFINITION_H 17 #define HISTREAMER_PLUGINS_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 VENDOR, ///< Offered by Vendor 64 UNKNOWN, ///< Unknown License 65 }; 66 67 /** 68 * @brief Definition of plugin packaging information. 69 * 70 * @since 1.0 71 * @version 1.0 72 */ 73 struct PackageDef { 74 uint32_t pkgVersion; ///< Package information version, which indicates the latest plug-in interface version 75 ///< used by the plugin in the package. The default value is PLUGIN_INTERFACE_VERSION. 76 77 std::string name; ///< Package name. The plugin framework registers the plugin using this name. 78 ///< If the plugins are packaged as a dynamic library, the name of library 79 ///< must be in the format of "libplugin_<name>.so". 80 81 LicenseType 82 licenseType; ///< The License information of the plugin in the package. 83 ///< The different plugins must be the same. 84 ///< The plugin framework processing in the plugin running state based on different license. 85 }; 86 87 /** 88 * @brief Data source operation interface. 89 * 90 * @since 1.0 91 * @version 1.0 92 */ 93 struct DataSource { 94 /// Destructor 95 virtual ~DataSource() = default; 96 97 /** 98 * @brief Read data from data source. 99 * 100 * @param offset Offset of read position 101 * @param buffer Storage of the read data 102 * @param expectedLen Expected data size to be read 103 * @return Execution status return 104 * @retval OK: Plugin ReadAt succeeded. 105 * @retval ERROR_NOT_ENOUGH_DATA: Data not enough 106 * @retval END_OF_STREAM: End of stream 107 */ 108 virtual Status ReadAt(int64_t offset, std::shared_ptr<Buffer>& buffer, size_t expectedLen) = 0; 109 110 /** 111 * @brief Get data source size. 112 * 113 * @param size data source size. 114 * @return Execution status return. 115 * @retval OK: Plugin GetSize succeeded. 116 */ 117 virtual Status GetSize(uint64_t& size) = 0; 118 119 /** 120 * @brief Indicates that the current data source seekable or not. 121 * 122 * The function is valid only after INITIALIZED state. 123 * 124 * @return Seekable status 125 */ 126 virtual Seekable GetSeekable() = 0; 127 128 virtual int32_t GetStreamID() = 0; 129 130 virtual bool IsDash() = 0; 131 }; 132 133 /// Plugin create function. All plugins must implement this function. 134 template <typename T> 135 using PluginCreatorFunc = std::function<std::shared_ptr<T>(const std::string& name)>; 136 137 /// Sniff function 138 using PluginSnifferFunc = int (*)(const std::string& name, std::shared_ptr<DataSource> dataSource); 139 140 /** 141 * @brief Describes the basic information about the plugin. 142 * 143 * @since 1.0 144 * @version 1.0 145 */ 146 struct PluginDefBase { 147 uint32_t apiVersion{0}; ///< Versions of different plugins. Different types of plugin have their own versions. 148 149 PluginType pluginType = PluginType::INVALID_TYPE; ///< Describe the plugin type, e.g. 'source', 'codec'. 150 151 std::string name; ///< Indicates the name of a plugin. The name of the same type plugins must be unique. 152 ///< Plugins with the same name may fail to be registered. 153 154 std::string description; ///< Detailed description of the plugin. 155 156 uint32_t rank{0}; ///< Plugin score. The plugin with a high score may be preferred. You can evaluate the 157 ///< plugin score in terms of performance, version support, and license. Range: 0 to 100. 158 PluginDefBasePluginDefBase159 PluginDefBase() 160 { 161 pluginType = PluginType::INVALID_TYPE; 162 } 163 ~PluginDefBasePluginDefBase164 virtual ~PluginDefBase() {} 165 AddInCapsPluginDefBase166 virtual void AddInCaps(Capability& capability) 167 { 168 inCaps.emplace_back(capability); 169 } 170 AddOutCapsPluginDefBase171 virtual void AddOutCaps(Capability& capability) 172 { 173 outCaps.emplace_back(capability); 174 } 175 AddExtensionsPluginDefBase176 virtual void AddExtensions(std::vector<std::string> ex) 177 { 178 auto iter = ex.begin(); 179 while (iter != ex.end()) { 180 extensions.emplace_back(*iter); 181 iter++; 182 } 183 } 184 GetExtensionsPluginDefBase185 virtual std::vector<std::string> GetExtensions() const 186 { 187 return extensions; 188 } 189 GetInCapsPluginDefBase190 virtual CapabilitySet GetInCaps() const 191 { 192 return inCaps; 193 } 194 GetOutCapsPluginDefBase195 virtual CapabilitySet GetOutCaps() const 196 { 197 return outCaps; 198 } 199 GetCreatorPluginDefBase200 virtual PluginCreatorFunc<PluginBase> GetCreator() const 201 { 202 return creator; 203 } 204 SetCreatorPluginDefBase205 virtual void SetCreator(PluginCreatorFunc<PluginBase> creatorFunc) 206 { 207 creator = creatorFunc; 208 } 209 GetSnifferPluginDefBase210 virtual PluginSnifferFunc GetSniffer() const 211 { 212 return sniffer; 213 } 214 SetSnifferPluginDefBase215 virtual void SetSniffer(PluginSnifferFunc sniffFunc) 216 { 217 sniffer = sniffFunc; 218 } 219 220 private: 221 std::vector<std::string> extensions; ///< File extensions 222 CapabilitySet inCaps; ///< Plug-in input capability, For details, @see Capability. 223 CapabilitySet outCaps; ///< Plug-in output capability, For details, @see Capability. 224 PluginCreatorFunc<PluginBase> creator {nullptr}; ///< plugin create function. 225 PluginSnifferFunc sniffer {nullptr}; ///< plugin sniff function. 226 }; 227 228 /** 229 * @brief The plugin registration interface. 230 * The plugin framework will provide the implementation. 231 * Developers only need to invoke the API to register the plugin. 232 * 233 * @since 1.0 234 * @version 1.0 235 */ 236 struct Register { 237 virtual ~Register() = default; 238 /** 239 * @brief Register the plugin. 240 * 241 * @param def Basic information about the plugin 242 * @return Registration status return 243 * @retval OK: The plugin is registered succeed. 244 * @retval ERROR_PLUGIN_ALREADY_EXISTS: The plugin already exists in plugin registered. 245 * @retval ERROR_INCOMPATIBLE_VERSION: Incompatible version during plugin registration. 246 */ 247 virtual Status AddPlugin(const PluginDefBase& def) = 0; 248 }; 249 250 /** 251 * @brief The package registration interface. 252 * The plugin framework will provide the implementation and auto invoke the API to 253 * finish the package registration when plugin framework first time be initialized. 254 * 255 * @since 1.0 256 * @version 1.0 257 */ 258 struct PackageRegister : Register { 259 ~PackageRegister() override = default; 260 261 /** 262 * @brief Register the package. 263 * During package registration, all plugins in the package are automatically registered. 264 * 265 * @param def plugin packaging information. 266 * @return Registration status return 267 * @retval OK: The package is registered succeed without any errors. 268 * @retval ERROR_PLUGIN_ALREADY_EXISTS: The package or plugins already exists. 269 * @retval ERROR_INCOMPATIBLE_VERSION: Incompatible plugin interface version or api version. 270 */ 271 virtual Status AddPackage(const PackageDef& def) = 0; 272 }; 273 274 /// Plugin registration function, all plugins must be implemented. 275 using RegisterFunc = Status (*)(const std::shared_ptr<PackageRegister>& reg); 276 277 /// Plugin deregister function, all plugins must be implemented. 278 using UnregisterFunc = void (*)(); 279 280 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) 281 #define PLUGIN_EXPORT extern "C" __declspec(dllexport) 282 #else 283 #if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) 284 #define PLUGIN_EXPORT extern "C" __attribute__((visibility("default"))) 285 #else 286 #define PLUGIN_EXPORT 287 #endif 288 #endif 289 290 /// Macro definition, string concatenation 291 #define PLUGIN_PASTE_ARGS(str1, str2) str1##str2 292 293 /// Macro definition, string concatenation 294 #define PLUGIN_PASTE(str1, str2) PLUGIN_PASTE_ARGS(str1, str2) 295 296 /// Macro definition, stringify 297 #define PLUGIN_STRINGIFY_ARG(str) #str 298 299 /// Macro definition, stringify 300 #define PLUGIN_STRINGIFY(str) PLUGIN_STRINGIFY_ARG(str) 301 302 /** 303 * @brief Macro definition, Defines basic plugin information. 304 * Which is invoked during plugin package registration. All plugin packages must be implemented. 305 * 306 * @param name Package name. For details, @see PackageDef::name 307 * @param license Package License, For details, @see PackageDef::licenseType 308 * @param registerFunc Plugin registration function, MUST NOT be NULL. 309 * @param unregisterFunc Plugin deregister function,MUST NOT be NULL. 310 */ 311 #define PLUGIN_DEFINITION(name, license, registerFunc, unregisterFunc) \ 312 PLUGIN_EXPORT OHOS::Media::Status PLUGIN_PASTE(register_, name)( \ 313 const std::shared_ptr<OHOS::Media::Plugins::PackageRegister>& pkgReg) \ 314 { \ 315 pkgReg->AddPackage({PLUGIN_INTERFACE_VERSION, PLUGIN_STRINGIFY(name), license}); \ 316 std::shared_ptr<OHOS::Media::Plugins::Register> pluginReg = pkgReg; \ 317 return registerFunc(pluginReg); \ 318 } \ 319 PLUGIN_EXPORT void PLUGIN_PASTE(unregister_, name)() \ 320 { \ 321 unregisterFunc(); \ 322 } 323 } // namespace Plugins 324 } // namespace Media 325 } // namespace OHOS 326 #endif // HISTREAMER_PLUGINS_INTF_PLUGIN_DEFINITION_H 327