• Home
Name Date Size #Lines LOC

..--

figures/22-Oct-2025-

framework/22-Oct-2025-18,40014,444

interfaces/22-Oct-2025-4,0111,416

services/22-Oct-2025-2,9172,065

test/22-Oct-2025-23,49818,010

.gitignoreD22-Oct-20252.1 KiB153125

BUILD.gnD22-Oct-2025842 2421

LICENSED22-Oct-20259.9 KiB178150

OAT.xmlD22-Oct-20254.2 KiB7418

README.mdD22-Oct-202522.3 KiB512460

README_zh.mdD22-Oct-202527.7 KiB654597

bundle.jsonD22-Oct-20254.8 KiB156155

config.gniD22-Oct-20254.4 KiB9986

README.md

1# VPE(multimedia_video_processing_engine)
2
3## Overview
4The Video Processing Engine (VPE) is a media engine for processing video and image data. It offers a range of fundamental capabilities including enhancements to details, contrast, luminance, and dynamic ranges. It also supports essential algorithms for color space conversion, scaling and upscaling, and dynamic metadata generation for transcoding, sharing, and post-processing for display.
5
6The following figure demonstrates the VPE architecture.
7
8![VPE architecture](./figures/videoProcessingEngine_architecture_english.png)
9
10
11#### 各模块功能说明
12
13<table>
14<tr>
15<td bgcolor=#F5F5F5> Level </td>
16<td bgcolor=#F5F5F5> module </td>
17<td bgcolor=#F5F5F5> Description of the function </td>
18</tr>
19<tr>
20<td rowspan="7" colspan="1" > Interface </td>
21<td> Video color space CAPI </td>
22<td> Provides interfaces for color space conversion in video scenes </td>
23</tr>
24<tr>
25<td> Picture color space CAPI </td>
26<td> Provides APIs for color space conversion of image scenes </td>
27</tr>
28<tr>
29<td> Video detail enhancement CAPI </td>
30<td> Provides APIs for video superresolution algorithms and sharpening algorithms </td>
31</tr>
32<tr>
33<td> Picture detail enhancement CAPI </td>
34<td> Provides APIs related to image superresolution algorithm and sharpening algorithm </td>
35</tr>
36<tr>
37<td> Video dynamic metadata CAPI </td>
38<td> APIs are provided for invoking dynamic metadata generation algorithms for video content </td>
39</tr>
40<tr>
41<td> Image dynamic metadata CAPI </td>
42<td> APIs are provided for dynamic metadata generation algorithms for image content </td>
43</tr>
44<tr>
45<td> The TS interface is enhanced for image details </td>
46<td> Provides TS interfaces for image super-resolution algorithm and sharpening algorithm </td>
47</tr>
48<tr>
49<td rowspan="6" colspan="1" > Atomically capable encapsulation layer </td>
50<td> Video color space atomic capabilities </td>
51<td> Realize the channel scheduling and context management of the video scene color space conversion software, and realize the process control of the video stream </td>
52</tr>
53<tr>
54<td> Picture color space atomic capability </td>
55<td> Realize the color space conversion software channel scheduling of picture scenes </td>
56</tr>
57<tr>
58<td> Video details enhance atomic capabilities </td>
59<td> Realize video scene clarity enhancement and scaling algorithm software channel scheduling and context management, and realize video stream process control </td>
60</tr>
61<tr>
62<td> Picture details enhance atomic capabilities </td>
63<td> Realize the image scene clarity enhancement and scaling algorithm software channel scheduling </td>
64</tr>
65<tr>
66<td> Dynamic metadata atomic capabilities for video </td>
67<td> Realize the dynamic metadata generation software channel scheduling of video scenes </td>
68</tr>
69<tr>
70<td> Dynamic metadata atomic capabilities for images </td>
71<td> Realize the dynamic metadata generation software channel scheduling of image scenes </td>
72</tr>
73<tr>
74<td rowspan="6" colspan="1" > Algorithm plug-in layer </td>
75<td> Video color space processing algorithm plug-in </td>
76<td> Implement the function of video color space conversion algorithm, including SDR2SDR, HDR2SDR, and HDR2HDR </td>
77</tr>
78<tr>
79<td> Plug-in for image color space algorithms </td>
80<td> Realize the function of image color space conversion algorithm, including SDR2SDR, single-layer to double-layer, double-layer to single-layer </td>
81</tr>
82<tr>
83<td> Video Detail Enhancement Algorithm Plug-in </td>
84<td> Implement video scaling and image quality enhancement algorithms </td>
85</tr>
86<tr>
87<td> Plug-in for image detail enhancement algorithms </td>
88<td> Implement image scaling and image quality enhancement algorithms </td>
89</tr>
90<tr>
91<td> Video dynamic metadata algorithm plug-in </td>
92<td> Implement the video dynamic metadata production algorithm </td>
93</tr>
94<tr>
95<td> Image dynamic metadata algorithm plug-in </td>
96<td> Implement the dynamic metadata generation algorithm for images </td>
97</tr>
98<tr>
99<td rowspan="3" colspan="1"> Plugin management </td>
100<td> Plugin registration </td>
101<td> Provide the function of system developer plug-in registration </td>
102</tr>
103<tr>
104<td> Capability inquiry </td>
105<td> Application developers can use the capability query function to confirm whether a given plug-in is supported on that device or system </td>
106</tr>
107<tr>
108<td> Plug-in calls </td>
109<td> Invoke specific plug-in capabilities to complete related algorithm functions </td>
110</tr>
111<tr>
112<td rowspan="2" colspan="1"> Service management </td>
113<td> Resource management </td>
114<td> Resource scheduling and algorithm context management, such as information about the frames before and after video content </td>
115</tr>
116<tr>
117<td> Process management </td>
118<td> Complete functions such as cross-process communication </td>
119</tr>
120</table>
121
122
123| Dependency modules | Description of the function |
124| :-- | :-- |
125| graphic_graphic_surface | Provide video surface support |
126| graphic_graphic_2d | Provide image surfacebuffer support |
127| multimedia_media_foundation | Pixelmap support is available |
128| multimedia_image_framework | Format parameter setting is supported |
129| third_party_skia | Provides a scaling algorithm |
130
131## Directory Structure
132
133The structure of the repository directory is as follows:
134
135```
136/foundation/multimedia/video_processing_engine/
137├── framework                                  # Framework code
138│   ├── algorithm                              # Algorithm framework
139│       ├── aihdr_enhancer                     # Image HDR enhancement algorithm framework
140│       ├── aihdr_enhancer_video               # Video HDR enhancement algorithm framework
141│       ├── colorspace_converter               # Image color space conversion algorithm framework
142│       ├── colorspace_converter_display       # Image color space display algorithm framework
143│       ├── colorspace_converter_video         # Video color space conversion algorithm framework
144│       ├── common                             # Common
145│       ├── contrast_enhancer                  # Contrast enhancement algorithm framework
146│       ├── detail_enhancer                    # Image detail enhancement algorithm framework
147│       ├── detail_enhancer_video              # Video detail enhancement algorithm framework
148│       ├── extension_manager                  # Plugin management
149│       ├── metadata_generator                 # Image metadata generation algorithm framework
150│       ├── metadata_generator_video           # Video metadata generation algorithm framework
151│       ├── video_variable_refresh_rate        # Video variable frame rate algorithm framework
152│   ├── capi                                   # CAPI layer
153│       ├── image_processing                   # Image CAPI
154│       ├── video_processing                   # Video CAPI
155│   ├── dfx                                    # DFX code
156├── interfaces                                 # API layer
157│   ├── inner_api                              # Internal APIs
158│   ├── kits                                   # Application APIs
159├── services                                   # Service code
160├── sertestvices                               # Test code
161```
162
163## Build
164
165Run the following command to build the VPE for the 32-bit ARM system:
166```
167./build.sh --product-name {product_name} --ccache --build-target video_processing_engine
168```
169
170Run the following command to build the VPE for the 64-bit ARM system:
171```
172./build.sh --product-name {product_name} --ccache --target-cpu arm64 --build-target video_processing_engine
173```
174
175**product_name** indicates the product supported, for example, **rk3568**.
176
177## Description
178
179### How to Use
180As a component of OpenHarmony, the VPE provides video and image processing capabilities, including color space conversion, dynamic metadata generation, and detail enhancement.
181
182#### The app developer calls the image scaling sample
1831. Add a header file.
184    ```cpp
185    #include <hilog/log.h>
186    #include <multimedia/image_framework/image_pixel_map_mdk.h>
187    #include <multimedia/image_framework/image/pixelmap_native.h>
188    #include <multimedia/video_processing_engine/image_processing.h>
189    #include <multimedia/video_processing_engine/image_processing_types.h>
190    #include <multimedia/player_framework/native_avformat.h>
191    #include <napi/native_api.h>
192    ```
1932. Optionally, initialize the environment.
194  Generally, it is called when it is used for the first time in the process, and some time-consuming operations can be completed in advance.
195    ```cpp
196    ImageProcessing_ErrorCode ret =  OH_ImageProcessing_InitializeEnvironment();
197    ```
1983. Create a detail enhancement module.
199  Applications can create image detail enhancement modules by image processing engine module types. The variables in the example are described as follows:
200  imageProcessor:an instance of the Detail Enhancement module.
201  IMAGE_PROCESSING_TYPE_DETAIL_ENHANCER:Detail enhancement type.
202  Expected return value: IMAGE_PROCESSING_SUCCESS
203    ```cpp
204    ImageProcessing_ErrorCode ret = OH_ImageProcessing_Create(&imageProcessor, IMAGE_PROCESSING_TYPE_DETAIL_ENHANCER);
205    ```
2064. (Optional) Configure the detail enhancement gear, there are currently three gears of high, medium and low and NONE optional, if not configured, the default gear is LOW.
207    ```cpp
208    OH_AVFormat* parameter = OH_AVFormat_Create();
209    OH_AVFormat_SetIntValue(parameter, IMAGE_DETAIL_ENHANCER_PARAMETER_KEY_QUALITY_LEVEL,
210        IMAGE_DETAIL_ENHANCER_QUALITY_LEVEL_HIGH);
211    ImageProcessing_ErrorCode ret = OH_ImageProcessing_SetParameter(imageProcessor,parameter);
212    ```
2135. Initiates detail enhancement processing.
214    ```cpp
215    ImageProcessing_ErrorCode ret = OH_ImageProcessing_EnhanceDetail(imageProcessor, srcImage, dstImage);
216    ```
2176. Release the processing instance.
218    ```cpp
219    ImageProcessing_ErrorCode ret = OH_ImageProcessing_Destroy(imageProcessor);
220    ```
2217. Free up processing resources.
222    ```cpp
223    OH_ImageProcessing_DeinitializeEnvironment();
224    ```
225#### The app developer calls the video zoom sample
2261. Add a header file.
227    ```cpp
228    #include <ace/xcomponent/native_interface_xcomponent.h>
229    #include <multimedia/player_framework/native_avformat.h>
230    #include <multimedia/video_processing_engine/video_processing.h>
231    #include <multimedia/video_processing_engine/video_processing_types.h>
232    #include <native_window/external_window.h>
233    #include <native_buffer/native_buffer.h>
234    ```
2352. Optionally, create a decode instance.
236  The input of the detail enhancement module can be a video stream decoded by the system, or the application can fill the window with video data (for example, the application directly fills the data into the window after internal soft decoding). If you select a system decoder to process a video file or video stream, you can create a decoder instance as input to the Detail Enhancement module.
237    ```cpp
238    OH_AVSource* source_ = OH_AVSource_CreateWithFD(inputFd, inputFileOffset, inputFileSize);
239    OH_AVDemuxer* demuxer_ = OH_AVDemuxer_CreateWithSource(source_);
240    auto sourceFormat = std::shared_ptr<OH_AVFormat>(OH_AVSource_GetSourceFormat(source_), OH_AVFormat_Destroy);
241    OH_AVCodec * decoder_ = OH_VideoDecoder_CreateByMime(videoCodecMime.c_str());
242    OH_AVFormat *format = OH_AVFormat_Create();
243    OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, videoWidth);
244    OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, videoHeight);
245    OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, frameRate);
246    OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, pixelFormat);
247    OH_AVFormat_SetIntValue(format, OH_MD_KEY_ROTATION, rotation);
248    int ret = OH_VideoDecoder_Configure(decoder_, format);
249    OH_AVFormat_Destroy(format);
250    OH_VideoDecoder_RegisterCallback(decoder_,
251            {SampleCallback::OnCodecError, SampleCallback::OnCodecFormatChange,
252            SampleCallback::OnNeedInputBuffer, SampleCallback::OnNewOutputBuffer}, videoDecContext_);
253
254    int ret = OH_VideoDecoder_Prepare(decoder_);
255
256    videoDecContext_ = new CodecUserData;
257    ```
2583. Optionally, initialize the environment.
259  Generally, it is called when it is used for the first time in the process, and some time-consuming operations can be completed in advance.
260    ```cpp
261    VideoProcessing_ErrorCode ret = OH_VideoProcessing_InitializeEnvironment();
262    ```
2634. Create a detail enhancement module.
264  Applications can create detail enhancement modules by video processing engine module types. The variables in the example are described as follows:
265  videoProcessor:an instance of the Detail Enhancement module.
266  VIDEO_PROCESSING_TYPE_DETAIL_ENHANCER:Detail enhancement type.
267  Expected return value: VIDEO_PROCESSING_SUCCESS
268    ```cpp
269    VideoProcessing_ErrorCode ret = OH_VideoProcessing_Create(&videoProcessor, VIDEO_PROCESSING_TYPE_DETAIL_ENHANCER);
270    ```
2715. Configure an asynchronous callback function.
272    ```cpp
273    ret = OH_VideoProcessingCallback_Create(&callback);
274    OH_VideoProcessingCallback_BindOnError(callback, OnError);
275    OH_VideoProcessingCallback_BindOnState(callback, OnState);
276    OH_VideoProcessingCallback_BindOnNewOutputBuffer(callback, OnNewOutputBuffer);
277    ret = OH_VideoProcessing_RegisterCallback(videoProcessor, callback, this);
278    void OnError(OH_VideoProcessing* videoProcessor, VideoProcessing_ErrorCode error, void* userData);
279    void OnState(OH_VideoProcessing* videoProcessor, VideoProcessing_State state, void* userData);
280    void OnNewOutputBuffer(OH_VideoProcessing* videoProcessor, uint32_t index, void* userData);
281    ```
2826. (Optional) Configure the detail enhancement gear, there are currently three gears of high, medium and low and NONE optional, if not configured, the default gear is LOW.
283    ```cpp
284    OH_AVFormat* parameter = OH_AVFormat_Create();
285    OH_AVFormat_SetIntValue(parameter, VIDEO_DETAIL_ENHANCER_PARAMETER_KEY_QUALITY_LEVEL, VIDEO_DETAIL_ENHANCER_QUALITY_LEVEL_HIGH);
286    OH_VideoProcessing_SetParameter(videoProcessor, parameter);
287    ```
2887. Get your Surface.
289    ```cpp
290    ret = OH_VideoProcessing_GetSurface(videoProcessor, inputWindow);
291    OH_VideoDecoder_SetSurface(decoder_,  inputWindow_);
292    ```
2938. Set Surface
294    ```cpp
295    ret = OH_VideoProcessing_SetSurface(videoProcessor, outWindow);
296    ```
2979. Create a decoder input and output thread.
298    ```cpp
299    std::unique_ptr<std::thread> videoDecInputThread_ = std::make_unique<std::thread>(&Player::VideoDecInputThread, this);
300    std::unique_ptr<std::thread> videoDecOutputThread_ = std::make_unique<std::thread>(&Player::VideoDecOutputThread, this);
301    ```
30210. Initiates detail enhancement processing.
303    ```cpp
304    int ret = OH_VideoDecoder_Start(decoder_);
305    ret = OH_VideoProcessing_Start(videoProcessor);
306    ```
30711. Call OH_VideoProcessing_Stop()
308    ```cpp
309    VideoProcessing_ErrorCode ret = OH_VideoProcessing_Stop(videoProcessor);
310    ```
31112. Release the processing instance.
312    ```cpp
313    VideoProcessing_ErrorCode ret = OH_VideoProcessing_Destroy(videoProcessor);
314    VideoProcessing_ErrorCode ret = OH_VideoProcessingCallback_Destroy(callback);
315    ```
31613. Free up processing resources.
317    ```cpp
318    VideoProcessing_ErrorCode ret = OH_VideoProcessing_DeinitializeEnvironment();
319    ```
320#### Custom algorithm plugin registration
3211. Implement plugin registration function
322    ```cpp
323    std::vector<MetadataGeneratorCapability> ImageMetadataGen::BuildCapabilities()
324    {
325        std::vector<MetadataGeneratorCapability> capabilities;
326        for (const auto &inColorspace : inColorspaceList) {
327            MetadataGeneratorCapability capability = { inColorspace, pixelFormatMap, RANK, IMAGEMETAGENVERSION };
328            capabilities.emplace_back(capability);
329        }
330        return capabilities;
331    }
332
333    static std::vector<std::shared_ptr<OHOS::Media::VideoProcessingEngine::Extension::ExtensionBase>> RegisterExtensions()
334    {
335        std::vector<std::shared_ptr<OHOS::Media::VideoProcessingEngine::Extension::ExtensionBase>> extensions;
336        auto extension = std::make_shared<OHOS::Media::VideoProcessingEngine::Extension::MetadataGeneratorExtension>();
337        extension->info = { OHOS::Media::VideoProcessingEngine::Extension::ExtensionType::METADATA_GENERATOR,
338        "ImageMetadataGen", "v1" };
339        extension->capabilitiesBuilder = OHOS::Media::VideoProcessingEngine::ImageMetadataGen::BuildCapabilities;
340        extensions.push_back(
341            std::static_pointer_cast<OHOS::Media::VideoProcessingEngine::Extension::ExtensionBase>(extension));
342        return extensions;
343    }
344
345    void RegisterImageMetadataGeneratorExtensions(uintptr_t extensionListAddr)
346    {
347        OHOS::Media::VideoProcessingEngine::Extension::DoRegisterExtensions(extensionListAddr, RegisterExtensions);
348    }
349    ```
3502. Implement algorithm
351    ```cpp
352    ImageMetadataGen::Process(const sptr<SurfaceBuffer> &input)
353    ```
3543. Add registered plugin callback function.
355  Add at staticExtensionsRegisterMap
356    ```cpp
357    const std::unordered_map<std::string, RegisterExtensionFunc> staticExtensionsRegisterMap = {
358        {"ImageMetadataGeneratorExtensions", RegisterImageMetadataGeneratorExtensions}
359    };
360    ```
361
362#### The system developer implements a custom algorithm plug-in registration example
363The video processing engine provides algorithm plug-in registration interfaces such as color space conversion, dynamic metadata generation, and detail enhancement, and system users can register their own algorithms to enrich algorithm plug-ins. The video processing engine defines the basic classes of various algorithms, as follows:
364| Function | Base class | 	Header file |
365| :-- | :-- | :-- |
366| Video color space conversion | ColorSpaceConverterBase | colorspace_converter_base.h |
367| Picture color space conversion | ColorSpaceConverterBase | colorspace_converter_base.h |
368| Video detail enhancement | DetailEnhancerBase | detail_enhancer_base.h |
369| Picture detail enhancement | DetailEnhancerBase | detail_enhancer_base.h |
370| Video dynamic metadata | MetadataGeneratorBase | metadata_generator_base.h |
371| Image dynamic metadata | MetadataGeneratorBase | metadata_generator_base.h |
372
373<br>
374Take the scaling algorithm as an example, the plug-in algorithm has been implemented in framework/algorithm/extensions/skia, and the specific development steps are described below
375
3761. Create a new folder in the framework/algorithm/extensions directory, for example, skia, along with the corresponding cpp and h files
377
3782. The scaling algorithm header file is implemented, see framework/algorithm/extensions/skia/include/skia_impl.h
379
380```cpp
381#ifndef SKIA_IMPL_H
382#define SKIA_IMPL_H
383
384#include "surface_buffer.h"
385#include "include/core/SkYUVAPixmaps.h"
386
387#include "algorithm_errors.h"
388#include "detail_enhancer_base.h"
389#include "detail_enhancer_capability.h"
390
391namespace OHOS {
392namespace Media {
393namespace VideoProcessingEngine {
394
395class Skia : public DetailEnhancerBase {
396public:
397    Skia() = default;
398    virtual ~Skia() = default;
399    Skia(const Skia&) = delete;
400    Skia& operator=(const Skia&) = delete;
401    Skia(Skia&&) = delete;
402    Skia& operator=(Skia&&) = delete;
403    static std::unique_ptr<DetailEnhancerBase> Create();
404    static DetailEnhancerCapability BuildCapabilities();
405    VPEAlgoErrCode Init() override;
406    VPEAlgoErrCode Deinit() override;
407    VPEAlgoErrCode SetParameter(const DetailEnhancerParameters& parameter, int type, bool flag) override;
408    VPEAlgoErrCode Process(const sptr<SurfaceBuffer>& input, const sptr<SurfaceBuffer>& output) override;
409};
410void RegisterSkiaExtensions(uintptr_t extensionListAddr);
411} // VideoProcessingEngine
412} // Media
413} // OHOS
414#endif // SKIA_IMPL_H
415```
4163. For details on plug-in algorithm capability registration and plug-in algorithm implementation, see framework/algorithm/extensions/skia/skia_impl.cpp
417
418```cpp
419#include "skia_impl.h"
420
421#include <array>
422#include <chrono>
423#include <dlfcn.h>
424#include "detail_enhancer_extension.h"
425#include "utils.h"
426
427#include "vpe_log.h"
428
429namespace OHOS {
430namespace Media {
431namespace VideoProcessingEngine {
432
433namespace {
434
435constexpr Extension::Rank RANK = Extension::Rank::RANK_DEFAULT;
436constexpr uint32_t VERSION = 0;
437} // namespace
438
439std::unique_ptr<DetailEnhancerBase> Skia::Create()
440{
441    return std::make_unique<Skia>();
442}
443
444
445DetailEnhancerCapability Skia::BuildCapabilities()
446{
447    std::vector<uint32_t> levels = { DETAIL_ENH_LEVEL_NONE, DETAIL_ENH_LEVEL_LOW, DETAIL_ENH_LEVEL_MEDIUM,
448        DETAIL_ENH_LEVEL_HIGH_EVE, DETAIL_ENH_LEVEL_HIGH_AISR, DETAIL_ENH_LEVEL_VIDEO};
449    DetailEnhancerCapability capability = { levels, RANK, VERSION };
450    return capability;
451}
452
453VPEAlgoErrCode Skia::Init()
454{
455    return VPE_ALGO_ERR_OK;
456}
457
458VPEAlgoErrCode Skia::Deinit()
459{
460    return VPE_ALGO_ERR_OK;
461}
462
463VPEAlgoErrCode Skia::SetParameter([[maybe_unused]] const DetailEnhancerParameters& parameter,
464    [[maybe_unused]] int type, [[maybe_unused]] bool flag)
465{
466    return VPE_ALGO_ERR_OK;
467}
468
469VPEAlgoErrCode Skia::Process(const sptr<SurfaceBuffer>& input, const sptr<SurfaceBuffer>& output)
470{
471    return errCode;
472}
473
474static std::vector<std::shared_ptr<Extension::ExtensionBase>> RegisterExtensions()
475{
476    std::vector<std::shared_ptr<Extension::ExtensionBase>> extensions;
477
478    auto extension = std::make_shared<Extension::DetailEnhancerExtension>();
479    CHECK_AND_RETURN_RET_LOG(extension != nullptr, extensions, "null pointer");
480    extension->info = { Extension::ExtensionType::DETAIL_ENHANCER, "SKIA", "0.0.1" };
481    extension->creator = Skia::Create;
482    extension->capabilitiesBuilder = Skia::BuildCapabilities;
483    extensions.push_back(std::static_pointer_cast<Extension::ExtensionBase>(extension));
484
485    return extensions;
486}
487
488void RegisterSkiaExtensions(uintptr_t extensionListAddr)
489{
490    Extension::DoRegisterExtensions(extensionListAddr, RegisterExtensions);
491}
492} // VideoProcessingEngine
493} // Media
494} // OHOS
495```
496
4974. Add a callback function for registering a plug-in, and the VPE plug-in management will iterate through all plug-in registration functions.
498 see framework/algorithm/extension_manager/include/static_extension_list.h
499```cpp
500const std::unordered_map<std::string, RegisterExtensionFunc> staticExtensionsRegisterMap = {
501    { "Skia", RegisterSkiaExtensions },
502};
503```
504
505## Repositories Involved
506
507- [graphic_graphic_2d](https://gitee.com/openharmony/graphic_graphic_2d)
508- [graphic_graphic_surface](https://gitee.com/openharmony/graphic_graphic_surface)
509- [multimedia_image_framework](https://gitee.com/openharmony/multimedia_image_framework)
510- [multimedia_media_foundation](https://gitee.com/openharmony/multimedia_media_foundation)
511- [third_party_skia](https://gitee.com/openharmony/third_party_skia)
512

README_zh.md

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)