1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "colorspace_helper.h"
17
18 #include <unordered_map>
19
20 #include "metadata_helper.h"
21 #include "colorspace_processor.h"
22 #include "metadata_processor.h"
23 #include "effect_log.h"
24
25 #include <hdr_type.h>
26 #include <v1_0/cm_color_space.h>
27 #include <v1_0/buffer_handle_meta_key_type.h>
28
29 namespace OHOS {
30 namespace Media {
31 namespace Effect {
32 using namespace OHOS::ColorManager;
33 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
34
35 static const std::unordered_map<EffectColorSpace, ColorSpaceName> EFFECT_TO_COLORMANAGER_COLORSPACE_MAP = {
36 { EffectColorSpace::SRGB, ColorSpaceName::SRGB },
37 { EffectColorSpace::SRGB_LIMIT, ColorSpaceName::SRGB_LIMIT },
38 { EffectColorSpace::DISPLAY_P3, ColorSpaceName::DISPLAY_P3 },
39 { EffectColorSpace::DISPLAY_P3_LIMIT, ColorSpaceName::DISPLAY_P3_LIMIT },
40 { EffectColorSpace::BT2020_HLG, ColorSpaceName::BT2020_HLG },
41 { EffectColorSpace::BT2020_HLG_LIMIT, ColorSpaceName::BT2020_HLG_LIMIT },
42 { EffectColorSpace::BT2020_PQ, ColorSpaceName::BT2020_PQ },
43 { EffectColorSpace::BT2020_PQ_LIMIT, ColorSpaceName::BT2020_PQ_LIMIT },
44 { EffectColorSpace::ADOBE_RGB, ColorSpaceName::ADOBE_RGB },
45 { EffectColorSpace::NOT_SUPPORTED, ColorSpaceName::DISPLAY_BT2020_SRGB },
46 };
47
48 static const std::unordered_map<EffectColorSpace, CM_ColorSpaceType> EFFECT_TO_GRAPHIC_COLORSPACE_MAP = {
49 { EffectColorSpace::SRGB, CM_ColorSpaceType::CM_SRGB_FULL },
50 { EffectColorSpace::SRGB_LIMIT, CM_ColorSpaceType::CM_SRGB_LIMIT },
51 { EffectColorSpace::DISPLAY_P3, CM_ColorSpaceType::CM_P3_FULL },
52 { EffectColorSpace::DISPLAY_P3_LIMIT, CM_ColorSpaceType::CM_P3_LIMIT },
53 { EffectColorSpace::BT2020_HLG, CM_ColorSpaceType::CM_BT2020_HLG_FULL },
54 { EffectColorSpace::BT2020_HLG_LIMIT, CM_ColorSpaceType::CM_BT2020_HLG_LIMIT },
55 { EffectColorSpace::BT2020_PQ, CM_ColorSpaceType::CM_BT2020_PQ_FULL },
56 { EffectColorSpace::BT2020_PQ_LIMIT, CM_ColorSpaceType::CM_BT2020_PQ_LIMIT },
57 { EffectColorSpace::ADOBE_RGB, CM_ColorSpaceType::CM_ADOBERGB_FULL },
58 { EffectColorSpace::NOT_SUPPORTED, CM_ColorSpaceType::CM_DISPLAY_BT2020_SRGB },
59 };
60
61 static const std::unordered_map<EffectColorSpace, OH_NativeBuffer_ColorSpace> EFFECT_TO_NATIVE_BUFFER_COLORSPACE_MAP = {
62 { EffectColorSpace::SRGB, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_SRGB_FULL },
63 { EffectColorSpace::SRGB_LIMIT, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_SRGB_LIMIT },
64 { EffectColorSpace::DISPLAY_P3, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_P3_FULL },
65 { EffectColorSpace::DISPLAY_P3_LIMIT, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_P3_LIMIT },
66 { EffectColorSpace::BT2020_HLG, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_BT2020_HLG_FULL },
67 { EffectColorSpace::BT2020_HLG_LIMIT, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_BT2020_HLG_LIMIT },
68 { EffectColorSpace::BT2020_PQ, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_BT2020_PQ_FULL },
69 { EffectColorSpace::BT2020_PQ_LIMIT, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_BT2020_PQ_LIMIT },
70 { EffectColorSpace::ADOBE_RGB, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_ADOBERGB_FULL },
71 { EffectColorSpace::NOT_SUPPORTED, OH_NativeBuffer_ColorSpace::OH_COLORSPACE_DISPLAY_BT2020_SRGB },
72 };
73
74 static const std::unordered_set<EffectColorSpace> TEX_SUPPORT_COLORSPACE_SET = {
75 EffectColorSpace::SRGB,
76 EffectColorSpace::SRGB_LIMIT,
77 EffectColorSpace::DISPLAY_P3,
78 EffectColorSpace::DISPLAY_P3_LIMIT,
79 EffectColorSpace::BT2020_HLG,
80 EffectColorSpace::BT2020_HLG_LIMIT,
81 EffectColorSpace::BT2020_PQ,
82 EffectColorSpace::BT2020_PQ_LIMIT
83 };
84
85 static const std::unordered_set<HdrFormat> SUPPORT_HDR_FORMAT_SET = {
86 HdrFormat::HDR10, HdrFormat::HDR8_GAINMAP
87 };
88
IsHdrColorSpace(EffectColorSpace colorSpace)89 bool ColorSpaceHelper::IsHdrColorSpace(EffectColorSpace colorSpace)
90 {
91 return colorSpace == EffectColorSpace::BT2020_HLG || colorSpace == EffectColorSpace::BT2020_HLG_LIMIT ||
92 colorSpace == EffectColorSpace::BT2020_PQ || colorSpace == EffectColorSpace::BT2020_PQ_LIMIT;
93 }
94
IsTexSupportedColorSpace(EffectColorSpace colorSpace)95 bool IsTexSupportedColorSpace(EffectColorSpace colorSpace)
96 {
97 auto it = TEX_SUPPORT_COLORSPACE_SET.find(colorSpace);
98 if (it != TEX_SUPPORT_COLORSPACE_SET.end()) {
99 return true;
100 }
101 return false;
102 }
103
ConvertToEffectColorSpace(ColorSpaceName colorSpaceName)104 EffectColorSpace ColorSpaceHelper::ConvertToEffectColorSpace(ColorSpaceName colorSpaceName)
105 {
106 EffectColorSpace colorSpaceType = EffectColorSpace::DEFAULT;
107
108 for (const auto &it : EFFECT_TO_COLORMANAGER_COLORSPACE_MAP) {
109 if (it.second == colorSpaceName) {
110 colorSpaceType = it.first;
111 break;
112 }
113 }
114
115 EFFECT_LOGD("ConvertToEffectColorSpace: colorSpaceName=%{public}d, effectColorSpaceType=%{public}d",
116 colorSpaceName, colorSpaceType);
117 return colorSpaceType;
118 }
119
ConvertToNativeBufferColorSpace(EffectColorSpace effectColorSpace)120 OH_NativeBuffer_ColorSpace ColorSpaceHelper::ConvertToNativeBufferColorSpace(EffectColorSpace effectColorSpace)
121 {
122 OH_NativeBuffer_ColorSpace nativeBufferColorSpace = OH_NativeBuffer_ColorSpace::OH_COLORSPACE_NONE;
123 auto it = EFFECT_TO_NATIVE_BUFFER_COLORSPACE_MAP.find(effectColorSpace);
124 if (it != EFFECT_TO_NATIVE_BUFFER_COLORSPACE_MAP.end()) {
125 nativeBufferColorSpace = it->second;
126 }
127
128 EFFECT_LOGD("ConvertToEffectColorSpace: colorSpaceType=%{public}d, effectColorSpaceType=%{public}d",
129 effectColorSpace, nativeBufferColorSpace);
130 return nativeBufferColorSpace;
131 }
132
ConvertToColorSpaceName(EffectColorSpace colorSpace)133 ColorSpaceName ColorSpaceHelper::ConvertToColorSpaceName(EffectColorSpace colorSpace)
134 {
135 ColorSpaceName colorSpaceName = ColorSpaceName::NONE;
136 auto it = EFFECT_TO_COLORMANAGER_COLORSPACE_MAP.find(colorSpace);
137 if (it != EFFECT_TO_COLORMANAGER_COLORSPACE_MAP.end()) {
138 colorSpaceName = it->second;
139 }
140
141 return colorSpaceName;
142 }
143
ConvertToEffectColorSpace(CM_ColorSpaceType type)144 EffectColorSpace ColorSpaceHelper::ConvertToEffectColorSpace(CM_ColorSpaceType type)
145 {
146 EffectColorSpace effectColorSpaceType = EffectColorSpace::DEFAULT;
147
148 for (const auto &it : EFFECT_TO_GRAPHIC_COLORSPACE_MAP) {
149 if (it.second == type) {
150 effectColorSpaceType = it.first;
151 break;
152 }
153 }
154
155 EFFECT_LOGD("ConvertToEffectColorSpace: colorSpaceType=%{public}d, effectColorSpaceType=%{public}d",
156 type, effectColorSpaceType);
157 return effectColorSpaceType;
158 }
159
ConvertToCMColorSpace(EffectColorSpace colorSpace)160 CM_ColorSpaceType ColorSpaceHelper::ConvertToCMColorSpace(EffectColorSpace colorSpace)
161 {
162 CM_ColorSpaceType cmColorSpaceType = CM_ColorSpaceType::CM_COLORSPACE_NONE;
163 auto it = EFFECT_TO_GRAPHIC_COLORSPACE_MAP.find(colorSpace);
164 if (it != EFFECT_TO_GRAPHIC_COLORSPACE_MAP.end()) {
165 cmColorSpaceType = it->second;
166 }
167
168 return cmColorSpaceType;
169 }
170
SetSurfaceBufferMetadataType(SurfaceBuffer * sb,const CM_HDR_Metadata_Type & type)171 ErrorCode ColorSpaceHelper::SetSurfaceBufferMetadataType(SurfaceBuffer *sb, const CM_HDR_Metadata_Type &type)
172 {
173 sptr<SurfaceBuffer> buffer = sb;
174 auto res = MetadataHelper::SetHDRMetadataType(buffer, type);
175 CHECK_AND_RETURN_RET_LOG(res == GSError::GSERROR_OK, ErrorCode::ERR_SET_METADATA_FAIL,
176 "SetSurfaceBufferMetadataType: SetHDRMetadataType fail! res=%{public}d", res);
177 return ErrorCode::SUCCESS;
178 }
179
GetSurfaceBufferMetadataType(SurfaceBuffer * sb,CM_HDR_Metadata_Type & type)180 ErrorCode ColorSpaceHelper::GetSurfaceBufferMetadataType(SurfaceBuffer *sb, CM_HDR_Metadata_Type &type)
181 {
182 sptr<SurfaceBuffer> buffer = sb;
183 auto res = MetadataHelper::GetHDRMetadataType(buffer, type);
184 CHECK_AND_RETURN_RET_LOG(res == GSError::GSERROR_OK, ErrorCode::ERR_GET_METADATA_FAIL,
185 "GetSurfaceBufferMetadataType: GetHDRMetadataType fail! res=%{public}d", res);
186 return ErrorCode::SUCCESS;
187 }
188
SetSurfaceBufferColorSpaceType(SurfaceBuffer * sb,const CM_ColorSpaceType & type)189 ErrorCode ColorSpaceHelper::SetSurfaceBufferColorSpaceType(SurfaceBuffer *sb, const CM_ColorSpaceType &type)
190 {
191 sptr<SurfaceBuffer> buffer = sb;
192 auto res = MetadataHelper::SetColorSpaceType(buffer, type);
193 CHECK_AND_RETURN_RET_LOG(res == GSError::GSERROR_OK, ErrorCode::ERR_SET_COLORSPACETYPE_FAIL,
194 "SetSurfaceBufferColorSpaceType: SetColorSpaceType fail! res=%{public}d", res);
195 return ErrorCode::SUCCESS;
196 }
197
GetSurfaceBufferColorSpaceType(SurfaceBuffer * sb,CM_ColorSpaceType & type)198 ErrorCode ColorSpaceHelper::GetSurfaceBufferColorSpaceType(SurfaceBuffer *sb, CM_ColorSpaceType &type)
199 {
200 sptr<SurfaceBuffer> buffer = sb;
201 auto res = MetadataHelper::GetColorSpaceType(buffer, type);
202 CHECK_AND_RETURN_RET_LOG(res == GSError::GSERROR_OK, ErrorCode::ERR_GET_COLORSPACETYPE_FAIL,
203 "GetSurfaceBufferColorSpaceType: GetColorSpaceType fail! res=%{public}d", res);
204 return ErrorCode::SUCCESS;
205 }
206
SetHDRDynamicMetadata(SurfaceBuffer * sb,const std::vector<uint8_t> & hdrDynamicMetadata)207 ErrorCode ColorSpaceHelper::SetHDRDynamicMetadata(SurfaceBuffer *sb, const std::vector<uint8_t> &hdrDynamicMetadata)
208 {
209 sptr<SurfaceBuffer> buffer = sb;
210 auto res = MetadataHelper::SetHDRDynamicMetadata(buffer, hdrDynamicMetadata);
211 CHECK_AND_RETURN_RET_LOG(res == GSError::GSERROR_OK, ErrorCode::ERR_SET_METADATA_FAIL,
212 "SetHDRDynamicMetadata: SetHDRDynamicMetadata fail! res=%{public}d", res);
213 return ErrorCode::SUCCESS;
214 }
215
GetHDRDynamicMetadata(SurfaceBuffer * sb,std::vector<uint8_t> & hdrDynamicMetadata)216 ErrorCode ColorSpaceHelper::GetHDRDynamicMetadata(SurfaceBuffer *sb, std::vector<uint8_t> &hdrDynamicMetadata)
217 {
218 sptr<SurfaceBuffer> buffer = sb;
219 auto res = MetadataHelper::GetHDRDynamicMetadata(buffer, hdrDynamicMetadata);
220 CHECK_AND_RETURN_RET_LOG(res == GSError::GSERROR_OK, ErrorCode::ERR_SET_METADATA_FAIL,
221 "GetHDRDynamicMetadata: GetHDRDynamicMetadata fail! res=%{public}d", res);
222 return ErrorCode::SUCCESS;
223 }
224
SetHDRStaticMetadata(SurfaceBuffer * sb,const std::vector<uint8_t> & hdrStaticMetadata)225 ErrorCode ColorSpaceHelper::SetHDRStaticMetadata(SurfaceBuffer *sb, const std::vector<uint8_t> &hdrStaticMetadata)
226 {
227 sptr<SurfaceBuffer> buffer = sb;
228 auto res = MetadataHelper::SetHDRStaticMetadata(buffer, hdrStaticMetadata);
229 CHECK_AND_RETURN_RET_LOG(res == GSError::GSERROR_OK, ErrorCode::ERR_SET_METADATA_FAIL,
230 "SetHDRStaticMetadata: SetHDRStaticMetadata fail! res=%{public}d", res);
231 return ErrorCode::SUCCESS;
232 }
233
UpdateMetadata(EffectBuffer * input,const std::shared_ptr<EffectContext> & context)234 ErrorCode ColorSpaceHelper::UpdateMetadata(EffectBuffer *input, const std::shared_ptr<EffectContext> &context)
235 {
236 CHECK_AND_RETURN_RET_LOG(input != nullptr && input->bufferInfo_ != nullptr && input->extraInfo_ != nullptr,
237 ErrorCode::ERR_INPUT_NULL, "UpdateMetadata: inputBuffer is null");
238
239 HdrFormat format = input->bufferInfo_->hdrFormat_;
240 if (format != HdrFormat::HDR8_GAINMAP && format != HdrFormat::HDR10) {
241 return ErrorCode::SUCCESS;
242 }
243
244 return UpdateMetadata(input->bufferInfo_->surfaceBuffer_, input->bufferInfo_->colorSpace_, context);
245 }
246
UpdateMetadata(SurfaceBuffer * input,const EffectColorSpace & colorSpace,const std::shared_ptr<EffectContext> & context)247 ErrorCode ColorSpaceHelper::UpdateMetadata(SurfaceBuffer *input, const EffectColorSpace &colorSpace,
248 const std::shared_ptr<EffectContext> &context)
249 {
250 EFFECT_LOGD("UpdateMetadata: colorSpace=%{public}d}", colorSpace);
251 CHECK_AND_RETURN_RET(context->metaInfoNegotiate_->IsNeedUpdate(), ErrorCode::SUCCESS);
252 if (input == nullptr || !ColorSpaceHelper::IsHdrColorSpace(colorSpace)) {
253 return ErrorCode::SUCCESS;
254 }
255
256 return context->colorSpaceManager_->GetMetaDataProcessor()->ProcessImage(input);
257 }
258
ApplyColorSpaceIfNeed(std::shared_ptr<EffectBuffer> & srcBuffer,const std::shared_ptr<EffectContext> & context,EffectColorSpace & colorSpace)259 ErrorCode ApplyColorSpaceIfNeed(std::shared_ptr<EffectBuffer> &srcBuffer, const std::shared_ptr<EffectContext> &context,
260 EffectColorSpace &colorSpace)
261 {
262 if (!ColorSpaceManager::IsNeedConvertColorSpace(colorSpace)) {
263 return ErrorCode::SUCCESS;
264 }
265
266 EFFECT_LOGD("ColorSpaceHelper::ApplyColorSpace");
267 void *buffer = srcBuffer->buffer_;
268 std::shared_ptr<Memory> memory = context->memoryManager_->GetMemoryByAddr(buffer);
269 EffectColorSpace outputColorSpace = EffectColorSpace::DEFAULT;
270 ErrorCode res = context->colorSpaceManager_->ApplyColorSpace(srcBuffer.get(), colorSpace, outputColorSpace);
271 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res,
272 "ApplyColorSpaceIfNeed: ConvertColorSpace fail! res=%{public}d, colorSpace=%{public}d", res, colorSpace);
273
274 // update memoryManager memory
275 if (buffer != srcBuffer->buffer_) {
276 EFFECT_LOGD("ApplyColorSpaceIfNeed: update memory.");
277 context->memoryManager_->RemoveMemory(memory);
278
279 std::shared_ptr<Memory> updateMemory = std::make_shared<Memory>();
280 updateMemory->memoryData_ = std::make_shared<MemoryData>();
281 updateMemory->memoryData_->data = srcBuffer->buffer_;
282 updateMemory->memoryData_->memoryInfo.bufferInfo = *srcBuffer->bufferInfo_;
283 updateMemory->memoryData_->memoryInfo.extra = srcBuffer->bufferInfo_->surfaceBuffer_;
284 updateMemory->memoryData_->memoryInfo.bufferType = srcBuffer->extraInfo_->bufferType;
285 updateMemory->memDataType_ = MemDataType::INPUT;
286 updateMemory->isAllowModify_ = true;
287 context->memoryManager_->AddMemory(updateMemory);
288 }
289
290 colorSpace = outputColorSpace;
291 return ErrorCode::SUCCESS;
292 }
293
isNeedDecomposeHdrImage(const EffectColorSpace & colorSpace,const EffectColorSpace & chosenColorSpace,std::shared_ptr<EffectBuffer> & buffer,const std::shared_ptr<EffectContext> & context)294 bool isNeedDecomposeHdrImage(const EffectColorSpace &colorSpace, const EffectColorSpace &chosenColorSpace,
295 std::shared_ptr<EffectBuffer> &buffer, const std::shared_ptr<EffectContext> &context)
296 {
297 bool isNeedDecompose = ColorSpaceHelper::IsHdrColorSpace(colorSpace) &&
298 !ColorSpaceHelper::IsHdrColorSpace(chosenColorSpace);
299
300 CHECK_AND_RETURN_RET_LOG(buffer, false, "isNeedDecomposeHdrImage buffer is nullptr");
301 bool isSupportHdr = !std::none_of(SUPPORT_HDR_FORMAT_SET.begin(), SUPPORT_HDR_FORMAT_SET.end(),
302 [&context](HdrFormat format) {
303 return context->filtersSupportedHdrFormat_.count(format) > 0;
304 }) && SUPPORT_HDR_FORMAT_SET.count(buffer->bufferInfo_->hdrFormat_) > 0;
305
306 EFFECT_LOGD("isNeedDecomposeHdrImage: colorSpace=%{public}d, chosenColorSpace=%{public}d, isSupportHdr=%{public}d",
307 colorSpace, chosenColorSpace, isSupportHdr);
308 return isNeedDecompose && !isSupportHdr;
309 }
310
DecomposeHdrImageIfNeed(const EffectColorSpace & colorSpace,const EffectColorSpace & chosenColorSpace,std::shared_ptr<EffectBuffer> & buffer,const std::shared_ptr<EffectContext> & context)311 ErrorCode DecomposeHdrImageIfNeed(const EffectColorSpace &colorSpace, const EffectColorSpace &chosenColorSpace,
312 std::shared_ptr<EffectBuffer> &buffer, const std::shared_ptr<EffectContext> &context)
313 {
314 if (!isNeedDecomposeHdrImage(colorSpace, chosenColorSpace, buffer, context)) {
315 EFFECT_LOGD("DecomposeHdrImageIfNeed: no need to decompose");
316 return ErrorCode::SUCCESS;
317 }
318
319 if (buffer->extraInfo_->dataType == DataType::TEX) {
320 return ErrorCode::ERR_COLORSPACE_NOT_SUPPORT_CONVERT;
321 }
322
323 EFFECT_LOGI("ColorSpaceHelper::DecomposeHdrImage");
324 std::shared_ptr<Memory> oldMemory = context->memoryManager_->GetMemoryByAddr(buffer->buffer_);
325 std::shared_ptr<EffectBuffer> sdrImage = nullptr;
326 ErrorCode res = context->colorSpaceManager_->GetColorSpaceProcessor()->ProcessHdrImage(buffer.get(), sdrImage);
327 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "DecomposeHdrImageIfNeed: ProcessHdrImage fail! "
328 "res=%{public}d, colorSpace=%{public}d, chosenColorSpace=%{public}d", res, colorSpace, chosenColorSpace);
329 CHECK_AND_RETURN_RET_LOG(sdrImage != nullptr, ErrorCode::ERR_INPUT_NULL,
330 "DecomposeHdrImageIfNeed: sdrImage is null, sdrImage=%{public}d", sdrImage == nullptr);
331 CHECK_AND_RETURN_RET_LOG(sdrImage->extraInfo_ != nullptr, ErrorCode::ERR_INPUT_NULL,
332 "DecomposeHdrImageIfNeed: extraInfo of sdrImage is null!, sdrImage->extraInfo_=%{public}d",
333 sdrImage->extraInfo_ == nullptr);
334
335 context->memoryManager_->RemoveMemory(oldMemory);
336 std::shared_ptr<MemoryData> memoryData = context->colorSpaceManager_->GetColorSpaceProcessor()
337 ->GetMemoryData(sdrImage->bufferInfo_->surfaceBuffer_);
338
339 SurfaceBuffer *sb = sdrImage->bufferInfo_->surfaceBuffer_;
340 ColorSpaceHelper::SetSurfaceBufferMetadataType(sb, CM_HDR_Metadata_Type::CM_METADATA_NONE);
341 ColorSpaceHelper::SetSurfaceBufferColorSpaceType(sb, CM_ColorSpaceType::CM_COLORSPACE_NONE);
342
343 std::shared_ptr<Memory> memory = std::make_shared<Memory>();
344 memory->memoryData_ = memoryData;
345 context->memoryManager_->AddMemory(memory);
346 *buffer = *sdrImage;
347
348 return ErrorCode::SUCCESS;
349 }
350
ConvertColorSpace(std::shared_ptr<EffectBuffer> & srcBuffer,std::shared_ptr<EffectContext> & context)351 ErrorCode ColorSpaceHelper::ConvertColorSpace(std::shared_ptr<EffectBuffer> &srcBuffer,
352 std::shared_ptr<EffectContext> &context)
353 {
354 EffectColorSpace colorSpace = srcBuffer->bufferInfo_->colorSpace_;
355 EFFECT_LOGD("ConvertColorSpace: colorSpace=%{public}d", colorSpace);
356
357 if (srcBuffer->extraInfo_->dataType == DataType::TEX && !IsTexSupportedColorSpace(colorSpace)) {
358 return ErrorCode::ERR_NOT_SUPPORT_INPUT_OUTPUT_COLORSPACE;
359 }
360
361 // If color space is none, it means that color space is not supported. But it still should return success,
362 // because the real color space maybe defined as ColorSpaceName::CUSTOM in ExtDecoder::getGrColorSpace or
363 // the color space is not exist when invoking InnerGetGrColorSpacePtr of pixelmap returned null ptr.
364 if (colorSpace == EffectColorSpace::DEFAULT) {
365 EFFECT_LOGI("ConvertColorSpace: colorspace is none! Do nothing!");
366 return ErrorCode::SUCCESS;
367 }
368
369 EFFECT_LOGD("ColorSpaceHelper::ConvertColorSpace colorSpace=%{public}d", colorSpace);
370 ErrorCode res = ApplyColorSpaceIfNeed(srcBuffer, context, colorSpace);
371 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "ConvertColorSpace: ConvertColorSpaceIfNeed fail! "
372 "res=%{public}d, colorSpace=%{public}d", res, colorSpace);
373
374 EffectColorSpace chosenColorSpace = EffectColorSpace::DEFAULT;
375 res = context->colorSpaceManager_->ChooseColorSpace(
376 context->filtersSupportedColorSpace_, colorSpace, chosenColorSpace);
377 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "ConvertColorSpace: ChooseColorSpace fail! "
378 "res=%{public}d, colorSpace=%{public}d", res, colorSpace);
379
380 EFFECT_LOGD("ConvertColorSpace: colorSpace=%{public}d, chosenColorSpace=%{public}d", colorSpace, chosenColorSpace);
381 res = DecomposeHdrImageIfNeed(colorSpace, chosenColorSpace, srcBuffer, context);
382 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "ConvertColorSpace: DecomposeHdrImageIfNeed fail! "
383 "res=%{public}d, colorSpace=%{public}d, chosenColorSpace=%{public}d", res, colorSpace, chosenColorSpace);
384
385 return ErrorCode::SUCCESS;
386 }
387
TryFixGainmapHdrMetadata(sptr<SurfaceBuffer> & gainmapSptr)388 void ColorSpaceHelper::TryFixGainmapHdrMetadata(sptr<SurfaceBuffer> &gainmapSptr)
389 {
390 std::vector<uint8_t> gainmapDynamicMetadata;
391 GetHDRDynamicMetadata(gainmapSptr.GetRefPtr(), gainmapDynamicMetadata);
392 if (gainmapDynamicMetadata.size() != sizeof(ISOMetadata)) {
393 EFFECT_LOGI("%{public}s no need to fix gainmap dynamic metadata, size: %{public}zu",
394 __func__, gainmapDynamicMetadata.size());
395 return;
396 }
397
398 HDRVividExtendMetadata extendMetadata = {};
399 int32_t memCpyRes = memcpy_s(&extendMetadata.metaISO, sizeof(ISOMetadata),
400 gainmapDynamicMetadata.data(), gainmapDynamicMetadata.size());
401 if (memCpyRes != EOK) {
402 EFFECT_LOGE("%{public}s memcpy_s ISOMetadata fail, error: %{public}d", __func__, memCpyRes);
403 return;
404 }
405 if (extendMetadata.metaISO.useBaseColorFlag != 0) {
406 extendMetadata.baseColorMeta.baseColorPrimary = COLORPRIMARIES_SRGB;
407 extendMetadata.gainmapColorMeta.combineColorPrimary = COLORPRIMARIES_SRGB;
408 } else {
409 extendMetadata.gainmapColorMeta.combineColorPrimary = COLORPRIMARIES_BT2020;
410 extendMetadata.gainmapColorMeta.alternateColorPrimary = COLORPRIMARIES_BT2020;
411 }
412 std::vector<uint8_t> extendMetadataVec(sizeof(HDRVividExtendMetadata));
413 memCpyRes = memcpy_s(extendMetadataVec.data(), extendMetadataVec.size(),
414 &extendMetadata, sizeof(HDRVividExtendMetadata));
415 if (memCpyRes != EOK) {
416 EFFECT_LOGE("%{public}s memcpy_s HDRVividExtendMetadata fail, error: %{public}d", __func__, memCpyRes);
417 return;
418 }
419 SetHDRDynamicMetadata(gainmapSptr.GetRefPtr(), extendMetadataVec);
420 }
421
ShouldComposeAsCuva(const sptr<SurfaceBuffer> & baseSptr,const sptr<SurfaceBuffer> & gainmapSptr)422 bool ColorSpaceHelper::ShouldComposeAsCuva(const sptr<SurfaceBuffer> &baseSptr, const sptr<SurfaceBuffer> &gainmapSptr)
423 {
424 std::vector<uint8_t> baseStaticMetadata;
425 GetHDRDynamicMetadata(baseSptr.GetRefPtr(), baseStaticMetadata);
426 std::vector<uint8_t> baseDynamicMetadata;
427 GetHDRDynamicMetadata(gainmapSptr.GetRefPtr(), baseDynamicMetadata);
428 if (baseStaticMetadata.size() == 0 || baseDynamicMetadata.size() == 0) {
429 return true;
430 }
431
432 std::vector<uint8_t> gainmapDynamicMetadata;
433 GetHDRDynamicMetadata(gainmapSptr.GetRefPtr(), gainmapDynamicMetadata);
434 if (gainmapDynamicMetadata.size() != sizeof(HDRVividExtendMetadata)) {
435 return true;
436 }
437 return false;
438 }
439 } // namespace Effect
440 } // namespace Media
441 } // namespace OHOS