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