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 "native_common_utils.h"
17
18 #include <set>
19 #include <algorithm>
20
21 #include "effect_log.h"
22 #include "efilter_factory.h"
23 #include "native_effect_base.h"
24 #include "pixelmap_native_impl.h"
25 #include "event_report.h"
26
27 namespace OHOS {
28 namespace Media {
29 namespace Effect {
30 static const std::map<IEffectFormat, ImageEffect_Format> FORMAT_TABLE = {
31 { IEffectFormat::RGBA8888, ImageEffect_Format::EFFECT_PIXEL_FORMAT_RGBA8888 },
32 { IEffectFormat::YUVNV12, ImageEffect_Format::EFFECT_PIXEL_FORMAT_NV12 },
33 { IEffectFormat::YUVNV21, ImageEffect_Format::EFFECT_PIXEL_FORMAT_NV21 },
34 { IEffectFormat::RGBA_1010102, ImageEffect_Format::EFFECT_PIXEL_FORMAT_RGBA1010102 },
35 { IEffectFormat::YCBCR_P010, ImageEffect_Format::EFFECT_PIXEL_FORMAT_YCBCR_P010 },
36 { IEffectFormat::YCRCB_P010, ImageEffect_Format::EFFECT_PIXEL_FORMAT_YCRCB_P010 }
37 };
38
39 static const std::unordered_map<std::string, std::unordered_map<std::string, uint32_t>> LOOK_UP_CAPABILITY = {
40 { "Format",
41 {
42 { "default", static_cast<uint32_t>(IEffectFormat::DEFAULT) },
43 { "rgba_8888", static_cast<uint32_t>(IEffectFormat::RGBA8888) },
44 { "nv21", static_cast<uint32_t>(IEffectFormat::YUVNV21) },
45 { "nv12", static_cast<uint32_t>(IEffectFormat::YUVNV12) },
46 }
47 },
48 };
49
50 static const std::map<IPType, ImageEffect_BufferType> IPTYPE_TABLE = {
51 { IPType::CPU, ImageEffect_BufferType::EFFECT_BUFFER_TYPE_PIXEL },
52 { IPType::GPU, ImageEffect_BufferType::EFFECT_BUFFER_TYPE_TEXTURE },
53 };
54
55 static const std::map<ErrorCode, ImageEffect_ErrorCode> ERRORCODE_TABLE = {
56 { ErrorCode::ERR_ALLOC_MEMORY_FAIL, ImageEffect_ErrorCode::EFFECT_ALLOCATE_MEMORY_FAILED },
57 { ErrorCode::ERR_NOT_SUPPORT_DIFF_DATATYPE, ImageEffect_ErrorCode::EFFECT_INPUT_OUTPUT_NOT_MATCH },
58 { ErrorCode::ERR_UNSUPPORTED_FORMAT_TYPE, ImageEffect_ErrorCode ::EFFECT_INPUT_OUTPUT_NOT_SUPPORTED },
59 { ErrorCode::ERR_NOT_SUPPORT_INPUT_OUTPUT_COLORSPACE, ImageEffect_ErrorCode::EFFECT_COLOR_SPACE_NOT_MATCH },
60 };
61
62 template <class ValueType>
AnyCastOHAny(const Plugin::Any & any,ImageEffect_DataType & ohDataType,ImageEffect_DataType ohDataTypeValue,ValueType & value)63 ErrorCode AnyCastOHAny(const Plugin::Any &any, ImageEffect_DataType &ohDataType, ImageEffect_DataType ohDataTypeValue,
64 ValueType &value)
65 {
66 auto result = Plugin::AnyCast<ValueType>(&any);
67 if (result == nullptr) {
68 return ErrorCode::ERR_ANY_CAST_TYPE_NOT_MATCH;
69 }
70 ohDataType = ohDataTypeValue;
71 value = *result;
72 return ErrorCode::SUCCESS;
73 }
74
ParseOHAny(const ImageEffect_Any * value,Plugin::Any & any)75 ErrorCode NativeCommonUtils::ParseOHAny(const ImageEffect_Any *value, Plugin::Any &any)
76 {
77 switch (value->dataType) {
78 case ImageEffect_DataType::EFFECT_DATA_TYPE_INT32:
79 any = value->dataValue.int32Value;
80 break;
81 case ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT:
82 any = value->dataValue.floatValue;
83 break;
84 case ImageEffect_DataType::EFFECT_DATA_TYPE_DOUBLE:
85 any = value->dataValue.doubleValue;
86 break;
87 case ImageEffect_DataType::EFFECT_DATA_TYPE_CHAR:
88 any = value->dataValue.charValue;
89 break;
90 case ImageEffect_DataType::EFFECT_DATA_TYPE_LONG:
91 any = value->dataValue.longValue;
92 break;
93 case ImageEffect_DataType::EFFECT_DATA_TYPE_BOOL:
94 any = value->dataValue.boolValue;
95 break;
96 case ImageEffect_DataType::EFFECT_DATA_TYPE_PTR:
97 any = value->dataValue.ptrValue;
98 break;
99 default:
100 EFFECT_LOGE("input any data type not support! dataType=%{public}d", value->dataType);
101 return ErrorCode::ERR_UNSUPPORTED_INPUT_ANYTYPE;
102 }
103 return ErrorCode::SUCCESS;
104 }
105
SwitchToOHAny(const Plugin::Any & any,ImageEffect_Any * value)106 ErrorCode NativeCommonUtils::SwitchToOHAny(const Plugin::Any &any, ImageEffect_Any *value)
107 {
108 CHECK_AND_RETURN_RET(AnyCastOHAny(any, value->dataType, ImageEffect_DataType::EFFECT_DATA_TYPE_INT32,
109 value->dataValue.int32Value) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
110 CHECK_AND_RETURN_RET(AnyCastOHAny(any, value->dataType, ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT,
111 value->dataValue.floatValue) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
112 CHECK_AND_RETURN_RET(AnyCastOHAny(any, value->dataType, ImageEffect_DataType::EFFECT_DATA_TYPE_DOUBLE,
113 value->dataValue.doubleValue) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
114 CHECK_AND_RETURN_RET(AnyCastOHAny(any, value->dataType, ImageEffect_DataType::EFFECT_DATA_TYPE_CHAR,
115 value->dataValue.charValue) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
116 CHECK_AND_RETURN_RET(AnyCastOHAny(any, value->dataType, ImageEffect_DataType::EFFECT_DATA_TYPE_LONG,
117 value->dataValue.longValue) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
118 CHECK_AND_RETURN_RET(AnyCastOHAny(any, value->dataType, ImageEffect_DataType::EFFECT_DATA_TYPE_PTR,
119 value->dataValue.ptrValue) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
120 CHECK_AND_RETURN_RET(AnyCastOHAny(any, value->dataType, ImageEffect_DataType::EFFECT_DATA_TYPE_BOOL,
121 value->dataValue.boolValue) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
122
123 #ifndef HST_ANY_WITH_NO_RTTI
124 EFFECT_LOGE("inner any type not support switch to oh_any! type:%{public}s", any.Type().name());
125 #else
126 EFFECT_LOGE("inner any type not support switch to oh_any! type:%{public}s", std::string(any.TypeName()).c_str());
127 #endif
128 return ErrorCode::ERR_NOT_SUPPORT_SWITCH_TO_OHANY;
129 }
130
SwitchToOHFormatType(const IEffectFormat & formatType,ImageEffect_Format & ohFormatType)131 void NativeCommonUtils::SwitchToOHFormatType(const IEffectFormat &formatType, ImageEffect_Format &ohFormatType)
132 {
133 auto it = FORMAT_TABLE.find(formatType);
134 if (it != FORMAT_TABLE.end()) {
135 ohFormatType = it->second;
136 } else {
137 ohFormatType = ImageEffect_Format::EFFECT_PIXEL_FORMAT_UNKNOWN;
138 }
139 }
140
SwitchToFormatType(const ImageEffect_Format & ohFormatType,IEffectFormat & formatType)141 void NativeCommonUtils::SwitchToFormatType(const ImageEffect_Format &ohFormatType, IEffectFormat &formatType)
142 {
143 auto formatIter = std::find_if(FORMAT_TABLE.begin(), FORMAT_TABLE.end(),
144 [&ohFormatType](const std::pair<IEffectFormat, ImageEffect_Format> &format) {
145 return format.second == ohFormatType;
146 });
147 if (formatIter != FORMAT_TABLE.end()) {
148 formatType = formatIter->first;
149 } else {
150 formatType = IEffectFormat::DEFAULT;
151 }
152 }
153
SwitchToOHBufferType(const IPType & ipType,ImageEffect_BufferType & ohBufferType)154 void SwitchToOHBufferType(const IPType &ipType, ImageEffect_BufferType &ohBufferType)
155 {
156 auto it = IPTYPE_TABLE.find(ipType);
157 if (it != IPTYPE_TABLE.end()) {
158 ohBufferType = it->second;
159 } else {
160 ohBufferType = ImageEffect_BufferType::EFFECT_BUFFER_TYPE_UNKNOWN;
161 }
162 }
163
SwitchToOHEffectInfo(const EffectInfo * effectInfo,OH_EffectFilterInfo * ohFilterInfo)164 void NativeCommonUtils::SwitchToOHEffectInfo(const EffectInfo *effectInfo, OH_EffectFilterInfo *ohFilterInfo)
165 {
166 CHECK_AND_RETURN_LOG(effectInfo != nullptr, "effectInfo is null!");
167 CHECK_AND_RETURN_LOG(ohFilterInfo != nullptr, "ohFilterInfo is null!");
168
169 ohFilterInfo->supportedBufferTypes.clear();
170 ohFilterInfo->supportedFormats.clear();
171 for (const auto &format : effectInfo->formats_) {
172 for (auto ipType : format.second) {
173 ImageEffect_BufferType bufferType = ImageEffect_BufferType::EFFECT_BUFFER_TYPE_UNKNOWN;
174 SwitchToOHBufferType(ipType, bufferType);
175 if (bufferType == ImageEffect_BufferType::EFFECT_BUFFER_TYPE_UNKNOWN) {
176 continue;
177 }
178 ohFilterInfo->supportedBufferTypes.emplace(bufferType);
179 }
180
181 ImageEffect_Format ohFormatType = ImageEffect_Format::EFFECT_PIXEL_FORMAT_UNKNOWN;
182 SwitchToOHFormatType(format.first, ohFormatType);
183 ohFilterInfo->supportedFormats.emplace(ohFormatType);
184 }
185 }
186
GetPixelMapFromOHPixelmap(OH_PixelmapNative * pixelmapNative)187 PixelMap *NativeCommonUtils::GetPixelMapFromOHPixelmap(OH_PixelmapNative *pixelmapNative)
188 {
189 CHECK_AND_RETURN_RET_LOG(pixelmapNative != nullptr, nullptr, "input pixelmapNative is null!");
190
191 std::shared_ptr<PixelMap> pixelMap = pixelmapNative->GetInnerPixelmap();
192 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "pixelMap is null!");
193
194 return pixelMap.get();
195 }
196
GetPictureFromNativePicture(OH_PictureNative * pictureNative)197 Picture *NativeCommonUtils::GetPictureFromNativePicture(OH_PictureNative *pictureNative)
198 {
199 CHECK_AND_RETURN_RET_LOG(pictureNative != nullptr, nullptr, "input pictureNative is null!");
200
201 std::shared_ptr<OHOS::Media::Picture> picture = pictureNative->GetInnerPicture();
202 CHECK_AND_RETURN_RET_LOG(picture != nullptr, nullptr, "GetPictureFromNativePicture: picture is null!");
203
204 return picture.get();
205 }
206
IsMatchLookupCondition(std::shared_ptr<EffectInfo> & effectInfo,std::string & type,uint32_t enumValue)207 bool IsMatchLookupCondition(std::shared_ptr<EffectInfo> &effectInfo, std::string &type, uint32_t enumValue)
208 {
209 if (type.compare("Format") == 0) {
210 auto formatType = static_cast<IEffectFormat>(enumValue);
211 if (formatType == IEffectFormat::DEFAULT) {
212 return true;
213 }
214
215 auto it = std::find_if(effectInfo->formats_.begin(), effectInfo->formats_.end(),
216 [&formatType](const std::pair<IEffectFormat, std::vector<IPType>> &format) {
217 return formatType == format.first;
218 });
219 return it != effectInfo->formats_.end();
220 } else {
221 return false;
222 }
223 }
224
IsMatchLookupCondition(std::shared_ptr<IFilterDelegate> & filterDelegate,std::string & type,uint32_t enumValue)225 bool IsMatchLookupCondition(std::shared_ptr<IFilterDelegate> &filterDelegate, std::string &type, uint32_t enumValue)
226 {
227 auto effectInfo = static_cast<OH_EffectFilterInfo *>(filterDelegate->GetEffectInfo());
228
229 if (type.compare("Format") == 0) {
230 auto formatType = static_cast<IEffectFormat>(enumValue);
231 if (formatType == IEffectFormat::DEFAULT) {
232 return true;
233 }
234 ImageEffect_Format ohFormatType = ImageEffect_Format::EFFECT_PIXEL_FORMAT_UNKNOWN;
235 NativeCommonUtils::SwitchToOHFormatType(formatType, ohFormatType);
236 return ohFormatType != ImageEffect_Format::EFFECT_PIXEL_FORMAT_UNKNOWN && effectInfo != nullptr &&
237 effectInfo->supportedFormats.find(ohFormatType) != effectInfo->supportedFormats.end();
238 } else {
239 return false;
240 }
241 }
242
ParseLookupKey(std::string & key,std::vector<const char * > & matchEFilter)243 void NativeCommonUtils::ParseLookupKey(std::string &key, std::vector<const char *> &matchEFilter)
244 {
245 auto pos = key.find(':');
246 CHECK_AND_RETURN_LOG(pos != std::string::npos, "key is invalid! key=%{public}s", key.c_str());
247
248 std::string type = key.substr(0, pos);
249 auto it = LOOK_UP_CAPABILITY.find(type);
250 CHECK_AND_RETURN_LOG(it != LOOK_UP_CAPABILITY.end(),
251 "type is invalid! key=%{public}s, type=%{public}s", key.c_str(), type.c_str());
252
253 std::string value = key.substr(pos + 1);
254 auto valueIterator = it->second.find(value);
255 CHECK_AND_RETURN_LOG(valueIterator != it->second.end(),
256 "value is invalid! key=%{public}s, type=%{public}s, value=%{public}s",
257 key.c_str(), type.c_str(), value.c_str());
258
259 std::vector<const char *> efilterNames;
260 EFilterFactory::Instance()->GetAllEffectNames(efilterNames);
261 std::shared_ptr<EffectInfo> effectInfo;
262 std::shared_ptr<IFilterDelegate> filterDelegate;
263 for (const auto &efilterName : efilterNames) {
264 // custom efilter
265 filterDelegate = EFilterFactory::Instance()->GetDelegate(efilterName);
266 if (filterDelegate != nullptr) {
267 if (IsMatchLookupCondition(filterDelegate, type, valueIterator->second)) {
268 matchEFilter.emplace_back(efilterName);
269 }
270 continue;
271 }
272
273 effectInfo = EFilterFactory::Instance()->GetEffectInfo(efilterName);
274 if (effectInfo == nullptr) {
275 EFFECT_LOGW("effectInfo is null! efilterName=%{public}s", efilterName);
276 continue;
277 }
278 if (IsMatchLookupCondition(effectInfo, type, valueIterator->second)) {
279 matchEFilter.emplace_back(efilterName);
280 }
281 }
282 }
283
SwitchToEffectInfo(const OH_EffectFilterInfo * info,const std::shared_ptr<EffectInfo> & effectInfo)284 void NativeCommonUtils::SwitchToEffectInfo(const OH_EffectFilterInfo *info,
285 const std::shared_ptr<EffectInfo> &effectInfo)
286 {
287 CHECK_AND_RETURN_LOG(info != nullptr, "SwitchToEffectInfo: info is null!");
288 effectInfo->category_ = Category::DEFAULT;
289 for (const auto &format: FORMAT_TABLE) {
290 ImageEffect_Format ohFormat = format.second;
291 if (ohFormat != ImageEffect_Format::EFFECT_PIXEL_FORMAT_UNKNOWN &&
292 info->supportedFormats.find(ohFormat) != info->supportedFormats.end()) {
293 effectInfo->formats_.emplace(format.first, std::vector<IPType>{ IPType::CPU });
294 }
295 }
296
297 // color space for custom filter
298 effectInfo->colorSpaces_.emplace_back(EffectColorSpace::SRGB);
299 effectInfo->colorSpaces_.emplace_back(EffectColorSpace::SRGB_LIMIT);
300 effectInfo->colorSpaces_.emplace_back(EffectColorSpace::DISPLAY_P3);
301 effectInfo->colorSpaces_.emplace_back(EffectColorSpace::DISPLAY_P3_LIMIT);
302 }
303
GetSupportedFormats(const OH_EffectFilterInfo * ohFilterInfo)304 uint32_t NativeCommonUtils::GetSupportedFormats(const OH_EffectFilterInfo *ohFilterInfo)
305 {
306 if (ohFilterInfo == nullptr) {
307 return 0;
308 }
309
310 uint32_t supportedFormats = 0;
311 auto formatBitLen = sizeof(supportedFormats);
312 for (auto format : ohFilterInfo->supportedFormats) {
313 if (format >= formatBitLen) {
314 continue;
315 }
316 supportedFormats |= (1 << format);
317 }
318
319 return supportedFormats;
320 }
321
ReportEventStartFailed(ImageEffect_ErrorCode errorCode,const char * errorMsg)322 void NativeCommonUtils::ReportEventStartFailed(ImageEffect_ErrorCode errorCode, const char *errorMsg)
323 {
324 EventInfo eventInfo = {
325 .errorInfo = {
326 .errorCode = errorCode,
327 .errorMsg = errorMsg,
328 }
329 };
330 EventReport::ReportHiSysEvent(RENDER_FAILED_FAULT, eventInfo);
331 }
332
ConvertStartResult(ErrorCode errorCode)333 ImageEffect_ErrorCode NativeCommonUtils::ConvertStartResult(ErrorCode errorCode)
334 {
335 auto iter = ERRORCODE_TABLE.find(errorCode);
336 if (iter == ERRORCODE_TABLE.end()) {
337 return ImageEffect_ErrorCode::EFFECT_UNKNOWN;
338 }
339 return iter->second;
340 }
341 } // namespace Effect
342 } // namespace Media
343 } // namespace OHOS