• 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_strategy.h"
17 
18 #include <unordered_map>
19 
20 #include "effect_log.h"
21 #include "colorspace_helper.h"
22 
23 namespace OHOS {
24 namespace Media {
25 namespace Effect {
26 
27 static const std::unordered_map<EffectColorSpace, EffectColorSpace> COLORSPACE_CONVERTER_MAP = {
28     { EffectColorSpace::SRGB, EffectColorSpace::SRGB },
29     { EffectColorSpace::SRGB_LIMIT, EffectColorSpace::SRGB_LIMIT },
30     { EffectColorSpace::DISPLAY_P3, EffectColorSpace::DISPLAY_P3 },
31     { EffectColorSpace::DISPLAY_P3_LIMIT, EffectColorSpace::DISPLAY_P3_LIMIT },
32     { EffectColorSpace::BT2020_HLG, EffectColorSpace::BT2020_HLG },
33     { EffectColorSpace::BT2020_HLG_LIMIT, EffectColorSpace::BT2020_HLG_LIMIT },
34     { EffectColorSpace::BT2020_PQ, EffectColorSpace::BT2020_PQ },
35     { EffectColorSpace::BT2020_PQ_LIMIT, EffectColorSpace::BT2020_PQ_LIMIT },
36     { EffectColorSpace::ADOBE_RGB, EffectColorSpace::DISPLAY_P3 },
37     { EffectColorSpace::NOT_SUPPORTED, EffectColorSpace::NOT_SUPPORTED },
38 };
39 
40 static const std::unordered_map<EffectColorSpace, EffectColorSpace> COLORSPACE_HDR_CONVERTER_MAP = {
41     { EffectColorSpace::BT2020_HLG, EffectColorSpace::DISPLAY_P3 },
42     { EffectColorSpace::BT2020_HLG_LIMIT, EffectColorSpace::DISPLAY_P3_LIMIT },
43     { EffectColorSpace::BT2020_PQ, EffectColorSpace::DISPLAY_P3 },
44     { EffectColorSpace::BT2020_PQ_LIMIT, EffectColorSpace::DISPLAY_P3_LIMIT },
45 };
46 
47 static const std::vector<EffectColorSpace> DEFAULT_SUPPORTED_COLORSPACE = {
48     EffectColorSpace::SRGB,
49     EffectColorSpace::SRGB_LIMIT,
50     EffectColorSpace::DISPLAY_P3,
51     EffectColorSpace::DISPLAY_P3_LIMIT
52 };
53 
IsSupportedColorSpace(EffectColorSpace colorSpace)54 bool ColorSpaceStrategy::IsSupportedColorSpace(EffectColorSpace colorSpace)
55 {
56     for (const auto &it : COLORSPACE_CONVERTER_MAP) {
57         if (it.first == colorSpace) {
58             return true;
59         }
60     }
61     return false;
62 }
63 
IsNeedConvertColorSpace(EffectColorSpace colorSpace)64 bool ColorSpaceStrategy::IsNeedConvertColorSpace(EffectColorSpace colorSpace)
65 {
66     EffectColorSpace converterColorSpace = EffectColorSpace::DEFAULT;
67     for (const auto &it : COLORSPACE_CONVERTER_MAP) {
68         if (it.first == colorSpace) {
69             converterColorSpace = it.second;
70             break;
71         }
72     }
73     return colorSpace != converterColorSpace;
74 }
75 
GetTargetColorSpace(EffectColorSpace src)76 EffectColorSpace ColorSpaceStrategy::GetTargetColorSpace(EffectColorSpace src)
77 {
78     auto it = COLORSPACE_CONVERTER_MAP.find(src);
79     return it == COLORSPACE_CONVERTER_MAP.end() ? EffectColorSpace::DEFAULT : it->second;
80 }
81 
GetAllSupportedColorSpaces()82 std::unordered_set<EffectColorSpace> ColorSpaceStrategy::GetAllSupportedColorSpaces()
83 {
84     std::unordered_set<EffectColorSpace> supportedColorSpace;
85     for (const auto &it : COLORSPACE_CONVERTER_MAP) {
86         supportedColorSpace.emplace(it.second);
87     }
88 
89     return supportedColorSpace;
90 }
91 
Init(const std::shared_ptr<EffectBuffer> & src,const std::shared_ptr<EffectBuffer> & dst)92 void ColorSpaceStrategy::Init(const std::shared_ptr<EffectBuffer> &src, const std::shared_ptr<EffectBuffer> &dst)
93 {
94     src_ = src;
95     dst_ = dst;
96 }
97 
ChooseColorSpaceInner(const EffectColorSpace & srcRealColorSpace,const std::unordered_set<EffectColorSpace> & filtersSupportedColorSpace,EffectColorSpace & outputColorSpace)98 ErrorCode ChooseColorSpaceInner(const EffectColorSpace &srcRealColorSpace,
99     const std::unordered_set<EffectColorSpace> &filtersSupportedColorSpace, EffectColorSpace &outputColorSpace)
100 {
101     if (filtersSupportedColorSpace.find(srcRealColorSpace) != filtersSupportedColorSpace.end()) {
102         outputColorSpace = srcRealColorSpace;
103         return ErrorCode::SUCCESS;
104     }
105 
106     if (std::find(DEFAULT_SUPPORTED_COLORSPACE.begin(), DEFAULT_SUPPORTED_COLORSPACE.end(), srcRealColorSpace) !=
107         DEFAULT_SUPPORTED_COLORSPACE.end()) {
108         outputColorSpace = srcRealColorSpace;
109         return ErrorCode::SUCCESS;
110     }
111 
112     auto it = COLORSPACE_HDR_CONVERTER_MAP.find(srcRealColorSpace);
113     if (it == COLORSPACE_HDR_CONVERTER_MAP.end()) {
114         EFFECT_LOGE("ChooseColorSpaceInner: colorSpace[%{public}d] not support convert.", srcRealColorSpace);
115         return ErrorCode::ERR_UNSUPPORTED_FORMAT_TYPE;
116     }
117 
118     outputColorSpace = it->second;
119     return ErrorCode::SUCCESS;
120 }
121 
ChooseColorSpaceWithOutput(const EffectColorSpace & srcRealColorSpace,EffectBuffer * src,EffectBuffer * dst,const std::unordered_set<EffectColorSpace> & filtersSupportedColorSpace,EffectColorSpace & outputColorSpace)122 ErrorCode ChooseColorSpaceWithOutput(const EffectColorSpace &srcRealColorSpace, EffectBuffer *src, EffectBuffer *dst,
123     const std::unordered_set<EffectColorSpace> &filtersSupportedColorSpace, EffectColorSpace &outputColorSpace)
124 {
125     const std::shared_ptr<BufferInfo> &dstBufferInfo = dst->bufferInfo_;
126     CHECK_AND_RETURN_RET_LOG(dstBufferInfo != nullptr, ErrorCode::ERR_INPUT_NULL,
127         "ChooseColorSpaceWithOutput: dstBufferInfo is null!");
128 
129     EffectColorSpace chooseColorSpace = EffectColorSpace::DEFAULT;
130     ErrorCode res = ChooseColorSpaceInner(srcRealColorSpace, filtersSupportedColorSpace, chooseColorSpace);
131     CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "ChooseColorSpaceWithOutput: ChooseColorSpaceInner fail!");
132 
133     if (src->extraInfo_->dataType == DataType::PIXEL_MAP && dst->extraInfo_->dataType == DataType::PIXEL_MAP) {
134         // color space is same.
135         bool isSrcHdr = ColorSpaceHelper::IsHdrColorSpace(srcRealColorSpace);
136         bool isChoseHdr = ColorSpaceHelper::IsHdrColorSpace(chooseColorSpace);
137         CHECK_AND_RETURN_RET_LOG(isSrcHdr == isChoseHdr, ErrorCode::ERR_NOT_SUPPORT_INPUT_OUTPUT_COLORSPACE,
138             "ChooseColorSpaceWithOutput: input and output color space not same! "
139             "srcRealColorSpace=%{public}d, chooseColorSpace=%{public}d", srcRealColorSpace, chooseColorSpace);
140     }
141 
142     outputColorSpace = chooseColorSpace;
143     return ErrorCode::SUCCESS;
144 }
145 
ChooseColorSpaceWithoutOutput(const EffectColorSpace & srcRealColorSpace,const std::unordered_set<EffectColorSpace> & filtersSupportedColorSpace,EffectColorSpace & outputColorSpace)146 ErrorCode ChooseColorSpaceWithoutOutput(const EffectColorSpace &srcRealColorSpace,
147     const std::unordered_set<EffectColorSpace> &filtersSupportedColorSpace, EffectColorSpace &outputColorSpace)
148 {
149     return ChooseColorSpaceInner(srcRealColorSpace, filtersSupportedColorSpace, outputColorSpace);
150 }
151 
ChooseColorSpace(const std::unordered_set<EffectColorSpace> & filtersSupportedColorSpace,const EffectColorSpace & srcRealColorSpace,EffectColorSpace & outputColorSpace)152 ErrorCode ColorSpaceStrategy::ChooseColorSpace(const std::unordered_set<EffectColorSpace> &filtersSupportedColorSpace,
153     const EffectColorSpace &srcRealColorSpace, EffectColorSpace &outputColorSpace)
154 {
155     CHECK_AND_RETURN_RET_LOG(src_ != nullptr, ErrorCode::ERR_INPUT_NULL, "ChooseColorSpace: src_ is null!");
156 
157     if (dst_ == nullptr || dst_->buffer_ == src_->buffer_) {
158         return ChooseColorSpaceWithoutOutput(srcRealColorSpace, filtersSupportedColorSpace, outputColorSpace);
159     }
160     return ChooseColorSpaceWithOutput(srcRealColorSpace, src_.get(), dst_.get(), filtersSupportedColorSpace,
161         outputColorSpace);
162 }
163 
CheckConverterColorSpace(const EffectColorSpace & targetColorSpace)164 ErrorCode ColorSpaceStrategy::CheckConverterColorSpace(const EffectColorSpace &targetColorSpace)
165 {
166     CHECK_AND_RETURN_RET_LOG(src_ != nullptr, ErrorCode::ERR_PARAM_INVALID,
167         "GetConverterEffectBuffer: src_ is null!");
168 
169     // only input data
170     if (dst_ == nullptr || dst_->buffer_ == src_->buffer_) {
171         return ErrorCode::SUCCESS;
172     }
173 
174     DataType dataType = dst_->extraInfo_->dataType;
175     if (dataType == DataType::NATIVE_WINDOW) {
176         return ErrorCode::SUCCESS;
177     }
178 
179     // check color space is match or not.
180     const std::shared_ptr<BufferInfo> &srcBufferInfo = src_->bufferInfo_;
181     const std::shared_ptr<BufferInfo> &dstBufferInfo = dst_->bufferInfo_;
182     CHECK_AND_RETURN_RET_LOG(srcBufferInfo != nullptr && dstBufferInfo != nullptr, ErrorCode::ERR_PARAM_INVALID,
183         "CheckConverterColorSpace: srcBufferInfo or dstBufferInfo is null!");
184     EffectColorSpace srcColorSpace = srcBufferInfo->colorSpace_;
185     EffectColorSpace dstColorSpace = dstBufferInfo->colorSpace_;
186     CHECK_AND_RETURN_RET_LOG(targetColorSpace == dstColorSpace, ErrorCode::ERR_NOT_SUPPORT_INPUT_OUTPUT_COLORSPACE,
187         "CheckConverterColorSpace: colorspace not match! target=%{public}d, src=%{public}d, dst=%{public}d",
188         targetColorSpace, srcColorSpace, dstColorSpace);
189 
190     return ErrorCode::SUCCESS;
191 }
192 
Deinit()193 void ColorSpaceStrategy::Deinit()
194 {
195     src_ = nullptr;
196     dst_ = nullptr;
197 }
198 
199 } // namespace Effect
200 } // namespace Media
201 } // namespace OHOS