• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# VPE引擎(multimedia_video_processing_engine)
2
3## 简介
4VPE(Video Processing Engine)引擎是处理视频和图像数据的媒体引擎,包括细节增强、对比度增强、亮度增强、动态范围增强等基础能力,为转码、分享、显示后处理等提供色彩空间转换、缩放超分、动态元数据集生成等基础算法。
5
6VPE引擎的主要结构如下图所示:
7
8![VPE引擎架构图](./figures/videoProcessingEngine_architecture.png)
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插件管理会遍历所有插件注册函数。
490framework/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 &parameter) override;
534    VPEAlgoErrCode GetParameter(MetadataGeneratorParameter &parameter) 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 &parameter)
598{
599    parameter_ = parameter;
600    return VPE_ALGO_ERR_OK;
601}
602// 实现参数获取函数
603VPEAlgoErrCode ImageMetadataGen::GetParameter(MetadataGeneratorParameter &parameter)
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插件管理会遍历所有插件注册函数。
641framework/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)