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