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 "image_effect_filter.h"
17
18 #include "common_utils.h"
19 #include "delegate.h"
20 #include "effect_log.h"
21 #include "efilter.h"
22 #include "efilter_factory.h"
23 #include "native_effect_base.h"
24 #include "native_common_utils.h"
25 #include "memcpy_helper.h"
26 #include "format_helper.h"
27 #include "event_report.h"
28 #include <cstring>
29
30 using namespace OHOS::Media;
31 using namespace OHOS::Media::Effect;
32
33 namespace {
34 constexpr char const *PARA_SRC_EFFECT_BUFFER = "PARA_SRC_EFFECT_BUFFER";
35 constexpr char const *PARA_RENDER_WITH_SRC_AND_DST = "PARA_RENDER_WITH_SRC_AND_DST";
36 constexpr char const *PARA_RENDER_INFO = "PARA_RENDER_INFO";
37
38 constexpr int const MAX_CHAR_LEN = 1024;
39
40 std::mutex filterMutex_;
41 }
42
43 static std::vector<std::shared_ptr<ImageEffect_FilterNames>> sOHFilterNames;
44
SetParameter(const std::string & key,Plugin::Any & param)45 void OH_EffectFilter::SetParameter(const std::string &key, Plugin::Any ¶m)
46 {
47 params_.erase(key);
48 params_.emplace(key, param);
49 }
50
GetParameter(const std::string & key,Plugin::Any & param)51 ErrorCode OH_EffectFilter::GetParameter(const std::string &key, Plugin::Any ¶m)
52 {
53 auto it = params_.find(key);
54 if (it == params_.end()) {
55 return ErrorCode::ERR_NO_VALUE;
56 }
57
58 param = std::move(it->second);
59 return ErrorCode::SUCCESS;
60 }
61
RemoveParameter(const std::string & key)62 void OH_EffectFilter::RemoveParameter(const std::string &key)
63 {
64 params_.erase(key);
65 }
66
67 class FilterDelegate : public IFilterDelegate {
68 public:
FilterDelegate(const OH_EffectFilterInfo * info,const ImageEffect_FilterDelegate * delegate)69 FilterDelegate(const OH_EffectFilterInfo *info, const ImageEffect_FilterDelegate *delegate)
70 : ohInfo_(*info), ohDelegate_(delegate) {}
71
72 ~FilterDelegate() override = default;
73
Render(void * efilter,EffectBuffer * src,EffectBuffer * dst,std::shared_ptr<EffectContext> & context)74 bool Render(void *efilter, EffectBuffer *src, EffectBuffer *dst, std::shared_ptr<EffectContext> &context) override
75 {
76 EFFECT_LOGI("FilterDelegate Render with src and dst.");
77 OH_EffectFilter *ohEFilter = (OH_EffectFilter *)efilter;
78 CHECK_AND_RETURN_RET_LOG(ohEFilter != nullptr && ohEFilter->filter_ != nullptr, false,
79 "FilterDelegateRender: filter is null!");
80 Plugin::Any param = true;
81 ohEFilter->SetParameter(PARA_RENDER_WITH_SRC_AND_DST, param);
82 Plugin::Any any = context;
83 ohEFilter->SetParameter(PARA_RENDER_INFO, any);
84
85 MemcpyHelper::CopyData(src, dst);
86 bool res = Render(efilter, dst, context);
87 ohEFilter->RemoveParameter(PARA_RENDER_WITH_SRC_AND_DST);
88 ohEFilter->RemoveParameter(PARA_RENDER_INFO);
89 return res;
90 }
91
Render(void * efilter,EffectBuffer * src,std::shared_ptr<EffectContext> & context)92 bool Render(void *efilter, EffectBuffer *src, std::shared_ptr<EffectContext> &context) override
93 {
94 EFFECT_LOGI("FilterDelegate Render.");
95 std::unique_ptr<OH_EffectBufferInfo> srcBuffer = std::make_unique<OH_EffectBufferInfo>();
96 srcBuffer->addr = src->buffer_;
97 srcBuffer->width = static_cast<int32_t>(src->bufferInfo_->width_);
98 srcBuffer->height = static_cast<int32_t>(src->bufferInfo_->height_);
99 srcBuffer->rowSize = static_cast<int32_t>(src->bufferInfo_->rowStride_);
100 NativeCommonUtils::SwitchToOHFormatType(src->bufferInfo_->formatType_, srcBuffer->format);
101 srcBuffer->timestamp = src->extraInfo_->timestamp;
102
103 OH_EffectFilter *ohEFilter = static_cast<OH_EffectFilter *>(efilter);
104 CHECK_AND_RETURN_RET_LOG(ohEFilter != nullptr && ohEFilter->filter_ != nullptr, false,
105 "FilterDelegateRender: filter is null!");
106
107 Plugin::Any any = src;
108 ohEFilter->SetParameter(PARA_SRC_EFFECT_BUFFER, any);
109 Plugin::Any parameter = context;
110 ohEFilter->SetParameter(PARA_RENDER_INFO, parameter);
111
112 OH_EffectFilterDelegate_PushData pushData = [](OH_EffectFilter *filter, OH_EffectBufferInfo *dst) {
113 FilterDelegate::PushData(filter, dst);
114 };
115
116 bool res = ohDelegate_->render((OH_EffectFilter *)efilter, srcBuffer.get(), pushData);
117 ohEFilter->RemoveParameter(PARA_SRC_EFFECT_BUFFER);
118 ohEFilter->RemoveParameter(PARA_RENDER_INFO);
119 return res;
120 }
121
SetValue(void * efilter,const std::string & key,const Plugin::Any & value)122 bool SetValue(void *efilter, const std::string &key, const Plugin::Any &value) override
123 {
124 EFFECT_LOGD("FilterDelegate SetValue.");
125 std::unique_ptr<ImageEffect_Any> ohValue = std::make_unique<ImageEffect_Any>();
126 NativeCommonUtils::SwitchToOHAny(value, ohValue.get());
127 return ohDelegate_->setValue((OH_EffectFilter *)efilter, key.c_str(), ohValue.get());
128 }
129
Save(void * efilter,EffectJsonPtr & res)130 bool Save(void *efilter, EffectJsonPtr &res) override
131 {
132 EFFECT_LOGI("FilterDelegate Save.");
133 char *result = nullptr;
134 if (!ohDelegate_->save((OH_EffectFilter *)efilter, &result)) {
135 return false;
136 }
137 if (result == nullptr) {
138 return true;
139 }
140 std::string content = result;
141 res = JsonHelper::ParseJsonData(content);
142 return true;
143 }
144
Restore(const EffectJsonPtr & values)145 void *Restore(const EffectJsonPtr &values) override
146 {
147 EFFECT_LOGI("FilterDelegate Restore.");
148 std::string valueStr = values->ToString();
149 return ohDelegate_->restore(valueStr.c_str());
150 }
151
GetEffectInfo()152 void *GetEffectInfo() override
153 {
154 EFFECT_LOGI("FilterDelegate GetEffectInfo.");
155 return &ohInfo_;
156 }
157 protected:
PushData(OH_EffectFilter * filter,OH_EffectBufferInfo * dst)158 static void PushData(OH_EffectFilter *filter, OH_EffectBufferInfo *dst)
159 {
160 CHECK_AND_RETURN_LOG(dst != nullptr && filter != nullptr && filter->filter_ != nullptr,
161 "FilterDelegatePushData: filter is null!");
162 Plugin::Any param;
163 if (filter->GetParameter(PARA_RENDER_WITH_SRC_AND_DST, param) == ErrorCode::SUCCESS) {
164 return;
165 }
166
167 Plugin::Any value;
168 ErrorCode res = filter->GetParameter(PARA_SRC_EFFECT_BUFFER, value);
169 CHECK_AND_RETURN_LOG(res == ErrorCode::SUCCESS, "FilterDelegatePushData: get param fail! key=%{public}s",
170 PARA_SRC_EFFECT_BUFFER);
171
172 EffectBuffer *src = nullptr;
173 res = CommonUtils::ParseAny(value, src);
174 CHECK_AND_RETURN_LOG(res == ErrorCode::SUCCESS && src != nullptr,
175 "FilterDelegatePushData: parse EffectBuffer ptr fail! res=%{public}d", res);
176
177 CHECK_AND_RETURN_LOG(src->buffer_ != nullptr, "FilterDelegatePushData: buffer of src is null!");
178
179 CHECK_AND_RETURN_LOG(src->bufferInfo_ != nullptr && src->extraInfo_ != nullptr,
180 "FilterDelegatePushData: bufferInfo of src is null or extraInfo of src is null!");
181
182 if (dst->addr == src->buffer_) {
183 std::shared_ptr<EffectBuffer> effectBuffer = std::make_shared<EffectBuffer>(src->bufferInfo_,
184 dst->addr, src->extraInfo_);
185 Plugin::Any any;
186 res = filter->GetParameter(PARA_RENDER_INFO, any);
187 CHECK_AND_RETURN_LOG(res == ErrorCode::SUCCESS, "FilterDelegatePushData: get param fail! key=%{public}s",
188 PARA_RENDER_INFO);
189
190 auto &context = Plugin::AnyCast<std::shared_ptr<EffectContext> &>(any);
191 EFFECT_LOGE("OH_EffectFilter PushData bufferType %{public}d", effectBuffer->extraInfo_->bufferType);
192 filter->filter_->PushData(effectBuffer.get(), context);
193 return;
194 }
195
196 std::shared_ptr<BufferInfo> bufferInfo = std::make_unique<BufferInfo>();
197 bufferInfo->width_ = static_cast<uint32_t>(dst->width);
198 bufferInfo->height_ = static_cast<uint32_t>(dst->height);
199 bufferInfo->rowStride_ = static_cast<uint32_t>(dst->rowSize);
200 NativeCommonUtils::SwitchToFormatType(dst->format, bufferInfo->formatType_);
201 bufferInfo->len_ =
202 FormatHelper::CalculateDataRowCount(bufferInfo->height_, bufferInfo->formatType_) * bufferInfo->rowStride_;
203 std::shared_ptr<ExtraInfo> extraInfo = std::make_unique<ExtraInfo>();
204 *extraInfo = *src->extraInfo_;
205 extraInfo->bufferType = BufferType::DEFAULT;
206 extraInfo->surfaceBuffer = nullptr;
207 std::shared_ptr<EffectBuffer> effectBuffer = std::make_shared<EffectBuffer>(bufferInfo, dst->addr, extraInfo);
208
209 Plugin::Any any;
210 res = filter->GetParameter(PARA_RENDER_INFO, any);
211 CHECK_AND_RETURN_LOG(res == ErrorCode::SUCCESS, "FilterDelegatePushData: get param fail! key=%{public}s",
212 PARA_RENDER_INFO);
213
214 auto &context = Plugin::AnyCast<std::shared_ptr<EffectContext> &>(any);
215 filter->filter_->PushData(effectBuffer.get(), context);
216 }
217 private:
218 OH_EffectFilterInfo ohInfo_;
219 const ImageEffect_FilterDelegate *ohDelegate_;
220 };
221
~OH_EffectFilterInfo()222 OH_EffectFilterInfo::~OH_EffectFilterInfo()
223 {
224 if (effectBufferType != nullptr) {
225 delete[] effectBufferType;
226 effectBufferType = nullptr;
227 }
228 if (effectFormat != nullptr) {
229 delete[] effectFormat;
230 effectFormat = nullptr;
231 }
232 }
233
234 #ifdef __cplusplus
235 extern "C" {
236 #endif
237
238 EFFECT_EXPORT
OH_EffectFilterInfo_Create()239 OH_EffectFilterInfo *OH_EffectFilterInfo_Create()
240 {
241 std::unique_ptr<OH_EffectFilterInfo> info = std::make_unique<OH_EffectFilterInfo>();
242 return info.release();
243 }
244
245 EFFECT_EXPORT
OH_EffectFilterInfo_SetFilterName(OH_EffectFilterInfo * info,const char * name)246 ImageEffect_ErrorCode OH_EffectFilterInfo_SetFilterName(OH_EffectFilterInfo *info, const char *name)
247 {
248 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
249 "InfoSetFilterName: input parameter info is null!");
250 CHECK_AND_RETURN_RET_LOG(name != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
251 "InfoSetFilterName: input parameter name is null!");
252 CHECK_AND_RETURN_RET_LOG(strlen(name) < MAX_CHAR_LEN, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
253 "InfoSetFilterName: the length of input parameter name is too long! len = %{public}zu", strlen(name));
254 EFFECT_LOGD("Set filter name. name=%{public}s", name);
255 info->filterName = name;
256 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
257 }
258
259 EFFECT_EXPORT
OH_EffectFilterInfo_GetFilterName(OH_EffectFilterInfo * info,char ** name)260 ImageEffect_ErrorCode OH_EffectFilterInfo_GetFilterName(OH_EffectFilterInfo *info, char **name)
261 {
262 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
263 "InfoGetFilterName: input parameter info is null!");
264 CHECK_AND_RETURN_RET_LOG(name != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
265 "InfoGetFilterName: input parameter name is null!");
266
267 *name = const_cast<char *>(info->filterName.c_str());
268 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
269 }
270
271 EFFECT_EXPORT
OH_EffectFilterInfo_SetSupportedBufferTypes(OH_EffectFilterInfo * info,uint32_t size,ImageEffect_BufferType * bufferTypeArray)272 ImageEffect_ErrorCode OH_EffectFilterInfo_SetSupportedBufferTypes(OH_EffectFilterInfo *info, uint32_t size,
273 ImageEffect_BufferType *bufferTypeArray)
274 {
275 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
276 "InfoSetSupportedBufferTypes: input parameter info is null!");
277 CHECK_AND_RETURN_RET_LOG(size > 0, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
278 "InfoSetSupportedBufferTypes: input parameter size is invalid! size=%{public}d", size);
279 CHECK_AND_RETURN_RET_LOG(bufferTypeArray != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
280 "InfoSetSupportedBufferTypes: input parameter bufferTypeArray is null!");
281 EFFECT_LOGD("Set supported buffer types. size=%{public}d", size);
282 info->supportedBufferTypes.clear();
283 for (uint32_t index = 0; index < size; index++) {
284 info->supportedBufferTypes.emplace(bufferTypeArray[index]);
285 }
286 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
287 }
288
289 EFFECT_EXPORT
OH_EffectFilterInfo_GetSupportedBufferTypes(OH_EffectFilterInfo * info,uint32_t * size,ImageEffect_BufferType ** bufferTypeArray)290 ImageEffect_ErrorCode OH_EffectFilterInfo_GetSupportedBufferTypes(OH_EffectFilterInfo *info, uint32_t *size,
291 ImageEffect_BufferType **bufferTypeArray)
292 {
293 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
294 "InfoGetSupportedBufferTypes: input parameter info is null!");
295 CHECK_AND_RETURN_RET_LOG(size != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
296 "InfoGetSupportedBufferTypes: input parameter size is invalid!");
297 CHECK_AND_RETURN_RET_LOG(bufferTypeArray != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
298 "InfoGetSupportedBufferTypes: input parameter bufferTypeArray is null!");
299
300 if (info->supportedBufferTypes.empty()) {
301 *size = 0;
302 *bufferTypeArray = nullptr;
303 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
304 }
305
306 auto bufferTypeRealSize = static_cast<uint32_t>(info->supportedBufferTypes.size());
307 if (bufferTypeRealSize > info->bufferTypeArraySize && info->effectBufferType != nullptr) {
308 delete[] info->effectBufferType;
309 info->effectBufferType = nullptr;
310 info->bufferTypeArraySize = 0;
311 }
312
313 if (info->effectBufferType == nullptr) {
314 std::unique_ptr<ImageEffect_BufferType[]> bufferType =
315 std::make_unique<ImageEffect_BufferType[]>(bufferTypeRealSize);
316 info->effectBufferType = bufferType.release();
317 info->bufferTypeArraySize = bufferTypeRealSize;
318 }
319
320 uint32_t index = 0;
321 for (const auto &bufferType : info->supportedBufferTypes) {
322 if (index >= info->bufferTypeArraySize) {
323 EFFECT_LOGW("supportedBufferTypes size over bufferTypeArraySize! supportedBufferTypesSize=%{public}zu, "
324 "bufferTypeArraySize=%{public}d", info->supportedBufferTypes.size(), info->bufferTypeArraySize);
325 break;
326 }
327 info->effectBufferType[index] = bufferType;
328 index++;
329 }
330 *size = index;
331 *bufferTypeArray = info->effectBufferType;
332
333 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
334 }
335
336 EFFECT_EXPORT
OH_EffectFilterInfo_SetSupportedFormats(OH_EffectFilterInfo * info,uint32_t size,ImageEffect_Format * formatArray)337 ImageEffect_ErrorCode OH_EffectFilterInfo_SetSupportedFormats(OH_EffectFilterInfo *info, uint32_t size,
338 ImageEffect_Format *formatArray)
339 {
340 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
341 "InfoSetSupportedFormats: input parameter info is null!");
342 CHECK_AND_RETURN_RET_LOG(size > 0, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
343 "InfoSetSupportedFormats: input parameter size is invalid! size=%{public}d", size);
344 CHECK_AND_RETURN_RET_LOG(formatArray != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
345 "InfoSetSupportedFormats: input parameter formatArray is null!");
346 EFFECT_LOGD("Set supported formats. size=%{public}d", size);
347 info->supportedFormats.clear();
348 for (uint32_t index = 0; index < size; index++) {
349 info->supportedFormats.emplace(formatArray[index]);
350 }
351 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
352 }
353
354 EFFECT_EXPORT
OH_EffectFilterInfo_GetSupportedFormats(OH_EffectFilterInfo * info,uint32_t * size,ImageEffect_Format ** formatArray)355 ImageEffect_ErrorCode OH_EffectFilterInfo_GetSupportedFormats(OH_EffectFilterInfo *info, uint32_t *size,
356 ImageEffect_Format **formatArray)
357 {
358 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
359 "InfoGetSupportedFormats: input parameter info is null!");
360 CHECK_AND_RETURN_RET_LOG(size != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
361 "InfoGetSupportedFormats: input parameter size is invalid!");
362 CHECK_AND_RETURN_RET_LOG(formatArray != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
363 "InfoGetSupportedFormats: input parameter formatArray is null!");
364
365 if (info->supportedFormats.empty()) {
366 *size = 0;
367 *formatArray = nullptr;
368 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
369 }
370
371 auto formatsRealSize = static_cast<uint32_t>(info->supportedFormats.size());
372 if (formatsRealSize > info->formatArraySize && info->effectFormat != nullptr) {
373 delete[] info->effectFormat;
374 info->effectFormat = nullptr;
375 info->formatArraySize = 0;
376 }
377
378 if (info->effectFormat == nullptr) {
379 std::unique_ptr<ImageEffect_Format []> bufferType = std::make_unique<ImageEffect_Format[]>(formatsRealSize);
380 info->effectFormat = bufferType.release();
381 info->formatArraySize = formatsRealSize;
382 }
383
384 uint32_t index = 0;
385 for (const auto &format : info->supportedFormats) {
386 if (index >= info->formatArraySize) {
387 EFFECT_LOGW("supportedFormats size over formatArraySize! supportedFormatsSize=%{public}zu, "
388 "formatArraySize=%{public}d", info->supportedFormats.size(), info->formatArraySize);
389 break;
390 }
391 info->effectFormat[index] = format;
392 index++;
393 }
394 *size = index;
395 *formatArray = info->effectFormat;
396
397 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
398 }
399
400 EFFECT_EXPORT
OH_EffectFilterInfo_Release(OH_EffectFilterInfo * info)401 ImageEffect_ErrorCode OH_EffectFilterInfo_Release(OH_EffectFilterInfo *info)
402 {
403 EFFECT_LOGD("Filter release info.");
404 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
405 "ReleaseInfo: input parameter info is null!");
406 delete (info);
407 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
408 }
409
410 EFFECT_EXPORT
OH_EffectBufferInfo_Create()411 OH_EffectBufferInfo *OH_EffectBufferInfo_Create()
412 {
413 std::unique_ptr<OH_EffectBufferInfo> info = std::make_unique<OH_EffectBufferInfo>();
414 return info.release();
415 }
416
417 EFFECT_EXPORT
OH_EffectBufferInfo_SetAddr(OH_EffectBufferInfo * info,void * addr)418 ImageEffect_ErrorCode OH_EffectBufferInfo_SetAddr(OH_EffectBufferInfo *info, void *addr)
419 {
420 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
421 "BufferInfoSetAddr: input parameter info is null!");
422 CHECK_AND_RETURN_RET_LOG(addr != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
423 "BufferInfoSetAddr: input parameter addr is null!");
424 EFFECT_LOGD("Set buffer info addr.");
425 info->addr = addr;
426 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
427 }
428
429 EFFECT_EXPORT
OH_EffectBufferInfo_GetAddr(OH_EffectBufferInfo * info,void ** addr)430 ImageEffect_ErrorCode OH_EffectBufferInfo_GetAddr(OH_EffectBufferInfo *info, void **addr)
431 {
432 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
433 "BufferInfoGetAddr: input parameter info is null!");
434 CHECK_AND_RETURN_RET_LOG(addr != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
435 "BufferInfoGetAddr: input parameter addr is null!");
436
437 *addr = info->addr;
438 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
439 }
440
441 EFFECT_EXPORT
OH_EffectBufferInfo_SetWidth(OH_EffectBufferInfo * info,int32_t width)442 ImageEffect_ErrorCode OH_EffectBufferInfo_SetWidth(OH_EffectBufferInfo *info, int32_t width)
443 {
444 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
445 "BufferInfoSetWidth: input parameter info is null!");
446 EFFECT_LOGD("BufferInfoSetWidth: width=%{public}d", width);
447 info->width = width;
448 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
449 }
450
451 EFFECT_EXPORT
OH_EffectBufferInfo_GetWidth(OH_EffectBufferInfo * info,int32_t * width)452 ImageEffect_ErrorCode OH_EffectBufferInfo_GetWidth(OH_EffectBufferInfo *info, int32_t *width)
453 {
454 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
455 "BufferInfoGetWidth: input parameter info is null!");
456 CHECK_AND_RETURN_RET_LOG(width != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
457 "BufferInfoGetWidth: input parameter width is null!");
458
459 *width = info->width;
460 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
461 }
462
463 EFFECT_EXPORT
OH_EffectBufferInfo_SetHeight(OH_EffectBufferInfo * info,int32_t height)464 ImageEffect_ErrorCode OH_EffectBufferInfo_SetHeight(OH_EffectBufferInfo *info, int32_t height)
465 {
466 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
467 "BufferInfoSetHeight: input parameter info is null!");
468 EFFECT_LOGD("BufferInfoSetHeight: height=%{public}d", height);
469 info->height = height;
470 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
471 }
472
473 EFFECT_EXPORT
OH_EffectBufferInfo_GetHeight(OH_EffectBufferInfo * info,int32_t * height)474 ImageEffect_ErrorCode OH_EffectBufferInfo_GetHeight(OH_EffectBufferInfo *info, int32_t *height)
475 {
476 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
477 "BufferInfoGetHeight: input parameter info is null!");
478 CHECK_AND_RETURN_RET_LOG(height != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
479 "BufferInfoGetHeight: input parameter height is null!");
480
481 *height = info->height;
482 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
483 }
484
485 EFFECT_EXPORT
OH_EffectBufferInfo_SetRowSize(OH_EffectBufferInfo * info,int32_t rowSize)486 ImageEffect_ErrorCode OH_EffectBufferInfo_SetRowSize(OH_EffectBufferInfo *info, int32_t rowSize)
487 {
488 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
489 "BufferInfoSetRowSize: input parameter info is null!");
490 EFFECT_LOGD("BufferInfoSetRowSize: rowSize=%{public}d", rowSize);
491 info->rowSize = rowSize;
492 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
493 }
494
495 EFFECT_EXPORT
OH_EffectBufferInfo_GetRowSize(OH_EffectBufferInfo * info,int32_t * rowSize)496 ImageEffect_ErrorCode OH_EffectBufferInfo_GetRowSize(OH_EffectBufferInfo *info, int32_t *rowSize)
497 {
498 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
499 "BufferInfoGetRowSize: input parameter info is null!");
500 CHECK_AND_RETURN_RET_LOG(rowSize != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
501 "BufferInfoGetRowSize: input parameter rowSize is null!");
502
503 *rowSize = info->rowSize;
504 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
505 }
506
507 EFFECT_EXPORT
OH_EffectBufferInfo_SetEffectFormat(OH_EffectBufferInfo * info,ImageEffect_Format format)508 ImageEffect_ErrorCode OH_EffectBufferInfo_SetEffectFormat(OH_EffectBufferInfo *info, ImageEffect_Format format)
509 {
510 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
511 "BufferInfoSetEffectFormat: input parameter info is null!");
512 EFFECT_LOGD("BufferInfoSetEffectFormat: format=%{public}d", format);
513 info->format = format;
514 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
515 }
516
517 EFFECT_EXPORT
OH_EffectBufferInfo_GetEffectFormat(OH_EffectBufferInfo * info,ImageEffect_Format * format)518 ImageEffect_ErrorCode OH_EffectBufferInfo_GetEffectFormat(OH_EffectBufferInfo *info, ImageEffect_Format *format)
519 {
520 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
521 "BufferInfoGetEffectFormat: input parameter info is null!");
522 CHECK_AND_RETURN_RET_LOG(format != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
523 "BufferInfoGetEffectFormat: input parameter format is null!");
524
525 *format = info->format;
526 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
527 }
528
529 EFFECT_EXPORT
OH_EffectBufferInfo_SetTimestamp(OH_EffectBufferInfo * info,int64_t timestamp)530 ImageEffect_ErrorCode OH_EffectBufferInfo_SetTimestamp(OH_EffectBufferInfo *info, int64_t timestamp)
531 {
532 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
533 "BufferInfoSetTimestamp: input parameter info is null!");
534 EFFECT_LOGD("BufferInfoSetTimestamp: timestamp=%{public}lld", static_cast<long long>(timestamp));
535 info->timestamp = timestamp;
536 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
537 }
538
539 EFFECT_EXPORT
OH_EffectBufferInfo_GetTimestamp(OH_EffectBufferInfo * info,int64_t * timestamp)540 ImageEffect_ErrorCode OH_EffectBufferInfo_GetTimestamp(OH_EffectBufferInfo *info, int64_t *timestamp)
541 {
542 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
543 "BufferInfoGetTimestamp: input parameter info is null!");
544 CHECK_AND_RETURN_RET_LOG(timestamp != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
545 "BufferInfoGetTimestamp: input parameter timestamp is null!");
546
547 *timestamp = info->timestamp;
548 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
549 }
550
551 EFFECT_EXPORT
OH_EffectBufferInfo_Release(OH_EffectBufferInfo * info)552 ImageEffect_ErrorCode OH_EffectBufferInfo_Release(OH_EffectBufferInfo *info)
553 {
554 EFFECT_LOGD("Filter release buffer info.");
555 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
556 "EffectFilter ReleaseBufferInfo: input parameter info is null!");
557 delete (info);
558 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
559 }
560
561 EFFECT_EXPORT
OH_EffectFilter_Create(const char * name)562 OH_EffectFilter *OH_EffectFilter_Create(const char *name)
563 {
564 CHECK_AND_RETURN_RET_LOG(name != nullptr, nullptr, "FilterCreate: input parameter name is null!");
565 CHECK_AND_RETURN_RET_LOG(strlen(name) < MAX_CHAR_LEN, nullptr,
566 "FilterCreate: the length of input parameter name is too long! len = %{public}zu", strlen(name));
567 EFFECT_LOGI("Filter create. name=%{public}s", name);
568 std::unique_ptr<OH_EffectFilter> nativeEFilter = std::make_unique<OH_EffectFilter>();
569 std::shared_ptr<EFilter> filter = EFilterFactory::Instance()->Create(name, nativeEFilter.get());
570 if (filter == nullptr) {
571 EFFECT_LOGW("FilterCreate: create filter fail. name=%{public}s not exist!", name);
572 return nullptr;
573 }
574 nativeEFilter->filter_ = filter;
575 return nativeEFilter.release();
576 }
577
578 EFFECT_EXPORT
OH_EffectFilter_SetValue(OH_EffectFilter * filter,const char * key,const ImageEffect_Any * value)579 ImageEffect_ErrorCode OH_EffectFilter_SetValue(OH_EffectFilter *filter, const char *key, const ImageEffect_Any *value)
580 {
581 CHECK_AND_RETURN_RET_LOG(filter != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
582 "FilterSetValue: input parameter filter is null!");
583 CHECK_AND_RETURN_RET_LOG(key != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
584 "FilterSetValue: input parameter key is null!");
585 CHECK_AND_RETURN_RET_LOG(strlen(key) < MAX_CHAR_LEN, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
586 "FilterSetValue: the length of input parameter key is too long! len = %{public}zu", strlen(key));
587 CHECK_AND_RETURN_RET_LOG(value != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
588 "FilterSetValue: input parameter value is null!");
589 EFFECT_LOGI("Effect filter set value. key=%{public}s", key);
590
591 Plugin::Any any;
592 ErrorCode result = NativeCommonUtils::ParseOHAny(value, any);
593 if (result != ErrorCode::SUCCESS) {
594 EFFECT_LOGE("FilterSetValue: parse any fail! result=%{public}d, dataType=%{public}d", result, value->dataType);
595 return ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID;
596 }
597
598 result = filter->filter_->SetValue(key, any);
599 if (result != ErrorCode::SUCCESS) {
600 EFFECT_LOGE("FilterSetValue: set value fail! result=%{public}d, key=%{public}s, dataType=%{public}d", result,
601 key, value->dataType);
602 return ImageEffect_ErrorCode::EFFECT_KEY_ERROR;
603 }
604
605 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
606 }
607
608 EFFECT_EXPORT
OH_EffectFilter_GetValue(OH_EffectFilter * nativeEFilter,const char * key,ImageEffect_Any * value)609 ImageEffect_ErrorCode OH_EffectFilter_GetValue(OH_EffectFilter *nativeEFilter, const char *key, ImageEffect_Any *value)
610 {
611 CHECK_AND_RETURN_RET_LOG(nativeEFilter != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
612 "FilterGetValue: input parameter nativeEFilter is null!");
613 CHECK_AND_RETURN_RET_LOG(key != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
614 "FilterGetValue: input parameter key is null!");
615 CHECK_AND_RETURN_RET_LOG(strlen(key) < MAX_CHAR_LEN, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
616 "FilterGetValue: the length of input parameter key is too long! len = %{public}zu", strlen(key));
617 CHECK_AND_RETURN_RET_LOG(value != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
618 "FilterGetValue: input parameter value is null!");
619 EFFECT_LOGD("Effect filter get value. key=%{public}s", key);
620
621 if (strcmp("FILTER_NAME", key) == 0) {
622 value->dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_PTR;
623 value->dataValue.ptrValue = static_cast<void *>(const_cast<char *>(nativeEFilter->filter_->GetName().c_str()));
624 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
625 }
626
627 Plugin::Any any;
628 ErrorCode result = nativeEFilter->filter_->GetValue(key, any);
629 if (result != ErrorCode::SUCCESS) {
630 EFFECT_LOGE("FilterGetValue: get value fail! result=%{public}d, key=%{public}s", result, key);
631 return ImageEffect_ErrorCode::EFFECT_KEY_ERROR;
632 }
633
634 result = NativeCommonUtils::SwitchToOHAny(any, value);
635 if (result != ErrorCode::SUCCESS) {
636 EFFECT_LOGE("FilterGetValue: get value fail! result=%{public}d, key=%{public}s", result, key);
637 return ImageEffect_ErrorCode::EFFECT_UNKNOWN;
638 }
639
640 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
641 }
642
643 EFFECT_EXPORT
OH_EffectFilter_Register(const OH_EffectFilterInfo * info,const ImageEffect_FilterDelegate * delegate)644 ImageEffect_ErrorCode OH_EffectFilter_Register(const OH_EffectFilterInfo *info,
645 const ImageEffect_FilterDelegate *delegate)
646 {
647 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
648 "RegisterFilter: input parameter info is null!");
649 CHECK_AND_RETURN_RET_LOG(delegate != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
650 "RegisterFilter: input parameter delegate is null!");
651 EFFECT_LOGI("Filter register. filterName=%{public}s", info->filterName.c_str());
652 std::shared_ptr<FilterDelegate> effectDelegate = std::make_shared<FilterDelegate>(info, delegate);
653
654 std::shared_ptr<EffectInfo> effectInfo = std::make_shared<EffectInfo>();
655 NativeCommonUtils::SwitchToEffectInfo(info, effectInfo);
656 EFilterFactory::Instance()->RegisterDelegate(info->filterName, effectDelegate, effectInfo);
657
658 EventInfo eventInfo = {
659 .filterName = info->filterName,
660 .supportedFormats = NativeCommonUtils::GetSupportedFormats(info),
661 };
662 EventReport::ReportHiSysEvent(REGISTER_CUSTOM_FILTER_STATISTIC, eventInfo);
663 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
664 }
665
666 EFFECT_EXPORT
OH_EffectFilter_LookupFilters(const char * key)667 ImageEffect_FilterNames *OH_EffectFilter_LookupFilters(const char *key)
668 {
669 std::unique_lock<std::mutex> lock(filterMutex_);
670 CHECK_AND_RETURN_RET_LOG(key != nullptr, nullptr, "LookupFilters: input parameter key is null!");
671 CHECK_AND_RETURN_RET_LOG(strlen(key) < MAX_CHAR_LEN, nullptr,
672 "LookupFilters: the length of input parameter key is too long! len = %{public}zu", strlen(key));
673 EFFECT_LOGD("Lookup filters. key=%{public}s", key);
674
675 std::string lookupKey = key;
676 std::vector<const char *> matchEFilter;
677 NativeCommonUtils::ParseLookupKey(lookupKey, matchEFilter);
678
679 std::shared_ptr<ImageEffect_FilterNames> filterNames = std::make_shared<ImageEffect_FilterNames>();
680 filterNames->size = matchEFilter.size();
681 if (filterNames->size != 0) {
682 const char **buffer = (const char **)malloc(matchEFilter.size() * sizeof(const char *));
683 if (buffer != nullptr) {
684 for (size_t i = 0; i < matchEFilter.size(); i++) {
685 buffer[i] = matchEFilter[i];
686 }
687 filterNames->nameList = buffer;
688 }
689 }
690 sOHFilterNames.emplace_back(filterNames);
691
692 return filterNames.get();
693 }
694
695 EFFECT_EXPORT
OH_EffectFilter_ReleaseFilterNames()696 void OH_EffectFilter_ReleaseFilterNames()
697 {
698 std::unique_lock<std::mutex> lock(filterMutex_);
699 EFFECT_LOGI("Release filter names.");
700 for (const auto &filterNames : sOHFilterNames) {
701 if (filterNames == nullptr) {
702 continue;
703 }
704 free(filterNames->nameList);
705 }
706 sOHFilterNames.clear();
707 }
708
709 EFFECT_EXPORT
OH_EffectFilter_LookupFilterInfo(const char * name,OH_EffectFilterInfo * info)710 ImageEffect_ErrorCode OH_EffectFilter_LookupFilterInfo(const char *name, OH_EffectFilterInfo *info)
711 {
712 CHECK_AND_RETURN_RET_LOG(name != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
713 "LookupFilterInfo: input parameter name is null!");
714 CHECK_AND_RETURN_RET_LOG(strlen(name) < MAX_CHAR_LEN, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
715 "LookupFilterInfo: the length of input parameter name is too long! len = %{public}zu", strlen(name));
716 CHECK_AND_RETURN_RET_LOG(info != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
717 "LookupFilterInfo: input parameter info is null!");
718 EFFECT_LOGD("Lookup filter info. name=%{public}s", name);
719
720 std::shared_ptr<IFilterDelegate> filterDelegate = EFilterFactory::Instance()->GetDelegate(name);
721 if (filterDelegate != nullptr) {
722 auto effectInfo = static_cast<OH_EffectFilterInfo *>(filterDelegate->GetEffectInfo());
723 CHECK_AND_RETURN_RET_LOG(effectInfo != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
724 "LookupFilterInfo: filter delegate get effect info is null! name=%{public}s", name);
725 *info = *effectInfo;
726 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
727 }
728
729 std::shared_ptr<EffectInfo> effectInfo = EFilterFactory::Instance()->GetEffectInfo(name);
730 CHECK_AND_RETURN_RET_LOG(effectInfo != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
731 "LookupFilterInfo: lookup fail! name=%{public}s", name);
732
733 info->filterName = name;
734 NativeCommonUtils::SwitchToOHEffectInfo(effectInfo.get(), info);
735 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
736 }
737
738 EFFECT_EXPORT
OH_EffectFilter_Render(OH_EffectFilter * filter,OH_PixelmapNative * inputPixelmap,OH_PixelmapNative * outputPixelmap)739 ImageEffect_ErrorCode OH_EffectFilter_Render(OH_EffectFilter *filter, OH_PixelmapNative *inputPixelmap,
740 OH_PixelmapNative *outputPixelmap)
741 {
742 EFFECT_LOGI("Filter render.");
743 CHECK_AND_RETURN_RET_LOG(filter != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
744 "FilterRender: input parameter filter is null!");
745 if (filter->filter_->IsTextureInput()) {
746 std::shared_ptr<EffectBuffer> tempEffectBuffer = nullptr;
747 ErrorCode res = filter->filter_->Render(tempEffectBuffer, tempEffectBuffer);
748 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, ImageEffect_ErrorCode::EFFECT_UNKNOWN,
749 "FilterRender: filter render fail! errorCode:%{public}d", res);
750 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
751 }
752 CHECK_AND_RETURN_RET_LOG(inputPixelmap != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
753 "FilterRender: input parameter inputPixelmap is null!");
754 CHECK_AND_RETURN_RET_LOG(outputPixelmap != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
755 "FilterRender: input parameter outputPixelmap is null!");
756
757 PixelMap *input = NativeCommonUtils::GetPixelMapFromOHPixelmap(inputPixelmap);
758 PixelMap *output = NativeCommonUtils::GetPixelMapFromOHPixelmap(outputPixelmap);
759
760 std::shared_ptr<EffectBuffer> inEffectBuffer = nullptr;
761 ErrorCode result = CommonUtils::LockPixelMap(input, inEffectBuffer);
762 if (result != ErrorCode::SUCCESS || inEffectBuffer == nullptr) {
763 EFFECT_LOGE("FilterRender: lock input native pixelMap error! errorCode:%{public}d", result);
764 CommonUtils::UnlockPixelMap(input);
765 return ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID;
766 }
767
768 std::shared_ptr<EffectBuffer> outEffectBuffer = nullptr;
769 result = CommonUtils::LockPixelMap(output, outEffectBuffer);
770 if (result != ErrorCode::SUCCESS || outEffectBuffer == nullptr) {
771 EFFECT_LOGE("FilterRender: lock output native pixelMap error! errorCode:%{public}d", result);
772 CommonUtils::UnlockPixelMap(output);
773 return ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID;
774 }
775
776 filter->filter_->PreRender(inEffectBuffer->bufferInfo_->formatType_);
777 result = filter->filter_->Render(inEffectBuffer, outEffectBuffer);
778 CommonUtils::UnlockPixelMap(input);
779 CommonUtils::UnlockPixelMap(output);
780 CHECK_AND_RETURN_RET_LOG(result == ErrorCode::SUCCESS, ImageEffect_ErrorCode::EFFECT_UNKNOWN,
781 "FilterRender: filter render fail! errorCode:%{public}d", result);
782
783 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
784 }
785
786 EFFECT_EXPORT
OH_EffectFilter_Release(OH_EffectFilter * filter)787 ImageEffect_ErrorCode OH_EffectFilter_Release(OH_EffectFilter *filter)
788 {
789 EFFECT_LOGI("Effect filter release.");
790 CHECK_AND_RETURN_RET_LOG(filter != nullptr, ImageEffect_ErrorCode::EFFECT_ERROR_PARAM_INVALID,
791 "FilterRelease: input parameter imageEffect is null!");
792 delete (filter);
793 return ImageEffect_ErrorCode::EFFECT_SUCCESS;
794 }
795 #ifdef __cplusplus
796 }
797 #endif