1# VPE引擎(multimedia_video_processing_engine) 2 3## 简介 4VPE(Video Processing Engine)引擎是处理视频和图像数据的媒体引擎,包括细节增强、对比度增强、亮度增强、动态范围增强等基础能力,为转码、分享、显示后处理等提供色彩空间转换、缩放超分、动态元数据集生成等基础算法。 5 6VPE引擎的主要结构如下图所示: 7 8 9 10#### 各模块功能说明 11 12<table> 13<tr> 14<td bgcolor=#F5F5F5> 层级 </td> 15<td bgcolor=#F5F5F5> 模块 </td> 16<td bgcolor=#F5F5F5> 功能描述 </td> 17</tr> 18<tr> 19<td rowspan="7" colspan="1" > Interface </td> 20<td> 视频色彩空间CAPI </td> 21<td> 提供用于视频场景色彩空间转换相关接口 </td> 22</tr> 23<tr> 24<td> 图片色彩空间CAPI </td> 25<td> 提供用于图片场景色彩空间转换相关接口 </td> 26</tr> 27<tr> 28<td> 视频细节增强CAPI </td> 29<td> 提供视频超分算法、锐化算法的相关接口 </td> 30</tr> 31<tr> 32<td> 图片细节增强CAPI </td> 33<td> 提供图片超分算法、锐化算法的相关接口 </td> 34</tr> 35<tr> 36<td> 视频动态元数据CAPI </td> 37<td> 提供接口可用于视频内容动态元数据生成算法调用 </td> 38</tr> 39<tr> 40<td> 图片动态元数据CAPI </td> 41<td> 提供接口可用于图片内容动态元数据生成算法调用 </td> 42</tr> 43<tr> 44<td> 图片细节增强TS接口 </td> 45<td> 提供图片超分算法、锐化算法的TS接口 </td> 46</tr> 47<tr> 48<td rowspan="6" colspan="1" > 原子能力封装层 </td> 49<td> 视频色彩空间原子能力 </td> 50<td> 实现视频场景色彩空间转换软件通路调度及上下文管理,实现视频流过程控制 </td> 51</tr> 52<tr> 53<td> 图片色彩空间原子能力 </td> 54<td> 实现图片场景色彩空间转换软件通路调度 </td> 55</tr> 56<tr> 57<td> 视频细节增强原子能力 </td> 58<td> 实现视频场景清晰度增强及缩放算法软件通路调度及上下文管理,实现视频流过程控制 </td> 59</tr> 60<tr> 61<td> 图片细节增强原子能力 </td> 62<td> 实现图片场景清晰度增强及缩放算法软件通路调度 </td> 63</tr> 64<tr> 65<td> 视频动态元数据原子能力 </td> 66<td> 实现视频场景动态元数据生成软件通路调度 </td> 67</tr> 68<tr> 69<td> 图片动态元数据原子能力 </td> 70<td> 实现图片场景动态元数据生成软件通路调度 </td> 71</tr> 72<tr> 73<td rowspan="6" colspan="1" > 算法插件层 </td> 74<td> 视频色彩空间处理算法插件 </td> 75<td> 实现视频色彩空间转换算法功能,具体包括SDR2SDR、HDR2SDR、HDR2HDR </td> 76</tr> 77<tr> 78<td> 图片色彩空间算法插件 </td> 79<td> 实现图片色彩空间转换算法功能,具体包括SDR2SDR、单层转双层、双层转单层 </td> 80</tr> 81<tr> 82<td> 视频细节增强算法插件 </td> 83<td> 实现视频缩放、画质增强算法 </td> 84</tr> 85<tr> 86<td> 图片细节增强算法插件 </td> 87<td> 实现图片缩放、画质增强算法 </td> 88</tr> 89<tr> 90<td> 视频动态元数据算法插件 </td> 91<td> 实现视频动态元数据生产算法 </td> 92</tr> 93<tr> 94<td> 图片动态元数据算法插件 </td> 95<td> 实现图片动态元数据生成算法 </td> 96</tr> 97<tr> 98<td rowspan="3" colspan="1"> 插件管理 </td> 99<td> 插件注册 </td> 100<td> 提供系统开发者插件注册的功能 </td> 101</tr> 102<tr> 103<td> 能力查询 </td> 104<td> 应用开发者可通过能力查询功能确认给定插件是否在该设备或系统支持 </td> 105</tr> 106<tr> 107<td> 插件调用 </td> 108<td> 调用具体的插件能力完成相关算法功能 </td> 109</tr> 110<tr> 111<td rowspan="2" colspan="1"> 服务管理 </td> 112<td> 资源管理 </td> 113<td> 进行资源调度及算法的上下文管理,例如视频内容前后帧的相关信息 </td> 114</tr> 115<tr> 116<td> 进程管理 </td> 117<td> 完成跨进程通信等功能 </td> 118</tr> 119</table> 120 121 122| 依赖模块 | 功能描述 | 123| :-- | :-- | 124| graphic_graphic_surface | 提供视频surface支持 | 125| graphic_graphic_2d | 提供图片surfacebuffer支持 | 126| multimedia_media_foundation | 提供pixelmap支持 | 127| multimedia_image_framework | 提供Format参数设置支持 | 128| third_party_skia | 提供缩放算法 | 129 130## 目录 131 132仓目录结构如下: 133 134``` 135/foundation/multimedia/video_processing_engine/ 136├── framework # 框架代码 137│ ├── algorithm # 算法框架 138│ ├── aihdr_enhancer # 图像HDR增强算法框架 139│ ├── aihdr_enhancer_video # 视频HDR增强算法框架 140│ ├── colorspace_converter # 图像颜色空间转换算法框架 141│ ├── colorspace_converter_display # 图像颜色空间显示算法框架 142│ ├── colorspace_converter_video # 视频颜色空间转换算法框架 143│ ├── common # 算法框架公共部分 144│ ├── contrast_enhancer # 对比度增强算法框架 145│ ├── detail_enhancer # 图像细节增强算法框架 146│ ├── detail_enhancer_video # 视频细节增强算法框架 147│ ├── extension_manager # 插件管理 148│ ├── extensions # 插件算法 149│ ├── metadata_generator # 图像元数据生成算法框架 150│ ├── metadata_generator_video # 视频元数据生成算法框架 151│ ├── video_variable_refresh_rate # 视频可变帧率算法框架 152│ ├── capi # CAPI层 153│ ├── image_processing # 图像CAPI 154│ ├── video_processing # 视频CAPI 155│ ├── dfx # dfx代码 156├── interfaces # 接口层 157│ ├── inner_api # 系统内部接口 158│ ├── kits # 应用接口 159├── services # 服务代码 160├── sertestvices # 测试代码 161``` 162 163## 编译构建 164 165编译32位ARM系统VPE引擎 166``` 167./build.sh --product-name {product_name} --ccache --build-target video_processing_engine 168``` 169 170编译64位ARM系统VPE引擎 171``` 172./build.sh --product-name {product_name} --ccache --target-cpu arm64 --build-target video_processing_engine 173``` 174 175{product_name}为当前支持的平台,比如rk3568。 176 177## 说明 178 179### 使用说明 180VPE引擎作为OpenHarmony的组件,提供系统的视频图像能力,包含视频处理算法框架,色彩空间转换、动态元数据生成以及细节增强等插件,支持开发者在插件中注册自定义算法,实现更多高阶图像和视频处理操作。 181 182#### 应用开发者调用图像缩放示例 183以下步骤详细说明了具体的开发流程。 1841. 添加头文件。 185 ```cpp 186 #include <hilog/log.h> 187 #include <multimedia/image_framework/image_pixel_map_mdk.h> 188 #include <multimedia/image_framework/image/pixelmap_native.h> 189 #include <multimedia/video_processing_engine/image_processing.h> 190 #include <multimedia/video_processing_engine/image_processing_types.h> 191 #include <multimedia/player_framework/native_avformat.h> 192 #include <napi/native_api.h> 193 ``` 1942. (可选)初始化环境。 195 一般在进程内第一次使用时调用,可提前完成部分耗时操作。 196 ```cpp 197 ImageProcessing_ErrorCode ret = OH_ImageProcessing_InitializeEnvironment(); 198 ``` 1993. 创建细节增强模块。 200 应用可以通过图片处理引擎模块类型来创建图片细节增强模块。示例中的变量说明如下: 201 imageProcessor:细节增强模块实例。 202 IMAGE_PROCESSING_TYPE_DETAIL_ENHANCER:细节增强类型。 203 预期返回值:IMAGE_PROCESSING_SUCCESS 204 ```cpp 205 // 创建图片细节增强模块实例 206 ImageProcessing_ErrorCode ret = OH_ImageProcessing_Create(&imageProcessor, IMAGE_PROCESSING_TYPE_DETAIL_ENHANCER); 207 ``` 2084. (可选)配置细节增强档位,当前有高中低三档及NONE可选,若不配置则默认档位为LOW档。 209 ```cpp 210 // 创建format实例 211 OH_AVFormat* parameter = OH_AVFormat_Create(); 212 // 指定档位 213 OH_AVFormat_SetIntValue(parameter, IMAGE_DETAIL_ENHANCER_PARAMETER_KEY_QUALITY_LEVEL, 214 IMAGE_DETAIL_ENHANCER_QUALITY_LEVEL_HIGH); 215 // 配置参数 216 ImageProcessing_ErrorCode ret = OH_ImageProcessing_SetParameter(imageProcessor,parameter); 217 ``` 2185. 启动细节增强处理。 219 ```cpp 220 // 启动细节增强处理 221 ImageProcessing_ErrorCode ret = OH_ImageProcessing_EnhanceDetail(imageProcessor, srcImage, dstImage); 222 ``` 2236. 释放处理实例。 224 ```cpp 225 ImageProcessing_ErrorCode ret = OH_ImageProcessing_Destroy(imageProcessor); 226 ``` 2277. 释放处理资源。 228 ```cpp 229 OH_ImageProcessing_DeinitializeEnvironment(); 230 ``` 231#### 应用开发者调用视频缩放示例 232以下步骤详细说明了具体的开发流程。 2331. 添加头文件。 234 ```cpp 235 #include <ace/xcomponent/native_interface_xcomponent.h> 236 #include <multimedia/player_framework/native_avformat.h> 237 #include <multimedia/video_processing_engine/video_processing.h> 238 #include <multimedia/video_processing_engine/video_processing_types.h> 239 #include <native_window/external_window.h> 240 #include <native_buffer/native_buffer.h> 241 ``` 2422. (可选)创建解码实例。 243 细节增强模块的输入可以是来自系统解码的视频流,也可以由应用自行往window填充视频数据(例如:应用内部软解后直接将数据填充到window中)。若选择系统解码器对视频文件或视频流媒体进行处理,则可以创建解码实例来作为细节增强模块的输入。 244 ```cpp 245 // 创建Demuxer(媒体多路分解器)解析音视频信息(详见代码示例) 246 OH_AVSource* source_ = OH_AVSource_CreateWithFD(inputFd, inputFileOffset, inputFileSize); 247 OH_AVDemuxer* demuxer_ = OH_AVDemuxer_CreateWithSource(source_); 248 auto sourceFormat = std::shared_ptr<OH_AVFormat>(OH_AVSource_GetSourceFormat(source_), OH_AVFormat_Destroy); 249 // 创建视频解码器 250 OH_AVCodec * decoder_ = OH_VideoDecoder_CreateByMime(videoCodecMime.c_str()); 251 // 配置视频信息 252 OH_AVFormat *format = OH_AVFormat_Create(); 253 OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, videoWidth); 254 OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, videoHeight); 255 OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, frameRate); 256 OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, pixelFormat); 257 OH_AVFormat_SetIntValue(format, OH_MD_KEY_ROTATION, rotation); 258 int ret = OH_VideoDecoder_Configure(decoder_, format); 259 OH_AVFormat_Destroy(format); 260 // 配置回调,维护视频解码器buffer队列(详见代码示例) 261 OH_VideoDecoder_RegisterCallback(decoder_, 262 {SampleCallback::OnCodecError, SampleCallback::OnCodecFormatChange, 263 SampleCallback::OnNeedInputBuffer, SampleCallback::OnNewOutputBuffer}, videoDecContext_); 264 // 准备视频解码器 265 int ret = OH_VideoDecoder_Prepare(decoder_); 266 // 创建解码上下文 267 videoDecContext_ = new CodecUserData; 268 ``` 2693. (可选)初始化环境。 270 一般在进程内第一次使用时调用,可提前完成部分耗时操作。 271 ```cpp 272 VideoProcessing_ErrorCode ret = OH_VideoProcessing_InitializeEnvironment(); 273 ``` 2744. 创建细节增强模块。 275 应用可以通过视频处理引擎模块类型来创建细节增强模块。示例中的变量说明如下: 276 videoProcessor:细节增强模块实例。 277 VIDEO_PROCESSING_TYPE_DETAIL_ENHANCER:细节增强类型。 278 预期返回值:VIDEO_PROCESSING_SUCCESS 279 ```cpp 280 // 通过指定视频处理引擎类型创建细节增强模块实例 281 VideoProcessing_ErrorCode ret = OH_VideoProcessing_Create(&videoProcessor, VIDEO_PROCESSING_TYPE_DETAIL_ENHANCER); 282 ``` 2835. 配置异步回调函数。 284 ```cpp 285 // 创建回调实例 286 ret = OH_VideoProcessingCallback_Create(&callback); 287 // 绑定回调函数 288 OH_VideoProcessingCallback_BindOnError(callback, OnError); 289 OH_VideoProcessingCallback_BindOnState(callback, OnState); 290 OH_VideoProcessingCallback_BindOnNewOutputBuffer(callback, OnNewOutputBuffer); 291 // 注册回调函数 292 ret = OH_VideoProcessing_RegisterCallback(videoProcessor, callback, this); 293 // 回调函数声明(其中userData会传递注册回调时传入的用户数据,如:this指针) 294 void OnError(OH_VideoProcessing* videoProcessor, VideoProcessing_ErrorCode error, void* userData); 295 void OnState(OH_VideoProcessing* videoProcessor, VideoProcessing_State state, void* userData); 296 void OnNewOutputBuffer(OH_VideoProcessing* videoProcessor, uint32_t index, void* userData); 297 ``` 2986. (可选)配置细节增强档位,当前有高中低三档及NONE可选,若不配置则默认档位为LOW档。 299 ```cpp 300 // 创建format实例 301 OH_AVFormat* parameter = OH_AVFormat_Create(); 302 // 指定档位 303 OH_AVFormat_SetIntValue(parameter, VIDEO_DETAIL_ENHANCER_PARAMETER_KEY_QUALITY_LEVEL, VIDEO_DETAIL_ENHANCER_QUALITY_LEVEL_HIGH); 304 // 配置参数 305 OH_VideoProcessing_SetParameter(videoProcessor, parameter); 306 ``` 3077. 获取Surface。 308 ```cpp 309 //配置算法的输入 310 ret = OH_VideoProcessing_GetSurface(videoProcessor, inputWindow); 311 // 将解码器的输出与算法的输入进行绑定,解码器输出的window分辨率即为算法输入分辨率 312 OH_VideoDecoder_SetSurface(decoder_, inputWindow_); 313 ``` 3148. 设置Surface(配置送显)。 315 ```cpp 316 // 配置算法的输出,配置的输出window的分辨率即为算法输出分辨率 317 ret = OH_VideoProcessing_SetSurface(videoProcessor, outWindow); 318 ``` 3199. 创建解码器输入输出线程。 320 ```cpp 321 std::unique_ptr<std::thread> videoDecInputThread_ = std::make_unique<std::thread>(&Player::VideoDecInputThread, this); 322 std::unique_ptr<std::thread> videoDecOutputThread_ = std::make_unique<std::thread>(&Player::VideoDecOutputThread, this); 323 ``` 32410. 启动细节增强处理。 325 ```cpp 326 // 启动解码 327 int ret = OH_VideoDecoder_Start(decoder_); 328 // 启动细节增强处理 329 ret = OH_VideoProcessing_Start(videoProcessor); 330 ``` 33111. 调用OH_VideoProcessing_Stop()停止细节增强。 332 ```cpp 333 VideoProcessing_ErrorCode ret = OH_VideoProcessing_Stop(videoProcessor); 334 ``` 33512. 释放处理实例。 336 ```cpp 337 VideoProcessing_ErrorCode ret = OH_VideoProcessing_Destroy(videoProcessor); 338 VideoProcessing_ErrorCode ret = OH_VideoProcessingCallback_Destroy(callback); 339 ``` 34013. 释放处理资源。 341 ```cpp 342 VideoProcessing_ErrorCode ret = OH_VideoProcessing_DeinitializeEnvironment(); 343 ``` 344 345#### 系统开发者实现自定义算法插件注册示例 346视频处理引擎提供色彩空间转换、动态元数据生成以及细节增强等算法插件注册接口,系统用户可以将自己的算法注册其中,丰富算法插件。视频处理引擎定义了各类算法的基类,具体如下: 347| 功能 | 基类 | 头文件 | 348| :-- | :-- | :-- | 349| 视频色彩空间转换 | ColorSpaceConverterBase | colorspace_converter_base.h | 350| 图片色彩空间转换 | ColorSpaceConverterBase | colorspace_converter_base.h | 351| 视频细节增强 | DetailEnhancerBase | detail_enhancer_base.h | 352| 图片细节增强 | DetailEnhancerBase | detail_enhancer_base.h | 353| 视频动态元数据 | MetadataGeneratorBase | metadata_generator_base.h | 354| 图片动态元数据 | MetadataGeneratorBase | metadata_generator_base.h | 355 356<br> 357以缩放算法为例,该插件算法在framework/algorithm/extensions/skia中已经实现,以下描述具体开发步骤 358 3591. 在framework/algorithm/extensions目录下新建一个文件夹,例如skia,以及对应的cpp和h文件 360 3612. 缩放算法头文件实现,具体可参考framework/algorithm/extensions/skia/include/skia_impl.h 362 363```cpp 364#ifndef SKIA_IMPL_H 365#define SKIA_IMPL_H 366 367#include "surface_buffer.h" 368#include "include/core/SkYUVAPixmaps.h" 369 370#include "algorithm_errors.h" 371#include "detail_enhancer_base.h" 372#include "detail_enhancer_capability.h" 373 374namespace OHOS { 375namespace Media { 376namespace VideoProcessingEngine { 377// 由基类DetailEnhancerBase创建一个自定义缩放算法类,例如Skia 378// 其它算法对应关系如上表所示 379class Skia : public DetailEnhancerBase { 380public: 381 Skia() = default; 382 virtual ~Skia() = default; 383 Skia(const Skia&) = delete; 384 Skia& operator=(const Skia&) = delete; 385 Skia(Skia&&) = delete; 386 Skia& operator=(Skia&&) = delete; 387 // 以下函数必须定义,基类虚函数必须实现 388 // 定义Create函数,函数名可以自定义,这里以Create()为例,用于实例创建, 返回值必须是DetailEnhancerBase指针。 389 static std::unique_ptr<DetailEnhancerBase> Create(); 390 // 定义能力构建函数,函数名可以自定义,这里以BuildCapabilities()为例,用于定义算法所支持的能力,返回值必须是 391 static DetailEnhancerCapability BuildCapabilities(); 392 VPEAlgoErrCode Init() override; 393 VPEAlgoErrCode Deinit() override; 394 VPEAlgoErrCode SetParameter(const DetailEnhancerParameters& parameter, int type, bool flag) override; 395 VPEAlgoErrCode Process(const sptr<SurfaceBuffer>& input, const sptr<SurfaceBuffer>& output) override; 396}; 397// 注册函数,函数名可自定义,满足void XXX(uintptr_t XXX)形式,如下: 398void RegisterSkiaExtensions(uintptr_t extensionListAddr); 399} // VideoProcessingEngine 400} // Media 401} // OHOS 402#endif // SKIA_IMPL_H 403``` 4043. 插件算法能力注册与插件算法实现,具体可参考framework/algorithm/extensions/skia/skia_impl.cpp 405 406```cpp 407#include "skia_impl.h" 408 409#include <array> 410#include <chrono> 411#include <dlfcn.h> 412#include "detail_enhancer_extension.h" 413#include "utils.h" 414 415#include "vpe_log.h" 416 417namespace OHOS { 418namespace Media { 419namespace VideoProcessingEngine { 420 421namespace { 422// 定义算法优先级,默认RANK_DEFAULT,若设置RANK_HIGH,则存在同类型算法时,优先使用RANK_HIGH算法。 423constexpr Extension::Rank RANK = Extension::Rank::RANK_DEFAULT; 424constexpr uint32_t VERSION = 0; 425} // namespace 426 427std::unique_ptr<DetailEnhancerBase> Skia::Create() 428{ 429 return std::make_unique<Skia>(); 430} 431 432// 算法能力注册 433DetailEnhancerCapability Skia::BuildCapabilities() 434{ 435 // 通过RANK设置当前算法高优先级,当存在同样能力的算法时,优先使用RANK_HIGH算法,默认为RANK_DEFAULT。 436 std::vector<uint32_t> levels = { DETAIL_ENH_LEVEL_NONE, DETAIL_ENH_LEVEL_LOW, DETAIL_ENH_LEVEL_MEDIUM, 437 DETAIL_ENH_LEVEL_HIGH_EVE, DETAIL_ENH_LEVEL_HIGH_AISR, DETAIL_ENH_LEVEL_VIDEO}; 438 DetailEnhancerCapability capability = { levels, RANK, VERSION }; 439 return capability; 440} 441 442VPEAlgoErrCode Skia::Init() 443{ 444 return VPE_ALGO_ERR_OK; 445} 446 447VPEAlgoErrCode Skia::Deinit() 448{ 449 return VPE_ALGO_ERR_OK; 450} 451 452VPEAlgoErrCode Skia::SetParameter([[maybe_unused]] const DetailEnhancerParameters& parameter, 453 [[maybe_unused]] int type, [[maybe_unused]] bool flag) 454{ 455 return VPE_ALGO_ERR_OK; 456} 457 458// 算法实现,具体可参考framework/algorithm/extensions/skia/skia_impl.cpp 459VPEAlgoErrCode Skia::Process(const sptr<SurfaceBuffer>& input, const sptr<SurfaceBuffer>& output) 460{ 461 return errCode; 462} 463 464// 实现注册函数,注册函数名可自定义修改,需与下面DoRegisterExtensions中的注册函数名一致 465static std::vector<std::shared_ptr<Extension::ExtensionBase>> RegisterExtensions() 466{ 467 std::vector<std::shared_ptr<Extension::ExtensionBase>> extensions; 468 469 auto extension = std::make_shared<Extension::DetailEnhancerExtension>(); 470 CHECK_AND_RETURN_RET_LOG(extension != nullptr, extensions, "null pointer"); 471 // 填写插件算法信息,当前算法为缩放算法,类型则填写DETAIL_ENHANCER,后面两个字符串分别为算法名称以及版本号,可自定义修改。 472 extension->info = { Extension::ExtensionType::DETAIL_ENHANCER, "SKIA", "0.0.1" }; 473 extension->creator = Skia::Create; 474 extension->capabilitiesBuilder = Skia::BuildCapabilities; 475 extensions.push_back(std::static_pointer_cast<Extension::ExtensionBase>(extension)); 476 477 return extensions; 478} 479// 注册函数,函数名可自定义 480void RegisterSkiaExtensions(uintptr_t extensionListAddr) 481{ 482 Extension::DoRegisterExtensions(extensionListAddr, RegisterExtensions); 483} 484} // VideoProcessingEngine 485} // Media 486} // OHOS 487``` 488 4894. 添加注册插件回调函数,VPE插件管理会遍历所有插件注册函数。 490 在framework/algorithm/extension_manager/include/static_extension_list.h文件staticExtensionsRegisterMap中添加算法插件。 491```cpp 492const std::unordered_map<std::string, RegisterExtensionFunc> staticExtensionsRegisterMap = { 493 // 添加自定义插件算法名和注册函数,注册函数需与cpp中定义的注册函数同名 494 { "Skia", RegisterSkiaExtensions }, 495}; 496``` 497 498再以图像动态元数据生成为例,以下描述了具体开发步骤。 4991. 在framework/algorithm/extensions目录下新建一个文件夹,例如image_metadata_generator,以及对应的cpp和h文件 500``` 501 /foundation/multimedia/video_processing_engine/ 502 ├── framework # 框架代码 503 │ ├── algorithm # 算法框架 504 │ ├── extensions # 插件算法 505 │ ├── image_metadata_generator # 图像动态元数据生成 506 │ ├── image_metadata_gen_impl.h 507 │ ├── image_metadata_gen_impl.cpp 508``` 5092. 图像动态元数据生成头文件实现 510 511```cpp 512#ifndef IMAGE_METADATA_GEN_IMPL_H 513#define IMAGE_METADATA_GEN_IMPL_H 514 515#include "metadata_generator_base.h" 516#include "metadata_generator_capability.h" 517 518namespace OHOS { 519namespace Media { 520namespace VideoProcessingEngine { 521// 由基类MetadataGeneratorBase创建一个自定义元数据生成类,例如ImageMetadataGen 522// 其余算法对应关系如上表所示 523 524class ImageMetadataGen : public MetadataGeneratorBase { 525public: 526 // 定义Create函数,函数名可以自定义,这里以Create()为例,用于实例创建, 返回值必须是MetadataGeneratorBase指针。 527 static std::unique_ptr<MetadataGeneratorBase> Create(); 528 // 定义能力构建函数,函数名可以自定义,这里以BuildCapabilities()为例,用于定义算法所支持的能力,返回值必须是vector<MetadataGeneratorCapability>。 529 static std::vector<MetadataGeneratorCapability> BuildCapabilities(); 530 // 基类虚函数必须实现 531 VPEAlgoErrCode Init(VPEContext context) override; 532 VPEAlgoErrCode Deinit() override; 533 VPEAlgoErrCode SetParameter(const MetadataGeneratorParameter ¶meter) override; 534 VPEAlgoErrCode GetParameter(MetadataGeneratorParameter ¶meter) override; 535 VPEAlgoErrCode Process(const sptr<SurfaceBuffer> &input) override; 536 537private: 538 MetadataGeneratorParameter parameter_; 539 540}; 541// 注册函数,函数名可自定义,满足void XXX(uintptr_t XXX)形式,如下: 542void RegisterImageMetadataGeneratorExtensions(uintptr_t extensionListAddr); 543} // namespace VideoProcessingEngine 544} // namespace Media 545} // namespace OHOS 546#endif // IMAGE_METADATA_GEN_IMPL_H 547 548``` 5493. 插件算法能力注册与插件算法实现 550```cpp 551#include "image_metadata_gen_impl.h" 552#include "metadata_generator_extension.h" 553 554namespace OHOS { 555namespace Media { 556namespace VideoProcessingEngine { 557// 实现create函数,创建实例 558std::unique_ptr<MetadataGeneratorBase> ImageMetadataGen::Create() 559{ 560 return std::make_unique<ImageMetadataGen>(); 561} 562 563// 算法能力注册 564std::vector<MetadataGeneratorCapability> ImageMetadataGen::BuildCapabilities() 565{ 566 // 设置算法支持的输入色彩空间,具体可参考framework/capi/image_processing/include/image_processing_capi_capability.h中定义 567 std::vector<ColorSpaceDescription> inColorspaceList = { 568 { GetColorSpaceInfo(CM_BT2020_PQ_LIMIT), CM_IMAGE_HDR_VIVID_SINGLE }}; 569 // 设置算法支持的pixelmap 570 std::vector<GraphicPixelFormat> pixelFormatMap; 571 pixelFormatMap.emplace_back(GRAPHIC_PIXEL_FMT_YCBCR_P010); // NV12 572 pixelFormatMap.emplace_back(GRAPHIC_PIXEL_FMT_YCRCB_P010); // NV21 573 pixelFormatMap.emplace_back(GRAPHIC_PIXEL_FMT_RGBA_1010102); // rgba1010102 574 575 // 遍历色彩空间和pixelmap格式的所有组合,表示算法支持的所有能力, 576 std::vector<MetadataGeneratorCapability> capabilities; 577 for (const auto &inColorspace : inColorspaceList) { 578 // 通过RANK_HIGH设置当前算法高优先级,当存在同样能力的算法时,优先使用RANK_HIGH算法,默认为RANK_DEFAULT。 579 MetadataGeneratorCapability capability = { inColorspace, pixelFormatMap, Extension::Rank::RANK_HIGH, 0 }; 580 capabilities.emplace_back(capability); 581 } 582 return capabilities; 583} 584 585// 实现Init函数,可以根据实际算法,用于一些资源的初始化 586VPEAlgoErrCode ImageMetadataGen::Init(VPEContext context) 587{ 588 return VPE_ALGO_ERR_OK; 589} 590 591// 实现Deinit函数,可以根据实际算法,释放初始化的资源 592VPEAlgoErrCode ImageMetadataGen::Deinit() 593{ 594 return VPE_ALGO_ERR_OK; 595} 596// 实现参数设置函数 597VPEAlgoErrCode ImageMetadataGen::SetParameter(const MetadataGeneratorParameter ¶meter) 598{ 599 parameter_ = parameter; 600 return VPE_ALGO_ERR_OK; 601} 602// 实现参数获取函数 603VPEAlgoErrCode ImageMetadataGen::GetParameter(MetadataGeneratorParameter ¶meter) 604{ 605 parameter = parameter_; 606 return VPE_ALGO_ERR_OK; 607} 608// 算法功能实现 609VPEAlgoErrCode ImageMetadataGen::Process(const sptr<SurfaceBuffer> &input) 610{ 611 return VPE_ALGO_ERR_OK; 612} 613 614// 实现注册函数,注册函数名可自定义修改,需与下面DoRegisterExtensions中的注册函数名一致 615static std::vector<std::shared_ptr<OHOS::Media::VideoProcessingEngine::Extension::ExtensionBase>> RegisterExtensions() 616{ 617 std::vector<std::shared_ptr<OHOS::Media::VideoProcessingEngine::Extension::ExtensionBase>> extensions; 618 619 auto extension = std::make_shared<OHOS::Media::VideoProcessingEngine::Extension::MetadataGeneratorExtension>(); 620 // 填写插件算法信息,当前算法为图像元数据生成,类型则填写METADATA_GENERATOR,后面两个字符串分别为算法名称以及版本号,可自定义修改。 621 extension->info = { OHOS::Media::VideoProcessingEngine::Extension::ExtensionType::METADATA_GENERATOR, 622 "ImageMetadataGen", "V1.0" }; 623 extension->creator = OHOS::Media::VideoProcessingEngine::ImageMetadataGen::Create; 624 extension->capabilitiesBuilder = OHOS::Media::VideoProcessingEngine::ImageMetadataGen::BuildCapabilities; 625 extensions.push_back( 626 std::static_pointer_cast<OHOS::Media::VideoProcessingEngine::Extension::ExtensionBase>(extension)); 627 return extensions; 628} 629 630// 注册函数,函数名可自定义 631void RegisterImageMetadataGeneratorExtensions(uintptr_t extensionListAddr) 632{ 633 OHOS::Media::VideoProcessingEngine::Extension::DoRegisterExtensions(extensionListAddr, RegisterExtensions); 634} 635} // namespace VideoProcessingEngine 636} // namespace Media 637} // namespace OHOS 638} 639``` 6404. 添加注册插件回调函数,VPE插件管理会遍历所有插件注册函数。 641 在framework/algorithm/extension_manager/include/static_extension_list.h文件staticExtensionsRegisterMap中添加算法插件。 642```cpp 643const std::unordered_map<std::string, RegisterExtensionFunc> staticExtensionsRegisterMap = { 644 // 添加自定义插件算法名和注册函数,注册函数需与cpp中定义的注册函数同名 645 {"ImgMetadataGeneratorExtensions", RegisterImageMetadataGeneratorExtensions} 646}; 647``` 648## 相关仓 649 650- [graphic_graphic_2d](https://gitee.com/openharmony/graphic_graphic_2d) 651- [graphic_graphic_surface](https://gitee.com/openharmony/graphic_graphic_surface) 652- [multimedia_image_framework](https://gitee.com/openharmony/multimedia_image_framework) 653- [multimedia_media_foundation](https://gitee.com/openharmony/multimedia_media_foundation) 654- [third_party_skia](https://gitee.com/openharmony/third_party_skia)