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 "common_utils.h"
17
18 #include <charconv>
19
20 #include "effect_log.h"
21 #include "effect_buffer.h"
22 #include "uri.h"
23 #include "string_helper.h"
24 #include "memcpy_helper.h"
25 #include "colorspace_helper.h"
26 #include "render_environment.h"
27 #include "format_helper.h"
28 #include "exif_metadata.h"
29 #include "v1_1/buffer_handle_meta_key_type.h"
30 #include "surface_buffer.h"
31
32 namespace OHOS {
33 namespace Media {
34 namespace Effect {
35 namespace {
36 const std::string IMAGE_LENGTH = "ImageLength";
37 const std::string IMAGE_WIDTH = "ImageWidth";
38 const std::string DATE_TIME = "DateTime";
39 const std::string PIXEL_X_DIMENSION = "PixelXDimension";
40 const std::string PIXEL_Y_DIMENSION = "PixelYDimension";
41 const int32_t TIME_MAX = 64;
42 const int32_t YUV_PLANE_COUNT = 2;
43 const int32_t YUV_HALF = 2;
44 const int32_t P010_BYTES_PIXEL = 2;
45 }
46
47 using namespace OHOS::ColorManager;
48 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
49
50 const std::unordered_map<PixelFormat, IEffectFormat> CommonUtils::pixelFmtToEffectFmt_ = {
51 { PixelFormat::RGBA_8888, IEffectFormat::RGBA8888 },
52 { PixelFormat::NV21, IEffectFormat::YUVNV21 },
53 { PixelFormat::NV12, IEffectFormat::YUVNV12 },
54 { PixelFormat::RGBA_1010102, IEffectFormat::RGBA_1010102 },
55 { PixelFormat::YCBCR_P010, IEffectFormat::YCBCR_P010 },
56 { PixelFormat::YCRCB_P010, IEffectFormat::YCRCB_P010 },
57 { PixelFormat::RGBA_F16, IEffectFormat::RGBA_F16 },
58 };
59
60 const std::unordered_map<GraphicPixelFormat, IEffectFormat> CommonUtils::surfaceBufferFmtToEffectFmt_ = {
61 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_8888, IEffectFormat::RGBA8888},
62 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCBCR_420_SP, IEffectFormat::YUVNV12 },
63 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCRCB_420_SP, IEffectFormat::YUVNV21 },
64 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_1010102, IEffectFormat::RGBA_1010102 },
65 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCBCR_P010, IEffectFormat::YCBCR_P010 },
66 { GraphicPixelFormat::GRAPHIC_PIXEL_FMT_YCRCB_P010, IEffectFormat::YCRCB_P010 },
67 };
68
69 const std::unordered_map<GLenum, PixelFormat> CommonUtils::glFmtToPixelFmt_ = {
70 { GL_RGBA8, PixelFormat::RGBA_8888 },
71 { GL_RGB10_A2, PixelFormat::RGBA_1010102 },
72 };
73
74 const std::unordered_map<GLenum, IEffectFormat> CommonUtils::glFmtToEffectFmt_ = {
75 { GL_RGBA8, IEffectFormat::RGBA8888 },
76 { GL_RGB10_A2, IEffectFormat::RGBA_1010102 },
77 };
78
79 const std::unordered_map<AllocatorType, BufferType> CommonUtils::allocatorTypeToEffectBuffType_ = {
80 { AllocatorType::HEAP_ALLOC, BufferType::HEAP_MEMORY },
81 { AllocatorType::DMA_ALLOC, BufferType::DMA_BUFFER },
82 { AllocatorType::SHARE_MEM_ALLOC, BufferType::SHARED_MEMORY },
83 };
84
85 const std::unordered_map<EffectPixelmapType, AuxiliaryPictureType> EffectPixelmapTypeToAuxPicType_ = {
86 { EffectPixelmapType::UNKNOWN, AuxiliaryPictureType::NONE },
87 { EffectPixelmapType::PRIMARY, AuxiliaryPictureType::NONE },
88 { EffectPixelmapType::GAINMAP, AuxiliaryPictureType::GAINMAP },
89 { EffectPixelmapType::DEPTHMAP, AuxiliaryPictureType::DEPTH_MAP },
90 { EffectPixelmapType::UNREFOCUS, AuxiliaryPictureType::UNREFOCUS_MAP },
91 { EffectPixelmapType::WATERMARK_CUT, AuxiliaryPictureType::NONE },
92 { EffectPixelmapType::LINEAR, AuxiliaryPictureType::LINEAR_MAP },
93 };
94
95 std::vector<std::string> FILE_TYPE_SUPPORT_TABLE = {"image/heic", "image/heif", "image/jpeg"};
96 std::vector<EffectPixelmapType> AUX_MAP_TYPE_LIST = {
97 EffectPixelmapType::GAINMAP,
98 EffectPixelmapType::DEPTHMAP,
99 EffectPixelmapType::UNREFOCUS,
100 EffectPixelmapType::LINEAR,
101 };
102
103 std::vector<int32_t> HDR_P010_LIST = {
104 GRAPHIC_PIXEL_FMT_YCBCR_P010,
105 GRAPHIC_PIXEL_FMT_YCRCB_P010,
106 };
107
108 template <class ValueType>
ParseJson(const std::string & key,Any & any,EffectJsonPtr & json)109 ErrorCode ParseJson(const std::string &key, Any &any, EffectJsonPtr &json)
110 {
111 auto result = AnyCast<ValueType>(&any);
112 if (result == nullptr) {
113 return ErrorCode::ERR_ANY_CAST_TYPE_NOT_MATCH;
114 }
115
116 json->Put(key, *result);
117 return ErrorCode::SUCCESS;
118 }
119
CreateExtraInfo(PixelMap * pixelMap)120 std::shared_ptr<ExtraInfo> CreateExtraInfo(PixelMap* pixelMap)
121 {
122 BufferType bufferType = CommonUtils::SwitchToEffectBuffType(pixelMap->GetAllocatorType());
123 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
124 extraInfo->dataType = DataType::PIXEL_MAP;
125 extraInfo->bufferType = bufferType;
126 EFFECT_LOGI("pixelMap extraInfos: dataType=%{public}d, bufferType=%{public}d",
127 extraInfo->dataType, extraInfo->bufferType);
128 return extraInfo;
129 }
130
CopyBufferInfo(const BufferInfo & src,BufferInfo & dst)131 void CommonUtils::CopyBufferInfo(const BufferInfo& src, BufferInfo& dst)
132 {
133 dst.width_ = src.width_;
134 dst.height_ = src.height_;
135 dst.len_ = src.len_;
136 dst.hdrFormat_ = src.hdrFormat_;
137 dst.formatType_ = src.formatType_;
138 dst.colorSpace_ = src.colorSpace_;
139 dst.rowStride_ = src.rowStride_;
140 dst.bufferType_ = src.bufferType_;
141 dst.pixelmapType_ = src.pixelmapType_;
142 dst.surfaceBuffer_ = src.surfaceBuffer_;
143 dst.fd_ = src.fd_;
144 dst.pixelMap_ = src.pixelMap_;
145 dst.tex_ = src.tex_;
146 dst.addr_ = src.addr_;
147 }
148
CopyExtraInfo(const ExtraInfo & src,ExtraInfo & dst)149 void CommonUtils::CopyExtraInfo(const ExtraInfo& src, ExtraInfo& dst)
150 {
151 dst.dataType = src.dataType;
152 dst.bufferType = src.bufferType;
153 dst.uri = src.uri;
154 dst.path = src.path;
155 dst.timestamp = src.timestamp;
156 dst.picture = src.picture;
157 dst.innerPixelMap = src.innerPixelMap;
158 dst.innerPicture = src.innerPicture;
159 }
160
CopyAuxiliaryBufferInfos(const EffectBuffer * src,EffectBuffer * dst)161 void CommonUtils::CopyAuxiliaryBufferInfos(const EffectBuffer *src, EffectBuffer *dst)
162 {
163 if (src->auxiliaryBufferInfos == nullptr) {
164 EFFECT_LOGD("CopyAuxiliaryBufferInfos: src auxiliaryBufferInfos is null");
165 return;
166 }
167 dst->auxiliaryBufferInfos =
168 std::make_unique<std::unordered_map<EffectPixelmapType, std::shared_ptr<BufferInfo>>>();
169 for (const auto &entry : *src->auxiliaryBufferInfos) {
170 std::shared_ptr<BufferInfo> auxiliaryBufferInfo = std::make_shared<BufferInfo>();
171 CopyBufferInfo(*(entry.second), *auxiliaryBufferInfo);
172 dst->auxiliaryBufferInfos->emplace(entry.first, auxiliaryBufferInfo);
173 }
174 }
175
GetMetaData(SurfaceBuffer * surfaceBuffer)176 MetaDataMap CommonUtils::GetMetaData(SurfaceBuffer* surfaceBuffer)
177 {
178 std::unordered_map<uint32_t, std::vector<uint8_t>> metadataMap;
179 std::vector<uint32_t> keys = {};
180 surfaceBuffer->ListMetadataKeys(keys);
181 EFFECT_LOGD("CommonUtils::GetMetaData: keys length = %{public}d", static_cast<int>(keys.size()));
182
183 for (const auto key : keys) {
184 std::vector<uint8_t> values;
185 auto ret = surfaceBuffer->GetMetadata(key, values);
186 if (ret != 0) {
187 EFFECT_LOGE("GetMetadata fail! key = %{public}d res = %{public}d", key, ret);
188 continue;
189 }
190
191 metadataMap.emplace(key, std::move(values));
192 }
193
194 return metadataMap;
195 }
196
SetMetaData(MetaDataMap & metaData,SurfaceBuffer * surfaceBuffer)197 void CommonUtils::SetMetaData(MetaDataMap& metaData, SurfaceBuffer* surfaceBuffer)
198 {
199 EFFECT_LOGD("CommonUtils::SetMetaData");
200 CHECK_AND_RETURN_LOG(surfaceBuffer != nullptr, "CommonUtils::SetMetaData: surfaceBuffer is null!");
201
202 for (const auto& [key, values] : metaData) {
203 GSError ret = surfaceBuffer->SetMetadata(key, values);
204 if (ret != 0) {
205 EFFECT_LOGE("SetMetadata failed! key = %{public}d, res = %{public}d", key, ret);
206 }
207 }
208 }
209
ParsePixelMapData(PixelMap * pixelMap,std::shared_ptr<EffectBuffer> & effectBuffer)210 ErrorCode CommonUtils::ParsePixelMapData(PixelMap *pixelMap, std::shared_ptr<EffectBuffer> &effectBuffer)
211 {
212 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INPUT_NULL, "pixelMap is null!");
213 ColorSpaceName colorSpaceName = pixelMap->InnerGetGrColorSpacePtr() == nullptr ? ColorSpaceName::NONE :
214 pixelMap->InnerGetGrColorSpacePtr()->GetColorSpaceName();
215 EFFECT_LOGD("pixelMapInfos::colorSpaceName = %{public}d", colorSpaceName);
216
217 IEffectFormat formatType = SwitchToEffectFormat(pixelMap->GetPixelFormat());
218 CHECK_AND_RETURN_RET_LOG(formatType != IEffectFormat::DEFAULT, ErrorCode::ERR_UNSUPPORTED_PIXEL_FORMAT,
219 "pixelFormat not support! pixelFormat=%{public}d", pixelMap->GetPixelFormat());
220
221 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
222 bufferInfo->width_ = static_cast<uint32_t>(pixelMap->GetWidth());
223 bufferInfo->height_ = static_cast<uint32_t>(pixelMap->GetHeight());
224 if (pixelMap->GetPixelFormat() == PixelFormat::NV21 ||
225 pixelMap->GetPixelFormat() == PixelFormat::NV12) {
226 YUVDataInfo info;
227 pixelMap->GetImageYUVInfo(info);
228 bufferInfo->rowStride_ = info.yStride;
229 } else if (pixelMap->GetPixelFormat() == PixelFormat::YCRCB_P010 ||
230 pixelMap->GetPixelFormat() == PixelFormat::YCBCR_P010) {
231 YUVDataInfo info;
232 pixelMap->GetImageYUVInfo(info);
233 bufferInfo->rowStride_ = info.yStride * P010_BYTES_PIXEL;
234 } else {
235 bufferInfo->rowStride_ = static_cast<uint32_t>(pixelMap->GetRowStride());
236 }
237 bufferInfo->len_ = (formatType == IEffectFormat::RGBA8888 || formatType == IEffectFormat::RGBA_1010102 ||
238 formatType == IEffectFormat::RGBA_F16) ? bufferInfo->height_ * bufferInfo->rowStride_ :
239 FormatHelper::CalculateSize(bufferInfo->rowStride_, bufferInfo->height_, formatType);
240 bufferInfo->formatType_ = formatType;
241 bufferInfo->colorSpace_ = ColorSpaceHelper::ConvertToEffectColorSpace(colorSpaceName);
242 bufferInfo->hdrFormat_ = formatType == IEffectFormat::RGBA_1010102 ? HdrFormat::HDR10 : bufferInfo->hdrFormat_;
243 BufferType bufferType = CommonUtils::SwitchToEffectBuffType(pixelMap->GetAllocatorType());
244 bufferInfo->bufferType_ = bufferType;
245 bufferInfo->surfaceBuffer_ = nullptr;
246 bufferInfo->pixelMap_ = pixelMap;
247 if (bufferType == BufferType::DMA_BUFFER && pixelMap->GetFd() != nullptr) {
248 bufferInfo->surfaceBuffer_ = reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd());
249 bufferInfo->len_ = bufferInfo->surfaceBuffer_->GetSize();
250 }
251 if (bufferType == BufferType::SHARED_MEMORY && pixelMap->GetFd() != nullptr) {
252 bufferInfo->fd_ = reinterpret_cast<int*>(pixelMap->GetFd());
253 }
254 uint8_t *pixels = const_cast<uint8_t *>(pixelMap->GetPixels());
255 void *srcData = static_cast<void *>(pixels);
256 CHECK_AND_RETURN_RET_LOG(srcData != nullptr, ErrorCode::ERR_PIXELMAP_ACCESSPIXELS_FAIL, "fail exec GetPixels!");
257 std::shared_ptr<ExtraInfo> extraInfo = CreateExtraInfo(pixelMap);
258 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, srcData, extraInfo);
259 return ErrorCode::SUCCESS;
260 }
261
LockPixelMap(PixelMap * pixelMap,std::shared_ptr<EffectBuffer> & effectBuffer)262 ErrorCode CommonUtils::LockPixelMap(PixelMap *pixelMap, std::shared_ptr<EffectBuffer> &effectBuffer)
263 {
264 EFFECT_LOGD("pixelMapInfos: width=%{public}d, height=%{public}d, formatType=%{public}d " \
265 "rowStride=%{public}d, byteCount=%{public}d, addr=%{private}p",
266 pixelMap->GetWidth(), pixelMap->GetHeight(), pixelMap->GetPixelFormat(), pixelMap->GetRowStride(),
267 pixelMap->GetByteCount(), pixelMap->GetPixels());
268 auto res = ParsePixelMapData(pixelMap, effectBuffer);
269 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "LockPixelMap::ParsePixelMapData fail! %{public}d", res);
270
271 auto bufferInfo = effectBuffer->bufferInfo_;
272 EFFECT_LOGI("pixelMap bufferInfos: width=%{public}d, height=%{public}d, formatType=%{public}d, " \
273 "rowStride_=%{public}d, len=%{public}d, colorspace=%{public}d, addr=%{private}p",
274 bufferInfo->width_, bufferInfo->height_, bufferInfo->formatType_, bufferInfo->rowStride_,
275 bufferInfo->len_, bufferInfo->colorSpace_, effectBuffer->buffer_);
276
277 EFFECT_LOGI("pixelMap extraInfos: dataType=%{public}d, bufferType=%{public}d",
278 effectBuffer->extraInfo_->dataType, effectBuffer->extraInfo_->bufferType);
279
280 if (effectBuffer->bufferInfo_->surfaceBuffer_ != nullptr) {
281 SurfaceBuffer *sb = effectBuffer->bufferInfo_->surfaceBuffer_;
282 EFFECT_LOGD("pixelMap surfaceBufferInfo: width=%{public}d, height=%{public}d, format=%{public}d, "
283 "rowStride=%{public}d, size=%{public}d, addr=%{private}p", sb->GetWidth(),
284 sb->GetHeight(), sb->GetFormat(), sb->GetStride(), sb->GetSize(), sb->GetVirAddr());
285 }
286
287 return ErrorCode::SUCCESS;
288 }
289
ParseNativeWindowData(std::shared_ptr<EffectBuffer> & effectBuffer,const DataType & dataType)290 ErrorCode CommonUtils::ParseNativeWindowData(std::shared_ptr<EffectBuffer> &effectBuffer, const DataType &dataType)
291 {
292 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
293 bufferInfo->width_ = 0;
294 bufferInfo->height_ = 0;
295 bufferInfo->rowStride_ = 0;
296 bufferInfo->len_ = 0;
297 bufferInfo->formatType_ = IEffectFormat::DEFAULT;
298 bufferInfo->surfaceBuffer_ = nullptr;
299 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
300 extraInfo->dataType = dataType;
301 extraInfo->bufferType = BufferType::DMA_BUFFER;
302 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, nullptr, extraInfo);
303 return ErrorCode::SUCCESS;
304 }
305
ParseSurfaceData(OHOS::SurfaceBuffer * surfaceBuffer,std::shared_ptr<EffectBuffer> & effectBuffer,const DataType & dataType,LOG_STRATEGY strategy,int64_t timestamp)306 ErrorCode CommonUtils::ParseSurfaceData(OHOS::SurfaceBuffer *surfaceBuffer,
307 std::shared_ptr<EffectBuffer> &effectBuffer, const DataType &dataType, LOG_STRATEGY strategy, int64_t timestamp)
308 {
309 CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, ErrorCode::ERR_INPUT_NULL, "surfaceBuffer is null!");
310
311 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
312 bufferInfo->width_ = static_cast<uint32_t>(surfaceBuffer->GetWidth());
313 bufferInfo->height_ = static_cast<uint32_t>(surfaceBuffer->GetHeight());
314 bufferInfo->rowStride_ = static_cast<uint32_t>(surfaceBuffer->GetStride());
315 bufferInfo->len_ = surfaceBuffer->GetSize();
316 bufferInfo->formatType_ = SwitchToEffectFormat((GraphicPixelFormat)surfaceBuffer->GetFormat());
317 CM_ColorSpaceType colorSpaceType = CM_ColorSpaceType::CM_COLORSPACE_NONE;
318 ColorSpaceHelper::GetSurfaceBufferColorSpaceType(surfaceBuffer, colorSpaceType);
319 bufferInfo->colorSpace_ = ColorSpaceHelper::ConvertToEffectColorSpace(colorSpaceType);
320 bufferInfo->surfaceBuffer_ = surfaceBuffer;
321
322 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
323 extraInfo->dataType = dataType;
324 extraInfo->bufferType = BufferType::DMA_BUFFER;
325 extraInfo->timestamp = timestamp;
326
327 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, surfaceBuffer->GetVirAddr(), extraInfo);
328 EFFECT_LOGI_WITH_STRATEGY(strategy,
329 "surfaceBuffer width=%{public}d, height=%{public}d, stride=%{public}d, format=%{public}d, "
330 "size=%{public}d, usage = %{public}llu, addr=%{private}p, colorSpace=%{public}d",
331 surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), surfaceBuffer->GetStride(), surfaceBuffer->GetFormat(),
332 surfaceBuffer->GetSize(), static_cast<unsigned long long>(surfaceBuffer->GetUsage()),
333 surfaceBuffer->GetVirAddr(), colorSpaceType);
334 return ErrorCode::SUCCESS;
335 }
336
UrlToPath(const std::string & url)337 std::string CommonUtils::UrlToPath(const std::string &url)
338 {
339 OHOS::Uri uri = OHOS::Uri(url);
340 return uri.GetPath();
341 }
342
ParseUri(std::string & uri,std::shared_ptr<EffectBuffer> & effectBuffer,bool isOutputData,IEffectFormat format)343 ErrorCode CommonUtils::ParseUri(std::string &uri, std::shared_ptr<EffectBuffer> &effectBuffer, bool isOutputData,
344 IEffectFormat format)
345 {
346 if (isOutputData) {
347 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
348 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
349 extraInfo->dataType = DataType::URI;
350 extraInfo->uri = std::move(uri);
351 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, nullptr, extraInfo);
352 return ErrorCode::SUCCESS;
353 }
354
355 auto path = UrlToPath(uri);
356 ErrorCode res = ParsePath(path, effectBuffer, isOutputData, format);
357 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res,
358 "ParseUri: path name fail! uri=%{public}s, res=%{public}d", uri.c_str(), res);
359
360 CHECK_AND_RETURN_RET_LOG(effectBuffer->extraInfo_ != nullptr, ErrorCode::ERR_EXTRA_INFO_NULL,
361 "ParseUri: extra info is null! uri=%{public}s", uri.c_str());
362 effectBuffer->extraInfo_->dataType = DataType::URI;
363 effectBuffer->extraInfo_->uri = std::move(uri);
364
365 return ErrorCode::SUCCESS;
366 }
367
ParsePath(std::string & path,std::shared_ptr<EffectBuffer> & effectBuffer,bool isOutputData,IEffectFormat format)368 ErrorCode CommonUtils::ParsePath(std::string &path, std::shared_ptr<EffectBuffer> &effectBuffer,
369 bool isOutputData, IEffectFormat format)
370 {
371 if (isOutputData) {
372 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
373 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
374 extraInfo->dataType = DataType::PATH;
375 extraInfo->path = std::move(path);
376 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, nullptr, extraInfo);
377 return ErrorCode::SUCCESS;
378 }
379
380 SourceOptions opts;
381 uint32_t errorCode = 0;
382 std::unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(path, opts, errorCode);
383 CHECK_AND_RETURN_RET_LOG(imageSource != nullptr, ErrorCode::ERR_CREATE_IMAGESOURCE_FAIL,
384 "ImageSource::CreateImageSource fail! path=%{public}s, errorCode=%{public}d", path.c_str(), errorCode);
385
386 ImageInfo info;
387 uint32_t ret = imageSource->GetImageInfo(info);
388 CHECK_AND_RETURN_RET_LOG(ret == 0, ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT, "imageSource get image info fail!");
389 std::string encodedFormat = info.encodedFormat;
390 if (std::find(FILE_TYPE_SUPPORT_TABLE.begin(), FILE_TYPE_SUPPORT_TABLE.end(), encodedFormat) ==
391 FILE_TYPE_SUPPORT_TABLE.end()) {
392 EFFECT_LOGE("ParsePath: encodedFormat not support! encodedFormat=%{public}s", encodedFormat.c_str());
393 return ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT;
394 }
395
396 DecodingOptionsForPicture options;
397 options.desiredPixelFormat = CommonUtils::SwitchToPixelFormat(format);
398 EFFECT_LOGD("CommonUtils::ParsePath. PixelFormat=%{public}d, encodedFormat=%{public}s", options.desiredPixelFormat,
399 encodedFormat.c_str());
400 std::unique_ptr<Picture> picture = imageSource->CreatePicture(options, errorCode);
401 CHECK_AND_RETURN_RET_LOG(picture != nullptr, ErrorCode::ERR_CREATE_PICTURE_FAIL,
402 "CreatePicture fail! path=%{public}s, errorCode=%{public}d", path.c_str(), errorCode);
403
404 ErrorCode res = ParsePicture(picture.get(), effectBuffer);
405 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res,
406 "ParsePath: parse picture fail! path=%{public}s, res=%{public}d", path.c_str(), res);
407
408 CHECK_AND_RETURN_RET_LOG(effectBuffer->extraInfo_ != nullptr, ErrorCode::ERR_EXTRA_INFO_NULL,
409 "ParsePath: extra info is null! uri=%{public}s", path.c_str());
410 effectBuffer->extraInfo_->dataType = DataType::PATH;
411 effectBuffer->extraInfo_->path = std::move(path);
412 effectBuffer->extraInfo_->picture = nullptr;
413 effectBuffer->extraInfo_->innerPicture = std::move(picture);
414
415 return ErrorCode::SUCCESS;
416 }
417
SwitchToEffectFormat(GraphicPixelFormat pixelFormat)418 IEffectFormat CommonUtils::SwitchToEffectFormat(GraphicPixelFormat pixelFormat)
419 {
420 IEffectFormat formatType = IEffectFormat::DEFAULT;
421
422 auto itr = surfaceBufferFmtToEffectFmt_.find(pixelFormat);
423 if (itr != surfaceBufferFmtToEffectFmt_.end()) {
424 formatType = itr->second;
425 }
426
427 return formatType;
428 }
429
SwitchToEffectFormat(PixelFormat pixelFormat)430 IEffectFormat CommonUtils::SwitchToEffectFormat(PixelFormat pixelFormat)
431 {
432 IEffectFormat formatType = IEffectFormat::DEFAULT;
433
434 auto itr = pixelFmtToEffectFmt_.find(pixelFormat);
435 if (itr != pixelFmtToEffectFmt_.end()) {
436 formatType = itr->second;
437 }
438
439 return formatType;
440 }
441
SwitchToGraphicPixelFormat(IEffectFormat formatType)442 GraphicPixelFormat CommonUtils::SwitchToGraphicPixelFormat(IEffectFormat formatType)
443 {
444 GraphicPixelFormat pixelFormat = GraphicPixelFormat::GRAPHIC_PIXEL_FMT_BUTT;
445
446 for (const auto &itr : surfaceBufferFmtToEffectFmt_) {
447 if (itr.second == formatType) {
448 pixelFormat = itr.first;
449 break;
450 }
451 }
452
453 return pixelFormat;
454 }
455
SwitchToPixelFormat(IEffectFormat formatType)456 PixelFormat CommonUtils::SwitchToPixelFormat(IEffectFormat formatType)
457 {
458 PixelFormat pixelFormat = PixelFormat::UNKNOWN;
459
460 for (const auto &itr : pixelFmtToEffectFmt_) {
461 if (itr.second == formatType) {
462 pixelFormat = itr.first;
463 break;
464 }
465 }
466
467 return pixelFormat;
468 }
469
SwitchGLFormatToEffectFormat(GLenum formatType)470 IEffectFormat CommonUtils::SwitchGLFormatToEffectFormat(GLenum formatType)
471 {
472 IEffectFormat effectFormat = IEffectFormat::DEFAULT;
473
474 for (const auto &itr : glFmtToEffectFmt_) {
475 if (itr.first == formatType) {
476 effectFormat = itr.second;
477 break;
478 }
479 }
480
481 return effectFormat;
482 }
483
SwitchGLFormatToPixelFormat(GLenum formatType)484 PixelFormat CommonUtils::SwitchGLFormatToPixelFormat(GLenum formatType)
485 {
486 PixelFormat pixelFormat = PixelFormat::UNKNOWN;
487
488 for (const auto &itr : glFmtToPixelFmt_) {
489 if (itr.first == formatType) {
490 pixelFormat = itr.second;
491 break;
492 }
493 }
494
495 return pixelFormat;
496 }
497
SwitchToEffectBuffType(AllocatorType allocatorType)498 BufferType CommonUtils::SwitchToEffectBuffType(AllocatorType allocatorType)
499 {
500 BufferType bufferType = BufferType::DEFAULT;
501
502 auto itr = allocatorTypeToEffectBuffType_.find(allocatorType);
503 if (itr != allocatorTypeToEffectBuffType_.end()) {
504 bufferType = itr->second;
505 }
506
507 return bufferType;
508 }
509
UnlockPixelMap(const PixelMap * pixelMap)510 void CommonUtils::UnlockPixelMap(const PixelMap *pixelMap)
511 {
512 EFFECT_LOGI("UnlockPixelMap!");
513 }
514
ParseAnyAndAddToJson(const std::string & key,Any & any,EffectJsonPtr & result)515 ErrorCode CommonUtils::ParseAnyAndAddToJson(const std::string &key, Any &any, EffectJsonPtr &result)
516 {
517 CHECK_AND_RETURN_RET(ParseJson<float>(key, any, result) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
518 CHECK_AND_RETURN_RET(ParseJson<int32_t>(key, any, result) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
519 CHECK_AND_RETURN_RET(ParseJson<uint32_t>(key, any, result) != ErrorCode::SUCCESS, ErrorCode::SUCCESS);
520 #ifndef HST_ANY_WITH_NO_RTTI
521 EFFECT_LOGE("inner any type not support switch to json! type:%{public}s", any.Type().name());
522 #else
523 EFFECT_LOGE("inner any type not support switch to json! type:%{public}s", std::string(any.TypeName()).c_str());
524 #endif
525 return ErrorCode::ERR_ANY_CAST_TYPE_NOT_MATCH;
526 }
527
EndsWithJPG(const std::string & input)528 bool CommonUtils::EndsWithJPG(const std::string &input)
529 {
530 return StringHelp::EndsWithIgnoreCase(input, "jpg") || StringHelp::EndsWithIgnoreCase(input, "jpeg");
531 }
532
EndsWithHEIF(const std::string & input)533 bool CommonUtils::EndsWithHEIF(const std::string &input)
534 {
535 return StringHelp::EndsWithIgnoreCase(input, "heic");
536 }
537
GetPixelsContext(std::shared_ptr<MemoryData> & memoryData,BufferType bufferType,void ** context)538 ErrorCode GetPixelsContext(std::shared_ptr<MemoryData> &memoryData, BufferType bufferType, void **context)
539 {
540 switch (bufferType) {
541 case BufferType::HEAP_MEMORY:
542 *context = nullptr;
543 break;
544 case BufferType::DMA_BUFFER: {
545 void *extra = memoryData->memoryInfo.extra;
546 auto surfaceBuffer = reinterpret_cast<SurfaceBuffer *>(extra);
547 CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, ErrorCode::ERR_INVALID_SURFACE_BUFFER,
548 "DMA_BUFFER: extra info error!");
549 *context = surfaceBuffer;
550 break;
551 }
552 case BufferType::SHARED_MEMORY: {
553 void *extra = memoryData->memoryInfo.extra;
554 auto fd = static_cast<int *>(extra);
555 CHECK_AND_RETURN_RET_LOG(fd != nullptr, ErrorCode::ERR_INVALID_FD, "SHARED_MEMORY: extra info error!");
556 *context = fd;
557 break;
558 }
559 default:
560 EFFECT_LOGE("bufferType not support! bufferType=%{public}d", bufferType);
561 return ErrorCode::ERR_UNSUPPORTED_BUFFER_TYPE;
562 }
563 return ErrorCode::SUCCESS;
564 }
565
GetImagePropertyInt(const std::shared_ptr<ExifMetadata> & exifMetadata,const std::string & key,int32_t & value)566 int32_t GetImagePropertyInt(const std::shared_ptr<ExifMetadata> &exifMetadata, const std::string &key, int32_t &value)
567 {
568 std::string strValue;
569 int ret = exifMetadata->GetValue(key, strValue);
570 if (ret != 0) {
571 return ret;
572 }
573
574 std::from_chars_result res = std::from_chars(strValue.data(), strValue.data() + strValue.size(), value);
575 if (res.ec != std::errc()) {
576 return static_cast<int32_t>(ErrorCode::ERR_IMAGE_DATA);
577 }
578
579 return 0;
580 }
581
PrintImageExifInfo(const std::shared_ptr<ExifMetadata> & exifMetadata,const std::string & tag)582 void PrintImageExifInfo(const std::shared_ptr<ExifMetadata> &exifMetadata, const std::string &tag)
583 {
584 if (exifMetadata == nullptr) {
585 return;
586 }
587
588 int32_t width = 0;
589 GetImagePropertyInt(exifMetadata, IMAGE_WIDTH, width);
590 int32_t length = 0;
591 GetImagePropertyInt(exifMetadata, IMAGE_LENGTH, length);
592 std::string dateTime;
593 exifMetadata->GetValue(DATE_TIME, dateTime);
594 int32_t xDimension = 0;
595 GetImagePropertyInt(exifMetadata, PIXEL_X_DIMENSION, xDimension);
596 int32_t yDimension = 0;
597 GetImagePropertyInt(exifMetadata, PIXEL_Y_DIMENSION, yDimension);
598
599 EFFECT_LOGD("%{public}s: width=%{public}d, length=%{public}d, dateTime=%{public}s, xDimension=%{public}d, "
600 "yDimension=%{public}d", tag.c_str(), width, length, dateTime.c_str(), xDimension, yDimension);
601 }
602
UpdateExifDataTime(const std::shared_ptr<ExifMetadata> & exifMetadata)603 void UpdateExifDataTime(const std::shared_ptr<ExifMetadata> &exifMetadata)
604 {
605 CHECK_AND_RETURN_LOG(exifMetadata != nullptr, "UpdateExifDataTime: exifMetadata is null!");
606
607 std::string dateTime;
608 if (exifMetadata->GetValue(DATE_TIME, dateTime) != 0 || dateTime.empty()) {
609 return;
610 }
611
612 time_t now = time(nullptr);
613 CHECK_AND_RETURN_LOG(now > 0, "UpdateExifDateTime: time fail!");
614
615 struct tm *locTime = localtime(&now);
616 CHECK_AND_RETURN_LOG(locTime != nullptr, "UpdateExifDateTime: localtime fail!");
617
618 char tempTime[TIME_MAX];
619 auto size = strftime(tempTime, sizeof(tempTime), "%Y:%m:%d %H:%M:%S", locTime);
620 CHECK_AND_RETURN_LOG(size > 0, "UpdateExifDateTime: strftime fail!");
621
622 std::string currentTime = std::string(tempTime, size);
623 bool res = exifMetadata->SetValue(DATE_TIME, currentTime);
624 CHECK_AND_RETURN_LOG(res, "UpdateExifDataTime: setValue fail!");
625 }
626
UpdateImageExifDateTime(PixelMap * pixelMap)627 void CommonUtils::UpdateImageExifDateTime(PixelMap *pixelMap)
628 {
629 CHECK_AND_RETURN_LOG(pixelMap != nullptr, "UpdateImageExifDateTime: pixelMap is null!");
630
631 UpdateExifDataTime(pixelMap->GetExifMetadata());
632 }
633
UpdateImageExifDateTime(Picture * picture)634 void CommonUtils::UpdateImageExifDateTime(Picture *picture)
635 {
636 CHECK_AND_RETURN_LOG(picture != nullptr, "UpdateImageExifDateTime: picture is null!");
637
638 UpdateExifDataTime(picture->GetExifMetadata());
639 }
640
UpdateExifMetadata(const std::shared_ptr<ExifMetadata> & exifMetadata,PixelMap * pixelMap)641 void UpdateExifMetadata(const std::shared_ptr<ExifMetadata> &exifMetadata, PixelMap *pixelMap)
642 {
643 if (exifMetadata == nullptr) {
644 EFFECT_LOGI("UpdateExifMetadata: no exif info.");
645 return;
646 }
647
648 CHECK_AND_RETURN_LOG(pixelMap != nullptr, "UpdateExifMetadata: pixelMap is null");
649 PrintImageExifInfo(exifMetadata, "UpdateImageExifInfo::update before");
650
651 // Set Width
652 int32_t width = 0;
653 if (GetImagePropertyInt(exifMetadata, IMAGE_WIDTH, width) == 0 && pixelMap->GetWidth() != width) {
654 exifMetadata->SetValue(IMAGE_WIDTH, std::to_string(pixelMap->GetWidth()));
655 }
656
657 // Set Length
658 int32_t length = 0;
659 if (GetImagePropertyInt(exifMetadata, IMAGE_LENGTH, length) == 0 && pixelMap->GetHeight() != length) {
660 exifMetadata->SetValue(IMAGE_LENGTH, std::to_string(pixelMap->GetHeight()));
661 }
662
663 // Set DateTime
664 UpdateExifDataTime(exifMetadata);
665
666 // Set PixelXDimension
667 int32_t xDimension = 0;
668 if (GetImagePropertyInt(exifMetadata, PIXEL_X_DIMENSION, xDimension) == 0 && pixelMap->GetWidth() != xDimension) {
669 exifMetadata->SetValue(PIXEL_X_DIMENSION, std::to_string(pixelMap->GetWidth()));
670 }
671
672 // Set PixelYDimension
673 int32_t yDimension = 0;
674 if (GetImagePropertyInt(exifMetadata, PIXEL_Y_DIMENSION, yDimension) == 0 && pixelMap->GetHeight() != yDimension) {
675 exifMetadata->SetValue(PIXEL_Y_DIMENSION, std::to_string(pixelMap->GetHeight()));
676 }
677
678 PrintImageExifInfo(exifMetadata, "UpdateImageExifInfo::update after");
679 }
680
UpdateImageExifInfo(PixelMap * pixelMap)681 void CommonUtils::UpdateImageExifInfo(PixelMap *pixelMap)
682 {
683 CHECK_AND_RETURN_LOG(pixelMap != nullptr, "UpdateImageExifInfo: pixelMap is null!");
684
685 UpdateExifMetadata(pixelMap->GetExifMetadata(), pixelMap);
686 }
687
UpdateImageExifInfo(Picture * picture)688 void CommonUtils::UpdateImageExifInfo(Picture *picture)
689 {
690 CHECK_AND_RETURN_LOG(picture != nullptr, "UpdateImageExifInfo: picture is null!");
691
692 UpdateExifMetadata(picture->GetExifMetadata(), picture->GetMainPixel().get());
693 }
694
CopyTexture(const std::shared_ptr<EffectContext> & context,RenderTexturePtr input,RenderTexturePtr output)695 void CommonUtils::CopyTexture(const std::shared_ptr<EffectContext> &context, RenderTexturePtr input,
696 RenderTexturePtr output)
697 {
698 context->renderEnvironment_->DrawTex(input, output);
699 }
700
IsEnableCopyMetaData(int numBuffers,...)701 bool CommonUtils::IsEnableCopyMetaData(int numBuffers, ...)
702 {
703 va_list args;
704 va_start(args, numBuffers);
705 for (int i = 0; i < numBuffers; ++i) {
706 EffectBuffer* buffer = va_arg(args, EffectBuffer*);
707 if (!buffer) {
708 EFFECT_LOGD("IsEnableCopyMetaData: buffer is null!");
709 va_end(args);
710 return false;
711 }
712 auto extraInfo = buffer->extraInfo_;
713 auto bufferInfo = buffer->bufferInfo_;
714 if (bufferInfo->bufferType_ != BufferType::DMA_BUFFER) {
715 EFFECT_LOGD("IsEnableCopyMetaData: outBuffer bufferType is %{public}d, not DMA_BUFFER!",
716 bufferInfo->bufferType_);
717 va_end(args);
718 return false;
719 }
720 if (!bufferInfo->pixelMap_ || !bufferInfo->surfaceBuffer_) {
721 EFFECT_LOGD("IsEnableCopyMetaData: pixelMap or surfaceBuffer is nullptr!");
722 va_end(args);
723 return false;
724 }
725 }
726 va_end(args);
727 return true;
728 }
729
SwitchToAuxiliaryPictureType(EffectPixelmapType pixelmapType)730 AuxiliaryPictureType SwitchToAuxiliaryPictureType(EffectPixelmapType pixelmapType)
731 {
732 AuxiliaryPictureType auxPicType = AuxiliaryPictureType::NONE;
733
734 auto itr = EffectPixelmapTypeToAuxPicType_.find(pixelmapType);
735 if (itr != EffectPixelmapTypeToAuxPicType_.end()) {
736 auxPicType = itr->second;
737 }
738
739 return auxPicType;
740 }
741
GetAuxiliaryPixelMap(Picture * picture,EffectPixelmapType auxiliaryPictureType)742 std::shared_ptr<PixelMap> GetAuxiliaryPixelMap(Picture *picture, EffectPixelmapType auxiliaryPictureType)
743 {
744 AuxiliaryPictureType auxPicType = SwitchToAuxiliaryPictureType(auxiliaryPictureType);
745 CHECK_AND_RETURN_RET_LOG(picture->HasAuxiliaryPicture(auxPicType), nullptr, "Auxiliary map:%{public}d not found.",
746 auxiliaryPictureType);
747
748 auto auxiliaryPicture = picture->GetAuxiliaryPicture(auxPicType);
749 CHECK_AND_RETURN_RET_LOG(auxiliaryPicture != nullptr, nullptr, "Get Auxiliary map:%{public}d failed.",
750 auxiliaryPictureType);
751 return auxiliaryPicture->GetContentPixel();
752 }
753
GetAuxiliaryEffectBuffer(Picture * picture,std::shared_ptr<EffectBuffer> & auxiliaryEffectBuffer,EffectPixelmapType auxiliaryPictureType)754 ErrorCode GetAuxiliaryEffectBuffer(Picture *picture, std::shared_ptr<EffectBuffer> &auxiliaryEffectBuffer,
755 EffectPixelmapType auxiliaryPictureType)
756 {
757 std::shared_ptr<PixelMap> auxMap = GetAuxiliaryPixelMap(picture, auxiliaryPictureType);
758
759 CHECK_AND_RETURN_RET_LOG(auxMap != nullptr, ErrorCode::ERR_AUXILIARY_MAP_NOT_FOUND,
760 "Get Auxiliary map:%{public}d failed.", auxiliaryPictureType);
761
762 ErrorCode errorCode = CommonUtils::LockPixelMap(auxMap.get(), auxiliaryEffectBuffer);
763 CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode,
764 "ParsePicture: parse auxMap %{public}d fail! errorCode=%{public}d", auxiliaryPictureType, errorCode);
765
766 auxiliaryEffectBuffer->bufferInfo_->pixelmapType_ = auxiliaryPictureType;
767 auxiliaryEffectBuffer->bufferInfo_->bufferType_ = auxiliaryEffectBuffer->extraInfo_->bufferType;
768 auxiliaryEffectBuffer->bufferInfo_->addr_ = auxiliaryEffectBuffer->buffer_;
769
770 return ErrorCode::SUCCESS;
771 }
772
ParseTex(unsigned int textureId,unsigned int colorSpace,std::shared_ptr<EffectBuffer> & effectBuffer)773 ErrorCode CommonUtils::ParseTex(unsigned int textureId, unsigned int colorSpace,
774 std::shared_ptr<EffectBuffer> &effectBuffer)
775 {
776 EFFECT_LOGI("CommonUtils::ParseTex enter.");
777 IEffectFormat format = SwitchGLFormatToEffectFormat(GLUtils::GetTexFormat(textureId));
778 CHECK_AND_RETURN_RET_LOG(textureId != 0, ErrorCode::ERR_INPUT_NULL, "ParseTex: textureId is 0!");
779 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
780 bufferInfo->width_ = GLUtils::GetTexWidth(textureId);
781 bufferInfo->height_ = GLUtils::GetTexHeight(textureId);
782 bufferInfo->formatType_ = format;
783 if (format == IEffectFormat::RGBA_1010102) {
784 bufferInfo->hdrFormat_ = HdrFormat::HDR10;
785 }
786 bufferInfo->colorSpace_ = ColorSpaceHelper::ConvertToEffectColorSpace(static_cast<ColorSpaceName>(colorSpace));
787 bufferInfo->rowStride_ = bufferInfo->width_;
788 bufferInfo->len_ = bufferInfo->width_ * bufferInfo->height_ * RGBA_BYTES_PER_PIXEL;
789 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
790 extraInfo->dataType = DataType::TEX;
791 extraInfo->bufferType = BufferType::DMA_BUFFER;
792 effectBuffer = std::make_unique<EffectBuffer>(bufferInfo, nullptr, extraInfo);
793 effectBuffer->bufferInfo_->tex_ = std::make_shared<RenderTexture>(bufferInfo->width_, bufferInfo->height_,
794 GLUtils::GetTexFormat(textureId));
795 effectBuffer->bufferInfo_->tex_->SetName(textureId);
796 return ErrorCode::SUCCESS;
797 }
798
ParsePicture(Picture * picture,std::shared_ptr<EffectBuffer> & effectBuffer)799 ErrorCode CommonUtils::ParsePicture(Picture *picture, std::shared_ptr<EffectBuffer> &effectBuffer)
800 {
801 EFFECT_LOGI("CommonUtils::ParsePicture enter.");
802 CHECK_AND_RETURN_RET_LOG(picture != nullptr, ErrorCode::ERR_INPUT_NULL, "ParsePicture: picture is null!");
803
804 std::shared_ptr<PixelMap> pixelMap = picture->GetMainPixel();
805 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INPUT_NULL, "ParsePicture: main pixel is null!");
806 ErrorCode errorCode = CommonUtils::LockPixelMap(pixelMap.get(), effectBuffer);
807 CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode,
808 "ParsePicture: parse main pixel fail! errorCode=%{public}d", errorCode);
809
810 effectBuffer->bufferInfo_->pixelmapType_ = EffectPixelmapType::PRIMARY;
811 effectBuffer->bufferInfo_->bufferType_ = effectBuffer->extraInfo_->bufferType;
812 effectBuffer->bufferInfo_->addr_ = effectBuffer->buffer_;
813 effectBuffer->extraInfo_->dataType = DataType::PICTURE;
814 effectBuffer->extraInfo_->picture = picture;
815
816 effectBuffer->auxiliaryBufferInfos =
817 std::make_shared<std::unordered_map<EffectPixelmapType, std::shared_ptr<BufferInfo>>>();
818
819 for (EffectPixelmapType auxMapType : AUX_MAP_TYPE_LIST) {
820 std::shared_ptr<EffectBuffer> auxMapEffectBuffer;
821 errorCode = GetAuxiliaryEffectBuffer(picture, auxMapEffectBuffer, auxMapType);
822 if (errorCode == ErrorCode::ERR_AUXILIARY_MAP_NOT_FOUND) {
823 EFFECT_LOGD("CommonUtils::ParsePicture not contain auxMap: %{public}d!", auxMapType);
824 } else if (errorCode == ErrorCode::SUCCESS) {
825 EFFECT_LOGD("CommonUtils::ParsePicture contain auxMap: %{public}d!", auxMapType);
826 if (auxMapType == EffectPixelmapType::GAINMAP &&
827 effectBuffer->bufferInfo_->formatType_ == IEffectFormat::RGBA8888) {
828 effectBuffer->bufferInfo_->hdrFormat_ = HdrFormat::HDR8_GAINMAP;
829 EFFECT_LOGD("CommonUtils::ParsePicture set HdrFormat: HDR8_GAINMAP");
830 }
831 effectBuffer->auxiliaryBufferInfos->emplace(auxMapType, auxMapEffectBuffer->bufferInfo_);
832 } else {
833 return errorCode;
834 }
835 }
836
837 return ErrorCode::SUCCESS;
838 }
839
IsYuvP010(int32_t pixelFmt)840 bool IsYuvP010(int32_t pixelFmt)
841 {
842 auto it = std::find(HDR_P010_LIST.begin(), HDR_P010_LIST.end(), pixelFmt);
843 return it != HDR_P010_LIST.end();
844 }
845
ProcessYUVInfo(PixelMap * pixelMap,const SurfaceBuffer * sBuffer,const OH_NativeBuffer_Planes * planes)846 void ProcessYUVInfo(PixelMap *pixelMap, const SurfaceBuffer *sBuffer, const OH_NativeBuffer_Planes *planes)
847 {
848 int32_t width = sBuffer->GetWidth();
849 int32_t height = sBuffer->GetHeight();
850 YUVDataInfo info;
851 info.imageSize = { width, height };
852 info.yWidth = static_cast<uint32_t>(width);
853 info.uvWidth = static_cast<uint32_t>(width / YUV_HALF);
854 info.yHeight = static_cast<uint32_t>(height);
855 info.uvHeight = static_cast<uint32_t>(height / YUV_HALF);
856 if (planes->planeCount >= YUV_PLANE_COUNT) {
857 int32_t pixelFmt = sBuffer->GetFormat();
858 bool isYuvP010 = IsYuvP010(pixelFmt);
859 int uvPlaneOffset = (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_420_SP ||
860 pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_P010) ? 1 : 2;
861 info.yStride = isYuvP010 ? (planes->planes[0].columnStride / YUV_HALF) : planes->planes[0].columnStride;
862 info.uvStride = isYuvP010 ? (planes->planes[uvPlaneOffset].columnStride / YUV_HALF) :
863 (planes->planes[uvPlaneOffset].columnStride);
864 info.yOffset = isYuvP010 ? (planes->planes[0].offset / YUV_HALF) : (planes->planes[0].offset);
865 info.uvOffset =
866 isYuvP010 ? (planes->planes[uvPlaneOffset].offset / YUV_HALF) : (planes->planes[uvPlaneOffset].offset);
867 pixelMap->SetImageYUVInfo(info);
868 }
869 }
870
SetSbDynamicMetadata(sptr<SurfaceBuffer> & buffer,const std::vector<uint8_t> & dynamicMetadata)871 bool SetSbDynamicMetadata(sptr<SurfaceBuffer> &buffer, const std::vector<uint8_t> &dynamicMetadata)
872 {
873 return buffer->SetMetadata(ATTRKEY_HDR_DYNAMIC_METADATA, dynamicMetadata) == 0;
874 }
875
GetSbDynamicMetadata(const sptr<SurfaceBuffer> & buffer,std::vector<uint8_t> & dynamicMetadata)876 bool GetSbDynamicMetadata(const sptr<SurfaceBuffer> &buffer, std::vector<uint8_t> &dynamicMetadata)
877 {
878 return buffer->GetMetadata(ATTRKEY_HDR_DYNAMIC_METADATA, dynamicMetadata) == 0;
879 }
880
SetSbStaticMetadata(sptr<SurfaceBuffer> & buffer,const std::vector<uint8_t> & staticMetadata)881 bool SetSbStaticMetadata(sptr<SurfaceBuffer> &buffer, const std::vector<uint8_t> &staticMetadata)
882 {
883 return buffer->SetMetadata(ATTRKEY_HDR_STATIC_METADATA, staticMetadata) == 0;
884 }
885
GetSbStaticMetadata(const sptr<SurfaceBuffer> & buffer,std::vector<uint8_t> & staticMetadata)886 bool GetSbStaticMetadata(const sptr<SurfaceBuffer> &buffer, std::vector<uint8_t> &staticMetadata)
887 {
888 return buffer->GetMetadata(ATTRKEY_HDR_STATIC_METADATA, staticMetadata) == 0;
889 }
890
CopySurfaceBufferInfo(sptr<SurfaceBuffer> & source,sptr<SurfaceBuffer> & dst)891 void CopySurfaceBufferInfo(sptr<SurfaceBuffer> &source, sptr<SurfaceBuffer> &dst)
892 {
893 if (source == nullptr || dst == nullptr) {
894 EFFECT_LOGI("VpeUtils CopySurfaceBufferInfo failed, source or dst is nullptr");
895 return;
896 }
897 std::vector<uint8_t> hdrMetadataTypeVec;
898 std::vector<uint8_t> colorSpaceInfoVec;
899 std::vector<uint8_t> staticData;
900 std::vector<uint8_t> dynamicData;
901
902 if (source->GetMetadata(ATTRKEY_HDR_METADATA_TYPE, hdrMetadataTypeVec) == 0) {
903 std::string str(hdrMetadataTypeVec.begin(), hdrMetadataTypeVec.end());
904 EFFECT_LOGI("ATTRKEY_HDR_METADATA_TYPE: length :%{public}zu, %{public}s",
905 hdrMetadataTypeVec.size(), str.c_str());
906 dst->SetMetadata(ATTRKEY_HDR_METADATA_TYPE, hdrMetadataTypeVec);
907 } else {
908 EFFECT_LOGE("get attrkey hdr metadata type failed");
909 }
910 if (source->GetMetadata(ATTRKEY_COLORSPACE_INFO, colorSpaceInfoVec) == 0) {
911 std::string str(colorSpaceInfoVec.begin(), colorSpaceInfoVec.end());
912 EFFECT_LOGI("ATTRKEY_COLORSPACE_INFO: length :%{public}zu, %{public}s", colorSpaceInfoVec.size(), str.c_str());
913 dst->SetMetadata(ATTRKEY_COLORSPACE_INFO, colorSpaceInfoVec);
914 } else {
915 EFFECT_LOGE("get attrkey colorspace info failed");
916 }
917 if (GetSbStaticMetadata(source, staticData) && (staticData.size() > 0)) {
918 std::string str(staticData.begin(), staticData.end());
919 EFFECT_LOGI("GetSbStaticMetadata val: length:%{public}zu, %{public}s", staticData.size(), str.c_str());
920 SetSbStaticMetadata(dst, staticData);
921 } else {
922 EFFECT_LOGE("get sb static metadata failed");
923 }
924 if (GetSbDynamicMetadata(source, dynamicData) && (dynamicData.size()) > 0) {
925 std::string str(dynamicData.begin(), dynamicData.end());
926 EFFECT_LOGI("GetSbDynamicMetadata val: length:%{public}zu, %{public}s", dynamicData.size(), str.c_str());
927 SetSbDynamicMetadata(dst, dynamicData);
928 } else {
929 EFFECT_LOGE("get sb dynamic metadata failed");
930 }
931 }
932
ModifyYUVInfo(PixelMap * pixelMap,void * context,const MemoryInfo & memoryInfo)933 ErrorCode ModifyYUVInfo(PixelMap *pixelMap, void *context, const MemoryInfo &memoryInfo)
934 {
935 CHECK_AND_RETURN_RET_LOG(context != nullptr, ErrorCode::ERR_INPUT_NULL, "handle yuv info, context is null.");
936 SurfaceBuffer *sBuffer = reinterpret_cast<SurfaceBuffer *>(context);
937 if (memoryInfo.bufferType == BufferType::SHARED_MEMORY || memoryInfo.bufferType == BufferType::HEAP_MEMORY) {
938 int32_t width = memoryInfo.bufferInfo.width_;
939 int32_t height = memoryInfo.bufferInfo.height_;
940 YUVDataInfo info;
941 info.imageSize = { width, height};
942 info.yWidth = static_cast<uint32_t>(width);
943 info.uvWidth = static_cast<uint32_t>(width / YUV_HALF);
944 info.yHeight = static_cast<uint32_t>(height);
945 info.uvHeight = static_cast<uint32_t>(height / YUV_HALF);
946
947 info.yStride = info.yWidth;
948 info.uvStride = info.uvWidth;
949 info.yOffset = 0;
950 info.uvOffset = info.yStride * info.yHeight;
951 pixelMap->SetImageYUVInfo(info);
952 } else {
953 if (sBuffer == nullptr) {
954 return ErrorCode::SUCCESS;
955 }
956 OH_NativeBuffer_Planes *planes = nullptr;
957 GSError retVal = sBuffer->GetPlanesInfo(reinterpret_cast<void **>(&planes));
958 if (retVal != OHOS::GSERROR_OK || planes == nullptr || planes->planeCount <= 1) {
959 return ErrorCode::SUCCESS;
960 }
961 ProcessYUVInfo(pixelMap, sBuffer, planes);
962 }
963 return ErrorCode::SUCCESS;
964 }
965
ModifyPixelMapPropertyInner(std::shared_ptr<MemoryData> & memoryData,PixelMap * pixelMap,AllocatorType & allocatorType,bool isUpdateExif,const std::shared_ptr<EffectContext> & effectContext)966 ErrorCode ModifyPixelMapPropertyInner(std::shared_ptr<MemoryData> &memoryData, PixelMap *pixelMap,
967 AllocatorType &allocatorType, bool isUpdateExif, const std::shared_ptr<EffectContext> &effectContext)
968 {
969 void *context = nullptr;
970 const MemoryInfo &memoryInfo = memoryData->memoryInfo;
971
972 if (memoryInfo.bufferType == BufferType::DMA_BUFFER) {
973 sptr<SurfaceBuffer> baseSptr(reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()));
974 void *extra = memoryData->memoryInfo.extra;
975 sptr<SurfaceBuffer> dstBuffer(reinterpret_cast<SurfaceBuffer*>(extra));
976 CopySurfaceBufferInfo(baseSptr, dstBuffer);
977 }
978
979 ErrorCode res = GetPixelsContext(memoryData, memoryInfo.bufferType, &context);
980 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "get pixels context fail! res=%{public}d", res);
981
982 // not need to release the origin buffer in pixelMap, SetPixelsAddr will release it.
983 pixelMap->SetPixelsAddr(memoryData->data, context, memoryInfo.bufferInfo.len_, allocatorType, nullptr);
984
985 ImageInfo imageInfo;
986 pixelMap->GetImageInfo(imageInfo);
987 imageInfo.size.width = static_cast<int32_t>(memoryInfo.bufferInfo.width_);
988 imageInfo.size.height = static_cast<int32_t>(memoryInfo.bufferInfo.height_);
989 imageInfo.pixelFormat = CommonUtils::SwitchToPixelFormat(memoryInfo.bufferInfo.formatType_);
990 uint32_t result = pixelMap->SetImageInfo(imageInfo, true);
991 if (imageInfo.pixelFormat == PixelFormat::NV12 || imageInfo.pixelFormat == PixelFormat::NV21 ||
992 imageInfo.pixelFormat == PixelFormat::YCBCR_P010 || imageInfo.pixelFormat == PixelFormat::YCRCB_P010) {
993 res = ModifyYUVInfo(pixelMap, context, memoryInfo);
994 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "HandleYUVInfo fail! res=%{public}d", res);
995 }
996 EFFECT_LOGI("ModifyPixelMapPropertyInner: SetImageInfo width=%{public}d, height=%{public}d, result: %{public}d",
997 imageInfo.size.width, imageInfo.size.height, result);
998 CHECK_AND_RETURN_RET_LOG(result == 0, ErrorCode::ERR_SET_IMAGE_INFO_FAIL,
999 "ModifyPixelMapPropertyInner: exec SetImageInfo fail! result=%{public}d", result);
1000
1001 // update rowStride
1002 pixelMap->SetRowStride(memoryInfo.bufferInfo.rowStride_);
1003
1004 if (isUpdateExif) {
1005 // update exif
1006 CommonUtils::UpdateImageExifInfo(pixelMap);
1007 }
1008
1009 EffectColorSpace colorSpace = memoryInfo.bufferInfo.colorSpace_;
1010 if (colorSpace != EffectColorSpace::DEFAULT) {
1011 OHOS::ColorManager::ColorSpace grColorSpace(ColorSpaceHelper::ConvertToColorSpaceName(colorSpace));
1012 pixelMap->InnerSetColorSpace(grColorSpace);
1013 }
1014
1015 // update colorspace if need
1016 if (memoryInfo.bufferType == BufferType::DMA_BUFFER) {
1017 EFFECT_LOGD("ModifyPixelMapPropertyInner: update colorspace");
1018 res = ColorSpaceHelper::UpdateMetadata(static_cast<SurfaceBuffer *>(memoryInfo.extra),
1019 memoryInfo.bufferInfo.colorSpace_, effectContext);
1020 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res,
1021 "ModifyPixelMapPropertyInner: UpdateMetadata fail! res=%{public}d", res);
1022 }
1023
1024 return ErrorCode::SUCCESS;
1025 }
1026
ModifyPixelMapProperty(PixelMap * pixelMap,const std::shared_ptr<EffectBuffer> & buffer,const std::shared_ptr<EffectContext> & context,bool isUpdateExif)1027 ErrorCode CommonUtils::ModifyPixelMapProperty(PixelMap *pixelMap, const std::shared_ptr<EffectBuffer> &buffer,
1028 const std::shared_ptr<EffectContext> &context, bool isUpdateExif)
1029 {
1030 EFFECT_LOGI("ModifyPixelMapProperty enter!");
1031 std::shared_ptr<EffectMemoryManager> memoryManager = context->memoryManager_;
1032 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INPUT_NULL, "pixel map is null");
1033 AllocatorType allocatorType = pixelMap->GetAllocatorType();
1034 BufferType bufferType = SwitchToEffectBuffType(allocatorType);
1035 EFFECT_LOGD("ModifyPixelMapProperty: allocatorType=%{public}d, bufferType=%{public}d", allocatorType, bufferType);
1036 std::shared_ptr<Memory> allocMemory = memoryManager->GetAllocMemoryByAddr(buffer->buffer_);
1037 std::shared_ptr<MemoryData> memoryData;
1038 if (allocMemory != nullptr && allocMemory->memoryData_->memoryInfo.bufferType == bufferType) {
1039 EFFECT_LOGD("ModifyPixelMapProperty reuse allocated memory.");
1040 allocMemory->memoryData_->memoryInfo.isAutoRelease = false;
1041 memoryData = allocMemory->memoryData_;
1042 } else {
1043 EFFECT_LOGD("ModifyPixelMapProperty alloc memory.");
1044 std::unique_ptr<AbsMemory> memory = EffectMemory::CreateMemory(bufferType);
1045 CHECK_AND_RETURN_RET_LOG(memory != nullptr, ErrorCode::ERR_CREATE_MEMORY_FAIL,
1046 "memory create fail! allocatorType=%{public}d", allocatorType);
1047
1048 MemoryInfo memoryInfo = {
1049 .isAutoRelease = false,
1050 .bufferInfo = *buffer->bufferInfo_,
1051 .extra = pixelMap->GetFd()
1052 };
1053 if (bufferType != BufferType::DMA_BUFFER) {
1054 memoryInfo.bufferInfo.len_ = FormatHelper::CalculateSize(buffer->bufferInfo_->width_,
1055 buffer->bufferInfo_->height_, buffer->bufferInfo_->formatType_);
1056 }
1057 memoryData = memory->Alloc(memoryInfo);
1058 CHECK_AND_RETURN_RET_LOG(memoryData != nullptr, ErrorCode::ERR_ALLOC_MEMORY_FAIL, "Alloc fail!");
1059 MemcpyHelper::CopyData(buffer.get(), memoryData.get());
1060 }
1061
1062 return ModifyPixelMapPropertyInner(memoryData, pixelMap, allocatorType, isUpdateExif, context);
1063 }
1064
ModifyPixelMapPropertyForTexture(PixelMap * pixelMap,const std::shared_ptr<EffectBuffer> & buffer,const std::shared_ptr<EffectContext> & context,bool isUpdateExif)1065 ErrorCode CommonUtils::ModifyPixelMapPropertyForTexture(PixelMap *pixelMap, const std::shared_ptr<EffectBuffer> &buffer,
1066 const std::shared_ptr<EffectContext> &context, bool isUpdateExif)
1067 {
1068 EFFECT_LOGI("ModifyPixelMapPropertyForTexture enter!");
1069 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INPUT_NULL, "pixel map is null");
1070 AllocatorType allocatorType = pixelMap->GetAllocatorType();
1071 BufferType bufferType = SwitchToEffectBuffType(allocatorType);
1072 EFFECT_LOGD("ModifyPixelMapProperty: allocatorType=%{public}d, bufferType=%{public}d", allocatorType, bufferType);
1073 std::unique_ptr<AbsMemory> memory = EffectMemory::CreateMemory(bufferType);
1074 CHECK_AND_RETURN_RET_LOG(memory != nullptr, ErrorCode::ERR_CREATE_MEMORY_FAIL,
1075 "memory create fail! allocatorType=%{public}d", allocatorType);
1076
1077 MemoryInfo memoryInfo = {
1078 .isAutoRelease = false,
1079 .bufferInfo = *buffer->bufferInfo_,
1080 .extra = pixelMap->GetFd()
1081 };
1082 std::shared_ptr<MemoryData> memoryData = memory->Alloc(memoryInfo);
1083 CHECK_AND_RETURN_RET_LOG(memoryData != nullptr, ErrorCode::ERR_ALLOC_MEMORY_FAIL, "Alloc fail!");
1084 context->renderEnvironment_->ReadPixelsFromTex(buffer->bufferInfo_->tex_, memoryData->data,
1085 buffer->bufferInfo_->width_, buffer->bufferInfo_->height_,
1086 memoryData->memoryInfo.bufferInfo.rowStride_ / RGBA_BYTES_PER_PIXEL);
1087
1088 return ModifyPixelMapPropertyInner(memoryData, pixelMap, allocatorType, isUpdateExif, context);
1089 }
1090
GetImageSourceFromPath(const std::string path)1091 std::shared_ptr<ImageSource> CommonUtils::GetImageSourceFromPath(const std::string path)
1092 {
1093 std::shared_ptr<ImageSource> imageSource;
1094 uint32_t errorCode = 0;
1095 SourceOptions opts;
1096 imageSource = ImageSource::CreateImageSource(path, opts, errorCode);
1097 CHECK_AND_RETURN_RET_LOG(imageSource != nullptr, imageSource,
1098 "ImageSource::CreateImageSource fail! path=%{public}s errorCode=%{public}d", path.c_str(), errorCode);
1099 return imageSource;
1100 }
1101 } // namespace Effect
1102 } // namespace Media
1103 } // namespace OHOS