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