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