1 /*
2  * Copyright (C) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "vpe_helper.h"
17 
18 #include <dlfcn.h>
19 
20 #include "effect_log.h"
21 #include "error_code.h"
22 #include "external_window.h"
23 
24 namespace OHOS {
25 namespace Media {
26 namespace Effect {
27 using VpeColorSpaceConverterCreate = int32_t (*)(int32_t *);
28 using VpeColorSpaceConverterComposeImage =
29     int32_t (*)(int32_t, OHNativeWindowBuffer*, OHNativeWindowBuffer *, OHNativeWindowBuffer *, bool);
30 using VpeColorSpaceConverterDecomposeImage =
31     int32_t (*)(int32_t, OHNativeWindowBuffer *, OHNativeWindowBuffer *, OHNativeWindowBuffer *);
32 using VpeColorSpaceConverterProcessImage =
33     int32_t (*)(int32_t, OHNativeWindowBuffer *, OHNativeWindowBuffer *);
34 using VpeColorSpaceConverterDestroy = int32_t (*)(int32_t *);
35 
36 using VpeMetadataGeneratorCreate = int32_t (*)(int32_t *);
37 using VpeMetadataGeneratorProcessImage = int32_t (*)(int32_t, OHNativeWindowBuffer *);
38 using VpeMetadataGeneratorDestroy = int32_t (*)(int32_t *);
39 
40 class VpeHelper::Impl {
41 public:
42     VpeColorSpaceConverterCreate colorSpaceConverterCreate_ = nullptr;
43     VpeColorSpaceConverterComposeImage colorSpaceConverterComposeImage_ = nullptr;
44     VpeColorSpaceConverterDecomposeImage colorSpaceConverterDecomposeImage_ = nullptr;
45     VpeColorSpaceConverterProcessImage colorSpaceConverterProcessImage_ = nullptr;
46     VpeColorSpaceConverterDestroy colorSpaceConverterDestroy_ = nullptr;
47 
48     VpeMetadataGeneratorCreate metadataGeneratorCreate_ = nullptr;
49     VpeMetadataGeneratorProcessImage metadataGeneratorProcessImage_ = nullptr;
50     VpeMetadataGeneratorDestroy metadataGeneratorDestroy_ = nullptr;
51 };
52 
VpeHelper()53 VpeHelper::VpeHelper()
54 {
55     impl_ = std::make_shared<VpeHelper::Impl>();
56     LoadVpeSo();
57 }
58 
~VpeHelper()59 VpeHelper::~VpeHelper()
60 {
61     UnloadVpeSo();
62 }
63 
LoadVpeSo()64 void VpeHelper::LoadVpeSo()
65 {
66     EFFECT_LOGI("VpeHelper::LoadVpeSo enter!");
67     void *vpeHandle = dlopen("libvideoprocessingengine.z.so", RTLD_NOW);
68     if (vpeHandle == nullptr) {
69         EFFECT_LOGE("VpeHelper: dlopen libvideoprocessingengine.so failed! dlerror=%{public}s", dlerror());
70         return;
71     }
72     EFFECT_LOGI("VpeHelper: dlopen libvideoprocessingengine.so success!");
73 
74     vpeHandle_ = vpeHandle;
75     impl_->colorSpaceConverterCreate_ =
76         reinterpret_cast<VpeColorSpaceConverterCreate>(dlsym(vpeHandle, "ColorSpaceConverterCreate"));
77     impl_->colorSpaceConverterComposeImage_ =
78         reinterpret_cast<VpeColorSpaceConverterComposeImage>(dlsym(vpeHandle, "ColorSpaceConverterComposeImage"));
79     impl_->colorSpaceConverterDecomposeImage_ =
80         reinterpret_cast<VpeColorSpaceConverterDecomposeImage>(dlsym(vpeHandle, "ColorSpaceConverterDecomposeImage"));
81     impl_->colorSpaceConverterProcessImage_ =
82         reinterpret_cast<VpeColorSpaceConverterProcessImage>(dlsym(vpeHandle, "ColorSpaceConverterProcessImage"));
83     impl_->colorSpaceConverterDestroy_ =
84         reinterpret_cast<VpeColorSpaceConverterDestroy>(dlsym(vpeHandle, "ColorSpaceConverterDestroy"));
85 
86     impl_->metadataGeneratorCreate_ =
87         reinterpret_cast<VpeMetadataGeneratorCreate>(dlsym(vpeHandle, "MetadataGeneratorCreate"));
88     impl_->metadataGeneratorProcessImage_ =
89         reinterpret_cast<VpeMetadataGeneratorProcessImage>(dlsym(vpeHandle, "MetadataGeneratorProcessImage"));
90     impl_->metadataGeneratorDestroy_ =
91         reinterpret_cast<VpeMetadataGeneratorDestroy>(dlsym(vpeHandle, "MetadataGeneratorDestroy"));
92 }
93 
UnloadVpeSo()94 void VpeHelper::UnloadVpeSo()
95 {
96     if (vpeHandle_ != nullptr) {
97         dlclose(vpeHandle_);
98         vpeHandle_ = nullptr;
99     }
100 }
101 
GetInstance()102 VpeHelper &VpeHelper::GetInstance()
103 {
104     static VpeHelper instance;
105     return instance;
106 }
107 
ColorSpaceConverterCreate(int32_t * instance)108 int32_t VpeHelper::ColorSpaceConverterCreate(int32_t *instance)
109 {
110     VpeColorSpaceConverterCreate &createFunc = GetInstance().impl_->colorSpaceConverterCreate_;
111     CHECK_AND_RETURN_RET_LOG(instance != nullptr && createFunc != nullptr, (int32_t)ErrorCode::ERR_PARAM_INVALID,
112         "ColorSpaceConverterCreate: function is null!");
113 
114     return createFunc(instance);
115 }
116 
ColorSpaceConverterComposeImage(int32_t instance,sptr<SurfaceBuffer> & inputSdrImage,sptr<SurfaceBuffer> & inputGainmap,sptr<SurfaceBuffer> & outputHdrImage,bool legacy)117 int32_t VpeHelper::ColorSpaceConverterComposeImage(int32_t instance, sptr<SurfaceBuffer> &inputSdrImage,
118     sptr<SurfaceBuffer> &inputGainmap, sptr<SurfaceBuffer> &outputHdrImage, bool legacy)
119 {
120     VpeColorSpaceConverterComposeImage &composeImageFunc = GetInstance().impl_->colorSpaceConverterComposeImage_;
121     CHECK_AND_RETURN_RET_LOG(composeImageFunc != nullptr, (int32_t)ErrorCode::ERR_PARAM_INVALID,
122         "ColorSpaceConverterComposeImage: function is null!");
123     OHNativeWindowBuffer *sdr = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&inputSdrImage);
124     OHNativeWindowBuffer *gainmap = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&inputGainmap);
125     OHNativeWindowBuffer *hdr = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&outputHdrImage);
126     int32_t res = composeImageFunc(instance, sdr, gainmap, hdr, legacy);
127     OH_NativeWindow_DestroyNativeWindowBuffer(hdr);
128     OH_NativeWindow_DestroyNativeWindowBuffer(gainmap);
129     OH_NativeWindow_DestroyNativeWindowBuffer(sdr);
130     return res;
131 }
132 
ColorSpaceConverterDecomposeImage(int32_t instance,sptr<SurfaceBuffer> & inputImage,sptr<SurfaceBuffer> & outputSdrImage,sptr<SurfaceBuffer> & outputGainmap)133 int32_t VpeHelper::ColorSpaceConverterDecomposeImage(int32_t instance, sptr<SurfaceBuffer> &inputImage,
134     sptr<SurfaceBuffer> &outputSdrImage, sptr<SurfaceBuffer> &outputGainmap)
135 {
136     VpeColorSpaceConverterDecomposeImage &decomposeImageFunc = GetInstance().impl_->colorSpaceConverterDecomposeImage_;
137     CHECK_AND_RETURN_RET_LOG(decomposeImageFunc != nullptr, (int32_t)ErrorCode::ERR_PARAM_INVALID,
138         "ColorSpaceConverterDecomposeImage: function is null!");
139     OHNativeWindowBuffer *hdr = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&inputImage);
140     OHNativeWindowBuffer *sdr = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&outputSdrImage);
141     OHNativeWindowBuffer *gainmap = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&outputGainmap);
142     int32_t res = decomposeImageFunc(instance, hdr, sdr, gainmap);
143     OH_NativeWindow_DestroyNativeWindowBuffer(gainmap);
144     OH_NativeWindow_DestroyNativeWindowBuffer(sdr);
145     OH_NativeWindow_DestroyNativeWindowBuffer(hdr);
146     return res;
147 }
148 
ColorSpaceConverterProcessImage(int32_t instance,sptr<SurfaceBuffer> & inputImage,sptr<SurfaceBuffer> & outputSdrImage)149 int32_t VpeHelper::ColorSpaceConverterProcessImage(int32_t instance, sptr<SurfaceBuffer> &inputImage,
150     sptr<SurfaceBuffer> &outputSdrImage)
151 {
152     VpeColorSpaceConverterProcessImage &processImageFunc = GetInstance().impl_->colorSpaceConverterProcessImage_;
153     CHECK_AND_RETURN_RET_LOG(processImageFunc != nullptr, (int32_t)ErrorCode::ERR_PARAM_INVALID,
154         "ColorSpaceConverterProcessImage: function is null!");
155     OHNativeWindowBuffer *hdr = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&inputImage);
156     OHNativeWindowBuffer *sdr = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&outputSdrImage);
157     int32_t res = processImageFunc(instance, hdr, sdr);
158     OH_NativeWindow_DestroyNativeWindowBuffer(sdr);
159     OH_NativeWindow_DestroyNativeWindowBuffer(hdr);
160     return res;
161 }
162 
ColorSpaceConverterDestroy(int32_t * instance)163 int32_t VpeHelper::ColorSpaceConverterDestroy(int32_t *instance)
164 {
165     VpeColorSpaceConverterDestroy &destroyFunc = GetInstance().impl_->colorSpaceConverterDestroy_;
166     CHECK_AND_RETURN_RET_LOG(instance != nullptr && destroyFunc != nullptr, (int32_t)ErrorCode::ERR_PARAM_INVALID,
167         "ColorSpaceConverterDestroy: function is null!");
168 
169     EFFECT_LOGI("ColorSpaceConverterDestroy: instance=%{public}d", *instance);
170     return destroyFunc(instance);
171 }
172 
MetadataGeneratorCreate(int32_t * instance)173 int32_t VpeHelper::MetadataGeneratorCreate(int32_t *instance)
174 {
175     VpeMetadataGeneratorCreate &createFunc = GetInstance().impl_->metadataGeneratorCreate_;
176     CHECK_AND_RETURN_RET_LOG(instance != nullptr && createFunc != nullptr, (int32_t)ErrorCode::ERR_PARAM_INVALID,
177         "MetadataGeneratorCreate: function is null!");
178 
179     return createFunc(instance);
180 }
181 
MetadataGeneratorProcessImage(int32_t instance,sptr<SurfaceBuffer> & inputImage)182 int32_t VpeHelper::MetadataGeneratorProcessImage(int32_t instance, sptr<SurfaceBuffer> &inputImage)
183 {
184     VpeMetadataGeneratorProcessImage &processImage = GetInstance().impl_->metadataGeneratorProcessImage_;
185     CHECK_AND_RETURN_RET_LOG(processImage != nullptr, (int32_t)ErrorCode::ERR_PARAM_INVALID,
186         "MetadataGeneratorProcessImage: function is null!");
187     OHNativeWindowBuffer *input = OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer(&inputImage);
188     int32_t res = processImage(instance, input);
189     OH_NativeWindow_DestroyNativeWindowBuffer(input);
190     return res;
191 }
192 
MetadataGeneratorDestroy(int32_t * instance)193 int32_t VpeHelper::MetadataGeneratorDestroy(int32_t *instance)
194 {
195     VpeMetadataGeneratorDestroy &destroyFunc = GetInstance().impl_->metadataGeneratorDestroy_;
196     CHECK_AND_RETURN_RET_LOG(instance != nullptr && destroyFunc != nullptr, (int32_t)ErrorCode::ERR_PARAM_INVALID,
197         "MetadataGeneratorDestroy: function is null!");
198 
199     EFFECT_LOGI("MetadataGeneratorDestroy: instance=%{public}d", *instance);
200     return destroyFunc(instance);
201 }
202 
203 } // namespace Effect
204 } // namespace Media
205 } // namespace OHOS