1 /*
2 * Copyright (C) 2023 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 "ext_encoder.h"
17 #include <algorithm>
18 #include <map>
19
20 #include "include/core/SkImageEncoder.h"
21 #include "src/images/SkImageEncoderFns.h"
22 #include "include/core/SkBitmap.h"
23 #include "pixel_yuv_utils.h"
24 #ifdef IMAGE_COLORSPACE_FLAG
25 #include "color_space.h"
26 #endif
27 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
28 #include "astc_codec.h"
29 #endif
30
31 #include "ext_pixel_convert.h"
32 #include "ext_wstream.h"
33 #include "image_data_statistics.h"
34 #include "image_dfx.h"
35 #include "image_func_timer.h"
36 #include "image_fwk_ext_manager.h"
37 #include "image_log.h"
38 #include "image_system_properties.h"
39 #include "image_type_converter.h"
40 #include "image_utils.h"
41 #include "jpeg_mpf_parser.h"
42 #include "media_errors.h"
43 #include "metadata_accessor.h"
44 #include "metadata_accessor_factory.h"
45 #include "pixel_map_utils.h"
46 #include "pixel_convert_adapter.h"
47 #include "string_ex.h"
48 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
49 #include "surface_buffer.h"
50 #include "v1_0/buffer_handle_meta_key_type.h"
51 #include "v1_0/cm_color_space.h"
52 #include "v1_0/hdr_static_metadata.h"
53 #include "vpe_utils.h"
54 #include "hdr_helper.h"
55 #endif
56 #include "color_utils.h"
57 #include "tiff_parser.h"
58 #include "image_mime_type.h"
59 #include "securec.h"
60 #include "file_packer_stream.h"
61 #include "memory_manager.h"
62 #ifdef HEIF_HW_ENCODE_ENABLE
63 #include "v2_0/icodec_image.h"
64 #include "iremote_object.h"
65 #include "iproxy_broker.h"
66 #endif
67
68 #undef LOG_DOMAIN
69 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_PLUGIN
70
71 #undef LOG_TAG
72 #define LOG_TAG "ExtEncoder"
73
74 namespace OHOS {
75 namespace ImagePlugin {
76 using namespace Media;
77 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
78 using namespace HDI::Display::Graphic::Common::V1_0;
79 const std::map<PixelFormat, GraphicPixelFormat> SURFACE_FORMAT_MAP = {
80 { PixelFormat::RGBA_8888, GRAPHIC_PIXEL_FMT_RGBA_8888 },
81 { PixelFormat::NV21, GRAPHIC_PIXEL_FMT_YCRCB_420_SP },
82 { PixelFormat::NV12, GRAPHIC_PIXEL_FMT_YCBCR_420_SP },
83 };
84 #endif
85
86 namespace {
87 constexpr static uint32_t PRIMARY_IMAGE_ITEM_ID = 1;
88 constexpr static uint32_t GAINMAP_IMAGE_ITEM_ID = 2;
89 constexpr static uint32_t TMAP_IMAGE_ITEM_ID = 3;
90 constexpr static uint32_t EXIF_META_ITEM_ID = 4;
91 constexpr static uint32_t DEPTH_MAP_ITEM_ID = 5;
92 constexpr static uint32_t UNREFOCUS_MAP_ITEM_ID = 6;
93 constexpr static uint32_t LINEAR_MAP_ITEM_ID = 7;
94 constexpr static uint32_t FRAGMENT_MAP_ITEM_ID = 8;
95 const static std::string COMPRESS_TYPE_TMAP = "tmap";
96 const static std::string COMPRESS_TYPE_HEVC = "hevc";
97 const static std::string COMPRESS_TYPE_NONE = "none";
98 const static std::string DEFAULT_ASHMEM_TAG = "Heif Encoder Default";
99 const static std::string ICC_ASHMEM_TAG = "Heif Encoder Property";
100 const static std::string IT35_ASHMEM_TAG = "Heif Encoder IT35";
101 const static std::string OUTPUT_ASHMEM_TAG = "Heif Encoder Output";
102 const static std::string IMAGE_DATA_TAG = "Heif Encoder Image";
103 const static std::string HDR_GAINMAP_TAG = "Heif Encoder Gainmap";
104 const static std::string EXIF_ASHMEM_TAG = "Heif Encoder Exif";
105 const static std::string GAINMAP_IMAGE_ITEM_NAME = "Gain map Image";
106 const static std::string DEPTH_MAP_ITEM_NAME = "Depth Map Image";
107 const static std::string UNREFOCUS_MAP_ITEM_NAME = "Unrefocus Map Image";
108 const static std::string LINEAR_MAP_ITEM_NAME = "Linear Map Image";
109 const static std::string FRAGMENT_MAP_ITEM_NAME = "Fragment Map Image";
110 const static size_t DEFAULT_OUTPUT_SIZE = 35 * 1024 * 1024; // 35M
111 const static uint16_t STATIC_METADATA_COLOR_SCALE = 50000;
112 const static uint16_t STATIC_METADATA_LUM_SCALE = 10000;
113 const static uint8_t INDEX_ZERO = 0;
114 const static uint8_t INDEX_ONE = 1;
115 const static uint8_t INDEX_TWO = 2;
116 constexpr uint32_t DEFAULT_DENOMINATOR = 1000000;
117 constexpr uint8_t GAINMAP_CHANNEL_MULTI = 3;
118 constexpr uint8_t GAINMAP_CHANNEL_SINGLE = 1;
119 constexpr uint8_t EXIF_PRE_SIZE = 6;
120 constexpr uint32_t JPEG_MARKER_TAG_SIZE = 2;
121 constexpr uint32_t DEPTH_MAP_BYTES = sizeof(float); // float16
122 constexpr uint32_t LINEAR_MAP_BYTES = sizeof(short) * 3 / 2; // 16bit yuv420
123 constexpr uint32_t PLACE_HOLDER_LENGTH = 1;
124 constexpr uint32_t LOW_QUALITY_BOUNDARY = 85;
125
126 // exif/0/0
127 constexpr uint8_t EXIF_PRE_TAG[EXIF_PRE_SIZE] = {
128 0x45, 0x78, 0x69, 0x66, 0x00, 0x00
129 };
130 }
131
132 struct HeifEncodeItemInfo {
133 uint32_t itemId = 0;
134 std::string itemName = "";
135 std::string itemType = "";
136 };
137
138 static const std::map<std::string, SkEncodedImageFormat> FORMAT_NAME = {
139 {IMAGE_BMP_FORMAT, SkEncodedImageFormat::kBMP},
140 {IMAGE_GIF_FORMAT, SkEncodedImageFormat::kGIF},
141 {IMAGE_ICO_FORMAT, SkEncodedImageFormat::kICO},
142 {IMAGE_JPEG_FORMAT, SkEncodedImageFormat::kJPEG},
143 {IMAGE_PNG_FORMAT, SkEncodedImageFormat::kPNG},
144 {IMAGE_WBMP_FORMAT, SkEncodedImageFormat::kWBMP},
145 {IMAGE_WEBP_FORMAT, SkEncodedImageFormat::kWEBP},
146 {IMAGE_HEIF_FORMAT, SkEncodedImageFormat::kHEIF},
147 {IMAGE_HEIC_FORMAT, SkEncodedImageFormat::kHEIF},
148 };
149
150 static const std::map<AuxiliaryPictureType, std::string> DEFAULT_AUXILIARY_TAG_MAP = {
151 {AuxiliaryPictureType::GAINMAP, AUXILIARY_TAG_GAINMAP},
152 {AuxiliaryPictureType::DEPTH_MAP, AUXILIARY_TAG_DEPTH_MAP_BACK},
153 {AuxiliaryPictureType::UNREFOCUS_MAP, AUXILIARY_TAG_UNREFOCUS_MAP},
154 {AuxiliaryPictureType::LINEAR_MAP, AUXILIARY_TAG_LINEAR_MAP},
155 {AuxiliaryPictureType::FRAGMENT_MAP, AUXILIARY_TAG_FRAGMENT_MAP},
156 };
157
158 static const uint8_t NUM_3 = 3;
159 static const uint8_t NUM_4 = 4;
160 static const uint8_t RGBA_BIT_DEPTH = 4;
161
162 static constexpr int32_t MAX_IMAGE_SIZE = 8196;
163 static constexpr int32_t MIN_IMAGE_SIZE = 128;
164 static constexpr int32_t MIN_RGBA_IMAGE_SIZE = 1024;
165
166 #ifdef HEIF_HW_ENCODE_ENABLE
167 using namespace OHOS::HDI::Codec::Image::V2_0;
168 static std::mutex g_codecMtx;
169 static sptr<ICodecImage> g_codecMgr;
170 class CodecHeifDeathRecipient : public IRemoteObject::DeathRecipient {
171 public:
OnRemoteDied(const wptr<OHOS::IRemoteObject> & object)172 void OnRemoteDied(const wptr<OHOS::IRemoteObject>& object) override
173 {
174 IMAGE_LOGW("codec_image_service died");
175 std::lock_guard<std::mutex> lk(g_codecMtx);
176 g_codecMgr = nullptr;
177 }
178 };
179
GetCodecManager()180 static sptr<ICodecImage> GetCodecManager()
181 {
182 std::lock_guard<std::mutex> lk(g_codecMtx);
183 if (g_codecMgr) {
184 return g_codecMgr;
185 }
186 IMAGE_LOGI("need to get ICodecImage");
187 g_codecMgr = ICodecImage::Get();
188 bool cond = g_codecMgr == nullptr;
189 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "ICodecImage get failed");
190 bool isDeathRecipientAdded = false;
191 const sptr<OHOS::IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ICodecImage>(g_codecMgr);
192 if (remote) {
193 sptr<CodecHeifDeathRecipient> deathCallBack(new CodecHeifDeathRecipient());
194 isDeathRecipientAdded = remote->AddDeathRecipient(deathCallBack);
195 }
196 if (!isDeathRecipientAdded) {
197 IMAGE_LOGI("failed to add deathRecipient for ICodecImage!");
198 }
199 return g_codecMgr;
200 }
201 #endif
202
ExtEncoder()203 ExtEncoder::ExtEncoder()
204 {
205 }
206
~ExtEncoder()207 ExtEncoder::~ExtEncoder()
208 {
209 if (releasePixelMap_ && pixelmap_ != nullptr) {
210 delete pixelmap_;
211 pixelmap_ = nullptr;
212 }
213 if (releasePicture_ && picture_ != nullptr) {
214 delete picture_;
215 picture_ = nullptr;
216 }
217 }
218
StartEncode(OutputDataStream & outputStream,PlEncodeOptions & option)219 uint32_t ExtEncoder::StartEncode(OutputDataStream &outputStream, PlEncodeOptions &option)
220 {
221 output_ = &outputStream;
222 opts_ = option;
223 return SUCCESS;
224 }
225
AddImage(PixelMap & pixelMap)226 uint32_t ExtEncoder::AddImage(PixelMap &pixelMap)
227 {
228 pixelmap_ = &pixelMap;
229 return SUCCESS;
230 }
231
AddPicture(Media::Picture & picture)232 uint32_t ExtEncoder::AddPicture(Media::Picture &picture)
233 {
234 picture_ = &picture;
235 return SUCCESS;
236 }
237
238 struct TmpBufferHolder {
239 std::unique_ptr<uint8_t[]> buf = nullptr;
240 };
241
242 struct ImageData {
243 uint8_t *dst;
244 uint8_t *pixels;
245 ImageInfo info;
246 };
247
ToSkColorSpace(PixelMap * pixelmap)248 static sk_sp<SkColorSpace> ToSkColorSpace(PixelMap *pixelmap)
249 {
250 #ifdef IMAGE_COLORSPACE_FLAG
251 bool cond = pixelmap->InnerGetGrColorSpacePtr() == nullptr;
252 CHECK_ERROR_RETURN_RET(cond, nullptr);
253
254 cond = pixelmap->InnerGetGrColorSpace().GetColorSpaceName() == ColorManager::ColorSpaceName::NONE;
255 CHECK_ERROR_RETURN_RET(cond, SkColorSpace::MakeSRGB());
256 return pixelmap->InnerGetGrColorSpacePtr()->ToSkColorSpace();
257 #else
258 return nullptr;
259 #endif
260 }
261
ToSkInfo(Media::PixelMap * pixelMap)262 static SkImageInfo ToSkInfo(Media::PixelMap *pixelMap)
263 {
264 ImageInfo info;
265 pixelMap->GetImageInfo(info);
266 SkColorType colorType = ImageTypeConverter::ToSkColorType(info.pixelFormat);
267 SkAlphaType alphaType = ImageTypeConverter::ToSkAlphaType(info.alphaType);
268 sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
269 #ifdef IMAGE_COLORSPACE_FLAG
270 if (pixelMap->InnerGetGrColorSpacePtr() != nullptr &&
271 pixelMap->InnerGetGrColorSpace().GetColorSpaceName() != ColorManager::ColorSpaceName::NONE) {
272 colorSpace = pixelMap->InnerGetGrColorSpacePtr()->ToSkColorSpace();
273 }
274 #endif
275 return SkImageInfo::Make(info.size.width, info.size.height, colorType, alphaType, colorSpace);
276 }
277
RGBToRGBx(PixelMap * pixelMap,SkImageInfo & skInfo,TmpBufferHolder & holder)278 static uint32_t RGBToRGBx(PixelMap *pixelMap, SkImageInfo &skInfo, TmpBufferHolder &holder)
279 {
280 holder.buf = std::make_unique<uint8_t[]>(skInfo.computeMinByteSize());
281 ExtPixels src = {
282 static_cast<uint8_t*>(pixelMap->GetWritablePixels()),
283 pixelMap->GetCapacity(), pixelMap->GetWidth()*pixelMap->GetHeight(),
284 };
285 ExtPixels dst = {
286 holder.buf.get(), skInfo.computeMinByteSize(), skInfo.width()*skInfo.height(),
287 };
288 return ExtPixelConvert::RGBToRGBx(src, dst);
289 }
290
IsYuvImage(PixelFormat format)291 static bool IsYuvImage(PixelFormat format)
292 {
293 return format == PixelFormat::NV21 || format == PixelFormat::NV12;
294 }
295
YuvToRgbaSkInfo(ImageInfo info,SkImageInfo & skInfo,uint8_t * dstData,Media::PixelMap * pixelMap)296 static uint32_t YuvToRgbaSkInfo(ImageInfo info, SkImageInfo &skInfo, uint8_t * dstData, Media::PixelMap *pixelMap)
297 {
298 uint8_t *srcData = static_cast<uint8_t*>(pixelMap->GetWritablePixels());
299 YUVDataInfo yuvInfo;
300 pixelMap->GetImageYUVInfo(yuvInfo);
301 YuvImageInfo srcInfo = {PixelYuvUtils::ConvertFormat(info.pixelFormat),
302 info.size.width, info.size.height, info.pixelFormat, yuvInfo};
303 YuvImageInfo dstInfo = {PixelYuvUtils::ConvertFormat(PixelFormat::RGBA_8888), info.size.width, info.size.height};
304 bool cond = !PixelConvertAdapter::YUV420ToRGB888(srcData, srcInfo, dstData, dstInfo);
305 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "YuvToSkInfo Support YUV format RGB convert failed ");
306 auto alpha = pixelMap->GetAlphaType();
307 if (alpha == AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN)
308 alpha = AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
309 SkAlphaType alphaType = ImageTypeConverter::ToSkAlphaType(alpha);
310 auto cs = ToSkColorSpace(pixelMap);
311 skInfo = SkImageInfo::Make(info.size.width, info.size.height, SkColorType::kRGBA_8888_SkColorType, alphaType, cs);
312 IMAGE_LOGD(" YuvToSkInfo: width:%{public}d, height:%{public}d, alpha:%{public}d \n ",
313 info.size.width, info.size.height, (int32_t)alphaType);
314 return SUCCESS;
315 }
316
pixelToSkInfo(ImageData & image,SkImageInfo & skInfo,Media::PixelMap * pixelMap,TmpBufferHolder & holder,SkEncodedImageFormat format)317 static uint32_t pixelToSkInfo(ImageData &image, SkImageInfo &skInfo, Media::PixelMap *pixelMap,
318 TmpBufferHolder &holder, SkEncodedImageFormat format)
319 {
320 skInfo = ToSkInfo(pixelMap);
321 image.pixels = static_cast<uint8_t*>(pixelMap->GetWritablePixels());
322 if (format == SkEncodedImageFormat::kJPEG &&
323 skInfo.colorType() == SkColorType::kRGB_888x_SkColorType &&
324 pixelMap->GetCapacity() < skInfo.computeMinByteSize()) {
325 uint32_t res = RGBToRGBx(pixelMap, skInfo, holder);
326 bool cond = res != SUCCESS;
327 CHECK_ERROR_RETURN_RET_LOG(cond, res, "ExtEncoder::BuildSkBitmap RGB convert failed %{public}d", res);
328 image.pixels = holder.buf.get();
329 skInfo = skInfo.makeColorType(SkColorType::kRGBA_8888_SkColorType);
330 }
331 return SUCCESS;
332 }
333
IsAstc(const std::string & format)334 bool IsAstc(const std::string &format)
335 {
336 return format.find("image/astc") == 0;
337 }
338
CreateAndWriteBlob(MetadataWStream & tStream,PixelMap * pixelmap,SkWStream & outStream,ImageInfo & imageInfo,PlEncodeOptions & opts)339 static uint32_t CreateAndWriteBlob(MetadataWStream &tStream, PixelMap *pixelmap, SkWStream& outStream,
340 ImageInfo &imageInfo, PlEncodeOptions &opts)
341 {
342 ImageFuncTimer imageFuncTimer("insert exif data (%d, %d)", imageInfo.size.width, imageInfo.size.height);
343 auto metadataAccessor =
344 MetadataAccessorFactory::Create(tStream.GetAddr(), tStream.bytesWritten(), BufferMetadataStream::Dynamic);
345 if (metadataAccessor != nullptr) {
346 auto metadataPtr = pixelmap->GetExifMetadata();
347 metadataAccessor->Set(metadataPtr);
348 if (metadataAccessor->Write() == SUCCESS) {
349 if (metadataAccessor->WriteToOutput(outStream)) {
350 return SUCCESS;
351 }
352 }
353 }
354 if (!outStream.write(tStream.GetAddr(), tStream.bytesWritten())) {
355 ReportEncodeFault(imageInfo.size.width, imageInfo.size.height, opts.format, "Failed to encode image");
356 return ERR_IMAGE_ENCODE_FAILED;
357 }
358 return SUCCESS;
359 }
360
PixelmapEncode(ExtWStream & wStream)361 uint32_t ExtEncoder::PixelmapEncode(ExtWStream& wStream)
362 {
363 uint32_t error;
364 #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM)
365 IMAGE_LOGD("pixelmapEncode EncodeImageByPixelMap");
366 error = EncodeImageByPixelMap(pixelmap_, opts_.needsPackProperties, wStream);
367 #else
368 switch (opts_.desiredDynamicRange) {
369 case EncodeDynamicRange::AUTO:
370 if (pixelmap_->IsHdr() &&
371 (encodeFormat_ == SkEncodedImageFormat::kJPEG || encodeFormat_ == SkEncodedImageFormat::kHEIF)) {
372 error = EncodeDualVivid(wStream);
373 } else {
374 error = EncodeSdrImage(wStream);
375 }
376 break;
377 case EncodeDynamicRange::SDR:
378 error = EncodeSdrImage(wStream);
379 break;
380 case EncodeDynamicRange::HDR_VIVID_DUAL:
381 error = EncodeDualVivid(wStream);
382 break;
383 case EncodeDynamicRange::HDR_VIVID_SINGLE:
384 error = EncodeSingleVivid(wStream);
385 break;
386 default:
387 error = ERR_IMAGE_ENCODE_FAILED;
388 break;
389 }
390 #endif
391 RecycleResources();
392 return error;
393 }
394 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
IsSuperFastEncode(const std::string & format)395 bool IsSuperFastEncode(const std::string &format)
396 {
397 return SUT_FORMAT_MAP.find(format) != SUT_FORMAT_MAP.end() ||
398 ASTC_FORMAT_MAP.find(format) != ASTC_FORMAT_MAP.end();
399 }
400 #endif
401
402 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
CheckPictureHasArgb(Picture * picture)403 static bool CheckPictureHasArgb(Picture *picture)
404 {
405 bool cond = picture == nullptr || picture->GetMainPixel() == nullptr;
406 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s picture is nullptr or mainPixelMap is nullptr", __func__);
407 if (picture->GetMainPixel()->GetPixelFormat() == PixelFormat::ARGB_8888) {
408 IMAGE_LOGI("%{public}s picture has ARGB format. mainPixelMap is ARGB!", __func__);
409 return true;
410 }
411 IMAGE_LOGD("%{public}s picture does not have ARGB format.", __func__);
412 return false;
413 }
414
ConvertToRgbaPicture(Picture * picture)415 static std::unique_ptr<Picture> ConvertToRgbaPicture(Picture *picture)
416 {
417 bool cond = picture == nullptr || picture->GetMainPixel() == nullptr;
418 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
419 "%{public}s picture or mainPixelMap is nullptr!", __func__);
420 cond = !CheckPictureHasArgb(picture);
421 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "%{public}s no need to convert!", __func__);
422
423 std::shared_ptr<PixelMap> mainPixelMap = picture->GetMainPixel();
424 std::unique_ptr<Picture> newPicture = Picture::Create(mainPixelMap);
425 cond = newPicture == nullptr;
426 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
427 "%{public}s newPicture create failed! Stop ConvertToRgbaPicture.", __func__);
428 int32_t errorCode;
429 if (mainPixelMap->GetPixelFormat() == PixelFormat::ARGB_8888) {
430 std::shared_ptr<PixelMap> newPixelMap = mainPixelMap->Clone(errorCode);
431 cond = errorCode != SUCCESS || newPixelMap == nullptr ||
432 ConvertArgbAndRgba(newPixelMap.get(), PixelFormat::RGBA_8888) != SUCCESS;
433 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
434 "%{public}s mainPixelMap Convert failed! Stop ConvertToRgbaPicture.", __func__);
435 newPicture->SetMainPixel(newPixelMap);
436 }
437
438 sptr<SurfaceBuffer> maintenanceData = picture->GetMaintenanceData();
439 if (maintenanceData != nullptr) {
440 cond = !newPicture->SetMaintenanceData(maintenanceData);
441 CHECK_ERROR_PRINT_LOG(cond, "%{public}s SetMaintenanceData for newPicture failed!", __func__);
442 }
443 std::shared_ptr<ExifMetadata> exifMetadata = picture->GetExifMetadata();
444 if (exifMetadata != nullptr) {
445 cond = newPicture->SetExifMetadata(exifMetadata) != SUCCESS;
446 CHECK_ERROR_PRINT_LOG(cond, "%{public}s SetExifMetadata for newPicture failed!", __func__);
447 }
448 return newPicture;
449 }
450
CheckArgbEncode()451 uint32_t ExtEncoder::CheckArgbEncode()
452 {
453 if (pixelmap_ != nullptr && pixelmap_->GetPixelFormat() == PixelFormat::ARGB_8888) {
454 int32_t errorCode = ERROR;
455 std::unique_ptr<PixelMap> newPixelMap = pixelmap_->Clone(errorCode);
456 if (errorCode != SUCCESS || ConvertArgbAndRgba(newPixelMap.get(), PixelFormat::RGBA_8888) != SUCCESS) {
457 IMAGE_LOGE("%{public}s Pixelmap Convert ARGB to RGBA failed!", __func__);
458 return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
459 }
460 pixelmap_ = newPixelMap.release();
461 releasePixelMap_ = true;
462 IMAGE_LOGI("%{public}s PixelMap Convert ARGB to RGBA success!", __func__);
463 }
464 if (picture_ != nullptr && CheckPictureHasArgb(picture_)) {
465 std::unique_ptr<Picture> newPicture = ConvertToRgbaPicture(picture_);
466 if (newPicture == nullptr) {
467 IMAGE_LOGE("%{public}s picture's mainPixelMap Convert ARGB to RGBA failed!", __func__);
468 return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
469 }
470 picture_ = newPicture.release();
471 releasePicture_ = true;
472 IMAGE_LOGI("%{public}s picture's mainPixelMap Convert ARGB to RGBA success!", __func__);
473 }
474 return SUCCESS;
475 }
476 #endif
477
FinalizeEncode()478 uint32_t ExtEncoder::FinalizeEncode()
479 {
480 if ((picture_ == nullptr && pixelmap_ == nullptr) || output_ == nullptr) {
481 return ERR_IMAGE_INVALID_PARAMETER;
482 }
483 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
484 uint32_t convertRes = CheckArgbEncode();
485 if (convertRes != SUCCESS) {
486 return convertRes;
487 }
488 #endif
489 ImageDataStatistics imageDataStatistics("[ExtEncoder]FinalizeEncode imageFormat = %s, quality = %d",
490 opts_.format.c_str(), opts_.quality);
491 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
492 if (IsAstc(opts_.format) || IsSuperFastEncode(opts_.format)) {
493 AstcCodec astcEncoder;
494 astcEncoder.SetAstcEncode(output_, opts_, pixelmap_);
495 return astcEncoder.ASTCEncode();
496 }
497 #endif
498 auto iter = FORMAT_NAME.find(LowerStr(opts_.format));
499 if (iter == FORMAT_NAME.end()) {
500 IMAGE_LOGE("ExtEncoder::FinalizeEncode unsupported format %{public}s", opts_.format.c_str());
501 ReportEncodeFault(0, 0, opts_.format, "Unsupported format:" + opts_.format);
502 return ERR_IMAGE_INVALID_PARAMETER;
503 }
504 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
505 if (picture_ != nullptr) {
506 encodeFormat_ = iter->second;
507 if ((encodeFormat_ == SkEncodedImageFormat::kHEIF) &&
508 picture_->GetMainPixel()->GetAllocatorType() == Media::AllocatorType::SHARE_MEM_ALLOC) {
509 pixelmap_ = picture_->GetMainPixel().get();
510 return EncodeHeifByPixelmap(picture_->GetMainPixel().get(), opts_);
511 }
512 return EncodePicture();
513 }
514 #endif
515 ImageInfo imageInfo;
516 pixelmap_->GetImageInfo(imageInfo);
517 imageDataStatistics.AddTitle(", width = %d, height =%d", imageInfo.size.width, imageInfo.size.height);
518 encodeFormat_ = iter->second;
519 ExtWStream wStream(output_);
520 return PixelmapEncode(wStream);
521 }
522
IsHardwareEncodeSupported(const PlEncodeOptions & opts,Media::PixelMap * pixelMap)523 bool ExtEncoder::IsHardwareEncodeSupported(const PlEncodeOptions &opts, Media::PixelMap* pixelMap)
524 {
525 if (pixelMap == nullptr) {
526 IMAGE_LOGE("pixelMap is nullptr");
527 return false;
528 }
529 if (opts.quality < LOW_QUALITY_BOUNDARY) {
530 IMAGE_LOGE("%{public}s Low quality use software encode", __func__);
531 return false;
532 }
533 bool isSupportedWithRgba = ImageSystemProperties::GetGenThumbWithGpu() &&
534 pixelMap->GetPixelFormat() == PixelFormat::RGBA_8888;
535 bool isSupport = ImageSystemProperties::GetHardWareEncodeEnabled() && opts.format == "image/jpeg" &&
536 (pixelMap->GetWidth() % 2 == 0) && (pixelMap->GetHeight() % 2 == 0) &&
537 (pixelMap->GetPixelFormat() == PixelFormat::NV12 || pixelMap->GetPixelFormat() == PixelFormat::NV21 ||
538 isSupportedWithRgba) &&
539 pixelMap->GetWidth() <= MAX_IMAGE_SIZE && pixelMap->GetHeight() <= MAX_IMAGE_SIZE &&
540 pixelMap->GetWidth() >= MIN_RGBA_IMAGE_SIZE && pixelMap->GetHeight() >= MIN_RGBA_IMAGE_SIZE;
541 if (!isSupport) {
542 IMAGE_LOGD("hardware encode is not support, dstEncodeFormat:%{public}s, pixelWidth:%{public}d, "
543 "pixelHeight:%{public}d, pixelFormat:%{public}d", opts.format.c_str(), pixelMap->GetWidth(),
544 pixelMap->GetHeight(), pixelMap->GetPixelFormat());
545 }
546 return isSupport;
547 }
548
DoHardWareEncode(SkWStream * skStream)549 uint32_t ExtEncoder::DoHardWareEncode(SkWStream* skStream)
550 {
551 static ImageFwkExtManager imageFwkExtManager;
552 if (imageFwkExtManager.doHardWareEncodeFunc_ != nullptr || imageFwkExtManager.LoadImageFwkExtNativeSo()) {
553 int32_t retCode = imageFwkExtManager.doHardWareEncodeFunc_(skStream, opts_, pixelmap_);
554 if (retCode == SUCCESS) {
555 IMAGE_LOGD("DoHardWareEncode Success return");
556 return SUCCESS;
557 }
558 IMAGE_LOGE("hardware encode failed, retCode is %{public}d", retCode);
559 ImageInfo imageInfo;
560 pixelmap_->GetImageInfo(imageInfo);
561 ReportEncodeFault(imageInfo.size.width, imageInfo.size.height, opts_.format, "hardware encode failed");
562 } else {
563 IMAGE_LOGE("hardware encode failed because of load native so failed");
564 }
565 return ERR_IMAGE_ENCODE_FAILED;
566 }
567
DoEncode(SkWStream * skStream,const SkBitmap & src,const SkEncodedImageFormat & skFormat)568 uint32_t ExtEncoder::DoEncode(SkWStream* skStream, const SkBitmap& src, const SkEncodedImageFormat& skFormat)
569 {
570 ImageFuncTimer imageFuncTimer("%s:(%d, %d)", __func__, pixelmap_->GetWidth(), pixelmap_->GetHeight());
571 ImageInfo imageInfo;
572 pixelmap_->GetImageInfo(imageInfo);
573 if (!SkEncodeImage(skStream, src, skFormat, opts_.quality)) {
574 IMAGE_LOGE("Failed to encode image without exif data");
575 ReportEncodeFault(imageInfo.size.width, imageInfo.size.height, opts_.format, "Failed to encode image");
576 return ERR_IMAGE_ENCODE_FAILED;
577 }
578 return SUCCESS;
579 }
580
HardwareEncode(SkWStream & skStream,bool needExif)581 bool ExtEncoder::HardwareEncode(SkWStream &skStream, bool needExif)
582 {
583 uint32_t retCode = ERR_IMAGE_ENCODE_FAILED;
584 if (IsHardwareEncodeSupported(opts_, pixelmap_)) {
585 if (!needExif || pixelmap_->GetExifMetadata() == nullptr ||
586 pixelmap_->GetExifMetadata()->GetExifData() == nullptr) {
587 retCode = DoHardWareEncode(&skStream);
588 IMAGE_LOGD("HardwareEncode retCode:%{public}d", retCode);
589 return (retCode == SUCCESS);
590 }
591 MetadataWStream tStream;
592 retCode = DoHardWareEncode(&tStream);
593 bool cond = retCode != SUCCESS;
594 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "HardwareEncode failed, retCode:%{public}d", retCode);
595 ImageInfo imageInfo;
596 pixelmap_->GetImageInfo(imageInfo);
597 retCode = CreateAndWriteBlob(tStream, pixelmap_, skStream, imageInfo, opts_);
598 IMAGE_LOGD("HardwareEncode retCode :%{public}d", retCode);
599 return (retCode == SUCCESS);
600 }
601 return (retCode == SUCCESS);
602 }
603
EncodeImageByBitmap(SkBitmap & bitmap,bool needExif,SkWStream & outStream)604 uint32_t ExtEncoder::EncodeImageByBitmap(SkBitmap& bitmap, bool needExif, SkWStream& outStream)
605 {
606 ImageInfo imageInfo;
607 pixelmap_->GetImageInfo(imageInfo);
608 if (!needExif || pixelmap_->GetExifMetadata() == nullptr ||
609 pixelmap_->GetExifMetadata()->GetExifData() == nullptr) {
610 return DoEncode(&outStream, bitmap, encodeFormat_);
611 }
612
613 MetadataWStream tStream;
614 uint32_t errCode = DoEncode(&tStream, bitmap, encodeFormat_);
615 bool cond = errCode != SUCCESS;
616 CHECK_ERROR_RETURN_RET(cond, errCode);
617 return CreateAndWriteBlob(tStream, pixelmap_, outStream, imageInfo, opts_);
618 }
619
EncodeImageByPixelMap(PixelMap * pixelMap,bool needExif,SkWStream & outputStream)620 uint32_t ExtEncoder::EncodeImageByPixelMap(PixelMap* pixelMap, bool needExif, SkWStream& outputStream)
621 {
622 if (encodeFormat_ == SkEncodedImageFormat::kHEIF) {
623 return EncodeHeifByPixelmap(pixelMap, opts_);
624 }
625 SkBitmap bitmap;
626 TmpBufferHolder holder;
627 SkImageInfo skInfo;
628 ImageData imageData;
629 pixelMap->GetImageInfo(imageData.info);
630 uint32_t width = static_cast<uint32_t>(imageData.info.size.width);
631 uint32_t height = static_cast<uint32_t>(imageData.info.size.height);
632
633 bool cond = HardwareEncode(outputStream, needExif) == true;
634 CHECK_DEBUG_RETURN_RET_LOG(cond, SUCCESS, "HardwareEncode Success return");
635 IMAGE_LOGD("HardwareEncode failed or not Supported");
636
637 std::unique_ptr<uint8_t[]> dstData;
638 uint64_t rowStride = 0;
639 if (IsYuvImage(imageData.info.pixelFormat)) {
640 IMAGE_LOGD("YUV format, convert to RGB");
641 dstData = std::make_unique<uint8_t[]>(width * height * NUM_4);
642 if (YuvToRgbaSkInfo(imageData.info, skInfo, dstData.get(), pixelMap) != SUCCESS) {
643 IMAGE_LOGD("YUV format, convert to RGB fail");
644 return ERR_IMAGE_ENCODE_FAILED;
645 }
646 imageData.pixels = dstData.get();
647 rowStride = skInfo.minRowBytes64();
648 } else {
649 dstData = std::make_unique<uint8_t[]>(width * height * NUM_3);
650 imageData.dst = dstData.get();
651 cond = pixelToSkInfo(imageData, skInfo, pixelMap, holder, encodeFormat_) != SUCCESS;
652 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED,
653 "ExtEncoder::EncodeImageByPixelMap pixel convert failed");
654 rowStride = skInfo.minRowBytes64();
655 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
656 if (pixelMap->GetAllocatorType() == AllocatorType::DMA_ALLOC) {
657 SurfaceBuffer* sbBuffer = reinterpret_cast<SurfaceBuffer*> (pixelMap->GetFd());
658 rowStride = static_cast<uint64_t>(sbBuffer->GetStride());
659 IMAGE_LOGD("rowStride DMA: %{public}llu", static_cast<unsigned long long>(rowStride));
660 }
661 #endif
662 }
663 if (!bitmap.installPixels(skInfo, imageData.pixels, rowStride)) {
664 IMAGE_LOGE("ExtEncoder::EncodeImageByPixelMap to SkBitmap failed");
665 return ERR_IMAGE_ENCODE_FAILED;
666 }
667 return EncodeImageByBitmap(bitmap, needExif, outputStream);
668 }
669
EncodeHeifByPixelmap(PixelMap * pixelmap,const PlEncodeOptions & opts)670 uint32_t ExtEncoder::EncodeHeifByPixelmap(PixelMap* pixelmap, const PlEncodeOptions& opts)
671 {
672 if (output_ == nullptr) {
673 return ERR_IMAGE_INVALID_PARAMETER;
674 }
675 Media::PixelFormat format = pixelmap->GetPixelFormat();
676 bool cond = format != PixelFormat::RGBA_8888 && format != PixelFormat::NV12 && format != PixelFormat::NV21;
677 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
678 "EncodeHeifByPixelmap, invalid format:%{public}d", format);
679 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) && \
680 defined(HEIF_HW_ENCODE_ENABLE)
681 sptr<SurfaceBuffer> surfaceBuffer;
682 bool needConvertToSurfaceBuffer = pixelmap->GetAllocatorType() != AllocatorType::DMA_ALLOC;
683 if (needConvertToSurfaceBuffer) {
684 surfaceBuffer = ConvertToSurfaceBuffer(pixelmap);
685 cond = surfaceBuffer == nullptr;
686 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
687 "EncodeHeifByPixelmap ConvertToSurfaceBuffer failed");
688 } else {
689 cond = pixelmap->GetFd() == nullptr;
690 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "EncodeHeifByPixelmap pixelmap get fd failed");
691 surfaceBuffer = sptr<SurfaceBuffer>(reinterpret_cast<SurfaceBuffer*>(pixelmap->GetFd()));
692 }
693 std::vector<ImageItem> inputImgs;
694 std::shared_ptr<ImageItem> primaryItem = AssemblePrimaryImageItem(surfaceBuffer, opts);
695 if (primaryItem == nullptr) {
696 if (needConvertToSurfaceBuffer) {
697 ImageUtils::SurfaceBuffer_Unreference(surfaceBuffer.GetRefPtr());
698 }
699 return ERR_IMAGE_INVALID_PARAMETER;
700 }
701 inputImgs.push_back(*primaryItem);
702 std::vector<MetaItem> inputMetas;
703 std::vector<ItemRef> refs;
704 if (AssembleExifMetaItem(inputMetas)) {
705 AssembleExifRefItem(refs);
706 }
707 uint32_t result = DoHeifEncode(inputImgs, inputMetas, refs);
708 if (needConvertToSurfaceBuffer) {
709 ImageUtils::SurfaceBuffer_Unreference(surfaceBuffer.GetRefPtr());
710 }
711 return result;
712 #endif
713 return ERR_IMAGE_INVALID_PARAMETER;
714 }
715
RecycleResources()716 void ExtEncoder::RecycleResources()
717 {
718 for (std::shared_ptr<AbsMemory> &memory: tmpMemoryList_) {
719 if (memory == nullptr) {
720 continue;
721 }
722 memory->Release();
723 }
724 tmpMemoryList_.clear();
725 }
726
727 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
AllocSurfaceBuffer(int32_t width,int32_t height,uint32_t format=GRAPHIC_PIXEL_FMT_RGBA_8888)728 static sptr<SurfaceBuffer> AllocSurfaceBuffer(int32_t width, int32_t height,
729 uint32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888)
730 {
731 sptr<SurfaceBuffer> sb = SurfaceBuffer::Create();
732 BufferRequestConfig requestConfig = {
733 .width = width,
734 .height = height,
735 .strideAlignment = 0x8,
736 .format = format,
737 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_MMZ_CACHE,
738 .timeout = 0,
739 };
740 GSError ret = sb->Alloc(requestConfig);
741 if (ret != GSERROR_OK) {
742 return nullptr;
743 }
744 void* nativeBuffer = sb.GetRefPtr();
745 int32_t err = ImageUtils::SurfaceBuffer_Reference(nativeBuffer);
746 bool cond = err != OHOS::GSERROR_OK;
747 CHECK_ERROR_RETURN_RET(cond, nullptr);
748 return sb;
749 }
750
ConvertToSurfaceBuffer(PixelMap * pixelmap)751 sptr<SurfaceBuffer> ExtEncoder::ConvertToSurfaceBuffer(PixelMap* pixelmap)
752 {
753 bool cond = pixelmap->GetHeight() <= 0 || pixelmap->GetWidth() <= 0;
754 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
755 "pixelmap height:%{public}d or width:%{public}d error", pixelmap->GetHeight(), pixelmap->GetWidth());
756 uint32_t height = static_cast<uint32_t>(pixelmap->GetHeight());
757 uint32_t width = static_cast<uint32_t>(pixelmap->GetWidth());
758 PixelFormat format = pixelmap->GetPixelFormat();
759 IMAGE_LOGD("ExtEncoder::ConvertToSurfaceBuffer format is %{public}d", format);
760 auto formatSearch = SURFACE_FORMAT_MAP.find(format);
761 cond = formatSearch == SURFACE_FORMAT_MAP.end();
762 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "format:[%{public}d] is not in SURFACE_FORMAT_MAP", format);
763 uint32_t graphicFormat = formatSearch->second;
764 sptr<SurfaceBuffer> surfaceBuffer = AllocSurfaceBuffer(width, height, graphicFormat);
765 cond = surfaceBuffer == nullptr || surfaceBuffer->GetStride() < 0;
766 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "ConvertToSurfaceBuffer surfaceBuffer is nullptr failed");
767 uint32_t dstStride = static_cast<uint32_t>(surfaceBuffer->GetStride());
768 uint8_t* src = const_cast<uint8_t*>(pixelmap->GetPixels());
769 uint8_t* dst = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
770 uint32_t dstSize = surfaceBuffer->GetSize();
771 uint32_t copyHeight = height;
772 uint64_t srcStride = width;
773 if (format == PixelFormat::NV12 || format == PixelFormat::NV21) {
774 const int32_t NUM_2 = 2;
775 copyHeight = height + height / NUM_2;
776 srcStride = width;
777 } else if (format == PixelFormat::RGBA_8888) {
778 copyHeight = height;
779 srcStride = static_cast<uint64_t>(width * NUM_4);
780 }
781 for (uint32_t i = 0; i < copyHeight; i++) {
782 if (memcpy_s(dst, dstSize, src, srcStride) != EOK) {
783 IMAGE_LOGE("ConvertToSurfaceBuffer memcpy failed");
784 ImageUtils::SurfaceBuffer_Unreference(surfaceBuffer.GetRefPtr());
785 return nullptr;
786 }
787 dst += dstStride;
788 dstSize -= dstStride;
789 src += srcStride;
790 }
791 if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
792 GSError err = surfaceBuffer->FlushCache();
793 if (err != GSERROR_OK) {
794 IMAGE_LOGE("FlushCache failed, GSError=%{public}d", err);
795 }
796 }
797 return surfaceBuffer;
798 }
799
FreeBaseAndGainMapSurfaceBuffer(sptr<SurfaceBuffer> & base,sptr<SurfaceBuffer> & gainMap)800 static void FreeBaseAndGainMapSurfaceBuffer(sptr<SurfaceBuffer>& base, sptr<SurfaceBuffer>& gainMap)
801 {
802 ImageUtils::SurfaceBuffer_Unreference(base.GetRefPtr());
803 ImageUtils::SurfaceBuffer_Unreference(gainMap.GetRefPtr());
804 }
805
GetHdrMetadata(sptr<SurfaceBuffer> & hdr,sptr<SurfaceBuffer> & gainmap)806 static HdrMetadata GetHdrMetadata(sptr<SurfaceBuffer>& hdr, sptr<SurfaceBuffer>& gainmap)
807 {
808 std::vector<uint8_t> dynamicMetadata = {};
809 VpeUtils::GetSbDynamicMetadata(hdr, dynamicMetadata);
810 std::vector<uint8_t> staticMetadata = {};
811 VpeUtils::GetSbStaticMetadata(hdr, staticMetadata);
812 HdrMetadata metadata = {
813 .staticMetadata = staticMetadata,
814 .dynamicMetadata = dynamicMetadata
815 };
816 std::vector<uint8_t> extendMetadataVec = {};
817 VpeUtils::GetSbDynamicMetadata(gainmap, extendMetadataVec);
818 if (extendMetadataVec.size() != sizeof(HDRVividExtendMetadata)) {
819 metadata.extendMetaFlag = false;
820 return metadata;
821 }
822 if (memcpy_s(&metadata.extendMeta, sizeof(HDRVividExtendMetadata),
823 extendMetadataVec.data(), extendMetadataVec.size()) != EOK) {
824 metadata.extendMetaFlag = false;
825 } else {
826 metadata.extendMetaFlag = true;
827 }
828 return metadata;
829 }
830
EncodeImageBySurfaceBuffer(sptr<SurfaceBuffer> & surfaceBuffer,SkImageInfo info,bool needExif,SkWStream & outputStream)831 uint32_t ExtEncoder::EncodeImageBySurfaceBuffer(sptr<SurfaceBuffer>& surfaceBuffer, SkImageInfo info,
832 bool needExif, SkWStream& outputStream)
833 {
834 SkBitmap bitmap;
835 ImageInfo imageInfo;
836 uint64_t rowStride = 0;
837 if (surfaceBuffer == nullptr) {
838 IMAGE_LOGE("EncodeImageBySurfaceBuffer failed, surfaceBuffer is nullptr");
839 return ERR_IMAGE_INVALID_PARAMETER;
840 }
841 auto pixels = surfaceBuffer->GetVirAddr();
842 if (pixels == nullptr) {
843 IMAGE_LOGE("EncodeImageBySurfaceBuffer failed, pixels is nullptr");
844 return ERR_IMAGE_INVALID_PARAMETER;
845 }
846 /* do hardwareEncode first, if fail then soft encode*/
847 bool cond = HardwareEncode(outputStream, needExif);
848 CHECK_DEBUG_RETURN_RET_LOG(cond, SUCCESS, "HardwareEncode Success return");
849 IMAGE_LOGD("HardwareEncode failed or not Supported");
850
851 pixelmap_->GetImageInfo(imageInfo);
852 cond = !PixelYuvUtils::CheckWidthAndHeightMult(imageInfo.size.width, imageInfo.size.height, RGBA_BIT_DEPTH);
853 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
854 "EncodeImageBySurfaceBuffer size overflow width(%{public}d), height(%{public}d)",
855 imageInfo.size.width, imageInfo.size.height);
856 std::unique_ptr<uint8_t[]> dstData;
857 if (IsYuvImage(imageInfo.pixelFormat)) {
858 IMAGE_LOGD("EncodeImageBySurfaceBuffer: YUV format, convert to RGB first");
859 dstData = std::make_unique<uint8_t[]>(imageInfo.size.width * imageInfo.size.height * NUM_4);
860 cond = dstData == nullptr;
861 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "Memory allocate fail");
862 cond = YuvToRgbaSkInfo(imageInfo, info, dstData.get(), pixelmap_) != SUCCESS;
863 CHECK_DEBUG_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "YUV format, convert to RGB fail");
864 pixels = dstData.get();
865 rowStride = info.minRowBytes64();
866 } else {
867 rowStride = surfaceBuffer->GetStride();
868 }
869 cond = !bitmap.installPixels(info, pixels, rowStride);
870 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED,
871 "ExtEncoder::EncodeImageBySurfaceBuffer to SkBitmap failed");
872 return EncodeImageByBitmap(bitmap, needExif, outputStream);
873 }
874
GetImageEncodeData(sptr<SurfaceBuffer> & surfaceBuffer,SkImageInfo info,bool needExif)875 sk_sp<SkData> ExtEncoder::GetImageEncodeData(sptr<SurfaceBuffer>& surfaceBuffer, SkImageInfo info, bool needExif)
876 {
877 SkDynamicMemoryWStream stream;
878 if (EncodeImageBySurfaceBuffer(surfaceBuffer, info, needExif, stream) != SUCCESS) {
879 return nullptr;
880 }
881 return stream.detachAsData();
882 }
883
SetHdrColorSpaceType(sptr<SurfaceBuffer> & surfaceBuffer)884 void ExtEncoder::SetHdrColorSpaceType(sptr<SurfaceBuffer>& surfaceBuffer)
885 {
886 if (pixelmap_ == nullptr) {
887 IMAGE_LOGI("SetHdrColorSpaceType pixelmap_ is nullptr");
888 return;
889 }
890 CM_ColorSpaceType colorspaceType;
891 VpeUtils::GetSbColorSpaceType(surfaceBuffer, colorspaceType);
892 if ((colorspaceType & CM_PRIMARIES_MASK) != COLORPRIMARIES_BT2020) {
893 #ifdef IMAGE_COLORSPACE_FLAG
894 ColorManager::ColorSpaceName colorspace = pixelmap_->InnerGetGrColorSpace().GetColorSpaceName();
895 IMAGE_LOGI("ExtEncoder SetHdrColorSpaceType, color is %{public}d", colorspace);
896 colorspaceType = ColorUtils::ConvertToCMColor(colorspace);
897 VpeUtils::SetSbColorSpaceType(surfaceBuffer, colorspaceType);
898 #endif
899 }
900 }
901
DecomposeImage(VpeSurfaceBuffers & buffers,HdrMetadata & metadata,bool onlySdr,bool sdrIsSRGB=false)902 static bool DecomposeImage(VpeSurfaceBuffers& buffers, HdrMetadata& metadata, bool onlySdr, bool sdrIsSRGB = false)
903 {
904 VpeUtils::SetSbMetadataType(buffers.sdr, CM_IMAGE_HDR_VIVID_DUAL);
905 VpeUtils::SetSbColorSpaceType(buffers.sdr, sdrIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
906 std::unique_ptr<VpeUtils> utils = std::make_unique<VpeUtils>();
907 int32_t res;
908 if (onlySdr) {
909 bool cond = buffers.hdr == nullptr || buffers.sdr == nullptr;
910 CHECK_ERROR_RETURN_RET(cond, false);
911 res = utils->ColorSpaceConverterImageProcess(buffers.hdr, buffers.sdr);
912 } else {
913 VpeUtils::SetSbMetadataType(buffers.gainmap, CM_METADATA_NONE);
914 VpeUtils::SetSbColorSpaceType(buffers.gainmap, sdrIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
915 res = utils->ColorSpaceConverterDecomposeImage(buffers);
916 }
917 bool cond = res != VPE_ERROR_OK;
918 CHECK_ERROR_RETURN_RET_LOG(cond, false, "DecomposeImage [%{public}d] failed, res = %{public}d", onlySdr, res);
919 if (!onlySdr) {
920 metadata = GetHdrMetadata(buffers.hdr, buffers.gainmap);
921 }
922 return true;
923 }
924
GetSkInfo(PixelMap * pixelMap,bool isGainmap,bool isSRGB=false)925 static SkImageInfo GetSkInfo(PixelMap* pixelMap, bool isGainmap, bool isSRGB = false)
926 {
927 ImageInfo info;
928 pixelMap->GetImageInfo(info);
929 SkColorType colorType = kRGBA_8888_SkColorType;
930 SkAlphaType alphaType = ImageTypeConverter::ToSkAlphaType(info.alphaType);
931 if (alphaType == SkAlphaType::kUnknown_SkAlphaType) {
932 alphaType = SkAlphaType::kOpaque_SkAlphaType;
933 }
934 sk_sp<SkColorSpace> colorSpace =
935 SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, isSRGB ? SkNamedGamut::kSRGB : SkNamedGamut::kDisplayP3);
936 int32_t width = info.size.width;
937 int32_t height = info.size.height;
938 if (isGainmap) {
939 const int halfSizeDenominator = 2;
940 width = width / halfSizeDenominator;
941 height = height / halfSizeDenominator;
942 #ifdef IMAGE_COLORSPACE_FLAG
943 if (pixelMap->InnerGetGrColorSpacePtr() != nullptr &&
944 pixelMap->InnerGetGrColorSpace().GetColorSpaceName() != ColorManager::ColorSpaceName::NONE) {
945 colorSpace = pixelMap->InnerGetGrColorSpacePtr()->ToSkColorSpace();
946 }
947 skcms_CICP cicp;
948 ColorUtils::ColorSpaceGetCicp(pixelMap->InnerGetGrColorSpace().GetColorSpaceName(),
949 cicp.colour_primaries, cicp.transfer_characteristics, cicp.matrix_coefficients, cicp.full_range_flag);
950 colorSpace->SetIccCicp(cicp);
951 #endif
952 }
953 return SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
954 }
955
EncodeSingleVivid(ExtWStream & outputStream)956 uint32_t ExtEncoder::EncodeSingleVivid(ExtWStream& outputStream)
957 {
958 return ERR_IMAGE_INVALID_PARAMETER;
959 }
960
961 #ifdef HEIF_HW_ENCODE_ENABLE
962 // format: enum + struct
FillLitePropertyItem(std::vector<uint8_t> & properties,size_t & offset,PropertyType type,const void * payloadData,size_t payloadSize)963 static bool FillLitePropertyItem(std::vector<uint8_t>& properties, size_t& offset, PropertyType type,
964 const void* payloadData, size_t payloadSize)
965 {
966 uint8_t* memData = properties.data();
967 bool cond = memData == nullptr;
968 CHECK_ERROR_RETURN_RET_LOG(cond, false, "FillLitePropertyItem memData is nullptr");
969 size_t memSize = properties.size();
970 size_t typeSize = sizeof(type);
971 size_t endOffset = offset + typeSize + payloadSize;
972 cond = endOffset > memSize;
973 CHECK_ERROR_RETURN_RET_LOG(cond, false,
974 "FillLitePropertyItem, endOffset[%{public}ld] over memSize[%{public}ld]", endOffset, memSize);
975 bool res = memcpy_s(memData + offset, memSize - offset, &type, typeSize) == EOK &&
976 memcpy_s(memData + offset + typeSize, memSize - offset - typeSize, payloadData, payloadSize) == EOK;
977 if (res) {
978 offset = endOffset;
979 }
980 return res;
981 }
982
983 // format: enum + strlen + str
FillLitePropertyItemByString(std::vector<uint8_t> & properties,size_t & offset,PropertyType type,std::string & payloadString)984 static bool FillLitePropertyItemByString(std::vector<uint8_t>& properties, size_t& offset, PropertyType type,
985 std::string& payloadString)
986 {
987 uint8_t* memData = properties.data();
988 bool cond = memData == nullptr;
989 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s memData is nullptr", __func__);
990 size_t memSize = properties.size();
991 cond = payloadString == "";
992 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s failed, payloadString is Null", __func__);
993 size_t lenSize = UINT32_BYTES_NUM;
994 size_t strLen = payloadString.length();
995 size_t typeSize = sizeof(type);
996 size_t endOffset = offset + typeSize + lenSize + strLen;
997 cond = endOffset >= memSize;
998 CHECK_ERROR_RETURN_RET_LOG(cond, false,
999 "%{public}s failed, offset[%{public}ld] over memSize[%{public}ld]", __func__, offset, memSize);
1000 size_t capacitySize = memSize - offset;
1001 const char* payloadData = payloadString.data();
1002 bool res = memcpy_s(memData + offset, capacitySize, &type, typeSize) == EOK &&
1003 memcpy_s(memData + offset + typeSize, capacitySize - typeSize, &strLen, lenSize) == EOK &&
1004 memcpy_s(memData + offset + typeSize + lenSize, capacitySize - typeSize - lenSize, payloadData, strLen) == EOK;
1005 properties[endOffset] = '\0';
1006
1007 if (res) {
1008 offset = endOffset + PLACE_HOLDER_LENGTH;
1009 }
1010 return res;
1011 }
1012
AssembleHdrBaseImageItem(sptr<SurfaceBuffer> & surfaceBuffer,ColorManager::ColorSpaceName color,HdrMetadata & metadata,const PlEncodeOptions & opts)1013 std::shared_ptr<ImageItem> ExtEncoder::AssembleHdrBaseImageItem(sptr<SurfaceBuffer>& surfaceBuffer,
1014 ColorManager::ColorSpaceName color, HdrMetadata& metadata, const PlEncodeOptions& opts)
1015 {
1016 bool cond = surfaceBuffer == nullptr;
1017 CHECK_INFO_RETURN_RET_LOG(cond, nullptr, "AssembleHdrBaseImageItem surfaceBuffer is nullptr");
1018 auto item = std::make_shared<ImageItem>();
1019 item->id = PRIMARY_IMAGE_ITEM_ID;
1020 item->isPrimary = true;
1021 item->isHidden = false;
1022 item->compressType = COMPRESS_TYPE_HEVC;
1023 item->quality = opts.quality;
1024 item->pixelBuffer = sptr<NativeBuffer>::MakeSptr(surfaceBuffer->GetBufferHandle());
1025 item->sharedProperties.fd = -1;
1026 item->pixelSharedBuffer.fd = -1;
1027 ColourInfo colorInfo;
1028 GetColourInfo(color, colorInfo);
1029 ContentLightLevel light;
1030 MasteringDisplayColourVolume colour;
1031 bool hasLight = GetStaticMetadata(metadata, colour, light);
1032 uint32_t propertiesSize = 0;
1033 propertiesSize +=
1034 (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType) + sizeof(PropertyType::COLOR_INFO) + sizeof(ColourInfo));
1035 if (hasLight) {
1036 propertiesSize += (sizeof(PropertyType::CONTENT_LIGHT_LEVEL) + sizeof(ContentLightLevel));
1037 }
1038 item->liteProperties.resize(propertiesSize);
1039 size_t offset = 0;
1040 if (!FillNclxColorProperty(item, offset, colorInfo)) {
1041 return nullptr;
1042 }
1043 if (hasLight && (!FillLitePropertyItem(item->liteProperties, offset,
1044 PropertyType::CONTENT_LIGHT_LEVEL, &colour, sizeof(ContentLightLevel)))) {
1045 return nullptr;
1046 }
1047 return item;
1048 }
1049
AssembleGainmapImageItem(sptr<SurfaceBuffer> & surfaceBuffer,ColorManager::ColorSpaceName color,const PlEncodeOptions & opts)1050 std::shared_ptr<ImageItem> ExtEncoder::AssembleGainmapImageItem(sptr<SurfaceBuffer>& surfaceBuffer,
1051 ColorManager::ColorSpaceName color, const PlEncodeOptions &opts)
1052 {
1053 bool cond = surfaceBuffer == nullptr;
1054 CHECK_INFO_RETURN_RET_LOG(cond, nullptr, "AssembleGainmapImageItem surfacebuffer is nullptr");
1055 auto item = std::make_shared<ImageItem>();
1056 item->id = GAINMAP_IMAGE_ITEM_ID;
1057 item->itemName = GAINMAP_IMAGE_ITEM_NAME;
1058 item->isPrimary = false;
1059 item->isHidden = true;
1060 item->compressType = COMPRESS_TYPE_HEVC;
1061 item->quality = opts.quality;
1062 item->sharedProperties.fd = -1;
1063 item->pixelSharedBuffer.fd = -1;
1064 item->pixelBuffer = sptr<NativeBuffer>::MakeSptr(surfaceBuffer->GetBufferHandle());
1065 ColourInfo colorInfo;
1066 GetColourInfo(color, colorInfo);
1067 uint32_t propertiesSize = 0;
1068 propertiesSize +=
1069 (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType) + sizeof(PropertyType::COLOR_INFO) + sizeof(ColourInfo));
1070 item->liteProperties.resize(propertiesSize);
1071 size_t offset = 0;
1072 cond = !FillNclxColorProperty(item, offset, colorInfo);
1073 CHECK_ERROR_RETURN_RET(cond, nullptr);
1074 return item;
1075 }
1076
AssembleHeifHdrPicture(sptr<SurfaceBuffer> & mainSptr,bool sdrIsSRGB,std::vector<ImageItem> & inputImgs)1077 uint32_t ExtEncoder::AssembleHeifHdrPicture(
1078 sptr<SurfaceBuffer>& mainSptr, bool sdrIsSRGB, std::vector<ImageItem>& inputImgs)
1079 {
1080 auto gainPixelMap = picture_->GetGainmapPixelMap();
1081 bool cond = gainPixelMap == nullptr || gainPixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1082 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1083 "%{public}s, the gainPixelMap is nullptr or gainPixelMap is nonDMA", __func__);
1084 sptr<SurfaceBuffer> gainMapSptr(reinterpret_cast<SurfaceBuffer*>(gainPixelMap->GetFd()));
1085 HdrMetadata metadata = GetHdrMetadata(mainSptr, gainMapSptr);
1086
1087 ColorManager::ColorSpaceName colorspaceName =
1088 sdrIsSRGB ? ColorManager::ColorSpaceName::SRGB : ColorManager::ColorSpaceName::DISPLAY_P3;
1089 std::shared_ptr<ImageItem> primaryItem = AssembleHdrBaseImageItem(mainSptr, colorspaceName, metadata, opts_);
1090 cond = primaryItem == nullptr;
1091 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s, get primary image failed", __func__);
1092 inputImgs.push_back(*primaryItem);
1093 std::shared_ptr<ImageItem> gainmapItem = AssembleGainmapImageItem(gainMapSptr, colorspaceName, opts_);
1094 cond = gainmapItem == nullptr;
1095 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1096 "%{public}s, get gainmap image item failed", __func__);
1097 inputImgs.push_back(*gainmapItem);
1098 ColorManager::ColorSpaceName tmapColor = picture_->GetMainPixel()->InnerGetGrColorSpace().GetColorSpaceName();
1099 std::shared_ptr<ImageItem> tmapItem = AssembleTmapImageItem(tmapColor, metadata, opts_);
1100 cond = tmapItem == nullptr;
1101 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s, get tmap image item failed", __func__);
1102 inputImgs.push_back(*tmapItem);
1103 return SUCCESS;
1104 }
1105
AssembleSdrImageItem(sptr<SurfaceBuffer> & surfaceBuffer,SkImageInfo sdrInfo,std::vector<ImageItem> & inputImgs)1106 uint32_t ExtEncoder::AssembleSdrImageItem(
1107 sptr<SurfaceBuffer>& surfaceBuffer, SkImageInfo sdrInfo, std::vector<ImageItem>& inputImgs)
1108 {
1109 bool cond = surfaceBuffer == nullptr;
1110 CHECK_INFO_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s surfaceBuffer is nullptr", __func__);
1111 ImageItem item;
1112 sk_sp<SkData> iccProfile = icc_from_color_space(sdrInfo);
1113 cond = !AssembleICCImageProperty(iccProfile, item.sharedProperties);
1114 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1115 "%{public}s AssembleICCImageProperty failed", __func__);
1116 item.id = PRIMARY_IMAGE_ITEM_ID;
1117 item.pixelBuffer = sptr<NativeBuffer>::MakeSptr(surfaceBuffer->GetBufferHandle());
1118 item.isPrimary = true;
1119 item.isHidden = false;
1120 item.compressType = COMPRESS_TYPE_HEVC;
1121 item.quality = opts_.quality;
1122 uint32_t litePropertiesSize = (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
1123 item.liteProperties.resize(litePropertiesSize);
1124 size_t offset = 0;
1125 ColorType colorType = ColorType::RICC;
1126 cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
1127 CHECK_INFO_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill color type failed", __func__);
1128 inputImgs.push_back(item);
1129 return SUCCESS;
1130 }
1131
AssembleHeifAuxiliaryPicture(std::vector<ImageItem> & inputImgs,std::vector<ItemRef> & refs)1132 uint32_t ExtEncoder::AssembleHeifAuxiliaryPicture(std::vector<ImageItem>& inputImgs, std::vector<ItemRef>& refs)
1133 {
1134 bool cond = !picture_;
1135 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "picture_ is nullptr");
1136 if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::DEPTH_MAP) &&
1137 AssembleHeifAuxiliaryNoncodingMap(inputImgs, AuxiliaryPictureType::DEPTH_MAP) == SUCCESS) {
1138 AssembleAuxiliaryRefItem(AuxiliaryPictureType::DEPTH_MAP, refs);
1139 }
1140 if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::UNREFOCUS_MAP) &&
1141 AssembleHeifUnrefocusMap(inputImgs) == SUCCESS) {
1142 AssembleAuxiliaryRefItem(AuxiliaryPictureType::UNREFOCUS_MAP, refs);
1143 }
1144 if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::LINEAR_MAP) &&
1145 AssembleHeifAuxiliaryNoncodingMap(inputImgs, AuxiliaryPictureType::LINEAR_MAP) == SUCCESS) {
1146 AssembleAuxiliaryRefItem(AuxiliaryPictureType::LINEAR_MAP, refs);
1147 }
1148 if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::FRAGMENT_MAP) &&
1149 AssembleHeifFragmentMap(inputImgs) == SUCCESS) {
1150 AssembleAuxiliaryRefItem(AuxiliaryPictureType::FRAGMENT_MAP, refs);
1151 }
1152 return SUCCESS;
1153 }
1154
InitAuxiliaryImageItem(uint32_t id,std::string itemName)1155 ImageItem ExtEncoder::InitAuxiliaryImageItem(uint32_t id, std::string itemName)
1156 {
1157 ImageItem item;
1158 item.id = id;
1159 item.itemName = itemName;
1160 item.isPrimary = false;
1161 item.isHidden = true;
1162 item.quality = opts_.quality;
1163 item.sharedProperties.fd = -1;
1164 item.pixelSharedBuffer.fd = -1;
1165 if (id == DEPTH_MAP_ITEM_ID || id == LINEAR_MAP_ITEM_ID) {
1166 item.compressType = COMPRESS_TYPE_NONE;
1167 } else {
1168 item.compressType = COMPRESS_TYPE_HEVC;
1169 }
1170 return item;
1171 }
1172
GetHeifEncodeItemInfo(AuxiliaryPictureType auxType)1173 HeifEncodeItemInfo GetHeifEncodeItemInfo(AuxiliaryPictureType auxType)
1174 {
1175 HeifEncodeItemInfo itemInfo;
1176 switch (auxType) {
1177 case AuxiliaryPictureType::GAINMAP:
1178 itemInfo.itemId = GAINMAP_IMAGE_ITEM_ID;
1179 itemInfo.itemName = GAINMAP_IMAGE_ITEM_NAME;
1180 itemInfo.itemType = HEIF_AUXTTYPE_ID_GAINMAP;
1181 break;
1182 case AuxiliaryPictureType::DEPTH_MAP:
1183 itemInfo.itemId = DEPTH_MAP_ITEM_ID;
1184 itemInfo.itemName = DEPTH_MAP_ITEM_NAME;
1185 itemInfo.itemType = HEIF_AUXTTYPE_ID_DEPTH_MAP;
1186 break;
1187 case AuxiliaryPictureType::UNREFOCUS_MAP:
1188 itemInfo.itemId = UNREFOCUS_MAP_ITEM_ID;
1189 itemInfo.itemName = UNREFOCUS_MAP_ITEM_NAME;
1190 itemInfo.itemType = HEIF_AUXTTYPE_ID_UNREFOCUS_MAP;
1191 break;
1192 case AuxiliaryPictureType::LINEAR_MAP:
1193 itemInfo.itemId = LINEAR_MAP_ITEM_ID;
1194 itemInfo.itemName = LINEAR_MAP_ITEM_NAME;
1195 itemInfo.itemType = HEIF_AUXTTYPE_ID_LINEAR_MAP;
1196 break;
1197 case AuxiliaryPictureType::FRAGMENT_MAP:
1198 itemInfo.itemId = FRAGMENT_MAP_ITEM_ID;
1199 itemInfo.itemName = FRAGMENT_MAP_ITEM_NAME;
1200 itemInfo.itemType = HEIF_AUXTTYPE_ID_FRAGMENT_MAP;
1201 break;
1202 default:
1203 break;
1204 }
1205 return itemInfo;
1206 }
1207
AssembleHeifAuxiliaryNoncodingMap(std::vector<ImageItem> & inputImgs,AuxiliaryPictureType auxType)1208 uint32_t ExtEncoder::AssembleHeifAuxiliaryNoncodingMap(std::vector<ImageItem>& inputImgs, AuxiliaryPictureType auxType)
1209 {
1210 auto auxMap = picture_->GetAuxiliaryPicture(auxType);
1211 if (!auxMap || !auxMap->GetContentPixel() ||
1212 auxMap->GetContentPixel()->GetAllocatorType() != AllocatorType::DMA_ALLOC) {
1213 IMAGE_LOGE("%{public}s The auxMap is nullptr or allocator type is not DMA_ALLOC", __func__);
1214 return ERR_IMAGE_INVALID_PARAMETER;
1215 }
1216 sptr<SurfaceBuffer> auxMapSptr(reinterpret_cast<SurfaceBuffer*>(auxMap->GetContentPixel()->GetFd()));
1217 bool cond = !auxMapSptr;
1218 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s auxMapSptr is nullptr", __func__);
1219
1220 HeifEncodeItemInfo itemInfo = GetHeifEncodeItemInfo(auxType);
1221 auto item = InitAuxiliaryImageItem(itemInfo.itemId, itemInfo.itemName);
1222 std::string auxTypeStr = itemInfo.itemType;
1223 Resolution resolution = {
1224 auxMap->GetContentPixel()->GetWidth(),
1225 auxMap->GetContentPixel()->GetHeight()
1226 };
1227 uint32_t litePropertiesSize =
1228 sizeof(PropertyType::AUX_TYPE) + UINT32_BYTES_NUM + auxTypeStr.length() + PLACE_HOLDER_LENGTH;
1229 litePropertiesSize += (sizeof(PropertyType::IMG_RESOLUTION) + sizeof(Resolution));
1230 size_t offset = 0;
1231 item.liteProperties.resize(litePropertiesSize);
1232 cond = !FillLitePropertyItemByString(item.liteProperties, offset, PropertyType::AUX_TYPE, auxTypeStr);
1233 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill auxiliary type failed", __func__);
1234 cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::IMG_RESOLUTION, &resolution,
1235 sizeof(Resolution));
1236 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill color type failed", __func__);
1237 uint32_t capacity = auxMap->GetContentPixel()->GetCapacity();
1238 cond = !FillPixelSharedBuffer(auxMapSptr, capacity, item.pixelSharedBuffer);
1239 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1240 "%{public}s Fill pixel shared buffer failed", __func__);
1241 inputImgs.push_back(item);
1242 return SUCCESS;
1243 }
1244
AssembleHeifUnrefocusMap(std::vector<ImageItem> & inputImgs)1245 uint32_t ExtEncoder::AssembleHeifUnrefocusMap(std::vector<ImageItem>& inputImgs)
1246 {
1247 auto unrefocusMap = picture_->GetAuxiliaryPicture(AuxiliaryPictureType::UNREFOCUS_MAP);
1248 bool cond = !unrefocusMap || !unrefocusMap->GetContentPixel() ||
1249 unrefocusMap->GetContentPixel()->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1250 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1251 "%{public}s The unrefocusMap is nullptr or allocator type is not DMA_ALLOC", __func__);
1252 HeifEncodeItemInfo itemInfo = GetHeifEncodeItemInfo(AuxiliaryPictureType::UNREFOCUS_MAP);
1253 auto item = InitAuxiliaryImageItem(itemInfo.itemId, itemInfo.itemName);
1254 bool sdrIsSRGB = unrefocusMap->GetContentPixel()->GetToSdrColorSpaceIsSRGB();
1255 SkImageInfo unrefocusInfo = GetSkInfo(unrefocusMap->GetContentPixel().get(), false, sdrIsSRGB);
1256 sk_sp<SkData> iccProfile = icc_from_color_space(unrefocusInfo);
1257 cond = !AssembleICCImageProperty(iccProfile, item.sharedProperties);
1258 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1259 "%{public}s AssembleICCImageProperty failed", __func__);
1260 sptr<SurfaceBuffer> unrefocusMapSptr(reinterpret_cast<SurfaceBuffer*>(unrefocusMap->GetContentPixel()->GetFd()));
1261 cond = !unrefocusMapSptr;
1262 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s unrefocusMapSptr is nullptr", __func__);
1263 item.pixelBuffer = sptr<NativeBuffer>::MakeSptr(unrefocusMapSptr->GetBufferHandle());
1264 std::string auxTypeStr = itemInfo.itemType;
1265
1266 uint32_t litePropertiesSize =
1267 sizeof(PropertyType::AUX_TYPE) + UINT32_BYTES_NUM + auxTypeStr.length() + PLACE_HOLDER_LENGTH;
1268 litePropertiesSize += (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
1269 item.liteProperties.resize(litePropertiesSize);
1270 size_t offset = 0;
1271 cond = !FillLitePropertyItemByString(item.liteProperties, offset, PropertyType::AUX_TYPE, auxTypeStr);
1272 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill auxiliary type failed", __func__);
1273 ColorType colorType = ColorType::RICC;
1274 cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
1275 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill color type failed", __func__);
1276 inputImgs.push_back(item);
1277 return SUCCESS;
1278 }
1279
GetFragmentRelLocation(std::shared_ptr<AuxiliaryPicture> & fragmentMap)1280 RelativeLocation GetFragmentRelLocation(std::shared_ptr<AuxiliaryPicture> &fragmentMap)
1281 {
1282 RelativeLocation loc;
1283 auto fragmentMeta = fragmentMap->GetMetadata(MetadataType::FRAGMENT);
1284 bool cond = fragmentMeta == nullptr;
1285 CHECK_ERROR_RETURN_RET_LOG(cond, loc, "The fragmentMap has not fragmentMap");
1286 std::string loc_x = "";
1287 std::string loc_y = "";
1288 uint32_t horizontalOffset = 0;
1289 uint32_t verticalOffset = 0;
1290 fragmentMeta->GetValue(FRAGMENT_METADATA_KEY_X, loc_x);
1291 fragmentMeta->GetValue(FRAGMENT_METADATA_KEY_Y, loc_y);
1292 ImageUtils::StrToUint32(loc_x, horizontalOffset);
1293 ImageUtils::StrToUint32(loc_y, verticalOffset);
1294 loc.horizontalOffset = horizontalOffset;
1295 loc.verticalOffset = verticalOffset;
1296 return loc;
1297 }
1298
AssembleHeifFragmentMap(std::vector<ImageItem> & inputImgs)1299 uint32_t ExtEncoder::AssembleHeifFragmentMap(std::vector<ImageItem>& inputImgs)
1300 {
1301 auto fragmentMap = picture_->GetAuxiliaryPicture(AuxiliaryPictureType::FRAGMENT_MAP);
1302 bool cond = !fragmentMap || !fragmentMap->GetContentPixel() ||
1303 fragmentMap->GetContentPixel()->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1304 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1305 "%{public}s The fragmentMap is nullptr or allocator type is not DMA_ALLOC", __func__);
1306 sptr<SurfaceBuffer> fragmentMapSptr(reinterpret_cast<SurfaceBuffer*>(fragmentMap->GetContentPixel()->GetFd()));
1307 cond = !fragmentMapSptr;
1308 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s fragmentMapSptr is nullptr", __func__);
1309 HeifEncodeItemInfo itemInfo = GetHeifEncodeItemInfo(AuxiliaryPictureType::FRAGMENT_MAP);
1310 auto item = InitAuxiliaryImageItem(itemInfo.itemId, itemInfo.itemName);
1311 bool sdrIsSRGB = fragmentMap->GetContentPixel()->GetToSdrColorSpaceIsSRGB();
1312 SkImageInfo fragmentInfo = GetSkInfo(fragmentMap->GetContentPixel().get(), false, sdrIsSRGB);
1313 sk_sp<SkData> iccProfile = icc_from_color_space(fragmentInfo);
1314 cond = !AssembleICCImageProperty(iccProfile, item.sharedProperties);
1315 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1316 "%{public}s AssembleICCImageProperty failed", __func__);
1317 item.pixelBuffer = sptr<NativeBuffer>::MakeSptr(fragmentMapSptr->GetBufferHandle());
1318 std::string auxTypeStr = itemInfo.itemType;
1319 uint32_t litePropertiesSize =
1320 sizeof(PropertyType::AUX_TYPE) + UINT32_BYTES_NUM + auxTypeStr.length() + PLACE_HOLDER_LENGTH;
1321 litePropertiesSize += (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
1322 litePropertiesSize += (sizeof(PropertyType::RLOC_INFO) + sizeof(RelativeLocation));
1323 item.liteProperties.resize(litePropertiesSize);
1324 size_t offset = 0;
1325 ColorType colorType = ColorType::RICC;
1326 cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
1327 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill color type failed", __func__);
1328 cond = !FillLitePropertyItemByString(item.liteProperties, offset, PropertyType::AUX_TYPE, auxTypeStr);
1329 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill auxiliary type failed", __func__);
1330 RelativeLocation loc = GetFragmentRelLocation(fragmentMap);
1331 cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::RLOC_INFO, &loc, sizeof(RelativeLocation));
1332 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s Fill auxiliary type failed", __func__);
1333 inputImgs.push_back(item);
1334 return SUCCESS;
1335 }
1336 #endif
1337
EncodeDualVivid(ExtWStream & outputStream)1338 uint32_t ExtEncoder::EncodeDualVivid(ExtWStream& outputStream)
1339 {
1340 IMAGE_LOGD("ExtEncoder::EncodeDualVivid");
1341 if (!pixelmap_->IsHdr() ||
1342 pixelmap_->GetAllocatorType() != AllocatorType::DMA_ALLOC ||
1343 (encodeFormat_ != SkEncodedImageFormat::kJPEG && encodeFormat_ != SkEncodedImageFormat::kHEIF)) {
1344 return ERR_IMAGE_INVALID_PARAMETER;
1345 }
1346 bool sdrIsSRGB = pixelmap_->GetToSdrColorSpaceIsSRGB();
1347 SkImageInfo baseInfo = GetSkInfo(pixelmap_, false, sdrIsSRGB);
1348 SkImageInfo gainmapInfo = GetSkInfo(pixelmap_, true, sdrIsSRGB);
1349 sptr<SurfaceBuffer> baseSptr = AllocSurfaceBuffer(baseInfo.width(), baseInfo.height());
1350 sptr<SurfaceBuffer> gainMapSptr = AllocSurfaceBuffer(gainmapInfo.width(), gainmapInfo.height());
1351 bool cond = baseSptr == nullptr || gainMapSptr == nullptr;
1352 CHECK_ERROR_RETURN_RET(cond, IMAGE_RESULT_CREATE_SURFAC_FAILED);
1353 HdrMetadata metadata;
1354 sptr<SurfaceBuffer> hdrSurfaceBuffer(reinterpret_cast<SurfaceBuffer*> (pixelmap_->GetFd()));
1355 SetHdrColorSpaceType(hdrSurfaceBuffer);
1356 CM_HDR_Metadata_Type hdrMetadataType;
1357 VpeUtils::GetSbMetadataType(hdrSurfaceBuffer, hdrMetadataType);
1358 VpeUtils::SetSbMetadataType(hdrSurfaceBuffer, CM_IMAGE_HDR_VIVID_SINGLE);
1359 VpeSurfaceBuffers buffers = {
1360 .sdr = baseSptr,
1361 .gainmap = gainMapSptr,
1362 .hdr = hdrSurfaceBuffer,
1363 };
1364 if (!DecomposeImage(buffers, metadata, false, sdrIsSRGB)) {
1365 IMAGE_LOGE("EncodeDualVivid decomposeImage failed");
1366 FreeBaseAndGainMapSurfaceBuffer(baseSptr, gainMapSptr);
1367 return IMAGE_RESULT_CREATE_SURFAC_FAILED;
1368 }
1369 metadata.hdrMetadataType = static_cast<int32_t>(hdrMetadataType);
1370 uint32_t error;
1371 if (encodeFormat_ == SkEncodedImageFormat::kJPEG) {
1372 sk_sp<SkData> baseImageData = GetImageEncodeData(baseSptr, baseInfo, opts_.needsPackProperties);
1373 sk_sp<SkData> gainMapImageData = GetImageEncodeData(gainMapSptr, gainmapInfo, false);
1374 error = HdrJpegPackerHelper::SpliceHdrStream(baseImageData, gainMapImageData, outputStream, metadata);
1375 } else if (encodeFormat_ == SkEncodedImageFormat::kHEIF) {
1376 error = EncodeHeifDualHdrImage(baseSptr, gainMapSptr, metadata);
1377 } else {
1378 error = ERR_IMAGE_INVALID_PARAMETER;
1379 }
1380 FreeBaseAndGainMapSurfaceBuffer(baseSptr, gainMapSptr);
1381 return error;
1382 }
1383
EncodeSdrImage(ExtWStream & outputStream)1384 uint32_t ExtEncoder::EncodeSdrImage(ExtWStream& outputStream)
1385 {
1386 IMAGE_LOGD("ExtEncoder EncodeSdrImage");
1387 if (!pixelmap_->IsHdr()) {
1388 return EncodeImageByPixelMap(pixelmap_, opts_.needsPackProperties, outputStream);
1389 }
1390 bool cond = pixelmap_->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1391 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "pixelmap is 10bit, but not dma buffer");
1392 ImageInfo info;
1393 pixelmap_->GetImageInfo(info);
1394 bool sdrIsSRGB = pixelmap_->GetToSdrColorSpaceIsSRGB();
1395 SkImageInfo baseInfo = GetSkInfo(pixelmap_, false, sdrIsSRGB);
1396 sptr<SurfaceBuffer> baseSptr = AllocSurfaceBuffer(baseInfo.width(), baseInfo.height());
1397 VpeUtils::SetSbMetadataType(baseSptr, CM_IMAGE_HDR_VIVID_DUAL);
1398 VpeUtils::SetSbColorSpaceType(baseSptr, CM_SRGB_FULL);
1399 cond = baseSptr == nullptr;
1400 CHECK_ERROR_RETURN_RET_LOG(cond, IMAGE_RESULT_CREATE_SURFAC_FAILED, "EncodeSdrImage sdr buffer alloc failed");
1401 sptr<SurfaceBuffer> hdrSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(pixelmap_->GetFd()));
1402 VpeUtils::SetSbMetadataType(hdrSurfaceBuffer, CM_IMAGE_HDR_VIVID_SINGLE);
1403 SetHdrColorSpaceType(hdrSurfaceBuffer);
1404 VpeSurfaceBuffers buffers = {
1405 .sdr = baseSptr,
1406 .hdr = hdrSurfaceBuffer,
1407 };
1408 HdrMetadata metadata;
1409 if (!DecomposeImage(buffers, metadata, true, sdrIsSRGB)) {
1410 IMAGE_LOGE("EncodeSdrImage decomposeImage failed");
1411 ImageUtils::SurfaceBuffer_Unreference(baseSptr.GetRefPtr());
1412 return IMAGE_RESULT_CREATE_SURFAC_FAILED;
1413 }
1414 uint32_t error;
1415 if (encodeFormat_ == SkEncodedImageFormat::kHEIF) {
1416 error = EncodeHeifSdrImage(baseSptr, baseInfo);
1417 } else {
1418 error = EncodeImageBySurfaceBuffer(baseSptr, baseInfo, opts_.needsPackProperties, outputStream);
1419 }
1420 ImageUtils::SurfaceBuffer_Unreference(baseSptr.GetRefPtr());
1421 return error;
1422 }
1423
EncodeHeifDualHdrImage(sptr<SurfaceBuffer> & sdr,sptr<SurfaceBuffer> & gainmap,Media::HdrMetadata & metadata,bool sdrIsSRGB)1424 uint32_t ExtEncoder::EncodeHeifDualHdrImage(sptr<SurfaceBuffer>& sdr, sptr<SurfaceBuffer>& gainmap,
1425 Media::HdrMetadata& metadata, bool sdrIsSRGB)
1426 {
1427 #ifdef HEIF_HW_ENCODE_ENABLE
1428 std::vector<ImageItem> inputImgs;
1429 ColorSpaceManager colorspaceName =
1430 sdrIsSRGB ? ColorManager::ColorSpaceName::SRGB : ColorManager::ColorSpaceName::DISPLAY_P3;
1431 std::shared_ptr<ImageItem> primaryItem =
1432 AssembleHdrBaseImageItem(sdr, colorspaceName, metadata, opts_);
1433 bool cond = primaryItem == nullptr;
1434 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "AssmbleHeifDualHdrImage, get primary image failed");
1435 inputImgs.push_back(*primaryItem);
1436 std::shared_ptr<ImageItem> gainmapItem =
1437 AssembleGainmapImageItem(gainmap, colorspaceName, opts_);
1438 cond = gainmapItem == nullptr;
1439 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1440 "AssembleDualHdrImage, get gainmap image item failed");
1441 inputImgs.push_back(*gainmapItem);
1442 ColorManager::ColorSpaceName tmapColor = pixelmap_->InnerGetGrColorSpace().GetColorSpaceName();
1443 std::shared_ptr<ImageItem> tmapItem = AssembleTmapImageItem(tmapColor, metadata, opts_);
1444 cond = tmapItem == nullptr;
1445 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "AssembleDualHdrImage, get tmap image item failed");
1446 inputImgs.push_back(*tmapItem);
1447 std::vector<MetaItem> inputMetas;
1448 std::vector<ItemRef> refs;
1449 if (AssembleExifMetaItem(inputMetas)) {
1450 AssembleExifRefItem(refs);
1451 }
1452 AssembleDualHdrRefItem(refs);
1453 return DoHeifEncode(inputImgs, inputMetas, refs);
1454 #else
1455 return ERR_IMAGE_INVALID_PARAMETER;
1456 #endif
1457 }
1458
EncodeHeifSdrImage(sptr<SurfaceBuffer> & sdr,SkImageInfo sdrInfo)1459 uint32_t ExtEncoder::EncodeHeifSdrImage(sptr<SurfaceBuffer>& sdr, SkImageInfo sdrInfo)
1460 {
1461 #ifdef HEIF_HW_ENCODE_ENABLE
1462 bool cond = sdr == nullptr;
1463 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "EncodeHeifSdrImage, sdr surfacebuffer is nullptr");
1464 ImageItem item;
1465 item.id = PRIMARY_IMAGE_ITEM_ID;
1466 item.pixelBuffer = sptr<NativeBuffer>::MakeSptr(sdr->GetBufferHandle());
1467 item.isPrimary = true;
1468 item.isHidden = false;
1469 item.compressType = COMPRESS_TYPE_HEVC;
1470 item.quality = opts_.quality;
1471 item.sharedProperties.fd = -1;
1472 item.pixelSharedBuffer.fd = -1;
1473 ImageInfo info;
1474 pixelmap_->GetImageInfo(info);
1475 sk_sp<SkData> iccProfile = icc_from_color_space(sdrInfo);
1476 bool tempRes = AssembleICCImageProperty(iccProfile, item.sharedProperties);
1477 cond = !tempRes;
1478 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "EncodeSdrImage AssembleICCImageProperty failed");
1479 uint32_t litePropertiesSize = (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
1480 item.liteProperties.resize(litePropertiesSize);
1481 size_t offset = 0;
1482 ColorType colorType = ColorType::RICC;
1483 cond = !FillLitePropertyItem(item.liteProperties, offset, PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
1484 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "EncodeHeifSdrImage Fill color type failed");
1485 std::vector<ImageItem> inputImgs;
1486 inputImgs.push_back(item);
1487 std::vector<MetaItem> inputMetas;
1488 std::vector<ItemRef> refs;
1489 if (AssembleExifMetaItem(inputMetas)) {
1490 AssembleExifRefItem(refs);
1491 }
1492 return DoHeifEncode(inputImgs, inputMetas, refs);
1493 #else
1494 return ERR_IMAGE_INVALID_PARAMETER;
1495 #endif
1496 }
1497
EncodePicture()1498 uint32_t ExtEncoder::EncodePicture()
1499 {
1500 bool cond = (encodeFormat_ != SkEncodedImageFormat::kJPEG && encodeFormat_ != SkEncodedImageFormat::kHEIF);
1501 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1502 "%{public}s: unsupported encode format: %{public}s", __func__, opts_.format.c_str());
1503 if (opts_.isEditScene && encodeFormat_ == SkEncodedImageFormat::kHEIF) {
1504 return EncodeEditScenePicture();
1505 }
1506 if (encodeFormat_ == SkEncodedImageFormat::kJPEG) {
1507 CheckJpegAuxiliaryTagName();
1508 }
1509 ExtWStream wStream(output_);
1510 return EncodeCameraScenePicture(wStream);
1511 }
1512
IsValidSizeForHardwareEncode(int32_t width,int32_t height)1513 static bool IsValidSizeForHardwareEncode(int32_t width, int32_t height)
1514 {
1515 if (ImageUtils::IsEven(width) && ImageUtils::IsInRange(width, MIN_IMAGE_SIZE, MAX_IMAGE_SIZE) &&
1516 ImageUtils::IsEven(height) && ImageUtils::IsInRange(height, MIN_IMAGE_SIZE, MAX_IMAGE_SIZE)) {
1517 return true;
1518 }
1519 IMAGE_LOGD("%{public}s hardware encode is not support, width: %{public}d, height: %{public}d",
1520 __func__, width, height);
1521 return false;
1522 }
1523
IsPictureSupportHardwareEncode()1524 bool ExtEncoder::IsPictureSupportHardwareEncode()
1525 {
1526 bool cond = !ImageSystemProperties::GetHardWareEncodeEnabled();
1527 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s hardware encode disabled", __func__);
1528 cond = picture_ == nullptr;
1529 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s picture is null", __func__);
1530
1531 if (opts_.quality < LOW_QUALITY_BOUNDARY) {
1532 IMAGE_LOGE("%{public}s Low quality use jpeg software encode", __func__);
1533 return false;
1534 }
1535 auto mainPixelMap = picture_->GetMainPixel();
1536 if (mainPixelMap == nullptr ||
1537 !IsValidSizeForHardwareEncode(mainPixelMap->GetWidth(), mainPixelMap->GetHeight())) {
1538 IMAGE_LOGI("%{public}s MainPixelMap not support hardware encode", __func__);
1539 return false;
1540 }
1541
1542 const auto& auxTypes = ImageUtils::GetAllAuxiliaryPictureType();
1543 for (const auto& auxType : auxTypes) {
1544 auto auxPicture = picture_->GetAuxiliaryPicture(auxType);
1545 if (auxPicture == nullptr) {
1546 continue;
1547 }
1548 auto auxPixelMap = auxPicture->GetContentPixel();
1549 if (auxPixelMap == nullptr) {
1550 continue;
1551 }
1552 cond = !IsValidSizeForHardwareEncode(auxPixelMap->GetWidth(), auxPixelMap->GetHeight());
1553 CHECK_INFO_RETURN_RET_LOG(cond, false,
1554 "%{public}s auxType: %{public}d not support hardware encode", __func__, auxType);
1555 }
1556 return true;
1557 }
1558
TryHardwareEncodePicture(SkWStream & skStream,std::string & errorMsg)1559 uint32_t ExtEncoder::TryHardwareEncodePicture(SkWStream& skStream, std::string& errorMsg)
1560 {
1561 errorMsg = "Hardware encode picture failed";
1562 if (picture_ == nullptr) {
1563 errorMsg = "picture is nullptr";
1564 return ERR_IMAGE_DATA_ABNORMAL;
1565 }
1566 static ImageFwkExtManager imageFwkExtManager;
1567 if (!imageFwkExtManager.LoadImageFwkExtNativeSo() || imageFwkExtManager.doHardwareEncodePictureFunc_ == nullptr) {
1568 errorMsg = "Load hardware encode library failed";
1569 return ERR_IMAGE_ENCODE_FAILED;
1570 }
1571 return imageFwkExtManager.doHardwareEncodePictureFunc_(&skStream, opts_, picture_);
1572 }
1573
EncodeCameraScenePicture(SkWStream & skStream)1574 uint32_t ExtEncoder::EncodeCameraScenePicture(SkWStream& skStream)
1575 {
1576 uint32_t retCode = ERR_IMAGE_ENCODE_FAILED;
1577 std::string errorMsg = "Unknown encode failed";
1578 if (encodeFormat_ == SkEncodedImageFormat::kHEIF) {
1579 retCode = TryHardwareEncodePicture(skStream, errorMsg);
1580 } else if (encodeFormat_ == SkEncodedImageFormat::kJPEG) {
1581 if (IsPictureSupportHardwareEncode()) {
1582 retCode = TryHardwareEncodePicture(skStream, errorMsg);
1583 } else {
1584 errorMsg = "Not support hardware encode";
1585 }
1586 if (retCode != SUCCESS) {
1587 IMAGE_LOGW("%{public}s, retCode is: %{public}d, try jpeg software encode", errorMsg.c_str(), retCode);
1588 retCode = EncodeJpegPicture(skStream);
1589 errorMsg = "Jpeg software encode picture failed";
1590 }
1591 }
1592 if (retCode != SUCCESS) {
1593 ImageInfo imageInfo;
1594 picture_->GetMainPixel()->GetImageInfo(imageInfo);
1595 IMAGE_LOGE("%{public}s, retCode is: %{public}d", errorMsg.c_str(), retCode);
1596 ReportEncodeFault(imageInfo.size.width, imageInfo.size.height, opts_.format, errorMsg);
1597 }
1598 return retCode;
1599 }
1600
EncodeEditScenePicture()1601 uint32_t ExtEncoder::EncodeEditScenePicture()
1602 {
1603 bool cond = !picture_;
1604 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_DATA_ABNORMAL, "picture_ is nullptr");
1605 auto mainPixelMap = picture_->GetMainPixel();
1606 cond = !mainPixelMap || mainPixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1607 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_DATA_ABNORMAL,
1608 "MainPixelMap is nullptr or mainPixelMap is not DMA buffer");
1609
1610 bool sdrIsSRGB = mainPixelMap->GetToSdrColorSpaceIsSRGB();
1611 SkImageInfo baseInfo = GetSkInfo(mainPixelMap.get(), false, false);
1612 sptr<SurfaceBuffer> baseSptr(reinterpret_cast<SurfaceBuffer*>(mainPixelMap->GetFd()));
1613 cond = !baseSptr;
1614 CHECK_ERROR_RETURN_RET_LOG(cond, IMAGE_RESULT_CREATE_SURFAC_FAILED, "creat main pixels surfaceBuffer error");
1615 uint32_t errorCode = EncodeHeifPicture(baseSptr, baseInfo, sdrIsSRGB);
1616 RecycleResources();
1617 return errorCode;
1618 }
1619
EncodeHeifPicture(sptr<SurfaceBuffer> & mainSptr,SkImageInfo mainInfo,bool sdrIsSRGB)1620 uint32_t ExtEncoder::EncodeHeifPicture(sptr<SurfaceBuffer>& mainSptr, SkImageInfo mainInfo, bool sdrIsSRGB)
1621 {
1622 #ifdef HEIF_HW_ENCODE_ENABLE
1623 uint32_t error = SUCCESS;
1624 std::vector<ImageItem> inputImgs;
1625 std::vector<MetaItem> inputMetas;
1626 std::vector<ItemRef> refs;
1627 switch (opts_.desiredDynamicRange) {
1628 case EncodeDynamicRange::AUTO:
1629 if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::GAINMAP) &&
1630 AssembleHeifHdrPicture(mainSptr, sdrIsSRGB, inputImgs) == SUCCESS) {
1631 AssembleDualHdrRefItem(refs);
1632 } else {
1633 inputImgs.clear();
1634 error = AssembleSdrImageItem(mainSptr, mainInfo, inputImgs);
1635 }
1636 break;
1637 case EncodeDynamicRange::SDR:
1638 error = AssembleSdrImageItem(mainSptr, mainInfo, inputImgs);
1639 break;
1640 case EncodeDynamicRange::HDR_VIVID_DUAL:
1641 if (picture_->HasAuxiliaryPicture(AuxiliaryPictureType::GAINMAP)) {
1642 error = AssembleHeifHdrPicture(mainSptr, sdrIsSRGB, inputImgs);
1643 AssembleDualHdrRefItem(refs);
1644 } else {
1645 IMAGE_LOGE("Picture don't has GAINMAP pixels");
1646 error = ERR_IMAGE_ENCODE_FAILED;
1647 }
1648 break;
1649 case EncodeDynamicRange::HDR_VIVID_SINGLE:
1650 IMAGE_LOGE("Heif picture not support HDR_VIVID_SINGLE");
1651 return ERR_IMAGE_ENCODE_FAILED;
1652 default:
1653 return ERR_IMAGE_INVALID_PARAMETER;
1654 }
1655 bool cond = error != SUCCESS;
1656 CHECK_ERROR_RETURN_RET(cond, error);
1657 if (AssembleExifMetaItem(inputMetas)) {
1658 AssembleExifRefItem(refs);
1659 }
1660 error = AssembleHeifAuxiliaryPicture(inputImgs, refs);
1661 cond = error != SUCCESS;
1662 CHECK_ERROR_RETURN_RET(cond, error);
1663 return DoHeifEncode(inputImgs, inputMetas, refs);
1664 #else
1665 return ERR_IMAGE_INVALID_PARAMETER;
1666 #endif
1667 }
1668
CheckJpegAuxiliaryTagName()1669 void ExtEncoder::CheckJpegAuxiliaryTagName()
1670 {
1671 if (picture_ == nullptr) {
1672 return;
1673 }
1674 auto auxTypes = ImageUtils::GetAllAuxiliaryPictureType();
1675 for (AuxiliaryPictureType auxType : auxTypes) {
1676 auto auxPicture = picture_->GetAuxiliaryPicture(auxType);
1677 if (auxPicture == nullptr) {
1678 continue;
1679 }
1680 AuxiliaryPictureInfo auxInfo = auxPicture->GetAuxiliaryPictureInfo();
1681 auto iter = DEFAULT_AUXILIARY_TAG_MAP.find(auxType);
1682 if (auxInfo.jpegTagName.size() == 0 && iter != DEFAULT_AUXILIARY_TAG_MAP.end()) {
1683 auxInfo.jpegTagName = iter->second;
1684 auxPicture->SetAuxiliaryPictureInfo(auxInfo);
1685 }
1686 }
1687 }
1688
EncodeJpegPicture(SkWStream & skStream)1689 uint32_t ExtEncoder::EncodeJpegPicture(SkWStream& skStream)
1690 {
1691 uint32_t error = ERR_IMAGE_ENCODE_FAILED;
1692 switch (opts_.desiredDynamicRange) {
1693 case EncodeDynamicRange::AUTO:
1694 error = EncodeJpegPictureDualVivid(skStream);
1695 if (error != SUCCESS) {
1696 IMAGE_LOGI("%{public}s jpeg picture encode dual vivid failed, try encode sdr", __func__);
1697 error = EncodeJpegPictureSdr(skStream);
1698 }
1699 break;
1700 case EncodeDynamicRange::SDR:
1701 error = EncodeJpegPictureSdr(skStream);
1702 break;
1703 case EncodeDynamicRange::HDR_VIVID_DUAL:
1704 error = EncodeJpegPictureDualVivid(skStream);
1705 break;
1706 case EncodeDynamicRange::HDR_VIVID_SINGLE:
1707 error = ERR_IMAGE_DECODE_FAILED;
1708 break;
1709 default:
1710 error = ERR_IMAGE_INVALID_PARAMETER;
1711 break;
1712 }
1713 return error;
1714 }
1715
EncodeJpegPictureDualVividInner(SkWStream & skStream,std::shared_ptr<PixelMap> & mainPixelmap,std::shared_ptr<PixelMap> & gainmapPixelmap)1716 uint32_t ExtEncoder::EncodeJpegPictureDualVividInner(SkWStream& skStream, std::shared_ptr<PixelMap>& mainPixelmap,
1717 std::shared_ptr<PixelMap>& gainmapPixelmap)
1718 {
1719 bool mainIsSRGB = mainPixelmap->GetToSdrColorSpaceIsSRGB();
1720 SkImageInfo baseInfo = GetSkInfo(mainPixelmap.get(), false, mainIsSRGB);
1721 sptr<SurfaceBuffer> baseSptr(reinterpret_cast<SurfaceBuffer*>(mainPixelmap->GetFd()));
1722 VpeUtils::SetSbMetadataType(baseSptr, CM_IMAGE_HDR_VIVID_DUAL);
1723 VpeUtils::SetSbColorSpaceType(baseSptr, mainIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
1724 pixelmap_ = mainPixelmap.get();
1725 sk_sp<SkData> baseImageData = GetImageEncodeData(baseSptr, baseInfo, opts_.needsPackProperties);
1726
1727 bool gainmapIsSRGB = gainmapPixelmap->GetToSdrColorSpaceIsSRGB();
1728 SkImageInfo gainmapInfo = GetSkInfo(gainmapPixelmap.get(), true, gainmapIsSRGB);
1729 ImageInfo tempInfo;
1730 gainmapPixelmap->GetImageInfo(tempInfo);
1731 gainmapInfo = gainmapInfo.makeWH(tempInfo.size.width, tempInfo.size.height);
1732 sptr<SurfaceBuffer> gainMapSptr(reinterpret_cast<SurfaceBuffer*>(gainmapPixelmap->GetFd()));
1733 VpeUtils::SetSbMetadataType(gainMapSptr, CM_METADATA_NONE);
1734 VpeUtils::SetSbColorSpaceType(gainMapSptr, gainmapIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
1735 pixelmap_ = gainmapPixelmap.get();
1736 sk_sp<SkData> gainMapImageData = GetImageEncodeData(gainMapSptr, gainmapInfo, false);
1737
1738 HdrMetadata hdrMetadata = GetHdrMetadata(baseSptr, gainMapSptr);
1739 SkDynamicMemoryWStream hdrStream;
1740 uint32_t error = HdrJpegPackerHelper::SpliceHdrStream(baseImageData, gainMapImageData, hdrStream, hdrMetadata);
1741 IMAGE_LOGD("%{public}s splice hdr stream result is: %{public}u", __func__, error);
1742 if (error == SUCCESS) {
1743 sk_sp<SkData> hdrSkData = hdrStream.detachAsData();
1744 skStream.write(hdrSkData->data(), hdrSkData->size());
1745 EncodeJpegAuxiliaryPictures(skStream);
1746 }
1747 return error;
1748 }
1749
EncodeJpegPictureDualVivid(SkWStream & skStream)1750 uint32_t ExtEncoder::EncodeJpegPictureDualVivid(SkWStream& skStream)
1751 {
1752 ImageFuncTimer imageFuncTimer("%s enter", __func__);
1753 if (!picture_->HasAuxiliaryPicture(AuxiliaryPictureType::GAINMAP)) {
1754 IMAGE_LOGE("%{public}s no gainmap in picture", __func__);
1755 return ERR_IMAGE_INVALID_PARAMETER;
1756 }
1757 auto mainPixelmap = picture_->GetMainPixel();
1758 auto gainmapPixelmap = picture_->GetGainmapPixelMap();
1759 bool cond = !mainPixelmap || !gainmapPixelmap;
1760 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
1761 "%{public}s mainPixelmap or gainmapPixelmap is null", __func__);
1762 AllocatorType mainAllocType = mainPixelmap->GetAllocatorType();
1763 AllocatorType gainmapAllocType = gainmapPixelmap->GetAllocatorType();
1764 cond = mainAllocType != AllocatorType::DMA_ALLOC || gainmapAllocType != AllocatorType::DMA_ALLOC;
1765 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED,
1766 "%{public}s AllocatorType is not DMA, mainAllocType: %{public}d, gainmapAllocType: %{public}d",
1767 __func__, mainAllocType, gainmapAllocType);
1768 return EncodeJpegPictureDualVividInner(skStream, mainPixelmap, gainmapPixelmap);
1769 }
1770
EncodeJpegPictureSdr(SkWStream & skStream)1771 uint32_t ExtEncoder::EncodeJpegPictureSdr(SkWStream& skStream)
1772 {
1773 ImageFuncTimer imageFuncTimer("%s enter", __func__);
1774 auto mainPixelmap = picture_->GetMainPixel();
1775 bool cond = !mainPixelmap;
1776 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s mainPixelmap is null", __func__);
1777 pixelmap_ = mainPixelmap.get();
1778 uint32_t error = ERR_IMAGE_ENCODE_FAILED;
1779 if (!mainPixelmap->IsHdr()) {
1780 error = EncodeImageByPixelMap(mainPixelmap.get(), opts_.needsPackProperties, skStream);
1781 IMAGE_LOGD("%{public}s encode sdr picture result is: %{public}u", __func__, error);
1782 } else {
1783 cond = mainPixelmap->GetAllocatorType() != AllocatorType::DMA_ALLOC;
1784 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "pixelmap is 10bit, but not dma buffer");
1785 bool mainIsSRGB = mainPixelmap->GetToSdrColorSpaceIsSRGB();
1786 SkImageInfo baseInfo = GetSkInfo(mainPixelmap.get(), false, mainIsSRGB);
1787 sptr<SurfaceBuffer> baseSptr(reinterpret_cast<SurfaceBuffer*>(mainPixelmap->GetFd()));
1788 VpeUtils::SetSbMetadataType(baseSptr, CM_IMAGE_HDR_VIVID_DUAL);
1789 VpeUtils::SetSbColorSpaceType(baseSptr, mainIsSRGB ? CM_SRGB_FULL : CM_P3_FULL);
1790 error = EncodeImageBySurfaceBuffer(baseSptr, baseInfo, opts_.needsPackProperties, skStream);
1791 IMAGE_LOGD("%{public}s encode hdr picture result is: %{public}u", __func__, error);
1792 }
1793 if (error == SUCCESS) {
1794 EncodeJpegAuxiliaryPictures(skStream);
1795 }
1796 return error;
1797 }
1798
GetMetadataValueInt32(const std::shared_ptr<ImageMetadata> & metadata,const std::string & key,int32_t & outVal)1799 static bool GetMetadataValueInt32(const std::shared_ptr<ImageMetadata>& metadata, const std::string& key,
1800 int32_t& outVal)
1801 {
1802 std::string strVal("");
1803 uint32_t u32Val = 0;
1804 bool cond = metadata == nullptr;
1805 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s: metadata is nullptr!", __func__);
1806 cond = metadata->GetValue(key, strVal) != SUCCESS || !ImageUtils::StrToUint32(strVal, u32Val);
1807 CHECK_ERROR_RETURN_RET_LOG(cond, false,
1808 "%{public}s: get metadata key[%{public}s]'s value failed!", __func__, key.c_str());
1809 outVal = static_cast<int32_t>(u32Val);
1810 return true;
1811 }
1812
CheckFragmentMetadata(Picture * picture,Media::Rect & outData)1813 static bool CheckFragmentMetadata(Picture* picture, Media::Rect& outData)
1814 {
1815 bool cond = !picture || !picture->GetMainPixel() ||
1816 !picture->HasAuxiliaryPicture(AuxiliaryPictureType::FRAGMENT_MAP);
1817 CHECK_ERROR_RETURN_RET_LOG(cond, false,
1818 "%{public}s: picture or mainPixelMap or fragment picture does not exist!", __func__);
1819 int32_t mainW = picture->GetMainPixel()->GetWidth();
1820 int32_t mainH = picture->GetMainPixel()->GetHeight();
1821
1822 auto fragmentPicture = picture->GetAuxiliaryPicture(AuxiliaryPictureType::FRAGMENT_MAP);
1823 auto fragmentMetadata = fragmentPicture->GetMetadata(MetadataType::FRAGMENT);
1824 cond = fragmentMetadata == nullptr;
1825 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s: fragmentMetadata is nullptr!", __func__);
1826 cond = !GetMetadataValueInt32(fragmentMetadata, FRAGMENT_METADATA_KEY_X, outData.left) ||
1827 !GetMetadataValueInt32(fragmentMetadata, FRAGMENT_METADATA_KEY_Y, outData.top) ||
1828 !GetMetadataValueInt32(fragmentMetadata, FRAGMENT_METADATA_KEY_WIDTH, outData.width) ||
1829 !GetMetadataValueInt32(fragmentMetadata, FRAGMENT_METADATA_KEY_HEIGHT, outData.height);
1830 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s: GetMetadataValueInt32 failed!", __func__);
1831 if (!ImageUtils::IsInRange(outData.left, 0, mainW) || !ImageUtils::IsInRange(outData.top, 0, mainH) ||
1832 !ImageUtils::IsInRange(outData.width, 0, mainW) || !ImageUtils::IsInRange(outData.height, 0, mainH) ||
1833 !ImageUtils::IsInRange(outData.left + outData.width, 0, mainW) ||
1834 !ImageUtils::IsInRange(outData.top + outData.height, 0, mainH)) {
1835 IMAGE_LOGW("%{public}s: Fragment Rect is not in main Rect!", __func__);
1836 return false;
1837 }
1838 return true;
1839 }
1840
EncodeJpegAuxiliaryPictures(SkWStream & skStream)1841 void ExtEncoder::EncodeJpegAuxiliaryPictures(SkWStream& skStream)
1842 {
1843 ImageFuncTimer imageFuncTimer("%s enter", __func__);
1844 auto auxTypes = ImageUtils::GetAllAuxiliaryPictureType();
1845 for (AuxiliaryPictureType auxType : auxTypes) {
1846 auto auxPicture = picture_->GetAuxiliaryPicture(auxType);
1847 // Gainmap has been encoded before
1848 if (auxPicture == nullptr || auxType == AuxiliaryPictureType::GAINMAP) {
1849 continue;
1850 }
1851 IMAGE_LOGI("%{public}s try to encode auxiliary picture type: %{public}d", __func__, auxType);
1852 uint32_t error = ERR_IMAGE_ENCODE_FAILED;
1853 size_t writtenSize = skStream.bytesWritten();
1854 if (ImageUtils::IsAuxiliaryPictureEncoded(auxType)) {
1855 error = WriteJpegCodedData(auxPicture, skStream);
1856 } else {
1857 error = WriteJpegUncodedData(auxPicture, skStream);
1858 }
1859 if (error != SUCCESS) {
1860 IMAGE_LOGE("%{public}s encode auxiliary picture type [%{public}d] failed, error: %{public}u",
1861 __func__, auxType, error);
1862 } else {
1863 uint32_t currentDataSize = static_cast<uint32_t>(skStream.bytesWritten() - writtenSize);
1864 WriteJpegAuxiliarySizeAndTag(currentDataSize, auxPicture, skStream);
1865 }
1866 }
1867 }
1868
WriteJpegCodedData(std::shared_ptr<AuxiliaryPicture> & auxPicture,SkWStream & skStream)1869 uint32_t ExtEncoder::WriteJpegCodedData(std::shared_ptr<AuxiliaryPicture>& auxPicture, SkWStream& skStream)
1870 {
1871 auto pixelMap = auxPicture->GetContentPixel();
1872 bool cond = pixelMap == nullptr;
1873 CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_DATA_ABNORMAL);
1874 pixelmap_ = pixelMap.get();
1875 sk_sp<SkData> skData = nullptr;
1876 if (pixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC || pixelMap->GetFd() == nullptr) {
1877 SkDynamicMemoryWStream nonDMAStream;
1878 uint32_t error = EncodeImageByPixelMap(pixelmap_, false, nonDMAStream);
1879 IMAGE_LOGD("%{public}s EncodeImageByPixelMap result: %{public}u", __func__, error);
1880 skData = nonDMAStream.detachAsData();
1881 } else {
1882 sptr<SurfaceBuffer> auxSptr(reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd()));
1883 bool isSRGB = pixelMap->GetToSdrColorSpaceIsSRGB();
1884 SkImageInfo skInfo = GetSkInfo(pixelmap_, false, isSRGB);
1885 skData = GetImageEncodeData(auxSptr, skInfo, false);
1886 }
1887 cond = skData == nullptr;
1888 CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_ENCODE_FAILED);
1889 cond = auxPicture->GetType() == AuxiliaryPictureType::FRAGMENT_MAP;
1890 CHECK_ERROR_RETURN_RET(cond, SpliceFragmentStream(skStream, skData));
1891 skStream.write(skData->data(), skData->size());
1892 return SUCCESS;
1893 }
1894
SpliceFragmentStream(SkWStream & skStream,sk_sp<SkData> & skData)1895 uint32_t ExtEncoder::SpliceFragmentStream(SkWStream& skStream, sk_sp<SkData>& skData)
1896 {
1897 Media::Rect fragmentMetadata;
1898 bool cond = !CheckFragmentMetadata(picture_, fragmentMetadata);
1899 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_PROPERTY_NOT_EXIST,
1900 "%{public}s: CheckFragmentMetadata failed!", __func__);
1901 const uint8_t* dataBytes = reinterpret_cast<const uint8_t*>(skData->data());
1902 // write JPEG SOI(0xFFD8)
1903 skStream.write(dataBytes, JPEG_MARKER_TAG_SIZE);
1904 std::vector<uint8_t> packedFragmentMetadata = JpegMpfPacker::PackFragmentMetadata(fragmentMetadata);
1905 // write fragment metadata
1906 skStream.write(packedFragmentMetadata.data(), packedFragmentMetadata.size());
1907 // write fragment auxiliary image data
1908 skStream.write(dataBytes + JPEG_MARKER_TAG_SIZE, skData->size() - JPEG_MARKER_TAG_SIZE);
1909 return SUCCESS;
1910 }
1911
WriteJpegUncodedData(std::shared_ptr<AuxiliaryPicture> & auxPicture,SkWStream & skStream)1912 uint32_t ExtEncoder::WriteJpegUncodedData(std::shared_ptr<AuxiliaryPicture>& auxPicture, SkWStream& skStream)
1913 {
1914 auto pixelMap = auxPicture->GetContentPixel();
1915 bool cond = pixelMap == nullptr;
1916 CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_DATA_ABNORMAL);
1917 void* bytes = nullptr;
1918 uint32_t size = 0;
1919 Size imageSize;
1920 if (pixelMap->GetAllocatorType() != AllocatorType::DMA_ALLOC || pixelMap->GetFd() == nullptr) {
1921 bytes = pixelMap->GetWritablePixels();
1922 size = pixelMap->GetCapacity();
1923 imageSize.width = pixelMap->GetWidth();
1924 imageSize.height = pixelMap->GetHeight();
1925 } else {
1926 auto surfaceBuffer = reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd());
1927 bytes = surfaceBuffer->GetVirAddr();
1928 size = surfaceBuffer->GetSize();
1929 imageSize.width = surfaceBuffer->GetWidth();
1930 imageSize.height = surfaceBuffer->GetHeight();
1931 }
1932 uint32_t writeSize = imageSize.width * imageSize.height;
1933 AuxiliaryPictureInfo auxInfo = auxPicture->GetAuxiliaryPictureInfo();
1934 if (auxInfo.auxiliaryPictureType == AuxiliaryPictureType::DEPTH_MAP) {
1935 writeSize *= DEPTH_MAP_BYTES;
1936 } else if (auxInfo.auxiliaryPictureType == AuxiliaryPictureType::LINEAR_MAP) {
1937 writeSize *= LINEAR_MAP_BYTES;
1938 }
1939 IMAGE_LOGD("%{public}s auxType: %{public}d, width: %{public}d, height: %{public}d, buffer size: %{public}u,"
1940 " write size: %{public}u", __func__, auxInfo.auxiliaryPictureType, imageSize.width, imageSize.height,
1941 size, writeSize);
1942 skStream.write(bytes, std::min(size, writeSize));
1943 return SUCCESS;
1944 }
1945
WriteJpegAuxiliarySizeAndTag(uint32_t size,std::shared_ptr<AuxiliaryPicture> & auxPicture,SkWStream & skStream)1946 void ExtEncoder::WriteJpegAuxiliarySizeAndTag(uint32_t size, std::shared_ptr<AuxiliaryPicture>& auxPicture,
1947 SkWStream& skStream)
1948 {
1949 // Write auxiliary image size(little endian)
1950 std::vector<uint8_t> auxSize = JpegMpfPacker::PackDataSize(size, false);
1951 skStream.write(auxSize.data(), auxSize.size());
1952
1953 // Write auxiliary tag name
1954 AuxiliaryPictureInfo auxInfo = auxPicture->GetAuxiliaryPictureInfo();
1955 std::vector<uint8_t> tagName = JpegMpfPacker::PackAuxiliaryTagName(auxInfo.jpegTagName);
1956 skStream.write(tagName.data(), tagName.size());
1957 }
1958 #endif
1959
1960 #ifdef HEIF_HW_ENCODE_ENABLE
GetBufferSize(size_t contentSize)1961 static size_t GetBufferSize(size_t contentSize)
1962 {
1963 return sizeof(PropertyType) + sizeof(int) + contentSize;
1964 }
1965
1966 // format: enum + int buffersize + buffer
FillImagePropertyItem(const std::shared_ptr<AbsMemory> & mem,const size_t offset,PropertyType type,const void * payloadData,size_t payloadSize)1967 static bool FillImagePropertyItem(const std::shared_ptr<AbsMemory> &mem, const size_t offset,
1968 PropertyType type, const void* payloadData, size_t payloadSize)
1969 {
1970 uint8_t* memData = reinterpret_cast<uint8_t*>(mem->data.data);
1971 size_t memSize = mem->data.size;
1972 IMAGE_LOGD("FileImagePropertyItem memSize is %{public}ld, payloadSize is %{public}ld", memSize, payloadSize);
1973 IMAGE_LOGD("FileImagePropertyItem sizeof(type) is %{public}ld, sizeof(payloadSize) %{public}ld",
1974 sizeof(type), sizeof(payloadSize));
1975 bool cond = payloadSize > INT32_MAX;
1976 CHECK_INFO_RETURN_RET_LOG(cond, false, "payloadSize is over INT32_MAX");
1977 int payloadIntSize = static_cast<int>(payloadSize);
1978 size_t typeSize = sizeof(type);
1979 size_t intSize = sizeof(int);
1980 bool res = (memcpy_s(memData + offset, memSize - offset, &type, typeSize) == EOK) &&
1981 (memcpy_s(memData + offset + typeSize, memSize - offset - typeSize, &payloadIntSize, intSize) == EOK) &&
1982 (memcpy_s(memData + offset + typeSize + intSize, memSize - offset - typeSize - intSize,
1983 payloadData, payloadSize) == EOK);
1984 return res;
1985 }
1986
AllocateNewSharedMem(size_t memorySize,std::string tag)1987 std::shared_ptr<AbsMemory> ExtEncoder::AllocateNewSharedMem(size_t memorySize, std::string tag)
1988 {
1989 MemoryData memoryData;
1990 memoryData.size = memorySize;
1991 memoryData.tag = tag.empty() ? DEFAULT_ASHMEM_TAG.c_str() : tag.c_str();
1992 std::unique_ptr<AbsMemory> memory =
1993 MemoryManager::CreateMemory(AllocatorType::SHARE_MEM_ALLOC, memoryData);
1994 std::shared_ptr<AbsMemory> res = std::move(memory);
1995 return res;
1996 }
1997
GetStaticMetadata(HdrMetadata & metadata,MasteringDisplayColourVolume & color,ContentLightLevel & light)1998 bool ExtEncoder::GetStaticMetadata(HdrMetadata& metadata, MasteringDisplayColourVolume& color, ContentLightLevel& light)
1999 {
2000 HdrStaticMetadata staticMetadata;
2001 size_t staticMetadataSize = sizeof(HdrStaticMetadata);
2002 bool cond = metadata.staticMetadata.size() < staticMetadataSize;
2003 CHECK_INFO_RETURN_RET_LOG(cond, false, "GetStaticMetadata failed");
2004 cond = memcpy_s(&staticMetadata, staticMetadataSize,
2005 metadata.staticMetadata.data(), metadata.staticMetadata.size()) != EOK;
2006 CHECK_INFO_RETURN_RET_LOG(cond, false, "GetStaticMetadata failed, memcpy_s failed");
2007 color.displayPrimariesRX =
2008 (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryRed.x);
2009 color.displayPrimariesRY =
2010 (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryRed.y);
2011 color.displayPrimariesGX =
2012 (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryGreen.x);
2013 color.displayPrimariesGY =
2014 (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryGreen.y);
2015 color.displayPrimariesBX =
2016 (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryBlue.x);
2017 color.displayPrimariesBY =
2018 (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.displayPrimaryBlue.y);
2019 color.whitePointX = (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.whitePoint.x);
2020 color.whitePointY = (uint16_t)(STATIC_METADATA_COLOR_SCALE * staticMetadata.smpte2086.whitePoint.y);
2021 color.maxDisplayMasteringLuminance = (uint32_t)staticMetadata.smpte2086.maxLuminance;
2022 color.minDisplayMasteringLuminance = (uint32_t)(STATIC_METADATA_LUM_SCALE * staticMetadata.smpte2086.minLuminance);
2023 light.maxContentLightLevel = (uint16_t)staticMetadata.cta861.maxContentLightLevel;
2024 light.maxPicAverageLightLevel = (uint16_t)staticMetadata.cta861.maxFrameAverageLightLevel;
2025 return true;
2026 }
2027
GetToneMapChannel(ISOMetadata & metadata,ToneMapChannel & channel,uint8_t index)2028 bool ExtEncoder::GetToneMapChannel(ISOMetadata& metadata, ToneMapChannel& channel, uint8_t index)
2029 {
2030 bool cond = index > GAINMAP_CHANNEL_MULTI - 1;
2031 CHECK_ERROR_RETURN_RET_LOG(cond, false, "GetToneMapChannel index:[%{public}d] unsupported", index);
2032 channel.gainMapMin.numerator = DEFAULT_DENOMINATOR * metadata.enhanceClippedThreholdMinGainmap[index];
2033 channel.gainMapMin.denominator = DEFAULT_DENOMINATOR;
2034 channel.gainMapMax.numerator = DEFAULT_DENOMINATOR * metadata.enhanceClippedThreholdMaxGainmap[index];
2035 channel.gainMapMax.denominator = DEFAULT_DENOMINATOR;
2036 if (metadata.enhanceMappingGamma[index] > 0.0f) {
2037 channel.gamma.numerator = DEFAULT_DENOMINATOR * metadata.enhanceMappingGamma[index];
2038 } else {
2039 channel.gamma.numerator = 0;
2040 }
2041 channel.gamma.denominator = DEFAULT_DENOMINATOR;
2042 channel.baseOffset.numerator = DEFAULT_DENOMINATOR * metadata.enhanceMappingBaselineOffset[index];
2043 channel.baseOffset.denominator = DEFAULT_DENOMINATOR;
2044 channel.alternateOffset.numerator = DEFAULT_DENOMINATOR * metadata.enhanceMappingAlternateOffset[index];
2045 channel.alternateOffset.denominator = DEFAULT_DENOMINATOR;
2046 IMAGE_LOGD("GetToneMapChannel [%{public}d],gainmapMin:%{public}f, gainmapMax:%{public}f,"
2047 "gamma:%{public}f,baseOffset:%{public}f, alternateOffset:%{public}f", index,
2048 metadata.enhanceClippedThreholdMinGainmap[index], metadata.enhanceClippedThreholdMaxGainmap[index],
2049 metadata.enhanceMappingGamma[index],
2050 metadata.enhanceMappingBaselineOffset[index], metadata.enhanceMappingAlternateOffset[index]);
2051 return true;
2052 }
2053
GetToneMapMetadata(HdrMetadata & metadata,ToneMapMetadata & toneMapMetadata)2054 bool ExtEncoder::GetToneMapMetadata(HdrMetadata& metadata, ToneMapMetadata& toneMapMetadata)
2055 {
2056 ISOMetadata isoMeta = metadata.extendMeta.metaISO;
2057 toneMapMetadata.useBaseColorSpace = (isoMeta.useBaseColorFlag == 1) ? true : false;
2058 toneMapMetadata.channelCnt = (isoMeta.gainmapChannelNum == 0) ? GAINMAP_CHANNEL_SINGLE : GAINMAP_CHANNEL_MULTI;
2059 toneMapMetadata.baseHdrHeadroom.denominator = DEFAULT_DENOMINATOR;
2060 if (isoMeta.baseHeadroom > 0.0f) {
2061 toneMapMetadata.baseHdrHeadroom.numerator = (uint32_t)(isoMeta.baseHeadroom * DEFAULT_DENOMINATOR);
2062 } else {
2063 toneMapMetadata.baseHdrHeadroom.numerator = 0;
2064 }
2065 toneMapMetadata.alternateHdrHeadroom.denominator = DEFAULT_DENOMINATOR;
2066 if (isoMeta.alternateHeadroom > 0.0f) {
2067 toneMapMetadata.alternateHdrHeadroom.numerator = (uint32_t)(isoMeta.alternateHeadroom * DEFAULT_DENOMINATOR);
2068 } else {
2069 toneMapMetadata.alternateHdrHeadroom.numerator = 0;
2070 }
2071 GetToneMapChannel(isoMeta, toneMapMetadata.channels1, INDEX_ZERO);
2072 if (toneMapMetadata.channelCnt == GAINMAP_CHANNEL_MULTI) {
2073 GetToneMapChannel(isoMeta, toneMapMetadata.channels2, INDEX_ONE);
2074 GetToneMapChannel(isoMeta, toneMapMetadata.channels3, INDEX_TWO);
2075 }
2076 IMAGE_LOGD("GetToneMapMetadata useBaseColorSpace:%{public}d, gainmapChannelNum:%{public}d,"
2077 "baseHeadroom:%{public}f,alternateHeadroom:%{public}f", isoMeta.useBaseColorFlag, isoMeta.gainmapChannelNum,
2078 isoMeta.baseHeadroom, isoMeta.alternateHeadroom);
2079 return true;
2080 }
2081
GetColourInfo(ColorManager::ColorSpaceName color,ColourInfo & info)2082 void ExtEncoder::GetColourInfo(ColorManager::ColorSpaceName color, ColourInfo& info)
2083 {
2084 uint8_t fullRangeFlag;
2085 ColorUtils::ColorSpaceGetCicp(color, info.colourPrimaries, info.transferCharacteristics, info.matrixCoefficients,
2086 fullRangeFlag);
2087 // 1 : full range ; 0 : limit range.
2088 info.fullRangeFlag = (fullRangeFlag == 1);
2089 }
2090
AssembleIT35SharedBuffer(HdrMetadata metadata,SharedBuffer & outBuffer)2091 bool ExtEncoder::AssembleIT35SharedBuffer(HdrMetadata metadata, SharedBuffer& outBuffer)
2092 {
2093 std::vector<uint8_t> it35Info;
2094 bool cond = !HdrHeifPackerHelper::PackIT35Info(metadata, it35Info);
2095 CHECK_ERROR_RETURN_RET_LOG(cond, false, "get it35 info failed");
2096 std::shared_ptr<AbsMemory> propertyAshmem =
2097 AllocateNewSharedMem(GetBufferSize(it35Info.size()), IT35_ASHMEM_TAG);
2098 cond = propertyAshmem == nullptr;
2099 CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleIT35SharedBuffer it35 alloc failed");
2100 tmpMemoryList_.push_back(propertyAshmem);
2101 cond = !FillImagePropertyItem(propertyAshmem, 0, PropertyType::IT35_INFO, it35Info.data(), it35Info.size());
2102 CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleIT35SharedBuffer fill failed");
2103 outBuffer.fd = *static_cast<int *>(propertyAshmem->extend.data);
2104 outBuffer.capacity = propertyAshmem->data.size;
2105 outBuffer.filledLen = propertyAshmem->data.size;
2106 return true;
2107 }
2108
AssembleICCImageProperty(sk_sp<SkData> & iccProfile,SharedBuffer & outBuffer)2109 bool ExtEncoder::AssembleICCImageProperty(sk_sp<SkData>& iccProfile, SharedBuffer& outBuffer)
2110 {
2111 bool cond = iccProfile == nullptr || iccProfile->size() == 0;
2112 CHECK_INFO_RETURN_RET_LOG(cond, false, "AssembleICCImageProperty iccprofile is nullptr");
2113 std::shared_ptr<AbsMemory> propertyAshmem =
2114 AllocateNewSharedMem(GetBufferSize(iccProfile->size()), ICC_ASHMEM_TAG);
2115 cond = propertyAshmem == nullptr;
2116 CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleICCImageProperty alloc failed");
2117 tmpMemoryList_.push_back(propertyAshmem);
2118 bool fillRes = FillImagePropertyItem(propertyAshmem, 0, PropertyType::ICC_PROFILE,
2119 iccProfile->data(), iccProfile->size());
2120 if (fillRes) {
2121 outBuffer.fd = *static_cast<int *>(propertyAshmem->extend.data);
2122 outBuffer.capacity = propertyAshmem->data.size;
2123 outBuffer.filledLen = propertyAshmem->data.size;
2124 }
2125 return fillRes;
2126 }
2127
FillNclxColorProperty(std::shared_ptr<ImageItem> & item,size_t & offset,ColourInfo & colorInfo)2128 bool ExtEncoder::FillNclxColorProperty(std::shared_ptr<ImageItem>& item, size_t& offset, ColourInfo& colorInfo)
2129 {
2130 ColorType colorType = ColorType::NCLX;
2131 bool cond = !FillLitePropertyItem(item->liteProperties, offset,
2132 PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
2133 CHECK_ERROR_RETURN_RET_LOG(cond, false, "Fill colorType failed");
2134 cond = !FillLitePropertyItem(item->liteProperties, offset,
2135 PropertyType::COLOR_INFO, &colorInfo, sizeof(ColourInfo));
2136 CHECK_INFO_RETURN_RET_LOG(cond, false, "Fill colorInfo failed");
2137 return true;
2138 }
2139
AssembleOutputSharedBuffer(SharedBuffer & outBuffer,std::shared_ptr<AbsMemory> & outMem)2140 bool ExtEncoder::AssembleOutputSharedBuffer(SharedBuffer& outBuffer, std::shared_ptr<AbsMemory>& outMem)
2141 {
2142 bool cond = output_ == nullptr;
2143 CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleOutputSharedBuffer output_ is nullptr");
2144 OutputStreamType outType = output_->GetType();
2145 size_t outputCapacity = DEFAULT_OUTPUT_SIZE;
2146 if (outType != OutputStreamType::FILE_PACKER) {
2147 output_->GetCapicity(outputCapacity);
2148 }
2149 std::shared_ptr<AbsMemory> mem = AllocateNewSharedMem(outputCapacity, OUTPUT_ASHMEM_TAG);
2150 cond = mem == nullptr;
2151 CHECK_ERROR_RETURN_RET_LOG(cond, false, "AssembleOutputSharedBuffer alloc out sharemem failed");
2152 outMem = mem;
2153 tmpMemoryList_.push_back(mem);
2154 if (mem->extend.data != nullptr) {
2155 outBuffer.fd = *static_cast<int *>(mem->extend.data);
2156 }
2157 outBuffer.capacity = outputCapacity;
2158 return true;
2159 }
2160
AssembleDualHdrRefItem(std::vector<ItemRef> & refs)2161 void ExtEncoder::AssembleDualHdrRefItem(std::vector<ItemRef>& refs)
2162 {
2163 auto item = std::make_shared<ItemRef>();
2164 item->type = ReferenceType::DIMG;
2165 item->from = TMAP_IMAGE_ITEM_ID;
2166 item->to.resize(INDEX_TWO);
2167 item->to[INDEX_ZERO] = PRIMARY_IMAGE_ITEM_ID;
2168 item->to[INDEX_ONE] = GAINMAP_IMAGE_ITEM_ID;
2169 refs.push_back(*item);
2170 }
2171
DoHeifEncode(std::vector<ImageItem> & inputImgs,std::vector<MetaItem> & inputMetas,std::vector<ItemRef> & refs)2172 uint32_t ExtEncoder::DoHeifEncode(std::vector<ImageItem>& inputImgs, std::vector<MetaItem>& inputMetas,
2173 std::vector<ItemRef>& refs)
2174 {
2175 SharedBuffer outputBuffer {};
2176 std::shared_ptr<AbsMemory> outputAshmem;
2177 bool tempRes = AssembleOutputSharedBuffer(outputBuffer, outputAshmem);
2178 bool cond = !tempRes;
2179 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER,
2180 "ExtEncoder::DoHeifEncode alloc sharedbuffer failed");
2181
2182 sptr<ICodecImage> codec = GetCodecManager();
2183 CHECK_ERROR_RETURN_RET(codec == nullptr, ERR_IMAGE_ENCODE_FAILED);
2184 uint32_t outSize = DEFAULT_OUTPUT_SIZE;
2185 int32_t encodeRes = codec->DoHeifEncode(inputImgs, inputMetas, refs, outputBuffer, outSize);
2186 cond = encodeRes != HDF_SUCCESS;
2187 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "ExtEncoder::DoHeifEncode DoHeifEncode failed");
2188 IMAGE_LOGI("ExtEncoder::DoHeifEncode output type is %{public}d", output_->GetType());
2189 bool writeRes = output_->Write(reinterpret_cast<uint8_t *>(outputAshmem->data.data), outSize);
2190 cond = !writeRes;
2191 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_ENCODE_FAILED, "ExtEncoder::DoHeifEncode Write failed");
2192 return SUCCESS;
2193 }
2194
AssembleTmapImageItem(ColorManager::ColorSpaceName color,HdrMetadata metadata,const PlEncodeOptions & opts)2195 std::shared_ptr<ImageItem> ExtEncoder::AssembleTmapImageItem(ColorManager::ColorSpaceName color,
2196 HdrMetadata metadata, const PlEncodeOptions &opts)
2197 {
2198 auto item = std::make_shared<ImageItem>();
2199 item->id = TMAP_IMAGE_ITEM_ID;
2200 item->itemName = "Tone-mapped representation";
2201 item->isPrimary = false;
2202 item->isHidden = false;
2203 item->compressType = COMPRESS_TYPE_TMAP;
2204 item->quality = opts.quality;
2205 item->sharedProperties.fd = -1;
2206 item->pixelSharedBuffer.fd = -1;
2207 ColourInfo colorInfo;
2208 GetColourInfo(color, colorInfo);
2209 ContentLightLevel light;
2210 MasteringDisplayColourVolume colour;
2211 bool hasLight = GetStaticMetadata(metadata, colour, light);
2212 uint32_t propertiesSize = 0;
2213 propertiesSize +=
2214 (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType) + sizeof(PropertyType::COLOR_INFO) + sizeof(ColourInfo));
2215 if (hasLight) {
2216 propertiesSize += (sizeof(PropertyType::CONTENT_LIGHT_LEVEL) + sizeof(ContentLightLevel));
2217 }
2218 ToneMapMetadata toneMap;
2219 bool hasToneMap = GetToneMapMetadata(metadata, toneMap);
2220 if (hasToneMap) {
2221 propertiesSize += (sizeof(PropertyType::TONE_MAP_METADATA) + sizeof(ToneMapMetadata));
2222 }
2223 item->liteProperties.resize(propertiesSize);
2224 size_t offset = 0;
2225 if (!FillNclxColorProperty(item, offset, colorInfo)) {
2226 return nullptr;
2227 }
2228 bool cond = hasLight && (!FillLitePropertyItem(item->liteProperties, offset,
2229 PropertyType::CONTENT_LIGHT_LEVEL, &colour, sizeof(ContentLightLevel)));
2230 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssembleTmapImageItem fill CONTENT_LIGHT_LEVEL failed");
2231 cond = hasToneMap && (!FillLitePropertyItem(item->liteProperties, offset,
2232 PropertyType::TONE_MAP_METADATA, &toneMap, sizeof(ToneMapMetadata)));
2233 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssembleTmapImageItem fill toneMap failed");
2234 cond = !AssembleIT35SharedBuffer(metadata, item->sharedProperties);
2235 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssembleTmapImageItem fill it35 failed");
2236 return item;
2237 }
2238
2239 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
AssemblePrimaryImageItem(sptr<SurfaceBuffer> & surfaceBuffer,const PlEncodeOptions & opts)2240 std::shared_ptr<ImageItem> ExtEncoder::AssemblePrimaryImageItem(sptr<SurfaceBuffer>& surfaceBuffer,
2241 const PlEncodeOptions &opts)
2242 {
2243 bool cond = pixelmap_ == nullptr || surfaceBuffer == nullptr;
2244 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssemblePrimaryImageItem surfaceBuffer is nullptr");
2245 auto item = std::make_shared<ImageItem>();
2246 item->id = PRIMARY_IMAGE_ITEM_ID;
2247 item->pixelBuffer = sptr<NativeBuffer>::MakeSptr(surfaceBuffer->GetBufferHandle());
2248 item->isPrimary = true;
2249 item->isHidden = false;
2250 item->compressType = COMPRESS_TYPE_HEVC;
2251 item->quality = opts.quality;
2252 item->sharedProperties.fd = -1;
2253 item->pixelSharedBuffer.fd = -1;
2254 sk_sp<SkData> iccProfile = icc_from_color_space(ToSkInfo(pixelmap_));
2255 bool tempRes = AssembleICCImageProperty(iccProfile, item->sharedProperties);
2256 CHECK_ERROR_RETURN_RET(!tempRes, nullptr);
2257 uint32_t litePropertiesSize = 0;
2258 litePropertiesSize += (sizeof(PropertyType::COLOR_TYPE) + sizeof(ColorType));
2259 item->liteProperties.resize(litePropertiesSize);
2260 size_t offset = 0;
2261 ColorType colorType = ColorType::RICC;
2262 cond = !FillLitePropertyItem(item->liteProperties, offset,
2263 PropertyType::COLOR_TYPE, &colorType, sizeof(ColorType));
2264 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "AssemblePrimaryImageItem Fill color type failed");
2265 return item;
2266 }
2267 #endif
2268
AssembleExifRefItem(std::vector<ItemRef> & refs)2269 void ExtEncoder::AssembleExifRefItem(std::vector<ItemRef>& refs)
2270 {
2271 auto item = std::make_shared<ItemRef>();
2272 item->type = ReferenceType::CDSC;
2273 item->from = EXIF_META_ITEM_ID;
2274 item->to.resize(INDEX_ONE);
2275 item->to[INDEX_ZERO] = PRIMARY_IMAGE_ITEM_ID;
2276 refs.push_back(*item);
2277 }
2278
FreeExifBlob(uint8_t ** exifBlob)2279 void inline FreeExifBlob(uint8_t** exifBlob)
2280 {
2281 if (exifBlob != nullptr && *exifBlob != nullptr) {
2282 free(*exifBlob);
2283 *exifBlob = nullptr;
2284 }
2285 }
2286
AssembleExifMetaItem(std::vector<MetaItem> & metaItems)2287 bool ExtEncoder::AssembleExifMetaItem(std::vector<MetaItem>& metaItems)
2288 {
2289 if (!opts_.needsPackProperties) {
2290 IMAGE_LOGD("no need encode exif");
2291 return false;
2292 }
2293 ExifData* exifData = nullptr;
2294 if (picture_ != nullptr && picture_->GetExifMetadata() != nullptr &&
2295 picture_->GetExifMetadata()->GetExifData() != nullptr) {
2296 exifData = picture_->GetExifMetadata()->GetExifData();
2297 } else if (pixelmap_ != nullptr && pixelmap_->GetExifMetadata() != nullptr &&
2298 pixelmap_->GetExifMetadata()->GetExifData() != nullptr) {
2299 exifData = pixelmap_->GetExifMetadata()->GetExifData();
2300 } else {
2301 IMAGE_LOGD("no exif");
2302 return false;
2303 }
2304 uint8_t* exifBlob = nullptr;
2305 uint32_t exifSize = 0;
2306 TiffParser::Encode(&exifBlob, exifSize, exifData);
2307 if (exifBlob == nullptr) {
2308 IMAGE_LOGE("Encode exif data failed");
2309 return false;
2310 }
2311 auto item = std::make_shared<MetaItem>();
2312 item->id = EXIF_META_ITEM_ID;
2313 item->itemName = "exif";
2314 item->data.fd = -1;
2315 std::shared_ptr<AbsMemory> propertyAshmem = AllocateNewSharedMem(exifSize + EXIF_PRE_SIZE, EXIF_ASHMEM_TAG);
2316 if (propertyAshmem == nullptr) {
2317 FreeExifBlob(&exifBlob);
2318 IMAGE_LOGE("AssembleExifMetaItem alloc propertyAshmem failed");
2319 return false;
2320 }
2321 tmpMemoryList_.push_back(propertyAshmem);
2322 uint8_t* memData = reinterpret_cast<uint8_t*>(propertyAshmem->data.data);
2323 size_t memSize = propertyAshmem->data.size;
2324 bool fillRes = (memcpy_s(memData, memSize, EXIF_PRE_TAG, EXIF_PRE_SIZE) == EOK) &&
2325 (memcpy_s(memData + EXIF_PRE_SIZE, memSize - EXIF_PRE_SIZE, exifBlob, exifSize) == EOK);
2326 if (fillRes) {
2327 item->data.fd = *static_cast<int *>(propertyAshmem->extend.data);
2328 item->data.capacity = propertyAshmem->data.size;
2329 item->data.filledLen = propertyAshmem->data.size;
2330 metaItems.push_back(*item);
2331 }
2332 FreeExifBlob(&exifBlob);
2333 return fillRes;
2334 }
2335
FillPixelSharedBuffer(sptr<SurfaceBuffer> sbBuffer,uint32_t capacity,SharedBuffer & outBuffer)2336 bool ExtEncoder::FillPixelSharedBuffer(sptr<SurfaceBuffer> sbBuffer, uint32_t capacity, SharedBuffer& outBuffer)
2337 {
2338 bool cond = sbBuffer == nullptr || capacity == 0;
2339 CHECK_INFO_RETURN_RET_LOG(cond, false, "%{public}s iccprofile is nullptr", __func__);
2340 std::shared_ptr<AbsMemory> sharedMem = AllocateNewSharedMem(capacity, IMAGE_DATA_TAG);
2341 cond = sharedMem == nullptr;
2342 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s alloc failed", __func__);
2343 tmpMemoryList_.push_back(sharedMem);
2344 uint8_t* memData = reinterpret_cast<uint8_t*>(sharedMem->data.data);
2345 size_t memSize = sharedMem->data.size;
2346 cond = capacity > memSize;
2347 CHECK_ERROR_RETURN_RET_LOG(cond, false,
2348 "%{public}s shared capacity[%{public}d] over memSize[%{public}ld]", __func__, capacity, memSize);
2349 cond = sharedMem->extend.data == nullptr;
2350 CHECK_ERROR_RETURN_RET_LOG(cond, false, "%{public}s sharedMem's extend data is nullptr", __func__);
2351 if (memcpy_s(memData, memSize, sbBuffer->GetVirAddr(), capacity) == EOK) {
2352 outBuffer.fd = *static_cast<int *>(sharedMem->extend.data);
2353 outBuffer.capacity = memSize;
2354 outBuffer.filledLen = memSize;
2355 } else {
2356 IMAGE_LOGE("%{public}s memcpy failed", __func__);
2357 return false;
2358 }
2359 return true;
2360 }
2361
AssembleAuxiliaryRefItem(AuxiliaryPictureType type,std::vector<ItemRef> & refs)2362 void ExtEncoder::AssembleAuxiliaryRefItem(AuxiliaryPictureType type, std::vector<ItemRef>& refs)
2363 {
2364 auto item = std::make_shared<ItemRef>();
2365 item->type = ReferenceType::AUXL;
2366 item->to.resize(INDEX_ONE);
2367 item->to[INDEX_ZERO] = PRIMARY_IMAGE_ITEM_ID;
2368 switch (type) {
2369 case AuxiliaryPictureType::DEPTH_MAP:
2370 item->from = DEPTH_MAP_ITEM_ID;
2371 break;
2372 case AuxiliaryPictureType::UNREFOCUS_MAP:
2373 item->from = UNREFOCUS_MAP_ITEM_ID;
2374 break;
2375 case AuxiliaryPictureType::LINEAR_MAP:
2376 item->from = LINEAR_MAP_ITEM_ID;
2377 break;
2378 case AuxiliaryPictureType::FRAGMENT_MAP:
2379 item->from = FRAGMENT_MAP_ITEM_ID;
2380 break;
2381 default:
2382 break;
2383 }
2384 refs.push_back(*item);
2385 }
2386 #endif
2387 } // namespace ImagePlugin
2388 } // namespace OHOS
2389