1 /*
2 * Copyright (c) 2025 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 "video_processing_algorithm_base.h"
17
18 #include "algorithm_errors.h"
19 #include "video_processing_algorithm_factory.h"
20 #include "vpe_sa_types.h"
21
22 using namespace OHOS;
23 using namespace OHOS::Media::VideoProcessingEngine;
24
25 namespace {
26 constexpr uint32_t MAX_CLIENT_GEN_COUNT = 500;
27 }
28
Initialize()29 int VideoProcessingAlgorithmBase::Initialize()
30 {
31 std::lock_guard<std::mutex> lock(lock_);
32 if (isInitialized_) {
33 VPE_LOGW("Already initialized!");
34 return VPE_ALGO_ERR_OK;
35 }
36 int ret = OnInitializeLocked();
37 if (ret != VPE_ALGO_ERR_OK) {
38 VPE_LOGE("Failed to initialize!");
39 return ret;
40 }
41 isInitialized_ = true;
42 return VPE_ALGO_ERR_OK;
43 }
44
Deinitialize()45 int VideoProcessingAlgorithmBase::Deinitialize()
46 {
47 std::lock_guard<std::mutex> lock(lock_);
48 if (!isInitialized_) {
49 VPE_LOGW("Already deinitialized!");
50 return VPE_ALGO_ERR_OK;
51 }
52 ClearClientsLocked();
53 int ret = OnDeinitializeLocked();
54 if (ret != VPE_ALGO_ERR_OK) {
55 VPE_LOGE("Failed to deinitialize!");
56 return ret;
57 }
58 isInitialized_ = false;
59 return VPE_ALGO_ERR_OK;
60 }
61
HasClient() const62 bool VideoProcessingAlgorithmBase::HasClient() const
63 {
64 return hasClient_.load();
65 }
66
Add(const std::string & clientName,uint32_t & clientID)67 int VideoProcessingAlgorithmBase::Add(const std::string& clientName, uint32_t& clientID)
68 {
69 CHECK_AND_RETURN_RET_LOG(!clientName.empty(), VPE_ALGO_ERR_INVALID_PARAM, "Invalid input: clientName is empty!");
70
71 std::lock_guard<std::mutex> lock(lock_);
72 int ret = AddClientIDLocked(clientName, clientID);
73 CHECK_AND_RETURN_RET_LOG(ret == VPE_ALGO_ERR_OK, ret, "Failed to add client for %{public}s!", clientName.c_str());
74
75 hasClient_ = true;
76 return VPE_ALGO_ERR_OK;
77 }
78
Del(uint32_t clientID)79 int VideoProcessingAlgorithmBase::Del(uint32_t clientID)
80 {
81 std::lock_guard<std::mutex> lock(lock_);
82 bool isEmpty;
83 int ret = DelClientIDLocked(clientID, isEmpty);
84 CHECK_AND_RETURN_RET_LOG(ret == VPE_ALGO_ERR_OK, ret, "Failed to del client(%{public}u)!", clientID);
85 if (isEmpty) {
86 hasClient_ = false;
87 }
88 return VPE_ALGO_ERR_OK;
89 }
90
UpdateMetadata(uint32_t clientID,SurfaceBufferInfo & image)91 int VideoProcessingAlgorithmBase::UpdateMetadata(uint32_t clientID, SurfaceBufferInfo& image)
92 {
93 CHECK_AND_RETURN_RET_LOG(IsValid(image), VPE_ALGO_ERR_INVALID_PARAM, "Invalid input: %{public}s!",
94 image.str().c_str());
95 return DoUpdateMetadata(clientID, image);
96 }
97
Process(uint32_t clientID,const SurfaceBufferInfo & input,SurfaceBufferInfo & output)98 int VideoProcessingAlgorithmBase::Process(uint32_t clientID,
99 const SurfaceBufferInfo& input, SurfaceBufferInfo& output)
100 {
101 CHECK_AND_RETURN_RET_LOG(IsValid(input) && IsValid(output), VPE_ALGO_ERR_INVALID_PARAM,
102 "Invalid input: input={%{public}s} output={%{public}s}!", input.str().c_str(), output.str().c_str());
103 return DoProcess(clientID, input, output);
104 }
105
ComposeImage(uint32_t clientID,const SurfaceBufferInfo & inputSdrImage,const SurfaceBufferInfo & inputGainmap,SurfaceBufferInfo & outputHdrImage,bool legacy)106 int VideoProcessingAlgorithmBase::ComposeImage(uint32_t clientID,
107 const SurfaceBufferInfo& inputSdrImage,
108 const SurfaceBufferInfo& inputGainmap,
109 SurfaceBufferInfo& outputHdrImage, bool legacy)
110 {
111 CHECK_AND_RETURN_RET_LOG(IsValid(inputSdrImage) && IsValid(inputGainmap) && IsValid(outputHdrImage),
112 VPE_ALGO_ERR_INVALID_PARAM,
113 "Invalid input: inputSdrImage={%{public}s} inputGainmap={%{public}s} outputHdrImage={%{public}s}!",
114 inputSdrImage.str().c_str(), inputGainmap.str().c_str(), outputHdrImage.str().c_str());
115 return DoComposeImage(clientID, inputSdrImage, inputGainmap, outputHdrImage, legacy);
116 }
117
DecomposeImage(uint32_t clientID,const SurfaceBufferInfo & inputImage,SurfaceBufferInfo & outputSdrImage,SurfaceBufferInfo & outputGainmap)118 int VideoProcessingAlgorithmBase::DecomposeImage(uint32_t clientID,
119 const SurfaceBufferInfo& inputImage,
120 SurfaceBufferInfo& outputSdrImage,
121 SurfaceBufferInfo& outputGainmap)
122 {
123 CHECK_AND_RETURN_RET_LOG(IsValid(inputImage) && IsValid(outputSdrImage) && IsValid(outputGainmap),
124 VPE_ALGO_ERR_INVALID_PARAM,
125 "Invalid input: inputImage={%{public}s} outputSdrImage={%{public}s} outputGainmap={%{public}s}!",
126 inputImage.str().c_str(), outputSdrImage.str().c_str(), outputGainmap.str().c_str());
127 return DoDecomposeImage(clientID, inputImage, outputSdrImage, outputGainmap);
128 }
129
OnInitializeLocked()130 int VideoProcessingAlgorithmBase::OnInitializeLocked()
131 {
132 return VPE_ALGO_ERR_OK;
133 }
134
OnDeinitializeLocked()135 int VideoProcessingAlgorithmBase::OnDeinitializeLocked()
136 {
137 return VPE_ALGO_ERR_OK;
138 }
139
AddClientIDLocked(const std::string & clientName,uint32_t & clientID)140 int VideoProcessingAlgorithmBase::AddClientIDLocked([[maybe_unused]] const std::string& clientName,
141 [[maybe_unused]] uint32_t& clientID)
142 {
143 return VPE_ALGO_ERR_OK;
144 }
145
DelClientIDLocked(uint32_t clientID,bool & isEmpty)146 int VideoProcessingAlgorithmBase::DelClientIDLocked([[maybe_unused]] uint32_t clientID, [[maybe_unused]] bool& isEmpty)
147 {
148 return VPE_ALGO_ERR_OK;
149 }
150
GetClientSizeLocked() const151 size_t VideoProcessingAlgorithmBase::GetClientSizeLocked() const
152 {
153 return 0;
154 }
155
ClearClientsLocked()156 void VideoProcessingAlgorithmBase::ClearClientsLocked()
157 {
158 }
159
DoUpdateMetadata(uint32_t clientID,SurfaceBufferInfo & image)160 int VideoProcessingAlgorithmBase::DoUpdateMetadata([[maybe_unused]] uint32_t clientID,
161 [[maybe_unused]] SurfaceBufferInfo& image)
162 {
163 return VPE_ALGO_ERR_OK;
164 }
165
DoProcess(uint32_t clientID,const SurfaceBufferInfo & input,SurfaceBufferInfo & output)166 int VideoProcessingAlgorithmBase::DoProcess([[maybe_unused]] uint32_t clientID,
167 [[maybe_unused]] const SurfaceBufferInfo& input, [[maybe_unused]] SurfaceBufferInfo& output)
168 {
169 return VPE_ALGO_ERR_OK;
170 }
171
DoComposeImage(uint32_t clientID,const SurfaceBufferInfo & inputSdrImage,const SurfaceBufferInfo & inputGainmap,SurfaceBufferInfo & outputHdrImage,bool legacy)172 int VideoProcessingAlgorithmBase::DoComposeImage([[maybe_unused]] uint32_t clientID,
173 [[maybe_unused]] const SurfaceBufferInfo& inputSdrImage,
174 [[maybe_unused]] const SurfaceBufferInfo& inputGainmap,
175 [[maybe_unused]] SurfaceBufferInfo& outputHdrImage, [[maybe_unused]] bool legacy)
176 {
177 return VPE_ALGO_ERR_OK;
178 }
179
DoDecomposeImage(uint32_t clientID,const SurfaceBufferInfo & inputImage,SurfaceBufferInfo & outputSdrImage,SurfaceBufferInfo & outputGainmap)180 int VideoProcessingAlgorithmBase::DoDecomposeImage([[maybe_unused]] uint32_t clientID,
181 [[maybe_unused]] const SurfaceBufferInfo& inputImage,
182 [[maybe_unused]] SurfaceBufferInfo& outputSdrImage,
183 [[maybe_unused]] SurfaceBufferInfo& outputGainmap)
184 {
185 return VPE_ALGO_ERR_OK;
186 }
187
ReturnNotSupport(const LogInfo & logInfo) const188 int VideoProcessingAlgorithmBase::ReturnNotSupport(const LogInfo& logInfo) const
189 {
190 VPE_ORG_LOGE(logInfo, "Not support this operation!");
191 return VPE_ALGO_ERR_OPERATION_NOT_SUPPORTED;
192 }
193
GenerateClientID(std::function<bool (uint32_t)> && isDuplicate,uint32_t & clientID)194 bool VideoProcessingAlgorithmBase::GenerateClientID(std::function<bool(uint32_t)>&& isDuplicate, uint32_t& clientID)
195 {
196 uint32_t id;
197 uint32_t i = 0;
198 do {
199 // MAX_CLIENT_GEN_COUNT will control the ID generation times,
200 // it will avoid an infinite loop during ID generation.
201 if (i++ > MAX_CLIENT_GEN_COUNT) {
202 VPE_LOGE("Failed to generate new client ID, maybe too many clients(size:%{public}zu).",
203 GetClientSizeLocked());
204 return false;
205 }
206 id = GenerateClientID();
207 } while (isDuplicate(id));
208 clientID = id;
209 return true;
210 }
211
GenerateClientID()212 uint32_t VideoProcessingAlgorithmBase::GenerateClientID()
213 {
214 // clientIdBase_ CAN overflow after self-adding, because the ID value maybe reused.
215 // And MAX_CLIENT_GEN_COUNT will control the ID generation times,
216 // it will avoid an infinite loop during ID generation.
217 // +---------------------------------------+
218 // | High <----------------------> Low |
219 // +---------+-----------------------------+
220 // | 1 Byte | 3 Bytes |
221 // +---------+---------+---------+---------+
222 // |FeatureID| ClientID |
223 // +---------+---------+---------+---------+
224 return (featureID_ << 24) | (clientIdBase_++ & 0xFFFFFF);
225 }
226