1 /*
2 * Copyright (C) 2021 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 "post_proc.h"
17
18 #include <memory>
19 #include <unistd.h>
20
21 #include "basic_transformer.h"
22 #include "image_log.h"
23 #include "image_system_properties.h"
24 #include "image_trace.h"
25 #include "image_type.h"
26 #include "image_utils.h"
27 #include "media_errors.h"
28 #include "memory_manager.h"
29 #include "pixel_convert_adapter.h"
30 #ifndef _WIN32
31 #include "securec.h"
32 #else
33 #include "memory.h"
34 #endif
35 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
36 #include <sys/mman.h>
37 #include "ashmem.h"
38 #include "surface_buffer.h"
39 #include "vpe_utils.h"
40 #include "pixel_map_program_manager.h"
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 #include "libswscale/swscale.h"
45 #ifdef __cplusplus
46 };
47 #endif
48 #endif
49
50 #undef LOG_DOMAIN
51 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
52
53 #undef LOG_TAG
54 #define LOG_TAG "PostProc"
55
56 namespace OHOS {
57 namespace Media {
58 using namespace std;
59 constexpr uint32_t NEED_NEXT = 1;
60 constexpr float EPSILON = 1e-6;
61 constexpr uint8_t HALF = 2;
62 constexpr float HALF_F = 2;
63 constexpr int FFMPEG_NUM = 8;
64 constexpr int SLR_CACHE_CAPACITY = 256;
65
66 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
67 static const map<PixelFormat, AVPixelFormat> PIXEL_FORMAT_MAP = {
68 { PixelFormat::ALPHA_8, AVPixelFormat::AV_PIX_FMT_GRAY8 },
69 { PixelFormat::RGB_565, AVPixelFormat::AV_PIX_FMT_RGB565BE },
70 { PixelFormat::RGB_888, AVPixelFormat::AV_PIX_FMT_RGB24 },
71 { PixelFormat::RGBA_8888, AVPixelFormat::AV_PIX_FMT_RGBA },
72 { PixelFormat::ARGB_8888, AVPixelFormat::AV_PIX_FMT_ARGB },
73 { PixelFormat::BGRA_8888, AVPixelFormat::AV_PIX_FMT_BGRA },
74 { PixelFormat::RGBA_F16, AVPixelFormat::AV_PIX_FMT_RGBA64BE },
75 };
76 #endif
77
DecodePostProc(const DecodeOptions & opts,PixelMap & pixelMap,FinalOutputStep finalOutputStep)78 uint32_t PostProc::DecodePostProc(const DecodeOptions &opts, PixelMap &pixelMap, FinalOutputStep finalOutputStep)
79 {
80 if (opts.cropAndScaleStrategy == CropAndScaleStrategy::SCALE_FIRST && opts.desiredSize.height > 0 &&
81 opts.desiredSize.width > 0) {
82 CHECK_ERROR_RETURN_RET_LOG(!ScalePixelMap(opts.desiredSize, pixelMap), ERR_IMAGE_TRANSFORM,
83 "[PostProc]scale:transform pixelMap failed");
84 CHECK_ERROR_RETURN_RET_LOG(pixelMap.crop(opts.CropRect) != SUCCESS, ERR_IMAGE_TRANSFORM,
85 "[PostProc]crop:transform pixelMap failed");
86 } else {
87 ImageInfo srcImageInfo;
88 pixelMap.GetImageInfo(srcImageInfo);
89 ImageInfo dstImageInfo;
90 GetDstImageInfo(opts, pixelMap, srcImageInfo, dstImageInfo);
91 uint32_t errorCode = ConvertProc(opts.CropRect, dstImageInfo, pixelMap, srcImageInfo);
92 if (errorCode != SUCCESS) {
93 IMAGE_LOGE("[PostProc]crop pixel map failed, errcode:%{public}u", errorCode);
94 return errorCode;
95 }
96 }
97 bool cond = false;
98 decodeOpts_.allocatorType = opts.allocatorType;
99 bool isNeedRotate = !ImageUtils::FloatCompareZero(opts.rotateDegrees);
100 if (isNeedRotate) {
101 cond = !RotatePixelMap(opts.rotateDegrees, pixelMap);
102 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_TRANSFORM, "[PostProc]rotate:transform pixel map failed");
103 }
104 decodeOpts_.allocatorType = opts.allocatorType;
105 if (opts.desiredSize.height > 0 && opts.desiredSize.width > 0 &&
106 opts.cropAndScaleStrategy != CropAndScaleStrategy::SCALE_FIRST) {
107 cond = !ScalePixelMap(opts.desiredSize, pixelMap);
108 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_TRANSFORM, "[PostProc]scale:transform pixel map failed");
109 } else if (opts.cropAndScaleStrategy != CropAndScaleStrategy::SCALE_FIRST) {
110 ImageInfo info;
111 pixelMap.GetImageInfo(info);
112 if ((finalOutputStep == FinalOutputStep::DENSITY_CHANGE) && (info.baseDensity != 0)) {
113 int targetWidth = (pixelMap.GetWidth() * opts.fitDensity + (info.baseDensity >> 1)) / info.baseDensity;
114 int targetHeight = (pixelMap.GetHeight() * opts.fitDensity + (info.baseDensity >> 1)) / info.baseDensity;
115 Size size;
116 size.height = targetHeight;
117 size.width = targetWidth;
118 cond = !ScalePixelMap(size, pixelMap);
119 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_TRANSFORM,
120 "[PostProc]density scale:transform pixel map failed");
121 info.baseDensity = opts.fitDensity;
122 pixelMap.SetImageInfo(info, true);
123 }
124 }
125 return SUCCESS;
126 }
127
GetDstImageInfo(const DecodeOptions & opts,PixelMap & pixelMap,ImageInfo srcImageInfo,ImageInfo & dstImageInfo)128 void PostProc::GetDstImageInfo(const DecodeOptions &opts, PixelMap &pixelMap,
129 ImageInfo srcImageInfo, ImageInfo &dstImageInfo)
130 {
131 dstImageInfo.size = opts.desiredSize;
132 dstImageInfo.pixelFormat = opts.desiredPixelFormat;
133 dstImageInfo.baseDensity = srcImageInfo.baseDensity;
134 decodeOpts_ = opts;
135 if (opts.desiredPixelFormat == PixelFormat::UNKNOWN) {
136 if (opts.preference == MemoryUsagePreference::LOW_RAM &&
137 srcImageInfo.alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE) {
138 dstImageInfo.pixelFormat = PixelFormat::RGB_565;
139 } else {
140 dstImageInfo.pixelFormat = PixelFormat::RGBA_8888;
141 }
142 }
143 // decode use, this value may be changed by real pixelFormat
144 if (pixelMap.GetAlphaType() == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL) {
145 dstImageInfo.alphaType = AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
146 } else {
147 dstImageInfo.alphaType = pixelMap.GetAlphaType();
148 }
149 }
150
CenterScale(const Size & size,PixelMap & pixelMap)151 bool PostProc::CenterScale(const Size &size, PixelMap &pixelMap)
152 {
153 int32_t srcWidth = pixelMap.GetWidth();
154 int32_t srcHeight = pixelMap.GetHeight();
155 int32_t targetWidth = size.width;
156 int32_t targetHeight = size.height;
157 if (targetWidth <= 0 || targetHeight <= 0 || srcWidth <= 0 || srcHeight <= 0) {
158 IMAGE_LOGE("[PostProc]params invalid, targetWidth:%{public}d, targetHeight:%{public}d, "
159 "srcWidth:%{public}d, srcHeight:%{public}d", targetWidth, targetHeight, srcWidth, srcHeight);
160 return false;
161 }
162 float widthScale = static_cast<float>(targetWidth) / static_cast<float>(srcWidth);
163 float heightScale = static_cast<float>(targetHeight) / static_cast<float>(srcHeight);
164 float scale = max(widthScale, heightScale);
165 if (pixelMap.IsAstc() && scale > 0) {
166 TransformData transformData;
167 pixelMap.GetTransformData(transformData);
168 transformData.scaleX *= scale;
169 transformData.scaleY *= scale;
170 transformData.cropLeft = (srcWidth - targetWidth / scale) / HALF_F;
171 transformData.cropTop = (srcHeight - targetHeight / scale) / HALF_F;
172 transformData.cropWidth = targetWidth / scale;
173 transformData.cropHeight = targetHeight / scale;
174 pixelMap.SetTransformData(transformData);
175 ImageInfo imageInfo;
176 pixelMap.GetImageInfo(imageInfo);
177 imageInfo.size.width = targetWidth;
178 imageInfo.size.height = targetHeight;
179 pixelMap.SetImageInfo(imageInfo, true);
180 return true;
181 }
182 bool cond = !ScalePixelMap(scale, scale, pixelMap);
183 CHECK_ERROR_RETURN_RET_LOG(cond, false, "[PostProc]center scale pixelmap %{public}f fail", scale);
184 srcWidth = pixelMap.GetWidth();
185 srcHeight = pixelMap.GetHeight();
186 if (srcWidth == targetWidth && srcHeight == targetHeight) {
187 return true;
188 }
189 cond = srcWidth < targetWidth || srcHeight < targetHeight;
190 CHECK_ERROR_RETURN_RET_LOG(cond, false,
191 "[PostProc]src size [%{public}d, %{public}d] must less than dst size [%{public}d, %{public}d]",
192 srcWidth, srcHeight, targetWidth, targetHeight);
193
194 return CenterDisplay(pixelMap, srcWidth, srcHeight, targetWidth, targetHeight);
195 }
196
CopyPixels(PixelMap & pixelMap,uint8_t * dstPixels,const Size & dstSize,const int32_t srcWidth,const int32_t srcHeight,int32_t srcRowStride,int32_t targetRowStride)197 bool PostProc::CopyPixels(PixelMap& pixelMap, uint8_t* dstPixels, const Size& dstSize,
198 const int32_t srcWidth, const int32_t srcHeight,
199 int32_t srcRowStride, int32_t targetRowStride)
200 {
201 int32_t targetWidth = dstSize.width;
202 int32_t targetHeight = dstSize.height;
203 int32_t left = max(0, srcWidth - targetWidth) / HALF;
204 int32_t top = max(0, srcHeight - targetHeight) / HALF;
205 int32_t pixelBytes = pixelMap.GetPixelBytes();
206 uint8_t *dstStartPixel = nullptr;
207 uint8_t *srcStartPixel = nullptr;
208 int32_t targetRowBytes = targetWidth * pixelBytes;
209 if (targetRowStride <= 0) {
210 targetRowStride = targetRowBytes;
211 }
212 int32_t srcRowBytes = srcWidth * pixelBytes;
213 if (srcRowStride <= 0) {
214 srcRowStride = srcRowBytes;
215 }
216 uint8_t *srcPixels = const_cast<uint8_t *>(pixelMap.GetPixels());
217 bool cond = (srcPixels == nullptr);
218 CHECK_ERROR_RETURN_RET_LOG(cond, false, "[PostProc]pixelMap data_ is nullptr");
219 srcPixels = srcPixels + top * srcRowStride + left * pixelBytes;
220 cond = std::min(srcWidth, targetWidth) != 0 &&
221 ImageUtils::CheckMulOverflow(std::min(srcWidth, targetWidth), pixelBytes);
222 CHECK_ERROR_RETURN_RET_LOG(cond, false,
223 "[PostProc]invalid params, srcWidth:%{public}d, targetWidth:%{public}d, pixelBytes:%{public}d",
224 srcWidth, targetWidth, pixelBytes);
225 uint32_t copyRowBytes = static_cast<uint32_t>(std::min(srcWidth, targetWidth) * pixelBytes);
226 for (int32_t scanLine = 0; scanLine < std::min(srcHeight, targetHeight); scanLine++) {
227 dstStartPixel = dstPixels + scanLine * targetRowStride;
228 srcStartPixel = srcPixels + scanLine * srcRowStride;
229 errno_t errRet = memcpy_s(dstStartPixel, static_cast<size_t>(targetRowBytes), srcStartPixel, copyRowBytes);
230 CHECK_ERROR_RETURN_RET_LOG(errRet != EOK, false,
231 "[PostProc]memcpy scanline %{public}d fail, errorCode = %{public}d", scanLine, errRet);
232 }
233 return true;
234 }
235
CenterDisplay(PixelMap & pixelMap,int32_t srcWidth,int32_t srcHeight,int32_t targetWidth,int32_t targetHeight)236 bool PostProc::CenterDisplay(PixelMap &pixelMap, int32_t srcWidth, int32_t srcHeight, int32_t targetWidth,
237 int32_t targetHeight)
238 {
239 ImageInfo dstImageInfo;
240 pixelMap.GetImageInfo(dstImageInfo);
241 int32_t srcRowStride = pixelMap.GetAllocatorType() == AllocatorType::DMA_ALLOC ? pixelMap.GetRowStride() : 0;
242 dstImageInfo.size.width = targetWidth;
243 dstImageInfo.size.height = targetHeight;
244 bool cond = false;
245 CHECK_ERROR_RETURN_RET_LOG(pixelMap.SetImageInfo(dstImageInfo, true) != SUCCESS, false, "update ImageInfo failed");
246 int32_t bufferSize = pixelMap.GetByteCount();
247 uint8_t *dstPixels = nullptr;
248 void *nativeBuffer = nullptr;
249 int fd = 0;
250 int targetRowStride = 0;
251 if (pixelMap.GetAllocatorType() == AllocatorType::HEAP_ALLOC) {
252 cond = !AllocHeapBuffer(bufferSize, &dstPixels);
253 CHECK_ERROR_RETURN_RET(cond, false);
254 } else if (pixelMap.GetAllocatorType() == AllocatorType::DMA_ALLOC) {
255 dstPixels = AllocDmaMemory(dstImageInfo, bufferSize, &nativeBuffer, targetRowStride);
256 } else {
257 dstPixels = AllocSharedMemory(dstImageInfo.size, bufferSize, fd, pixelMap.GetUniqueId());
258 }
259 cond = dstPixels == nullptr;
260 CHECK_ERROR_RETURN_RET_LOG(cond, false,
261 "[PostProc]CenterDisplay AllocMemory[%{public}d] failed",
262 pixelMap.GetAllocatorType());
263 if (!CopyPixels(pixelMap, dstPixels, dstImageInfo.size, srcWidth, srcHeight, srcRowStride, targetRowStride)) {
264 IMAGE_LOGE("[PostProc]CopyPixels failed");
265 ReleaseBuffer(pixelMap.GetAllocatorType(), fd, bufferSize, &dstPixels, nativeBuffer);
266 return false;
267 }
268 void *fdBuffer = nullptr;
269 if (pixelMap.GetAllocatorType() == AllocatorType::HEAP_ALLOC) {
270 pixelMap.SetPixelsAddr(dstPixels, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
271 } else if (pixelMap.GetAllocatorType() == AllocatorType::DMA_ALLOC) {
272 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
273 sptr<SurfaceBuffer> sourceSurfaceBuffer(reinterpret_cast<SurfaceBuffer*> (pixelMap.GetFd()));
274 sptr<SurfaceBuffer> dstSurfaceBuffer(reinterpret_cast<SurfaceBuffer*> (nativeBuffer));
275 VpeUtils::CopySurfaceBufferInfo(sourceSurfaceBuffer, dstSurfaceBuffer);
276 #endif
277 pixelMap.SetPixelsAddr(dstPixels, nativeBuffer, bufferSize, AllocatorType::DMA_ALLOC, nullptr);
278 } else {
279 fdBuffer = new int32_t();
280 *static_cast<int32_t *>(fdBuffer) = fd;
281 pixelMap.SetPixelsAddr(dstPixels, fdBuffer, bufferSize, AllocatorType::SHARE_MEM_ALLOC, nullptr);
282 }
283 ImageUtils::FlushSurfaceBuffer(&pixelMap);
284 return true;
285 }
286
ProcessScanlineFilter(ScanlineFilter & scanlineFilter,const Rect & cropRect,PixelMap & pixelMap,uint8_t * resultData,uint32_t rowBytes)287 bool PostProc::ProcessScanlineFilter(ScanlineFilter &scanlineFilter, const Rect &cropRect, PixelMap &pixelMap,
288 uint8_t *resultData, uint32_t rowBytes)
289 {
290 auto srcData = pixelMap.GetPixels();
291 int32_t scanLine = 0;
292 while (scanLine < pixelMap.GetHeight()) {
293 FilterRowType filterRow = scanlineFilter.GetFilterRowType(scanLine);
294 if (filterRow == FilterRowType::NON_REFERENCE_ROW) {
295 scanLine++;
296 continue;
297 }
298 if (filterRow == FilterRowType::LAST_REFERENCE_ROW) {
299 break;
300 }
301 uint32_t ret = scanlineFilter.FilterLine(resultData + ((scanLine - cropRect.top) * rowBytes), rowBytes,
302 srcData + (scanLine * pixelMap.GetRowBytes()));
303 bool cond = ret != SUCCESS;
304 CHECK_ERROR_RETURN_RET_LOG(cond, false, "[PostProc]scan line failed, ret:%{public}u", ret);
305 scanLine++;
306 }
307 return true;
308 }
309
CheckScanlineFilter(const Rect & cropRect,ImageInfo & dstImageInfo,PixelMap & pixelMap,int32_t pixelBytes,ScanlineFilter & scanlineFilter)310 uint32_t PostProc::CheckScanlineFilter(const Rect &cropRect, ImageInfo &dstImageInfo, PixelMap &pixelMap,
311 int32_t pixelBytes, ScanlineFilter &scanlineFilter)
312 {
313 if (ImageUtils::CheckMulOverflow(dstImageInfo.size.width, dstImageInfo.size.height, pixelBytes)) {
314 IMAGE_LOGE("[PostProc]size is too large, width:%{public}d, height:%{public}d",
315 dstImageInfo.size.width, dstImageInfo.size.height);
316 return ERR_IMAGE_CROP;
317 }
318 uint64_t bufferSize = static_cast<uint64_t>(dstImageInfo.size.width) *
319 static_cast<uint64_t>(dstImageInfo.size.height) *
320 static_cast<uint64_t>(pixelBytes);
321 uint8_t *resultData = nullptr;
322 int fd = 0;
323 if (decodeOpts_.allocatorType == AllocatorType::SHARE_MEM_ALLOC) {
324 resultData = AllocSharedMemory(dstImageInfo.size, bufferSize, fd, pixelMap.GetUniqueId());
325 bool cond = resultData == nullptr;
326 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_CROP, "[PostProc]AllocSharedMemory failed");
327 } else {
328 if (!AllocHeapBuffer(bufferSize, &resultData)) {
329 return ERR_IMAGE_CROP;
330 }
331 }
332 if (ImageUtils::CheckMulOverflow(dstImageInfo.size.width, pixelBytes)) {
333 IMAGE_LOGE("[PostProc]size.width:%{public}d, is too large",
334 dstImageInfo.size.width);
335 ReleaseBuffer(decodeOpts_.allocatorType, fd, bufferSize, &resultData);
336 return ERR_IMAGE_CROP;
337 }
338 uint32_t rowBytes = pixelBytes * dstImageInfo.size.width;
339 if (!ProcessScanlineFilter(scanlineFilter, cropRect, pixelMap, resultData, rowBytes)) {
340 IMAGE_LOGE("[PostProc]ProcessScanlineFilter failed");
341 ReleaseBuffer(decodeOpts_.allocatorType, fd, bufferSize, &resultData);
342 return ERR_IMAGE_CROP;
343 }
344 uint32_t result = pixelMap.SetImageInfo(dstImageInfo);
345 if (result != SUCCESS) {
346 ReleaseBuffer(decodeOpts_.allocatorType, fd, bufferSize, &resultData);
347 return result;
348 }
349
350 if (decodeOpts_.allocatorType == AllocatorType::HEAP_ALLOC) {
351 pixelMap.SetPixelsAddr(resultData, nullptr, bufferSize, decodeOpts_.allocatorType, nullptr);
352 return result;
353 }
354 void *fdBuffer = new int32_t();
355 *static_cast<int32_t *>(fdBuffer) = fd;
356 pixelMap.SetPixelsAddr(resultData, fdBuffer, bufferSize, decodeOpts_.allocatorType, nullptr);
357 return result;
358 }
359
ConvertProc(const Rect & cropRect,ImageInfo & dstImageInfo,PixelMap & pixelMap,ImageInfo & srcImageInfo)360 uint32_t PostProc::ConvertProc(const Rect &cropRect, ImageInfo &dstImageInfo, PixelMap &pixelMap,
361 ImageInfo &srcImageInfo)
362 {
363 bool hasPixelConvert = HasPixelConvert(srcImageInfo, dstImageInfo);
364 uint32_t ret = NeedScanlineFilter(cropRect, srcImageInfo.size, hasPixelConvert);
365 if (ret != NEED_NEXT) {
366 return ret;
367 }
368
369 // we suppose a quick method to scanline in mostly seen cases: NO CROP && hasPixelConvert
370 if (GetCropValue(cropRect, srcImageInfo.size) == CropValue::NOCROP &&
371 dstImageInfo.pixelFormat == PixelFormat::ARGB_8888 && hasPixelConvert) {
372 IMAGE_LOGI("[PostProc]no need crop, only pixel convert.");
373 return PixelConvertProc(dstImageInfo, pixelMap, srcImageInfo);
374 }
375
376 ScanlineFilter scanlineFilter(srcImageInfo.pixelFormat);
377 // this method maybe update dst image size to crop size
378 SetScanlineCropAndConvert(cropRect, dstImageInfo, srcImageInfo, scanlineFilter, hasPixelConvert);
379
380 int32_t pixelBytes = ImageUtils::GetPixelBytes(dstImageInfo.pixelFormat);
381 if (pixelBytes == 0) {
382 return ERR_IMAGE_CROP;
383 }
384 bool cond = ImageUtils::CheckMulOverflow(dstImageInfo.size.width, dstImageInfo.size.height, pixelBytes);
385 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_CROP,
386 "[PostProc]size.width:%{public}d, size.height:%{public}d is too large",
387 dstImageInfo.size.width, dstImageInfo.size.height);
388 return CheckScanlineFilter(cropRect, dstImageInfo, pixelMap, pixelBytes, scanlineFilter);
389 }
390
PixelConvertProc(ImageInfo & dstImageInfo,PixelMap & pixelMap,ImageInfo & srcImageInfo)391 uint32_t PostProc::PixelConvertProc(ImageInfo &dstImageInfo, PixelMap &pixelMap,
392 ImageInfo &srcImageInfo)
393 {
394 uint32_t ret;
395 int fd = 0;
396 uint64_t bufferSize = 0;
397 uint8_t *resultData = nullptr;
398
399 // as no crop, the size is same as src
400 dstImageInfo.size = srcImageInfo.size;
401 if (AllocBuffer(dstImageInfo, &resultData, bufferSize, fd, pixelMap.GetUniqueId()) != SUCCESS) {
402 ReleaseBuffer(decodeOpts_.allocatorType, fd, bufferSize, &resultData);
403 return ERR_IMAGE_CROP;
404 }
405
406 int32_t pixelBytes = ImageUtils::GetPixelBytes(srcImageInfo.pixelFormat);
407 if (pixelBytes == 0) {
408 ReleaseBuffer(decodeOpts_.allocatorType, fd, bufferSize, &resultData);
409 return ERR_IMAGE_CROP;
410 }
411
412 ret = pixelMap.SetImageInfo(dstImageInfo);
413 if (ret != SUCCESS) {
414 ReleaseBuffer(decodeOpts_.allocatorType, fd, bufferSize, &resultData);
415 return ret;
416 }
417
418 if (decodeOpts_.allocatorType == AllocatorType::HEAP_ALLOC) {
419 pixelMap.SetPixelsAddr(resultData, nullptr, bufferSize, decodeOpts_.allocatorType, nullptr);
420 return ret;
421 }
422
423 void *fdBuffer = new int32_t();
424 *static_cast<int32_t *>(fdBuffer) = fd;
425 pixelMap.SetPixelsAddr(resultData, fdBuffer, bufferSize, decodeOpts_.allocatorType, nullptr);
426 return ret;
427 }
428
AllocBuffer(ImageInfo imageInfo,uint8_t ** resultData,uint64_t & bufferSize,int & fd,uint32_t id)429 uint32_t PostProc::AllocBuffer(ImageInfo imageInfo, uint8_t **resultData, uint64_t &bufferSize, int &fd, uint32_t id)
430 {
431 int32_t pixelBytes = ImageUtils::GetPixelBytes(imageInfo.pixelFormat);
432 bool cond = false;
433 if (pixelBytes == 0) {
434 return ERR_IMAGE_CROP;
435 }
436 if (ImageUtils::CheckMulOverflow(imageInfo.size.width, imageInfo.size.height, pixelBytes)) {
437 IMAGE_LOGE("[PostProc]size.width:%{public}d, size.height:%{public}d is too large",
438 imageInfo.size.width, imageInfo.size.height);
439 return ERR_IMAGE_CROP;
440 }
441 bufferSize = static_cast<uint64_t>(imageInfo.size.width) *
442 static_cast<uint64_t>(imageInfo.size.height) *
443 static_cast<uint64_t>(pixelBytes);
444 IMAGE_LOGD("[PostProc]size.width:%{public}d, size.height:%{public}d, bufferSize:%{public}lld",
445 imageInfo.size.width, imageInfo.size.height, static_cast<long long>(bufferSize));
446 if (decodeOpts_.allocatorType == AllocatorType::SHARE_MEM_ALLOC) {
447 *resultData = AllocSharedMemory(imageInfo.size, bufferSize, fd, id);
448 cond = *resultData == nullptr;
449 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_CROP, "[PostProc]AllocSharedMemory failed");
450 } else {
451 cond = !AllocHeapBuffer(bufferSize, resultData);
452 CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_CROP);
453 }
454 return SUCCESS;
455 }
456
AllocHeapBuffer(uint64_t bufferSize,uint8_t ** buffer)457 bool PostProc::AllocHeapBuffer(uint64_t bufferSize, uint8_t **buffer)
458 {
459 bool cond = bufferSize == 0 || bufferSize > MALLOC_MAX_LENTH;
460 CHECK_ERROR_RETURN_RET_LOG(cond, false, "[PostProc]Invalid value of bufferSize");
461 *buffer = static_cast<uint8_t *>(malloc(bufferSize));
462 CHECK_ERROR_RETURN_RET_LOG(*buffer == nullptr, false,
463 "[PostProc]alloc covert color buffersize[%{public}llu] failed.", static_cast<unsigned long long>(bufferSize));
464 #ifdef _WIN32
465 errno_t backRet = memset_s(*buffer, 0, bufferSize);
466 if (backRet != EOK) {
467 IMAGE_LOGE("[PostProc]memset convertData fail, errorCode = %{public}d", backRet);
468 ReleaseBuffer(AllocatorType::HEAP_ALLOC, 0, 0, buffer);
469 return false;
470 }
471 return true;
472 #else
473 errno_t errRet = memset_s(*buffer, bufferSize, 0, bufferSize);
474 if (errRet != EOK) {
475 IMAGE_LOGE("[PostProc]memset convertData fail, errorCode = %{public}d", errRet);
476 ReleaseBuffer(AllocatorType::HEAP_ALLOC, 0, 0, buffer);
477 return false;
478 }
479 return true;
480 #endif
481 }
482
AllocSharedMemory(const Size & size,const uint64_t bufferSize,int & fd,uint32_t uniqueId)483 uint8_t *PostProc::AllocSharedMemory(const Size &size, const uint64_t bufferSize, int &fd, uint32_t uniqueId)
484 {
485 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
486 return nullptr;
487 #else
488 std::string name = "Parcel RawData, uniqueId: " + std::to_string(getpid()) + '_' + std::to_string(uniqueId);
489 fd = AshmemCreate(name.c_str(), bufferSize);
490 CHECK_ERROR_RETURN_RET_LOG(fd < 0, nullptr, "[PostProc]AllocSharedMemory fd error, bufferSize %{public}lld",
491 static_cast<long long>(bufferSize));
492 int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
493 if (result < 0) {
494 IMAGE_LOGE("[PostProc]AshmemSetProt error");
495 ::close(fd);
496 return nullptr;
497 }
498 void* ptr = ::mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
499 if (ptr == MAP_FAILED) {
500 IMAGE_LOGE("[PostProc]mmap error, errno: %{public}s, fd %{public}d, bufferSize %{public}lld",
501 strerror(errno), fd, (long long)bufferSize);
502 ::close(fd);
503 return nullptr;
504 }
505 return reinterpret_cast<uint8_t *>(ptr);
506 #endif
507 }
508
AllocDmaMemory(ImageInfo info,const uint64_t bufferSize,void ** nativeBuffer,int & targetRowStride)509 uint8_t *PostProc::AllocDmaMemory(ImageInfo info, const uint64_t bufferSize,
510 void **nativeBuffer, int &targetRowStride)
511 {
512 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
513 return nullptr;
514 #else
515 MemoryData memoryData = {nullptr, (uint32_t)bufferSize, "PostProc", {info.size.width, info.size.height}};
516 memoryData.format = info.pixelFormat;
517 auto dstMemory = MemoryManager::CreateMemory(AllocatorType::DMA_ALLOC, memoryData);
518 bool cond = dstMemory == nullptr;
519 CHECK_ERROR_RETURN_RET(cond, nullptr);
520 *nativeBuffer = dstMemory->extend.data;
521 auto sbBuffer = reinterpret_cast<SurfaceBuffer *>(dstMemory->extend.data);
522 targetRowStride = sbBuffer->GetStride();
523 return (uint8_t *)dstMemory->data.data;
524 #endif
525 }
526
ReleaseBuffer(AllocatorType allocatorType,int fd,uint64_t dataSize,uint8_t ** buffer,void * nativeBuffer)527 void PostProc::ReleaseBuffer(AllocatorType allocatorType, int fd,
528 uint64_t dataSize, uint8_t **buffer, void *nativeBuffer)
529 {
530 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
531 if (allocatorType == AllocatorType::SHARE_MEM_ALLOC) {
532 if (*buffer != nullptr) {
533 ::munmap(*buffer, dataSize);
534 ::close(fd);
535 }
536 return;
537 }
538 if (allocatorType == AllocatorType::DMA_ALLOC) {
539 if (nativeBuffer != nullptr) {
540 int32_t err = ImageUtils::SurfaceBuffer_Unreference(static_cast<SurfaceBuffer*>(nativeBuffer));
541 CHECK_ERROR_PRINT_LOG(err != OHOS::GSERROR_OK, "PostProc NativeBufferReference failed");
542 }
543 return;
544 }
545 #endif
546
547 if (allocatorType == AllocatorType::HEAP_ALLOC) {
548 if (*buffer != nullptr) {
549 free(*buffer);
550 *buffer = nullptr;
551 }
552 return;
553 }
554 }
555
NeedScanlineFilter(const Rect & cropRect,const Size & srcSize,const bool & hasPixelConvert)556 uint32_t PostProc::NeedScanlineFilter(const Rect &cropRect, const Size &srcSize, const bool &hasPixelConvert)
557 {
558 CropValue value = GetCropValue(cropRect, srcSize);
559 if (value == CropValue::NOCROP && !hasPixelConvert) {
560 IMAGE_LOGD("[PostProc]no need crop and pixel convert.");
561 return SUCCESS;
562 } else if (value == CropValue::INVALID) {
563 IMAGE_LOGE("[PostProc]invalid corp region, top:%{public}d, left:%{public}d, "
564 "width:%{public}d, height:%{public}d", cropRect.top, cropRect.left, cropRect.width, cropRect.height);
565 return ERR_IMAGE_CROP;
566 }
567 return NEED_NEXT;
568 }
569
ConvertPixelMapToPixmapInfo(PixelMap & pixelMap,PixmapInfo & pixmapInfo)570 void PostProc::ConvertPixelMapToPixmapInfo(PixelMap &pixelMap, PixmapInfo &pixmapInfo)
571 {
572 pixmapInfo.imageInfo.size.width = pixelMap.GetWidth();
573 pixmapInfo.imageInfo.size.height = pixelMap.GetHeight();
574 pixmapInfo.imageInfo.pixelFormat = pixelMap.GetPixelFormat();
575 pixmapInfo.imageInfo.colorSpace = pixelMap.GetColorSpace();
576 pixmapInfo.imageInfo.alphaType = pixelMap.GetAlphaType();
577 pixmapInfo.imageInfo.baseDensity = pixelMap.GetBaseDensity();
578 pixmapInfo.data = const_cast<uint8_t *>(pixelMap.GetPixels());
579 pixmapInfo.bufferSize = pixelMap.GetByteCount();
580 }
581
RotatePixelMap(float rotateDegrees,PixelMap & pixelMap)582 bool PostProc::RotatePixelMap(float rotateDegrees, PixelMap &pixelMap)
583 {
584 BasicTransformer trans;
585 PixmapInfo input(false);
586 ConvertPixelMapToPixmapInfo(pixelMap, input);
587 // Default rotation at the center of the image, so divide 2
588 trans.SetRotateParam(rotateDegrees, static_cast<float>(input.imageInfo.size.width) * FHALF,
589 static_cast<float>(input.imageInfo.size.height) * FHALF);
590 return Transform(trans, input, pixelMap);
591 }
592
ScalePixelMap(const Size & size,PixelMap & pixelMap)593 bool PostProc::ScalePixelMap(const Size &size, PixelMap &pixelMap)
594 {
595 int32_t srcWidth = pixelMap.GetWidth();
596 int32_t srcHeight = pixelMap.GetHeight();
597 bool cond = srcWidth <= 0 || srcHeight <= 0;
598 CHECK_ERROR_RETURN_RET_LOG(cond, false,
599 "[PostProc]src width:%{public}d, height:%{public}d is invalid.", srcWidth, srcHeight);
600 float scaleX = static_cast<float>(size.width) / static_cast<float>(srcWidth);
601 float scaleY = static_cast<float>(size.height) / static_cast<float>(srcHeight);
602 return ScalePixelMap(scaleX, scaleY, pixelMap);
603 }
604
ScalePixelMap(float scaleX,float scaleY,PixelMap & pixelMap)605 bool PostProc::ScalePixelMap(float scaleX, float scaleY, PixelMap &pixelMap)
606 {
607 // returns directly with a scale of 1.0
608 if ((fabs(scaleX - 1.0f) < EPSILON) && (fabs(scaleY - 1.0f) < EPSILON)) {
609 return true;
610 }
611 return pixelMap.resize(scaleX, scaleY);
612 }
TranslatePixelMap(float tX,float tY,PixelMap & pixelMap)613 bool PostProc::TranslatePixelMap(float tX, float tY, PixelMap &pixelMap)
614 {
615 BasicTransformer trans;
616 PixmapInfo input(false);
617 ConvertPixelMapToPixmapInfo(pixelMap, input);
618
619 trans.SetTranslateParam(tX, tY);
620 return Transform(trans, input, pixelMap);
621 }
622
Transform(BasicTransformer & trans,const PixmapInfo & input,PixelMap & pixelMap)623 bool PostProc::Transform(BasicTransformer &trans, const PixmapInfo &input, PixelMap &pixelMap)
624 {
625 if (pixelMap.IsTransformered()) {
626 IMAGE_LOGE("[PostProc]Transform pixelmap is transforming");
627 return false;
628 }
629 pixelMap.SetTransformered(true);
630 PixmapInfo output(false);
631 output.uniqueId = pixelMap.GetUniqueId();
632 uint32_t ret;
633 if (decodeOpts_.allocatorType == AllocatorType::SHARE_MEM_ALLOC) {
634 typedef uint8_t *(*AllocMemory)(const Size &size, const uint64_t bufferSize, int &fd, uint32_t uniqueId);
635 AllocMemory allcFunc = AllocSharedMemory;
636 ret = trans.TransformPixmap(input, output, allcFunc);
637 } else {
638 ret = trans.TransformPixmap(input, output);
639 }
640 if (ret != IMAGE_SUCCESS) {
641 output.Destroy();
642 return false;
643 }
644
645 if (pixelMap.SetImageInfo(output.imageInfo) != SUCCESS) {
646 output.Destroy();
647 return false;
648 }
649 pixelMap.SetPixelsAddr(output.data, output.context, output.bufferSize, decodeOpts_.allocatorType, nullptr);
650 pixelMap.SetTransformered(false);
651 return true;
652 }
653
GetCropValue(const Rect & rect,const Size & size)654 CropValue PostProc::GetCropValue(const Rect &rect, const Size &size)
655 {
656 bool isSameSize = (rect.top == 0 && rect.left == 0 && rect.height == size.height && rect.width == size.width);
657 if (!IsHasCrop(rect) || isSameSize) {
658 return CropValue::NOCROP;
659 }
660 bool isValid = ((rect.top >= 0 && rect.width > 0 && rect.left >= 0 && rect.height > 0) &&
661 (rect.top + rect.height <= size.height) && (rect.left + rect.width <= size.width));
662 if (!isValid) {
663 return CropValue::INVALID;
664 }
665 return CropValue::VALID;
666 }
667
ValidCropValue(Rect & rect,const Size & size)668 CropValue PostProc::ValidCropValue(Rect &rect, const Size &size)
669 {
670 CropValue res = GetCropValue(rect, size);
671 if (res == CropValue::INVALID) {
672 if (rect.top + rect.height > size.height) {
673 rect.height = size.height - rect.top;
674 }
675 if (rect.left + rect.width > size.width) {
676 rect.width = size.width - rect.left;
677 }
678 res = GetCropValue(rect, size);
679 }
680 return res;
681 }
682
IsHasCrop(const Rect & rect)683 bool PostProc::IsHasCrop(const Rect &rect)
684 {
685 return (rect.top != 0 || rect.left != 0 || rect.width != 0 || rect.height != 0);
686 }
687
HasPixelConvert(const ImageInfo & srcImageInfo,ImageInfo & dstImageInfo)688 bool PostProc::HasPixelConvert(const ImageInfo &srcImageInfo, ImageInfo &dstImageInfo)
689 {
690 dstImageInfo.alphaType = ImageUtils::GetValidAlphaTypeByFormat(dstImageInfo.alphaType, dstImageInfo.pixelFormat);
691 return (dstImageInfo.pixelFormat != srcImageInfo.pixelFormat || dstImageInfo.alphaType != srcImageInfo.alphaType);
692 }
693
SetScanlineCropAndConvert(const Rect & cropRect,ImageInfo & dstImageInfo,ImageInfo & srcImageInfo,ScanlineFilter & scanlineFilter,bool hasPixelConvert)694 void PostProc::SetScanlineCropAndConvert(const Rect &cropRect, ImageInfo &dstImageInfo, ImageInfo &srcImageInfo,
695 ScanlineFilter &scanlineFilter, bool hasPixelConvert)
696 {
697 if (hasPixelConvert) {
698 scanlineFilter.SetPixelConvert(srcImageInfo, dstImageInfo);
699 }
700
701 Rect srcRect = cropRect;
702 if (IsHasCrop(cropRect)) {
703 dstImageInfo.size.width = cropRect.width;
704 dstImageInfo.size.height = cropRect.height;
705 } else {
706 srcRect = { 0, 0, srcImageInfo.size.width, srcImageInfo.size.height };
707 dstImageInfo.size = srcImageInfo.size;
708 }
709 scanlineFilter.SetSrcRegion(srcRect);
710 }
711
712 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
GetScaleFormat(const PixelFormat & format,AVPixelFormat & pixelFormat)713 bool GetScaleFormat(const PixelFormat &format, AVPixelFormat &pixelFormat)
714 {
715 if (format != PixelFormat::UNKNOWN) {
716 auto formatPair = PIXEL_FORMAT_MAP.find(format);
717 if (formatPair != PIXEL_FORMAT_MAP.end() && formatPair->second != 0) {
718 pixelFormat = formatPair->second;
719 return true;
720 }
721 }
722 return false;
723 }
724
GetInterpolation(const AntiAliasingOption & option)725 int GetInterpolation(const AntiAliasingOption &option)
726 {
727 switch (option) {
728 case AntiAliasingOption::NONE:
729 return SWS_POINT;
730 case AntiAliasingOption::LOW:
731 return SWS_BILINEAR;
732 case AntiAliasingOption::MEDIUM:
733 return SWS_BICUBIC;
734 case AntiAliasingOption::HIGH:
735 return SWS_AREA;
736 case AntiAliasingOption::FAST_BILINEAER:
737 return SWS_FAST_BILINEAR;
738 case AntiAliasingOption::BICUBLIN:
739 return SWS_BICUBLIN;
740 case AntiAliasingOption::GAUSS:
741 return SWS_GAUSS;
742 case AntiAliasingOption::SINC:
743 return SWS_SINC;
744 case AntiAliasingOption::LANCZOS:
745 return SWS_LANCZOS;
746 case AntiAliasingOption::SPLINE:
747 return SWS_SPLINE;
748 default:
749 return SWS_POINT;
750 }
751 }
752
GetNewSkSLRCacheMgr()753 static SkSLRCacheMgr GetNewSkSLRCacheMgr()
754 {
755 static SkMutex slrMutex;
756 static SLRLRUCache slrCache(SLR_CACHE_CAPACITY);
757 return SkSLRCacheMgr(slrCache, slrMutex);
758 }
759
initSLRFactor(Size srcSize,Size dstSize)760 std::shared_ptr<SLRWeightTuple> initSLRFactor(Size srcSize, Size dstSize)
761 {
762 bool cond = srcSize.width == 0 || srcSize.height == 0 || dstSize.width == 0 || dstSize.height == 0;
763 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
764 "initSLRFactor invalid size, %{public}d, %{public}d, %{public}d, %{public}d",
765 srcSize.width, srcSize.height, dstSize.width, dstSize.height);
766 SkSLRCacheMgr cacheMgr = GetNewSkSLRCacheMgr();
767 SLRWeightKey key(srcSize, dstSize);
768 std::shared_ptr<SLRWeightTuple> weightTuplePtr = cacheMgr.find(key.fKey);
769 if (weightTuplePtr == nullptr) {
770 SLRWeightMat slrWeightX = SLRProc::GetWeights(static_cast<float>(dstSize.width) / srcSize.width,
771 static_cast<int>(dstSize.width));
772 SLRWeightMat slrWeightY = SLRProc::GetWeights(static_cast<float>(dstSize.height) / srcSize.height,
773 static_cast<int>(dstSize.height));
774 SLRWeightTuple value{slrWeightX, slrWeightY, key};
775 std::shared_ptr<SLRWeightTuple> weightPtr = std::make_shared<SLRWeightTuple>(value);
776 cacheMgr.insert(key.fKey, weightPtr);
777 IMAGE_LOGI("initSLRFactor insert:%{public}d", key.fKey);
778 return weightPtr;
779 }
780 return weightTuplePtr;
781 }
782
CheckPixelMapSLR(const Size & desiredSize,PixelMap & pixelMap)783 bool CheckPixelMapSLR(const Size &desiredSize, PixelMap &pixelMap)
784 {
785 ImageInfo imgInfo;
786 pixelMap.GetImageInfo(imgInfo);
787 bool cond = imgInfo.pixelFormat != PixelFormat::RGBA_8888;
788 CHECK_ERROR_RETURN_RET_LOG(cond, false, "CheckPixelMapSLR only support RGBA_8888 format");
789 int32_t srcWidth = pixelMap.GetWidth();
790 int32_t srcHeight = pixelMap.GetHeight();
791 cond = srcWidth <= 0 || srcHeight <= 0 || !pixelMap.GetWritablePixels();
792 CHECK_ERROR_RETURN_RET_LOG(cond, false,
793 "CheckPixelMapSLR invalid src size, %{public}d, %{public}d", srcWidth, srcHeight);
794
795 cond = desiredSize.width <= 0 || desiredSize.height <= 0;
796 CHECK_ERROR_RETURN_RET_LOG(cond, false, "CheckPixelMapSLR invalid desired size, %{public}d, %{public}d",
797 desiredSize.width, desiredSize.height);
798
799 cond = desiredSize.width == srcWidth && desiredSize.height == srcHeight;
800 CHECK_ERROR_RETURN_RET_LOG(cond, false, "CheckPixelMapSLR same source and desired size, %{public}d, %{public}d",
801 desiredSize.width, desiredSize.height);
802
803 cond = static_cast<float>(desiredSize.width) / srcWidth < EPSILON ||
804 static_cast<float>(desiredSize.height) / srcHeight < EPSILON;
805 CHECK_ERROR_RETURN_RET_LOG(cond, false, "CheckPixelMapSLR scaling factor overflow");
806
807 int32_t pixelBytes = pixelMap.GetPixelBytes();
808 CHECK_ERROR_RETURN_RET_LOG(pixelBytes <= 0, false, "CheckPixelMapSLR invalid pixel bytes, %{public}d", pixelBytes);
809
810 uint64_t dstSizeOverflow =
811 static_cast<uint64_t>(desiredSize.width) * static_cast<uint64_t>(desiredSize.height) *
812 static_cast<uint64_t>(pixelBytes);
813 CHECK_ERROR_RETURN_RET_LOG(dstSizeOverflow > UINT_MAX, false, "ScalePixelMapWithSLR desired size overflow");
814 return true;
815 }
816
817 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
818 static int g_minSize = 512;
819 static constexpr int g_maxTextureSize = 8192;
CheckPixelMapSLR(PixelMap & pixelMap,const Size & desiredSize,GPUTransformData & trans)820 static bool CheckPixelMapSLR(PixelMap &pixelMap, const Size &desiredSize, GPUTransformData &trans)
821 {
822 ImageInfo imgInfo;
823 pixelMap.GetImageInfo(imgInfo);
824 if (imgInfo.pixelFormat != PixelFormat::RGBA_8888) {
825 IMAGE_LOGE("slr_gpu CheckPixelMapSLR only support RGBA_8888 format %{public}d", imgInfo.pixelFormat);
826 return false;
827 }
828 int32_t srcWidth = pixelMap.GetWidth();
829 int32_t srcHeight = pixelMap.GetHeight();
830 if (srcWidth <= 0 || srcHeight <= 0 || !pixelMap.GetWritablePixels()) {
831 IMAGE_LOGE("slr_gpu CheckPixelMapSLR invalid src size, %{public}d, %{public}d", srcWidth, srcHeight);
832 return false;
833 }
834 if (desiredSize.width <= 0 || desiredSize.height <= 0) {
835 IMAGE_LOGE("slr_gpu CheckPixelMapSLR invalid desired size, %{public}d, %{public}d",
836 desiredSize.width, desiredSize.height);
837 return false;
838 }
839 int32_t pixelBytes = pixelMap.GetPixelBytes();
840 if (pixelBytes <= 0) {
841 IMAGE_LOGE("slr_gpu CheckPixelMapSLR invalid pixel bytes, %{public}d", pixelBytes);
842 return false;
843 }
844 if (srcWidth > g_maxTextureSize || srcHeight > g_maxTextureSize) {
845 IMAGE_LOGI("slr_gpu CheckPixelMapSLR The maximum width and height cannot exceed:%{public}d.", g_maxTextureSize);
846 return false;
847 }
848 uint64_t dstSizeOverflow = static_cast<uint64_t>(desiredSize.width) * static_cast<uint64_t>(desiredSize.height) *
849 static_cast<uint64_t>(pixelBytes);
850 if (dstSizeOverflow > UINT_MAX) {
851 IMAGE_LOGE("slr_gpu ScalePixelMapWithSLR desired size overflow");
852 return false;
853 }
854 if (trans.transformationType == TransformationType::SCALE &&
855 (srcWidth <= desiredSize.width || srcHeight <= desiredSize.height)) {
856 IMAGE_LOGI("slr_gpu CheckPixelMapSLR failed. Only zoom-out is supported.");
857 return false;
858 }
859 if (trans.transformationType == TransformationType::SCALE &&
860 (srcWidth * srcHeight < g_minSize * g_minSize)) {
861 IMAGE_LOGI("slr_gpu CheckPixelMapSLR failed. srcWidth * srcHeight < minSize * minSize.");
862 return false;
863 }
864 if (trans.transformationType == TransformationType::ROTATE &&
865 !(std::fabs(std::fmod(trans.rotateDegreeZ, 90.f)) < 1e-6)) {
866 IMAGE_LOGI("slr_gpu CheckPixelMapSLR failed. Only 90* is supported.");
867 return false;
868 }
869 return true;
870 }
871
GetPixelMapInfo(PixelMap & source,Size & size,GLenum & glFormat,int & perPixelSize)872 static void GetPixelMapInfo(PixelMap &source, Size &size, GLenum &glFormat, int &perPixelSize)
873 {
874 size = {
875 .width = source.GetWidth(),
876 .height = source.GetHeight(),
877 };
878 glFormat = GL_RGBA;
879 perPixelSize = ImageUtils::GetPixelBytes(PixelFormat::RGBA_8888);
880 PixelFormat originFormat = source.GetPixelFormat();
881 switch (originFormat) {
882 case PixelFormat::RGBA_8888:
883 glFormat = GL_RGBA;
884 break;
885 case PixelFormat::RGB_565:
886 glFormat = GL_RGB565;
887 perPixelSize = ImageUtils::GetPixelBytes(PixelFormat::RGB_565);
888 break;
889 case PixelFormat::RGB_888:
890 glFormat = GL_RGB;
891 perPixelSize = ImageUtils::GetPixelBytes(PixelFormat::RGB_888);
892 break;
893 case PixelFormat::BGRA_8888:
894 glFormat = GL_BGRA_EXT;
895 break;
896 case PixelFormat::ALPHA_8:
897 glFormat = GL_ALPHA8_EXT;
898 perPixelSize = ImageUtils::GetPixelBytes(PixelFormat::ALPHA_8);
899 break;
900 default:
901 IMAGE_LOGE("slr_gpu %{public}s format %{public}d is not support! ", __func__, originFormat);
902 break;
903 }
904 }
905
PixelMapPostProcWithGL(PixelMap & sourcePixelMap,GPUTransformData & trans,bool needHighQuality)906 static bool PixelMapPostProcWithGL(PixelMap &sourcePixelMap, GPUTransformData &trans, bool needHighQuality)
907 {
908 Size &desiredSize = trans.targetInfo_.size;
909 if (!CheckPixelMapSLR(sourcePixelMap, trans.targetInfo_.size, trans)) {
910 return false;
911 }
912 Size sourceSize;
913 GLenum glFormat = GL_RGBA;
914 int perPixelSize = ImageUtils::GetPixelBytes(sourcePixelMap.GetPixelFormat());
915 GetPixelMapInfo(sourcePixelMap, sourceSize, glFormat, perPixelSize);
916 ImageTrace imageTrace("PixelMapPostProcWithGL (%d, %d)=>(%d, %d) stride %d type %d transtype:%d",
917 sourceSize.width, sourceSize.height, desiredSize.width, desiredSize.height,
918 sourcePixelMap.GetRowStride(), (int)sourcePixelMap.GetAllocatorType(), (int)trans.transformationType);
919 IMAGE_LOGI("slr_gpu PixelMapPostProcWithGL uniqueId:%{public}d AllocatorType:%{public}d "
920 "size (%{public}d, %{public}d)=>(%{public}d, %{public}d) stride %{public}d transtype:%{public}d",
921 sourcePixelMap.GetUniqueId(), (int)sourcePixelMap.GetAllocatorType(), sourceSize.width, sourceSize.height,
922 desiredSize.width, desiredSize.height, sourcePixelMap.GetRowStride(), (int)trans.transformationType);
923 AllocatorType allocType = sourcePixelMap.GetAllocatorType();
924 size_t buffersize = static_cast<size_t>(4 * desiredSize.width * desiredSize.height); // 4: 4 bytes per pixel
925 MemoryData memoryData = {nullptr, buffersize, "PixelMapPostProcWithGL", desiredSize};
926 memoryData.usage = sourcePixelMap.GetNoPaddingUsage();
927 std::unique_ptr<AbsMemory> dstMemory = MemoryManager::CreateMemory(allocType, memoryData);
928 if (dstMemory == nullptr || dstMemory->data.data == nullptr) {
929 IMAGE_LOGE("slr_gpu PixelMapPostProcWithGL dstMemory is null");
930 return false;
931 }
932 int outputStride = 4 * desiredSize.width;
933 if (allocType == AllocatorType::DMA_ALLOC) {
934 SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*>(dstMemory->extend.data);
935 outputStride = sbBuffer->GetStride();
936 buffersize = static_cast<uint32_t>(sbBuffer->GetStride() * desiredSize.height);
937 }
938 PixelMapProgramManager::BuildShader();
939 bool ret = true;
940 auto program = PixelMapProgramManager::GetInstance().GetProgram();
941 if (program == nullptr) {
942 IMAGE_LOGE("slr_gpu PixelMapPostProcWithGL %{public}s create gl context failed", __func__);
943 ret = false;
944 } else {
945 trans.targetInfo_.stride = outputStride;
946 trans.targetInfo_.pixelBytes = perPixelSize;
947 trans.targetInfo_.outdata = dstMemory->data.data;
948 trans.targetInfo_.context = dstMemory->extend.data;
949 trans.glFormat = glFormat;
950 trans.isDma = allocType == AllocatorType::DMA_ALLOC ? true : false;
951 program->SetGPUTransformData(trans);
952 ret = PixelMapProgramManager::GetInstance().ExecutProgram(program);
953 }
954 if (!ret) {
955 dstMemory->Release();
956 IMAGE_LOGE("slr_gpu PixelMapPostProcWithGL Resize failed");
957 return false;
958 }
959 sourcePixelMap.SetPixelsAddr(dstMemory->data.data, dstMemory->extend.data,
960 desiredSize.height * outputStride, allocType, nullptr);
961 ImageInfo info;
962 info.size = desiredSize;
963 info.pixelFormat = PixelFormat::RGBA_8888;
964 info.alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
965 sourcePixelMap.SetImageInfo(info, true);
966 return true;
967 }
968 #endif
969
RotateInRectangularSteps(PixelMap & pixelMap,float degrees,bool useGpu)970 bool PostProc::RotateInRectangularSteps(PixelMap &pixelMap, float degrees, bool useGpu)
971 {
972 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
973 float oldDegrees = degrees;
974 if (useGpu && ImageSystemProperties::GetGenThumbWithGpu() &&
975 ImageSystemProperties::UseGPUScalingCapabilities() &&
976 std::fabs(std::fmod(degrees, 90.f)) < 1e-6) { // degrees 90
977 ImageTrace imageTrace("RotateInRectangularSteps:%f", degrees);
978 IMAGE_LOGI("slr_gpu RotateInRectangularSteps in :%{public}f", degrees);
979 GPUTransformData gpuTransform;
980 ImageInfo imageInfo;
981 pixelMap.GetImageInfo(imageInfo);
982 GlCommon::Mat4 tmpMat4;
983 std::array<float, 3> axis = { 0.0f, 0.0f, 1.0f }; // capacity 3
984 float angle = degrees * M_PI / 180.f; // degrees 180
985 gpuTransform.targetInfo_.size = {
986 std::abs(imageInfo.size.width * std::cos(angle)) + std::abs(imageInfo.size.height * std::sin(angle)),
987 std::abs(imageInfo.size.height * std::cos(angle)) + std::abs(imageInfo.size.width * std::sin(angle))
988 };
989 degrees = std::fmod(degrees, 360.f); // degrees 360
990 degrees = std::fmod(360.f - degrees, 360.f); // degrees 360
991 gpuTransform.rotateTrans = GlCommon::Mat4(tmpMat4, degrees, axis);
992 gpuTransform.rotateDegreeZ = degrees;
993 gpuTransform.sourceInfo_ = {
994 .size = imageInfo.size,
995 .stride = pixelMap.GetRowStride(),
996 .pixelBytes = ImageUtils::GetPixelBytes(pixelMap.GetPixelFormat()),
997 .addr = pixelMap.GetPixels(),
998 .context = pixelMap.GetFd(),
999 };
1000 gpuTransform.transformationType = TransformationType::ROTATE;
1001 if (PixelMapPostProcWithGL(pixelMap, gpuTransform, true)) {
1002 IMAGE_LOGI("slr_gpu RotateInRectangularSteps success");
1003 return true;
1004 }
1005 IMAGE_LOGI("slr_gpu RotateInRectangularSteps rotate with cpu");
1006 }
1007 #endif
1008 pixelMap.rotate(oldDegrees);
1009 return true;
1010 }
1011
ScalePixelMapWithGPU(PixelMap & pixelMap,const Size & desiredSize,const AntiAliasingOption & option,bool useGpu)1012 bool PostProc::ScalePixelMapWithGPU(PixelMap &pixelMap, const Size &desiredSize,
1013 const AntiAliasingOption &option, bool useGpu)
1014 {
1015 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1016 if (useGpu && ImageSystemProperties::GetGenThumbWithGpu() &&
1017 ImageSystemProperties::UseGPUScalingCapabilities() &&
1018 option == AntiAliasingOption::HIGH) {
1019 ImageTrace imageTrace("ScalePixelMapWithGPU:wh(%d,%d)->(%d,%d)",
1020 pixelMap.GetWidth(), pixelMap.GetHeight(), desiredSize.width, desiredSize.height);
1021 IMAGE_LOGI("slr_gpu ScalePixelMapWithGPU:wh(%{public}d,%{public}d)->(%{public}d,%{public}d)",
1022 pixelMap.GetWidth(), pixelMap.GetHeight(), desiredSize.width, desiredSize.height);
1023 GPUTransformData gpuTransform;
1024 gpuTransform.targetInfo_.size = desiredSize;
1025 ImageInfo imageInfo;
1026 pixelMap.GetImageInfo(imageInfo);
1027 gpuTransform.sourceInfo_ = {
1028 .size = imageInfo.size,
1029 .stride = pixelMap.GetRowStride(),
1030 .pixelBytes = ImageUtils::GetPixelBytes(pixelMap.GetPixelFormat()),
1031 .addr = pixelMap.GetPixels(),
1032 .context = pixelMap.GetFd(),
1033 };
1034 gpuTransform.transformationType = TransformationType::SCALE;
1035 if (PixelMapPostProcWithGL(pixelMap, gpuTransform, true)) {
1036 IMAGE_LOGI("slr_gpu ScalePixelMapWithGPU success");
1037 return true;
1038 }
1039 IMAGE_LOGI("slr_gpu ScalePixelMapWithGPU failed scale with cpu");
1040 }
1041 #endif
1042 PostProc postProc;
1043 return postProc.ScalePixelMapEx(desiredSize, pixelMap, option);
1044 }
1045
CreateSLRMemory(PixelMap & pixelMap,uint32_t dstBufferSize,const Size & desiredSize,std::unique_ptr<AbsMemory> & dstMemory,bool useLap)1046 static std::unique_ptr<AbsMemory> CreateSLRMemory(PixelMap &pixelMap, uint32_t dstBufferSize, const Size &desiredSize,
1047 std::unique_ptr<AbsMemory> &dstMemory, bool useLap)
1048 {
1049 AllocatorType allocatorType = pixelMap.GetAllocatorType();
1050 if (useLap && allocatorType == AllocatorType::DMA_ALLOC) {
1051 allocatorType = AllocatorType::SHARE_MEM_ALLOC;
1052 }
1053 MemoryData memoryData = {nullptr, dstBufferSize, "ScalePixelMapWithSLR ImageData", desiredSize,
1054 pixelMap.GetPixelFormat()};
1055 memoryData.usage = pixelMap.GetNoPaddingUsage();
1056 dstMemory = MemoryManager::CreateMemory(allocatorType, memoryData);
1057 CHECK_ERROR_RETURN_RET_LOG(dstMemory == nullptr, nullptr, "ScalePixelMapWithSLR create dstMemory failed");
1058 std::unique_ptr<AbsMemory> lapMemory = nullptr;
1059 if (useLap) {
1060 MemoryData lapMemoryData = {nullptr, dstBufferSize, "ScalePixelMapWithSLR ImageData Lap", desiredSize,
1061 pixelMap.GetPixelFormat()};
1062 lapMemoryData.usage = pixelMap.GetNoPaddingUsage();
1063 lapMemory = MemoryManager::CreateMemory(pixelMap.GetAllocatorType(), lapMemoryData);
1064 if (lapMemory == nullptr) {
1065 IMAGE_LOGE("ScalePixelMapWithSLR create lapMemory failed");
1066 dstMemory->Release();
1067 return nullptr;
1068 }
1069 }
1070 return lapMemory;
1071 }
1072
getLapFactor(const ImageInfo & imgInfo,const Size & desiredSize)1073 float getLapFactor(const ImageInfo& imgInfo, const Size &desiredSize)
1074 {
1075 float coeff = ((float)desiredSize.width) / imgInfo.size.width;
1076 if (coeff > 0.8f) {
1077 return .0f;
1078 }
1079 if (coeff > 0.6f) {
1080 return 0.06f;
1081 }
1082 if (coeff > 0.5f) {
1083 return 0.1f;
1084 }
1085 return 0.15f;
1086 }
1087
1088 struct SLRContext {
1089 void *data;
1090 bool useLap;
1091 };
1092
ExecuteSLR(PixelMap & pixelMap,const Size & desiredSize,SLRMat & src,SLRMat & dst,SLRContext scalingContext)1093 bool ExecuteSLR(PixelMap& pixelMap, const Size& desiredSize, SLRMat &src, SLRMat &dst,
1094 SLRContext scalingContext)
1095 {
1096 ImageInfo imgInfo;
1097 pixelMap.GetImageInfo(imgInfo);
1098 std::shared_ptr<SLRWeightTuple> weightTuplePtr = initSLRFactor(imgInfo.size, desiredSize);
1099 CHECK_ERROR_RETURN_RET_LOG(weightTuplePtr == nullptr, false, "PostProcExecuteSLR init failed");
1100 SLRWeightMat slrWeightX = std::get<0>(*weightTuplePtr);
1101 SLRWeightMat slrWeightY = std::get<1>(*weightTuplePtr);
1102 if (ImageSystemProperties::GetSLRParallelEnabled()) {
1103 SLRProc::Parallel(src, dst, slrWeightX, slrWeightY);
1104 } else {
1105 SLRProc::Serial(src, dst, slrWeightX, slrWeightY);
1106 }
1107 if (scalingContext.useLap) {
1108 float factor = getLapFactor(imgInfo, desiredSize);
1109 SLRProc::Laplacian(dst, scalingContext.data, factor);
1110 }
1111 return true;
1112 }
1113
ScalePixelMapWithSLR(const Size & desiredSize,PixelMap & pixelMap,bool useLap)1114 bool PostProc::ScalePixelMapWithSLR(const Size &desiredSize, PixelMap &pixelMap, bool useLap)
1115 {
1116 ImageInfo imgInfo;
1117 pixelMap.GetImageInfo(imgInfo);
1118 bool cond = !CheckPixelMapSLR(desiredSize, pixelMap);
1119 CHECK_ERROR_RETURN_RET(cond, false);
1120 useLap = useLap && ImageSystemProperties::GetSLRLaplacianEnabled();
1121 ImageTrace imageTrace("ScalePixelMapWithSLR");
1122 int32_t pixelBytes = pixelMap.GetPixelBytes();
1123 SLRMat src(imgInfo.size, imgInfo.pixelFormat, pixelMap.GetWritablePixels(), pixelMap.GetRowStride() / pixelBytes);
1124 uint32_t dstBufferSize = desiredSize.height * desiredSize.width * pixelBytes;
1125 std::unique_ptr<AbsMemory> m = nullptr;
1126 auto lapMemory = CreateSLRMemory(pixelMap, dstBufferSize, desiredSize, m, useLap);
1127 cond = m == nullptr || (useLap && (lapMemory == nullptr));
1128 CHECK_ERROR_RETURN_RET_LOG(cond, false, "pixelMap scale slr memory nullptr");
1129 size_t rowStride;
1130 if (m->GetType() == AllocatorType::DMA_ALLOC) {
1131 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
1132 rowStride = reinterpret_cast<SurfaceBuffer*>(m->extend.data)->GetStride();
1133 #endif
1134 } else {
1135 rowStride = desiredSize.width * pixelBytes;
1136 }
1137 void *data = useLap ? lapMemory->data.data : m->data.data;
1138 SLRMat dst({desiredSize.width, desiredSize.height}, imgInfo.pixelFormat, data, rowStride / pixelBytes);
1139 if (!ExecuteSLR(pixelMap, desiredSize, src, dst, {m->data.data, useLap})) {
1140 m->Release();
1141 if (useLap && lapMemory) {
1142 lapMemory->Release();
1143 }
1144 return false;
1145 }
1146 pixelMap.SetPixelsAddr(m->data.data, m->extend.data, dstBufferSize, m->GetType(), nullptr);
1147 imgInfo.size = desiredSize;
1148 pixelMap.SetImageInfo(imgInfo, true);
1149 if (m->GetType() == AllocatorType::DMA_ALLOC) {
1150 ImageUtils::FlushSurfaceBuffer(&pixelMap);
1151 }
1152 if (lapMemory) {
1153 lapMemory->Release();
1154 }
1155 return true;
1156 }
1157
ScalePixelMapEx(const Size & desiredSize,PixelMap & pixelMap,const AntiAliasingOption & option)1158 bool PostProc::ScalePixelMapEx(const Size &desiredSize, PixelMap &pixelMap, const AntiAliasingOption &option)
1159 {
1160 ImageTrace imageTrace("PixelMap ScalePixelMapEx, srcSize[%d, %d], dstSize[%d, %d] ",
1161 pixelMap.GetWidth(), pixelMap.GetHeight(), desiredSize.width, desiredSize.height);
1162 IMAGE_LOGI("slr_gpu ScalePixelMapEx pixelMap: width = %{public}d, height = %{public}d, pixelFormat = %{public}d, "
1163 "allocatorType = %{public}d; desiredSize: width = %{public}d, height = %{public}d",
1164 pixelMap.GetWidth(), pixelMap.GetHeight(), pixelMap.GetPixelFormat(),
1165 pixelMap.GetAllocatorType(), desiredSize.width, desiredSize.height);
1166 ImageInfo imgInfo;
1167 pixelMap.GetImageInfo(imgInfo);
1168 int32_t srcWidth = pixelMap.GetWidth();
1169 int32_t srcHeight = pixelMap.GetHeight();
1170 bool cond = srcWidth <= 0 || srcHeight <= 0 || !pixelMap.GetWritablePixels();
1171 CHECK_ERROR_RETURN_RET_LOG(cond, false, "pixelMap param is invalid, src width:%{public}d, height:%{public}d",
1172 srcWidth, srcHeight);
1173 AVPixelFormat pixelFormat;
1174 cond = !GetScaleFormat(imgInfo.pixelFormat, pixelFormat);
1175 CHECK_ERROR_RETURN_RET_LOG(cond, false, "pixelMap format is invalid, format: %{public}d", imgInfo.pixelFormat);
1176 uint64_t dstBufferSizeOverflow =
1177 static_cast<uint64_t>(desiredSize.width) * static_cast<uint64_t>(desiredSize.height) *
1178 static_cast<uint64_t>(ImageUtils::GetPixelBytes(imgInfo.pixelFormat));
1179 CHECK_ERROR_RETURN_RET_LOG(dstBufferSizeOverflow > UINT_MAX, false, "ScalePixelMapEx target size too large");
1180 uint32_t dstBufferSize = static_cast<uint32_t>(dstBufferSizeOverflow);
1181 MemoryData memoryData = {nullptr, dstBufferSize, "ScalePixelMapEx ImageData", desiredSize};
1182 memoryData.usage = pixelMap.GetNoPaddingUsage();
1183 auto mem = MemoryManager::CreateMemory(pixelMap.GetAllocatorType() == AllocatorType::CUSTOM_ALLOC ?
1184 AllocatorType::DEFAULT : pixelMap.GetAllocatorType(), memoryData);
1185 CHECK_ERROR_RETURN_RET_LOG(mem == nullptr, false, "ScalePixelMapEx CreateMemory failed");
1186
1187 const uint8_t *srcPixels[FFMPEG_NUM] = {};
1188 uint8_t *dstPixels[FFMPEG_NUM] = {};
1189 srcPixels[0] = pixelMap.GetPixels();
1190 dstPixels[0] = reinterpret_cast<uint8_t *>(mem->data.data);
1191 int srcRowStride[FFMPEG_NUM] = {};
1192 int dstRowStride[FFMPEG_NUM] = {};
1193 srcRowStride[0] = pixelMap.GetRowStride();
1194 dstRowStride[0] = (mem->GetType() == AllocatorType::DMA_ALLOC) ?
1195 reinterpret_cast<SurfaceBuffer*>(mem->extend.data)->GetStride() :
1196 desiredSize.width * ImageUtils::GetPixelBytes(imgInfo.pixelFormat);
1197
1198 void *inBuf = nullptr;
1199 if (srcWidth % HALF != 0 && pixelMap.GetAllocatorType() == AllocatorType::SHARE_MEM_ALLOC) {
1200 // Workaround for crash on odd number width, caused by FFmpeg 5.0 upgrade
1201 uint64_t byteCount = static_cast<uint64_t>(srcRowStride[0]) * static_cast<uint64_t>(srcHeight);
1202 uint64_t allocSize = static_cast<uint64_t>(srcWidth + 1) * static_cast<uint64_t>(srcHeight) *
1203 static_cast<uint64_t>(ImageUtils::GetPixelBytes(imgInfo.pixelFormat));
1204 if (srcRowStride[0] <= 0 || byteCount > UINT_MAX || allocSize < byteCount || allocSize > UINT_MAX) {
1205 mem->Release();
1206 IMAGE_LOGE("ScalePixelMapEx invalid srcRowStride or pixelMap size too large");
1207 return false;
1208 }
1209 inBuf = malloc(allocSize);
1210 srcPixels[0] = reinterpret_cast<uint8_t*>(inBuf);
1211 errno_t errRet = memcpy_s(inBuf, allocSize, pixelMap.GetWritablePixels(), byteCount);
1212 if (errRet != EOK) {
1213 if (inBuf != nullptr) {
1214 free(inBuf);
1215 }
1216 mem->Release();
1217 IMAGE_LOGE("ScalePixelMapEx memcpy_s failed with error code: %{public}d", errRet);
1218 return false;
1219 }
1220 }
1221
1222 SwsContext *swsContext = sws_getContext(srcWidth, srcHeight, pixelFormat, desiredSize.width, desiredSize.height,
1223 pixelFormat, GetInterpolation(option), nullptr, nullptr, nullptr);
1224 if (swsContext == nullptr) {
1225 if (inBuf != nullptr) {
1226 free(inBuf);
1227 }
1228 mem->Release();
1229 IMAGE_LOGE("sws_getContext failed");
1230 return false;
1231 }
1232 auto res = sws_scale(swsContext, srcPixels, srcRowStride, 0, srcHeight, dstPixels, dstRowStride);
1233
1234 sws_freeContext(swsContext);
1235 if (inBuf != nullptr) {
1236 free(inBuf);
1237 }
1238 if (!res) {
1239 mem->Release();
1240 IMAGE_LOGE("sws_scale failed");
1241 return false;
1242 }
1243 pixelMap.SetPixelsAddr(mem->data.data, mem->extend.data, dstBufferSize, mem->GetType(), nullptr);
1244 imgInfo.size = desiredSize;
1245 pixelMap.SetImageInfo(imgInfo, true);
1246 ImageUtils::FlushSurfaceBuffer(&pixelMap);
1247 return true;
1248 }
1249 #endif
1250 } // namespace Media
1251 } // namespace OHOS
1252