• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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