• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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