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 "contrast_efilter.h"
17
18 #include "effect_log.h"
19 #include "efilter_factory.h"
20 #include "json_helper.h"
21 #include "common_utils.h"
22 #include "cpu_contrast_algo.h"
23 #include "gpu_contrast_algo.h"
24
25 namespace OHOS {
26 namespace Media {
27 namespace Effect {
28 REGISTER_EFILTER_FACTORY(ContrastEFilter, "Contrast");
29 std::shared_ptr<EffectInfo> ContrastEFilter::info_ = nullptr;
30 const float ContrastEFilter::Parameter::INTENSITY_RANGE[] = { -100.f, 100.f };
31 const std::string ContrastEFilter::Parameter::KEY_INTENSITY = "FilterIntensity";
32
ContrastEFilter(const std::string & name)33 ContrastEFilter::ContrastEFilter(const std::string &name) : EFilter(name)
34 {
35 gpuContrastAlgo_ = std::make_shared<GpuContrastAlgo>();
36 contrastFilterInfo_ = {
37 {
38 IPType::CPU,
39 {
40 { IEffectFormat::RGBA8888, CpuContrastAlgo::OnApplyRGBA8888 },
41 { IEffectFormat::YUVNV12, CpuContrastAlgo::OnApplyYUVNV12 },
42 { IEffectFormat::YUVNV21, CpuContrastAlgo::OnApplyYUVNV21 },
43 }
44 },
45 {
46 IPType::GPU,
47 {
48 {
49 IEffectFormat::RGBA8888,
50 [this](EffectBuffer *src, EffectBuffer *dst, std::map<std::string, Plugin::Any> &value,
51 std::shared_ptr<EffectContext> &context)
52 { return gpuContrastAlgo_->OnApplyRGBA8888(src, dst, value, context); }
53 },
54 }
55 }
56 };
57 }
58
~ContrastEFilter()59 ContrastEFilter::~ContrastEFilter()
60 {
61 gpuContrastAlgo_->Release();
62 }
63
Render(EffectBuffer * buffer,std::shared_ptr<EffectContext> & context)64 ErrorCode ContrastEFilter::Render(EffectBuffer *buffer, std::shared_ptr<EffectContext> &context)
65 {
66 if (context->ipType_ == IPType::GPU) {
67 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
68 std::shared_ptr<ExtraInfo> extraInfo = std::make_shared<ExtraInfo>();
69 extraInfo->dataType = DataType::TEX;
70 std::shared_ptr<EffectBuffer> effectBuffer = std::make_shared<EffectBuffer>(bufferInfo, nullptr, extraInfo);
71 ErrorCode res = Render(buffer, effectBuffer.get(), context);
72 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "filter(%{public}s) render fail", name_.c_str());
73 return PushData(effectBuffer.get(), context);
74 }
75 ErrorCode res = Render(buffer, buffer, context);
76 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "filter(%{public}s) render fail", name_.c_str());
77 return PushData(buffer, context);
78 }
79
Render(EffectBuffer * src,EffectBuffer * dst,std::shared_ptr<EffectContext> & context)80 ErrorCode ContrastEFilter::Render(EffectBuffer *src, EffectBuffer *dst, std::shared_ptr<EffectContext> &context)
81 {
82 IPType ipType = context->ipType_;
83 auto it = contrastFilterInfo_.find(ipType);
84 CHECK_AND_RETURN_RET_LOG(it != contrastFilterInfo_.end(), ErrorCode::ERR_UNSUPPORTED_IPTYPE_FOR_EFFECT,
85 "ipType=%{public}d is not support! filter=%{public}s", ipType, name_.c_str());
86
87 IEffectFormat formatType = src->bufferInfo_->formatType_;
88 std::unordered_map<IEffectFormat, ApplyFunc> formatFuncs = it->second;
89 auto formatIter = formatFuncs.find(formatType);
90 CHECK_AND_RETURN_RET_LOG(formatIter != formatFuncs.end(), ErrorCode::ERR_UNSUPPORTED_FORMAT_TYPE,
91 "format=%{public}d is not support! filter=%{public}s", formatType, name_.c_str());
92
93 return formatIter->second(src, dst, values_, context);
94 }
95
SetValue(const std::string & key,Plugin::Any & value)96 ErrorCode ContrastEFilter::SetValue(const std::string &key, Plugin::Any &value)
97 {
98 if (Parameter::KEY_INTENSITY.compare(key) != 0) {
99 EFFECT_LOGE("key is not support! key=%{public}s", key.c_str());
100 return ErrorCode::ERR_UNSUPPORTED_VALUE_KEY;
101 }
102
103 auto contrastPtr = Plugin::AnyCast<float>(&value);
104 if (contrastPtr == nullptr) {
105 EFFECT_LOGE("the type is not float! key=%{public}s", key.c_str());
106 return ErrorCode::ERR_ANY_CAST_TYPE_NOT_FLOAT;
107 }
108
109 float contrast = *contrastPtr;
110 if (contrast < Parameter::INTENSITY_RANGE[0] || contrast > Parameter::INTENSITY_RANGE[1]) {
111 EFFECT_LOGW("the value is out of range! key=%{public}s, value=%{public}f, range=[%{public}f, %{public}f]",
112 key.c_str(), contrast, Parameter::INTENSITY_RANGE[0], Parameter::INTENSITY_RANGE[1]);
113 *contrastPtr = CommonUtils::Clip(contrast, Parameter::INTENSITY_RANGE[0], Parameter::INTENSITY_RANGE[1]);
114 }
115
116 return EFilter::SetValue(key, value);
117 }
118
Restore(const EffectJsonPtr & values)119 ErrorCode ContrastEFilter::Restore(const EffectJsonPtr &values)
120 {
121 // If the developer does not set parameters, the function returns a failure, but it is a normal case.
122 if (!values->HasElement(Parameter::KEY_INTENSITY)) {
123 EFFECT_LOGW("not set value! key=%{public}s", Parameter::KEY_INTENSITY.c_str());
124 return ErrorCode::SUCCESS;
125 }
126
127 float contrast = values->GetFloat(Parameter::KEY_INTENSITY);
128 if (contrast < Parameter::INTENSITY_RANGE[0] || contrast > Parameter::INTENSITY_RANGE[1]) {
129 return ErrorCode::ERR_VALUE_OUT_OF_RANGE;
130 }
131 Plugin::Any any = contrast;
132 return SetValue(Parameter::KEY_INTENSITY, any);
133 }
134
GetEffectInfo(const std::string & name)135 std::shared_ptr<EffectInfo> ContrastEFilter::GetEffectInfo(const std::string &name)
136 {
137 if (info_ != nullptr) {
138 return info_;
139 }
140 info_ = std::make_unique<EffectInfo>();
141 info_->formats_.emplace(IEffectFormat::RGBA8888, std::vector<IPType>{ IPType::CPU, IPType::GPU });
142 info_->formats_.emplace(IEffectFormat::YUVNV21, std::vector<IPType>{ IPType::CPU });
143 info_->formats_.emplace(IEffectFormat::YUVNV12, std::vector<IPType>{ IPType::CPU });
144 info_->category_ = Category::COLOR_ADJUST;
145 info_->colorSpaces_ = {
146 EffectColorSpace::SRGB,
147 EffectColorSpace::SRGB_LIMIT,
148 EffectColorSpace::DISPLAY_P3,
149 EffectColorSpace::DISPLAY_P3_LIMIT
150 };
151 return info_;
152 }
153
PreRender(IEffectFormat & format)154 ErrorCode ContrastEFilter::PreRender(IEffectFormat &format)
155 {
156 return ErrorCode::SUCCESS;
157 }
158 } // namespace Effect
159 } // namespace Media
160 } // namespace OHOS