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_inner.h"
17
18 #include <cassert>
19 #include <securec.h>
20 #include <algorithm>
21 #include <sync_fence.h>
22 #include <thread>
23
24 #include "qos.h"
25 #include "metadata_helper.h"
26 #include "common_utils.h"
27 #include "filter_factory.h"
28 #include "image_sink_filter.h"
29 #include "image_source_filter.h"
30 #include "effect_surface_adapter.h"
31 #include "pipeline_core.h"
32 #include "effect_json_helper.h"
33 #include "efilter_factory.h"
34 #include "external_loader.h"
35 #include "effect_context.h"
36 #include "colorspace_helper.h"
37 #include "memcpy_helper.h"
38
39 #include "v1_1/buffer_handle_meta_key_type.h"
40 #include "effect_log.h"
41 #include "effect_trace.h"
42 #include "render_task.h"
43 #include "render_environment.h"
44 #include "native_window.h"
45 #include "image_source.h"
46 #include "capability_negotiate.h"
47
48 #define RENDER_QUEUE_SIZE 8
49 #define COMMON_TASK_TAG 0
50 namespace OHOS {
51 namespace Media {
52 namespace Effect {
53 using namespace OHOS::HDI::Display::Graphic::Common;
54
55 enum class EffectState {
56 IDLE,
57 RUNNING,
58 };
59
60 const int STRUCT_IMAGE_EFFECT_CONSTANT = 1;
61 const int DESTRUCTOR_IMAGE_EFFECT_CONSTANT = 2;
62 const int VIDEO_SINK_FILTER_STATUS = 3;
63 const std::string FUNCTION_FLUSH_SURFACE_BUFFER = "flushSurfaceBuffer";
64
65 class ImageEffect::Impl {
66 public:
Impl()67 Impl()
68 {
69 InitPipeline();
70 InitEffectContext();
71 }
72
73 void CreatePipeline(std::vector<std::shared_ptr<EFilter>> &efilters);
74
75 bool CheckEffectSurface() const;
76 GSError AcquireConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& syncFence,
77 int64_t& timestamp, OHOS::Rect& damages) const;
78 GSError ReleaseConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& syncFence) const;
79 GSError DetachConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer) const;
80 GSError AttachConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer) const;
81 private:
82 void InitPipeline();
83 void InitEffectContext();
84
85 public:
86 std::unique_ptr<EffectSurfaceAdapter> surfaceAdapter_;
87 std::shared_ptr<PipelineCore> pipeline_;
88 std::shared_ptr<ImageSourceFilter> srcFilter_;
89 std::shared_ptr<ImageSinkFilter> sinkFilter_;
90 std::shared_ptr<EffectContext> effectContext_;
91 EffectState effectState_ = EffectState::IDLE;
92 bool isQosEnabled_ = false;
93 };
94
InitPipeline()95 void ImageEffect::Impl::InitPipeline()
96 {
97 srcFilter_ = FilterFactory::Instance().CreateFilterWithType<ImageSourceFilter>(GET_FILTER_NAME(ImageSourceFilter));
98 sinkFilter_ = FilterFactory::Instance().CreateFilterWithType<ImageSinkFilter>(GET_FILTER_NAME(ImageSinkFilter));
99 CHECK_AND_RETURN(srcFilter_ != nullptr);
100 CHECK_AND_RETURN(sinkFilter_ != nullptr);
101 }
102
InitEffectContext()103 void ImageEffect::Impl::InitEffectContext()
104 {
105 effectContext_ = std::make_shared<EffectContext>();
106 effectContext_->memoryManager_ = std::make_shared<EffectMemoryManager>();
107 effectContext_->renderStrategy_ = std::make_shared<RenderStrategy>();
108 effectContext_->capNegotiate_ = std::make_shared<CapabilityNegotiate>();
109 effectContext_->renderEnvironment_ = std::make_shared<RenderEnvironment>();
110 effectContext_->colorSpaceManager_ = std::make_shared<ColorSpaceManager>();
111 effectContext_->cacheNegotiate_ = std::make_shared<EFilterCacheNegotiate>();
112 effectContext_->metaInfoNegotiate_ = std::make_shared<EfilterMetaInfoNegotiate>();
113 }
114
CreatePipeline(std::vector<std::shared_ptr<EFilter>> & efilters)115 void ImageEffect::Impl::CreatePipeline(std::vector<std::shared_ptr<EFilter>> &efilters)
116 {
117 pipeline_ = std::make_shared<PipelineCore>();
118 pipeline_->Init(nullptr);
119
120 CHECK_AND_RETURN_LOG(srcFilter_ != nullptr, "srcFilter is null");
121 std::vector<Filter *> filtersToPipeline; // Note: Filters must be inserted in sequence.
122 filtersToPipeline.push_back(srcFilter_.get());
123 for (const auto &eFilter : efilters) {
124 filtersToPipeline.push_back(eFilter.get());
125 }
126 filtersToPipeline.push_back(sinkFilter_.get());
127
128 ErrorCode res = pipeline_->AddFilters(filtersToPipeline);
129 CHECK_AND_RETURN_LOG(res == ErrorCode::SUCCESS, "pipeline add filters fail! res=%{public}d", res);
130
131 res = pipeline_->LinkFilters(filtersToPipeline);
132 CHECK_AND_RETURN_LOG(res == ErrorCode::SUCCESS, "pipeline link filter fail! res=%{public}d", res);
133 }
134
CheckEffectSurface() const135 bool ImageEffect::Impl::CheckEffectSurface() const
136 {
137 CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, false, "Impl::CheckEffectSurface: surfaceAdapter is nullptr");
138
139 return surfaceAdapter_->CheckEffectSurface();
140 }
141
AcquireConsumerSurfaceBuffer(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & syncFence,int64_t & timestamp,OHOS::Rect & damages) const142 GSError ImageEffect::Impl::AcquireConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& syncFence,
143 int64_t& timestamp, OHOS::Rect& damages) const
144 {
145 CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, GSERROR_NOT_INIT,
146 "Impl::AcquireConsumerSurfaceBuffer: surfaceAdapter is nullptr");
147
148 return surfaceAdapter_->AcquireConsumerSurfaceBuffer(buffer, syncFence, timestamp, damages);
149 }
150
ReleaseConsumerSurfaceBuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & syncFence) const151 GSError ImageEffect::Impl::ReleaseConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer,
152 const sptr<SyncFence>& syncFence) const
153 {
154 CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, GSERROR_NOT_INIT,
155 "Impl::ReleaseConsumerSurfaceBuffer: surfaceAdapter is nullptr");
156
157 return surfaceAdapter_->ReleaseConsumerSurfaceBuffer(buffer, syncFence);
158 }
159
DetachConsumerSurfaceBuffer(sptr<SurfaceBuffer> & buffer) const160 GSError ImageEffect::Impl::DetachConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer) const
161 {
162 CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, GSERROR_NOT_INIT,
163 "Impl::DetachConsumerSurfaceBuffer: surfaceAdapter is nullptr");
164
165 return surfaceAdapter_->DetachConsumerSurfaceBuffer(buffer);
166 }
167
AttachConsumerSurfaceBuffer(sptr<SurfaceBuffer> & buffer) const168 GSError ImageEffect::Impl::AttachConsumerSurfaceBuffer(sptr<SurfaceBuffer>& buffer) const
169 {
170 CHECK_AND_RETURN_RET_LOG(surfaceAdapter_ != nullptr, GSERROR_NOT_INIT,
171 "Impl::AttachConsumerSurfaceBuffer: surfaceAdapter is nullptr");
172
173 return surfaceAdapter_->AttachConsumerSurfaceBuffer(buffer);
174 }
175
176 struct EffectParameters {
EffectParametersOHOS::Media::Effect::EffectParameters177 EffectParameters(std::shared_ptr<EffectBuffer> &srcEffectBuffer, std::shared_ptr<EffectBuffer> &dstEffectBuffer,
178 std::map<ConfigType, Plugin::Any> &config, std::shared_ptr<EffectContext> &effectContext)
179 : srcEffectBuffer_(std::move(srcEffectBuffer)),
180 dstEffectBuffer_(std::move(dstEffectBuffer)),
181 config_(std::move(config)),
182 effectContext_(std::move(effectContext)) {};
183 std::shared_ptr<EffectBuffer> &&srcEffectBuffer_;
184 std::shared_ptr<EffectBuffer> &&dstEffectBuffer_;
185 std::map<ConfigType, Plugin::Any> &&config_;
186 std::shared_ptr<EffectContext> &&effectContext_;
187 };
188
189 enum class RunningType : int32_t {
190 DEFAULT = 0,
191 FOREGROUND = 1,
192 BACKGROUND = 2,
193 };
194
195 const std::vector<std::string> priorityEFilter_ = {
196 "Crop"
197 };
198 const std::unordered_map<std::string, ConfigType> configTypeTab_ = {
199 { "runningType", ConfigType::IPTYPE },
200 };
201 const std::unordered_map<int32_t, std::vector<IPType>> runningTypeTab_{
202 { std::underlying_type<RunningType>::type(RunningType::FOREGROUND), { IPType::CPU, IPType::GPU } },
203 { std::underlying_type<RunningType>::type(RunningType::BACKGROUND), { IPType::CPU } },
204 };
205
ImageEffect(const char * name)206 ImageEffect::ImageEffect(const char *name)
207 {
208 imageEffectFlag_ = STRUCT_IMAGE_EFFECT_CONSTANT;
209 impl_ = std::make_shared<Impl>();
210 if (name != nullptr) {
211 name_ = name;
212 }
213 ExternLoader::Instance()->InitExt();
214 ExtInitModule();
215
216 if (m_renderThread == nullptr) {
217 auto func = [this]() {
218 EFFECT_LOGW("ImageEffect has no render work to do!");
219 };
220 m_renderThread = new RenderThread<>(RENDER_QUEUE_SIZE, func);
221 m_renderThread->Start();
222 if (name != nullptr && strcmp(name, "Photo") == 0) {
223 auto task = std::make_shared<RenderTask<>>([this]() { this->InitEGLEnv(); }, COMMON_TASK_TAG,
224 RequestTaskId());
225 m_renderThread->AddTask(task);
226 task->Wait();
227 }
228 }
229 }
230
~ImageEffect()231 ImageEffect::~ImageEffect()
232 {
233 EFFECT_LOGI("ImageEffect destruct enter!");
234 if (failureCount_ > 0) {
235 EFFECT_LOGE("ImageEffect::SwapBuffers attach fail %{public}d times", failureCount_);
236 }
237 imageEffectFlag_ = DESTRUCTOR_IMAGE_EFFECT_CONSTANT;
238 impl_->surfaceAdapter_ = nullptr;
239 m_renderThread->ClearTask();
240 auto task = std::make_shared<RenderTask<>>([this]() { this->DestroyEGLEnv(); }, COMMON_TASK_TAG,
241 RequestTaskId());
242 m_renderThread->AddTask(task);
243 task->Wait();
244 EFFECT_LOGI("ImageEffect destruct destroy egl env!");
245 ExtDeinitModule();
246 m_renderThread->Stop();
247 delete m_renderThread;
248
249 impl_->effectContext_->renderEnvironment_ = nullptr;
250 if (toProducerSurface_) {
251 auto res = toProducerSurface_->Disconnect();
252 EFFECT_LOGI("ImageEffect::~ImageEffect disconnect res=%{public}d, id=%{public}" PRIu64,
253 res, toProducerSurface_->GetUniqueId());
254 toProducerSurface_ = nullptr;
255 }
256 fromProducerSurface_ = nullptr;
257 impl_ = nullptr;
258 EFFECT_LOGI("ImageEffect destruct end!");
259 }
260
AddEFilter(const std::shared_ptr<EFilter> & efilter)261 void ImageEffect::AddEFilter(const std::shared_ptr<EFilter> &efilter)
262 {
263 std::unique_lock<std::mutex> lock(innerEffectMutex_);
264 auto priorityEFilter = std::find_if(priorityEFilter_.begin(), priorityEFilter_.end(),
265 [&efilter](const std::string &name) { return name.compare(efilter->GetName()) == 0; });
266 if (priorityEFilter == priorityEFilter_.end()) {
267 efilters_.emplace_back(efilter);
268 } else {
269 auto result =
270 std::find_if(efilters_.rbegin(), efilters_.rend(), [&priorityEFilter](std::shared_ptr<EFilter> &efilter) {
271 return priorityEFilter->compare(efilter->GetName()) == 0;
272 });
273 if (result == efilters_.rend()) {
274 efilters_.insert(efilters_.begin(), efilter);
275 } else {
276 efilters_.insert(result.base(), efilter);
277 }
278 }
279
280 impl_->CreatePipeline(efilters_);
281 }
282
InsertEFilter(const std::shared_ptr<EFilter> & efilter,uint32_t index)283 ErrorCode ImageEffect::InsertEFilter(const std::shared_ptr<EFilter> &efilter, uint32_t index)
284 {
285 std::unique_lock<std::mutex> lock(innerEffectMutex_);
286 ErrorCode res = Effect::InsertEFilter(efilter, index);
287 if (res == ErrorCode::SUCCESS) {
288 impl_->CreatePipeline(efilters_);
289 }
290 return res;
291 }
292
RemoveEFilter(const std::shared_ptr<EFilter> & efilter)293 void ImageEffect::RemoveEFilter(const std::shared_ptr<EFilter> &efilter)
294 {
295 Effect::RemoveEFilter(efilter);
296 impl_->CreatePipeline(efilters_);
297 }
298
RemoveEFilter(uint32_t index)299 ErrorCode ImageEffect::RemoveEFilter(uint32_t index)
300 {
301 ErrorCode res = Effect::RemoveEFilter(index);
302 if (res == ErrorCode::SUCCESS) {
303 impl_->CreatePipeline(efilters_);
304 }
305 return res;
306 }
307
ReplaceEFilter(const std::shared_ptr<EFilter> & efilter,uint32_t index)308 ErrorCode ImageEffect::ReplaceEFilter(const std::shared_ptr<EFilter> &efilter, uint32_t index)
309 {
310 std::unique_lock<std::mutex> lock(innerEffectMutex_);
311 ErrorCode res = Effect::ReplaceEFilter(efilter, index);
312 if (res == ErrorCode::SUCCESS) {
313 impl_->CreatePipeline(efilters_);
314 }
315 return res;
316 }
317
RequestTaskId()318 unsigned long int ImageEffect::RequestTaskId()
319 {
320 return m_currentTaskId.fetch_add(1);
321 }
322
SetInputPixelMap(PixelMap * pixelMap)323 ErrorCode ImageEffect::SetInputPixelMap(PixelMap* pixelMap)
324 {
325 std::unique_lock<std::mutex> lock(innerEffectMutex_);
326 EFFECT_LOGD("ImageEffect::SetInputPixelMap");
327 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, ErrorCode::ERR_INVALID_SRC_PIXELMAP, "invalid source pixelMap");
328 impl_->effectContext_->renderEnvironment_->NotifyInputChanged();
329
330 ClearDataInfo(inDateInfo_);
331 inDateInfo_.dataType_ = DataType::PIXEL_MAP;
332 inDateInfo_.pixelMap_ = pixelMap;
333 return ErrorCode::SUCCESS;
334 }
335
ConfigSourceFilter(std::shared_ptr<ImageSourceFilter> & srcFilter,std::shared_ptr<EffectBuffer> & srcBuffer,std::shared_ptr<EffectContext> & context)336 ErrorCode ConfigSourceFilter(std::shared_ptr<ImageSourceFilter> &srcFilter, std::shared_ptr<EffectBuffer> &srcBuffer,
337 std::shared_ptr<EffectContext> &context)
338 {
339 CHECK_AND_RETURN_RET_LOG(srcFilter != nullptr, ErrorCode::ERR_INPUT_NULL, "srcFilter is null");
340
341 ErrorCode res = srcFilter->SetSource(srcBuffer, context);
342 FALSE_RETURN_MSG_E(res == ErrorCode::SUCCESS, res, "set source fail! res=%{public}d", res);
343
344 return ErrorCode::SUCCESS;
345 }
346
ConfigSinkFilter(std::shared_ptr<ImageSinkFilter> & sinkFilter,std::shared_ptr<EffectBuffer> & sinkBuffer)347 ErrorCode ConfigSinkFilter(std::shared_ptr<ImageSinkFilter> &sinkFilter, std::shared_ptr<EffectBuffer> &sinkBuffer)
348 {
349 CHECK_AND_RETURN_RET_LOG(sinkFilter != nullptr, ErrorCode::ERR_INPUT_NULL, "sinkFilter is null");
350
351 ErrorCode res = sinkFilter->SetSink(sinkBuffer);
352 FALSE_RETURN_MSG_E(res == ErrorCode::SUCCESS, res, "set sink fail! res=%{public}d", res);
353
354 return ErrorCode::SUCCESS;
355 }
356
GetConfigIPTypes(const std::map<ConfigType,Plugin::Any> & config,std::vector<IPType> & configIPTypes)357 void GetConfigIPTypes(const std::map<ConfigType, Plugin::Any> &config, std::vector<IPType> &configIPTypes)
358 {
359 auto it = config.find(ConfigType::IPTYPE);
360 if (it == config.end()) {
361 EFFECT_LOGE("ipType config not set! use default config.");
362 configIPTypes = { IPType::CPU, IPType::GPU };
363 return;
364 }
365
366 ErrorCode result = CommonUtils::ParseAny(it->second, configIPTypes);
367 if (result == ErrorCode::SUCCESS) {
368 return;
369 }
370 EFFECT_LOGE("parse ipType fail! use default config.");
371 configIPTypes = { IPType::CPU, IPType::GPU };
372 }
373
ChooseIPType(const std::shared_ptr<EffectBuffer> & srcEffectBuffer,const std::shared_ptr<EffectContext> & context,const std::map<ConfigType,Plugin::Any> & config,IPType & runningIPType)374 ErrorCode ChooseIPType(const std::shared_ptr<EffectBuffer> &srcEffectBuffer,
375 const std::shared_ptr<EffectContext> &context, const std::map<ConfigType, Plugin::Any> &config,
376 IPType &runningIPType)
377 {
378 std::vector<IPType> configIPTypes;
379 GetConfigIPTypes(config, configIPTypes);
380
381 runningIPType = IPType::DEFAULT;
382 IPType priorityIPType = IPType::GPU;
383 IEffectFormat effectFormat = srcEffectBuffer->bufferInfo_->formatType_;
384 const std::vector<std::shared_ptr<Capability>> &caps = context->capNegotiate_->GetCapabilityList();
385 for (const auto &capability : caps) {
386 if (capability == nullptr || capability->pixelFormatCap_ == nullptr) {
387 continue;
388 }
389 std::map<IEffectFormat, std::vector<IPType>> &formats = capability->pixelFormatCap_->formats;
390 if (runningIPType == IPType::GPU) {
391 effectFormat = IEffectFormat::RGBA8888;
392 }
393
394 auto it = formats.find(effectFormat);
395 if (it == formats.end()) {
396 EFFECT_LOGE("effectFormat not support! effectFormat=%{public}d, name=%{public}s",
397 effectFormat, capability->name_.c_str());
398 return ErrorCode::SUCCESS;
399 }
400
401 std::vector<IPType> &ipTypes = it->second;
402 if (std::find(configIPTypes.begin(), configIPTypes.end(), priorityIPType) != configIPTypes.end() &&
403 std::find(ipTypes.begin(), ipTypes.end(), priorityIPType) != ipTypes.end()) {
404 runningIPType = IPType::GPU;
405 } else {
406 if (runningIPType == IPType::DEFAULT) {
407 runningIPType = IPType::CPU;
408 }
409 return ErrorCode::SUCCESS;
410 }
411 }
412
413 return ErrorCode::SUCCESS;
414 }
415
ProcessPipelineTask(std::shared_ptr<PipelineCore> pipeline,const EffectParameters & effectParameters)416 ErrorCode ProcessPipelineTask(std::shared_ptr<PipelineCore> pipeline, const EffectParameters &effectParameters)
417 {
418 ErrorCode res = ColorSpaceHelper::ConvertColorSpace(effectParameters.srcEffectBuffer_,
419 effectParameters.effectContext_);
420 if (res != ErrorCode::SUCCESS) {
421 EFFECT_LOGE("ProcessPipelineTask:ConvertColorSpace fail! res=%{public}d", res);
422 return res;
423 }
424
425 IPType runningIPType;
426 res = ChooseIPType(effectParameters.srcEffectBuffer_, effectParameters.effectContext_, effectParameters.config_,
427 runningIPType);
428 if (res != ErrorCode::SUCCESS) {
429 EFFECT_LOGE("choose running ip type fail! res=%{public}d", res);
430 return res;
431 }
432 if (effectParameters.effectContext_->renderEnvironment_->GetEGLStatus() != EGLStatus::READY
433 && runningIPType == IPType::GPU) {
434 effectParameters.effectContext_->renderEnvironment_->Init();
435 effectParameters.effectContext_->renderEnvironment_->Prepare();
436 }
437 effectParameters.effectContext_->ipType_ = runningIPType;
438 effectParameters.effectContext_->memoryManager_->SetIPType(runningIPType);
439
440 res = pipeline->Start();
441 if (res != ErrorCode::SUCCESS) {
442 EFFECT_LOGE("pipeline start fail! res=%{public}d", res);
443 return res;
444 }
445 return ErrorCode::SUCCESS;
446 }
447
StartPipelineInner(std::shared_ptr<PipelineCore> & pipeline,const EffectParameters & effectParameters,unsigned long int taskId,RenderThread<> * thread,bool isNeedCreateThread=false)448 ErrorCode StartPipelineInner(std::shared_ptr<PipelineCore> &pipeline, const EffectParameters &effectParameters,
449 unsigned long int taskId, RenderThread<> *thread, bool isNeedCreateThread = false)
450 {
451 if (thread == nullptr) {
452 EFFECT_LOGE("pipeline Prepare fail! render thread is nullptr");
453 return ErrorCode::ERR_INVALID_OPERATION;
454 }
455
456 if (!isNeedCreateThread) {
457 return ProcessPipelineTask(pipeline, effectParameters);
458 } else {
459 auto prom = std::make_shared<std::promise<ErrorCode>>();
460 std::future<ErrorCode> fut = prom->get_future();
461 auto task = std::make_shared<RenderTask<>>([pipeline, &effectParameters, &prom]() {
462 auto res = ProcessPipelineTask(pipeline, effectParameters);
463 prom->set_value(res);
464 return;
465 }, 0, taskId);
466 thread->AddTask(task);
467 task->Wait();
468 ErrorCode res = fut.get();
469 return res;
470 }
471 return ErrorCode::SUCCESS;
472 }
473
StartPipeline(std::shared_ptr<PipelineCore> & pipeline,const EffectParameters & effectParameters,unsigned long int taskId,RenderThread<> * thread,bool isNeedCreateThread=false)474 ErrorCode StartPipeline(std::shared_ptr<PipelineCore> &pipeline, const EffectParameters &effectParameters,
475 unsigned long int taskId, RenderThread<> *thread, bool isNeedCreateThread = false)
476 {
477 effectParameters.effectContext_->renderStrategy_->Init(effectParameters.srcEffectBuffer_,
478 effectParameters.dstEffectBuffer_);
479 effectParameters.effectContext_->colorSpaceManager_->Init(effectParameters.srcEffectBuffer_,
480 effectParameters.dstEffectBuffer_);
481 effectParameters.effectContext_->memoryManager_->Init(effectParameters.srcEffectBuffer_,
482 effectParameters.dstEffectBuffer_);
483 ErrorCode res = StartPipelineInner(pipeline, effectParameters, taskId, thread, isNeedCreateThread);
484 effectParameters.effectContext_->memoryManager_->Deinit();
485 effectParameters.effectContext_->colorSpaceManager_->Deinit();
486 effectParameters.effectContext_->renderStrategy_->Deinit();
487 effectParameters.effectContext_->capNegotiate_->ClearNegotiateResult();
488 return res;
489 }
490
Start()491 ErrorCode ImageEffect::Start()
492 {
493 switch (inDateInfo_.dataType_) {
494 case DataType::PIXEL_MAP:
495 case DataType::SURFACE_BUFFER:
496 case DataType::URI:
497 case DataType::PATH:
498 case DataType::PICTURE: {
499 impl_->effectState_ = EffectState::RUNNING;
500 ErrorCode res = this->Render();
501 Stop();
502 return res;
503 }
504 case DataType::SURFACE:
505 impl_->effectState_ = EffectState::RUNNING;
506 if (impl_->surfaceAdapter_) {
507 impl_->surfaceAdapter_->ConsumerRequestCpuAccess(true);
508 }
509 break;
510 default:
511 EFFECT_LOGE("Not set input data!");
512 return ErrorCode::ERR_NOT_SET_INPUT_DATA;
513 }
514 return ErrorCode::SUCCESS;
515 }
516
Stop()517 void ImageEffect::Stop()
518 {
519 std::unique_lock<std::mutex> lock(innerEffectMutex_);
520 impl_->effectState_ = EffectState::IDLE;
521 if (impl_->surfaceAdapter_) {
522 impl_->surfaceAdapter_->ConsumerRequestCpuAccess(false);
523 }
524 impl_->effectContext_->memoryManager_->ClearMemory();
525 }
526
SetInputSurfaceBuffer(OHOS::SurfaceBuffer * surfaceBuffer)527 ErrorCode ImageEffect::SetInputSurfaceBuffer(OHOS::SurfaceBuffer *surfaceBuffer)
528 {
529 CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, ErrorCode::ERR_INVALID_SRC_SURFACEBUFFER,
530 "invalid source surface buffer");
531 if (needPreFlush_) {
532 surfaceBuffer->FlushCache();
533 }
534
535 ClearDataInfo(inDateInfo_);
536 inDateInfo_.dataType_ = DataType::SURFACE_BUFFER;
537 inDateInfo_.surfaceBufferInfo_.surfaceBuffer_ = surfaceBuffer;
538
539 return ErrorCode::SUCCESS;
540 }
541
SetOutputSurfaceBuffer(OHOS::SurfaceBuffer * surfaceBuffer)542 ErrorCode ImageEffect::SetOutputSurfaceBuffer(OHOS::SurfaceBuffer *surfaceBuffer)
543 {
544 ClearDataInfo(outDateInfo_);
545 if (surfaceBuffer == nullptr) {
546 EFFECT_LOGI("SetOutputSurfaceBuffer: surfaceBuffer set to null!");
547 return ErrorCode::SUCCESS;
548 }
549
550 outDateInfo_.dataType_ = DataType::SURFACE_BUFFER;
551 outDateInfo_.surfaceBufferInfo_.surfaceBuffer_ = surfaceBuffer;
552
553 return ErrorCode::SUCCESS;
554 }
555
SetInputUri(const std::string & uri)556 ErrorCode ImageEffect::SetInputUri(const std::string &uri)
557 {
558 EFFECT_LOGD("ImageEffect::SetInputUri");
559 if (!CommonUtils::EndsWithJPG(uri) && !CommonUtils::EndsWithHEIF(uri)) {
560 EFFECT_LOGE("SetInputUri: file type is not support! only support jpg/jpeg and heif.");
561 return ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT;
562 }
563 ClearDataInfo(inDateInfo_);
564 inDateInfo_.dataType_ = DataType::URI;
565 inDateInfo_.uri_ = std::move(uri);
566
567 return ErrorCode::SUCCESS;
568 }
569
SetOutputUri(const std::string & uri)570 ErrorCode ImageEffect::SetOutputUri(const std::string &uri)
571 {
572 EFFECT_LOGD("ImageEffect::SetOutputUri");
573 if (uri.empty()) {
574 EFFECT_LOGI("SetOutputUri: uri set to null!");
575 ClearDataInfo(outDateInfo_);
576 return ErrorCode::SUCCESS;
577 }
578
579 if (!CommonUtils::EndsWithJPG(uri) && !CommonUtils::EndsWithHEIF(uri)) {
580 EFFECT_LOGE("SetOutputUri: file type is not support! only support jpg/jpeg and heif.");
581 return ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT;
582 }
583 ClearDataInfo(outDateInfo_);
584 outDateInfo_.dataType_ = DataType::URI;
585 outDateInfo_.uri_ = std::move(uri);
586
587 return ErrorCode::SUCCESS;
588 }
589
SetInputPath(const std::string & path)590 ErrorCode ImageEffect::SetInputPath(const std::string &path)
591 {
592 EFFECT_LOGD("ImageEffect::SetInputPath");
593 if (!CommonUtils::EndsWithJPG(path) && !CommonUtils::EndsWithHEIF(path)) {
594 EFFECT_LOGE("SetInputPath: file type is not support! only support jpg/jpeg and heif.");
595 return ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT;
596 }
597 ClearDataInfo(inDateInfo_);
598 inDateInfo_.dataType_ = DataType::PATH;
599 inDateInfo_.path_ = std::move(path);
600
601 return ErrorCode::SUCCESS;
602 }
603
SetOutputPath(const std::string & path)604 ErrorCode ImageEffect::SetOutputPath(const std::string &path)
605 {
606 EFFECT_LOGD("ImageEffect::SetOutputPath");
607 if (path.empty()) {
608 EFFECT_LOGI("SetOutputPath: path set to null!");
609 ClearDataInfo(outDateInfo_);
610 return ErrorCode::SUCCESS;
611 }
612
613 if (!CommonUtils::EndsWithJPG(path) && !CommonUtils::EndsWithHEIF(path)) {
614 EFFECT_LOGE("SetOutputPath: file type is not support! only support jpg/jpeg and heif.");
615 return ErrorCode::ERR_FILE_TYPE_NOT_SUPPORT;
616 }
617 ClearDataInfo(outDateInfo_);
618 outDateInfo_.dataType_ = DataType::PATH;
619 outDateInfo_.path_ = std::move(path);
620
621 return ErrorCode::SUCCESS;
622 }
623
CheckToRenderPara(std::shared_ptr<EffectBuffer> & srcEffectBuffer,std::shared_ptr<EffectBuffer> & dstEffectBuffer)624 ErrorCode CheckToRenderPara(std::shared_ptr<EffectBuffer> &srcEffectBuffer,
625 std::shared_ptr<EffectBuffer> &dstEffectBuffer)
626 {
627 CHECK_AND_RETURN_RET_LOG(srcEffectBuffer != nullptr, ErrorCode::ERR_PARSE_FOR_EFFECT_BUFFER_FAIL,
628 "invalid srcEffectBuffer");
629
630 // allow developers not to set the out parameter.
631 if (dstEffectBuffer == nullptr) {
632 return ErrorCode::SUCCESS;
633 }
634
635 CHECK_AND_RETURN_RET_LOG(srcEffectBuffer->bufferInfo_ != nullptr && dstEffectBuffer->bufferInfo_ != nullptr,
636 ErrorCode::ERR_BUFFER_INFO_NULL,
637 "buffer info is null! srcBufferInfo=%{public}d, dstBufferInfo=%{public}d",
638 srcEffectBuffer->bufferInfo_ == nullptr, dstEffectBuffer->bufferInfo_ == nullptr);
639 CHECK_AND_RETURN_RET_LOG(srcEffectBuffer->extraInfo_ != nullptr && dstEffectBuffer->extraInfo_ != nullptr,
640 ErrorCode::ERR_EXTRA_INFO_NULL,
641 "extra info is null! srcExtraInfo=%{public}d, dstExtraInfo=%{public}d",
642 srcEffectBuffer->extraInfo_ == nullptr, dstEffectBuffer->extraInfo_ == nullptr);
643
644 // input and output type is same or not.
645 DataType srcDataType = srcEffectBuffer->extraInfo_->dataType;
646 DataType dtsDataType = dstEffectBuffer->extraInfo_->dataType;
647 std::function<bool(DataType, DataType)> dataTypeCheckFunc = [](DataType srcDataType, DataType dstDataType) {
648 if (srcDataType == dstDataType) {
649 return true;
650 }
651 std::vector<std::pair<DataType, DataType>> extraSupportTab = {
652 { DataType::PIXEL_MAP, DataType::NATIVE_WINDOW },
653 { DataType::PICTURE, DataType::NATIVE_WINDOW },
654 };
655 return extraSupportTab.end() != std::find_if(extraSupportTab.begin(), extraSupportTab.end(),
656 [&srcDataType, &dstDataType](const std::pair<DataType, DataType> &data) {
657 return data.first == srcDataType && data.second == dstDataType;
658 });
659 };
660 CHECK_AND_RETURN_RET_LOG(dataTypeCheckFunc(srcDataType, dtsDataType), ErrorCode::ERR_NOT_SUPPORT_DIFF_DATATYPE,
661 "not supported dataType. srcDataType=%{public}d, dstDataType=%{public}d", srcDataType, dtsDataType);
662
663 // color space is same or not.
664 if (srcDataType == DataType::PIXEL_MAP && dtsDataType != DataType::NATIVE_WINDOW) {
665 // the format for pixel map is same or not.
666 CHECK_AND_RETURN_RET_LOG(srcEffectBuffer->bufferInfo_->formatType_ == dstEffectBuffer->bufferInfo_->formatType_,
667 ErrorCode::ERR_NOT_SUPPORT_DIFF_FORMAT,
668 "not support different format. srcFormat=%{public}d, dstFormat=%{public}d",
669 srcEffectBuffer->bufferInfo_->formatType_, dstEffectBuffer->bufferInfo_->formatType_);
670
671 // color space is same or not.
672 EffectColorSpace srcColorSpace = srcEffectBuffer->bufferInfo_->colorSpace_;
673 EffectColorSpace dstColorSpace = dstEffectBuffer->bufferInfo_->colorSpace_;
674 bool isSrcHdr = ColorSpaceHelper::IsHdrColorSpace(srcColorSpace);
675 bool isDstHdr = ColorSpaceHelper::IsHdrColorSpace(dstColorSpace);
676 CHECK_AND_RETURN_RET_LOG(isSrcHdr == isDstHdr, ErrorCode::ERR_NOT_SUPPORT_INPUT_OUTPUT_COLORSPACE,
677 "not support different colorspace. src=%{public}d, dst=%{public}d", srcColorSpace, dstColorSpace);
678 }
679
680 return ErrorCode::SUCCESS;
681 }
682
GetImageInfoFromPixelMap(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat,std::shared_ptr<ExifMetadata> & exifMetadata) const683 ErrorCode ImageEffect::GetImageInfoFromPixelMap(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat,
684 std::shared_ptr<ExifMetadata> &exifMetadata) const
685 {
686 width = static_cast<uint32_t>(inDateInfo_.pixelMap_->GetWidth());
687 height = static_cast<uint32_t>(inDateInfo_.pixelMap_->GetHeight());
688 pixelFormat = inDateInfo_.pixelMap_->GetPixelFormat();
689 exifMetadata = inDateInfo_.pixelMap_->GetExifMetadata();
690 return ErrorCode::SUCCESS;
691 }
692
GetImageInfoFromSurface(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat) const693 ErrorCode ImageEffect::GetImageInfoFromSurface(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat) const
694 {
695 width = static_cast<uint32_t>(inDateInfo_.surfaceBufferInfo_.surfaceBuffer_->GetWidth());
696 height = static_cast<uint32_t>(inDateInfo_.surfaceBufferInfo_.surfaceBuffer_->GetHeight());
697 pixelFormat = static_cast<PixelFormat>(inDateInfo_.surfaceBufferInfo_.surfaceBuffer_->GetFormat());
698 return ErrorCode::SUCCESS;
699 }
700
GetImageInfoFromPath(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat,std::shared_ptr<ExifMetadata> & exifMetadata) const701 ErrorCode ImageEffect::GetImageInfoFromPath(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat,
702 std::shared_ptr<ExifMetadata> &exifMetadata) const
703 {
704 auto path = inDateInfo_.dataType_ == DataType::URI ? CommonUtils::UrlToPath(inDateInfo_.uri_) : inDateInfo_.path_;
705 std::shared_ptr<ImageSource> imageSource = CommonUtils::GetImageSourceFromPath(path);
706 CHECK_AND_RETURN_RET_LOG(imageSource != nullptr, ErrorCode::ERR_CREATE_IMAGESOURCE_FAIL,
707 "CreateImageSource fail! path=%{public}s", path.c_str());
708 ImageInfo info;
709 imageSource->GetImageInfo(info);
710 width = static_cast<uint32_t>(info.size.width);
711 height = static_cast<uint32_t>(info.size.height);
712 pixelFormat = info.pixelFormat;
713 exifMetadata = imageSource->GetExifMetadata();
714 return ErrorCode::SUCCESS;
715 }
716
GetImageInfoFromPicture(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat,std::shared_ptr<ExifMetadata> & exifMetadata) const717 ErrorCode ImageEffect::GetImageInfoFromPicture(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat,
718 std::shared_ptr<ExifMetadata> &exifMetadata) const
719 {
720 std::shared_ptr<PixelMap> pixelMap = inDateInfo_.picture_->GetMainPixel();
721 width = static_cast<uint32_t>(pixelMap->GetWidth());
722 height = static_cast<uint32_t>(pixelMap->GetHeight());
723 pixelFormat = pixelMap->GetPixelFormat();
724 exifMetadata = inDateInfo_.picture_->GetExifMetadata();
725 return ErrorCode::SUCCESS;
726 }
727
GetImageInfo(uint32_t & width,uint32_t & height,PixelFormat & pixelFormat,std::shared_ptr<ExifMetadata> & exifMetadata)728 ErrorCode ImageEffect::GetImageInfo(uint32_t &width, uint32_t &height, PixelFormat &pixelFormat,
729 std::shared_ptr<ExifMetadata> &exifMetadata)
730 {
731 ErrorCode errorCode = ErrorCode::SUCCESS;
732 switch (inDateInfo_.dataType_) {
733 case DataType::PIXEL_MAP: {
734 errorCode = GetImageInfoFromPixelMap(width, height, pixelFormat, exifMetadata);
735 CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode, "GetImageInfoFromPixelMap fail!");
736 break;
737 }
738 case DataType::SURFACE:
739 case DataType::SURFACE_BUFFER: {
740 errorCode = GetImageInfoFromSurface(width, height, pixelFormat);
741 CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode, "GetImageInfoFromSurface fail!");
742 break;
743 }
744 case DataType::URI:
745 case DataType::PATH: {
746 errorCode = GetImageInfoFromPath(width, height, pixelFormat, exifMetadata);
747 CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode, "GetImageInfoFromPath fail!");
748 break;
749 }
750 case DataType::NATIVE_WINDOW:
751 width = 0;
752 height = 0;
753 break;
754 case DataType::PICTURE: {
755 errorCode = GetImageInfoFromPicture(width, height, pixelFormat, exifMetadata);
756 CHECK_AND_RETURN_RET_LOG(errorCode == ErrorCode::SUCCESS, errorCode, "GetImageInfoFromPicture fail!");
757 break;
758 }
759 case DataType::UNKNOWN:
760 EFFECT_LOGE("dataType is unknown! DataType is not set!");
761 return ErrorCode::ERR_UNSUPPORTED_DATA_TYPE;
762 default:
763 EFFECT_LOGE("dataType is not support! dataType=%{public}d", static_cast<int>(inDateInfo_.dataType_));
764 return ErrorCode::ERR_UNSUPPORTED_DATA_TYPE;
765 }
766 return errorCode;
767 }
768
ConfigureFilters(std::shared_ptr<EffectBuffer> srcEffectBuffer,std::shared_ptr<EffectBuffer> dstEffectBuffer)769 ErrorCode ImageEffect::ConfigureFilters(std::shared_ptr<EffectBuffer> srcEffectBuffer,
770 std::shared_ptr<EffectBuffer> dstEffectBuffer) {
771 std::shared_ptr<ImageSourceFilter> &sourceFilter = impl_->srcFilter_;
772 ErrorCode res = ConfigSourceFilter(sourceFilter, srcEffectBuffer, impl_->effectContext_);
773 if (res != ErrorCode::SUCCESS) {
774 UnLockAll();
775 return res;
776 }
777
778 std::shared_ptr<ImageSinkFilter> &sinkFilter = impl_->sinkFilter_;
779 res = ConfigSinkFilter(sinkFilter, dstEffectBuffer);
780 if (res != ErrorCode::SUCCESS) {
781 UnLockAll();
782 return res;
783 }
784
785 return ErrorCode::SUCCESS;
786 }
787
SetPathToSink()788 void ImageEffect::SetPathToSink()
789 {
790 if (inDateInfo_.dataType_ == DataType::URI) {
791 impl_->sinkFilter_->inPath_ = CommonUtils::UrlToPath(inDateInfo_.uri_);
792 } else if (inDateInfo_.dataType_ == DataType::PATH) {
793 impl_->sinkFilter_->inPath_ = inDateInfo_.path_;
794 }
795 }
796
Render()797 ErrorCode ImageEffect::Render()
798 {
799 CHECK_AND_RETURN_RET_LOG(!efilters_.empty(), ErrorCode::ERR_NOT_FILTERS_WITH_RENDER, "efilters is empty");
800
801 uint32_t width = 0;
802 uint32_t height = 0;
803 PixelFormat pixelFormat = PixelFormat::RGBA_8888;
804 std::shared_ptr<ExifMetadata> exifMetadata = nullptr;
805
806 ErrorCode res = GetImageInfo(width, height, pixelFormat, exifMetadata);
807 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "set image info fail! res = %{public}d", res);
808 IEffectFormat format = CommonUtils::SwitchToEffectFormat(pixelFormat);
809 impl_->effectContext_->exifMetadata_ = exifMetadata;
810
811 std::shared_ptr<ImageSourceFilter> &sourceFilter = impl_->srcFilter_;
812 sourceFilter->SetNegotiateParameter(width, height, format, impl_->effectContext_);
813
814 res = impl_->pipeline_->Prepare();
815 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "pipeline prepare fail! res=%{public}d", res);
816
817 if (inDateInfo_.dataType_ == DataType::URI || inDateInfo_.dataType_ == DataType::PATH) {
818 const std::vector<std::shared_ptr<Capability>> &capabilities =
819 impl_->effectContext_->capNegotiate_->GetCapabilityList();
820 format = CapabilityNegotiate::NegotiateFormat(capabilities);
821 }
822 EFFECT_LOGD("image effect render, negotiate format=%{public}d", format);
823 SetPathToSink();
824
825 std::shared_ptr<EffectBuffer> srcEffectBuffer = nullptr;
826 std::shared_ptr<EffectBuffer> dstEffectBuffer = nullptr;
827 res = LockAll(srcEffectBuffer, dstEffectBuffer, format);
828 if (res != ErrorCode::SUCCESS) {
829 UnLockAll();
830 return res;
831 }
832
833 res = CheckToRenderPara(srcEffectBuffer, dstEffectBuffer);
834 if (res != ErrorCode::SUCCESS) {
835 UnLockAll();
836 return res;
837 }
838
839 res = ConfigureFilters(srcEffectBuffer, dstEffectBuffer);
840 CHECK_AND_RETURN_RET_LOG(res == ErrorCode::SUCCESS, res, "configure filters fail! res=%{puiblic}d", res);
841
842 if (dstEffectBuffer != nullptr) {
843 impl_->effectContext_->renderEnvironment_->SetOutputType(dstEffectBuffer->extraInfo_->dataType);
844 } else {
845 impl_->effectContext_->renderEnvironment_->SetOutputType(srcEffectBuffer->extraInfo_->dataType);
846 }
847 EffectParameters effectParameters(srcEffectBuffer, dstEffectBuffer, config_, impl_->effectContext_);
848 res = StartPipeline(impl_->pipeline_, effectParameters, RequestTaskId(), m_renderThread, !impl_->isQosEnabled_);
849 if (res != ErrorCode::SUCCESS) {
850 EFFECT_LOGE("StartPipeline fail! res=%{public}d", res);
851 UnLockAll();
852 return res;
853 }
854
855 UnLockAll();
856 return res;
857 }
858
Save(EffectJsonPtr & res)859 ErrorCode ImageEffect::Save(EffectJsonPtr &res)
860 {
861 EffectJsonPtr effect = EffectJsonHelper::CreateArray();
862 for (auto it = efilters_.begin(); it != efilters_.end(); it++) {
863 EffectJsonPtr data = EffectJsonHelper::CreateObject();
864 std::shared_ptr<EFilter> efilter = *it;
865 efilter->Save(data);
866 effect->Add(data);
867 }
868
869 EffectJsonPtr info = EffectJsonHelper::CreateObject();
870 info->Put("filters", effect);
871 info->Put("name", name_);
872 if (extraInfo_ != nullptr) {
873 extraInfo_->Replace("imageEffect", info);
874 res = extraInfo_;
875 } else {
876 res->Put("imageEffect", info);
877 }
878 return ErrorCode::SUCCESS;
879 }
880
Restore(std::string & info)881 std::shared_ptr<ImageEffect> ImageEffect::Restore(std::string &info)
882 {
883 const EffectJsonPtr root = EffectJsonHelper::ParseJsonData(info);
884 CHECK_AND_RETURN_RET_LOG(root->HasElement("imageEffect"), nullptr, "Restore: no imageEffect");
885 const EffectJsonPtr &imageInfo = root->GetElement("imageEffect");
886 CHECK_AND_RETURN_RET_LOG(imageInfo != nullptr, nullptr, "Restore: imageInfo is null!");
887 CHECK_AND_RETURN_RET_LOG(imageInfo->HasElement("name"), nullptr, "Restore: imageEffect no name");
888 std::string effectName = imageInfo->GetString("name");
889 CHECK_AND_RETURN_RET_LOG(!effectName.empty(), nullptr, "Restore: imageEffect get name failed");
890
891 CHECK_AND_RETURN_RET_LOG(imageInfo->HasElement("filters"), nullptr, "Restore: imageEffect no filters");
892 std::vector<EffectJsonPtr> efiltersInfo = imageInfo->GetArray("filters");
893 CHECK_AND_RETURN_RET_LOG(!efiltersInfo.empty(), nullptr, "Restore: filters not array");
894
895 std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(effectName.c_str());
896 for (auto &efilterInfo : efiltersInfo) {
897 std::string name = efilterInfo->GetString("name");
898 CHECK_AND_CONTINUE_LOG(!name.empty(), "Restore: [name] not exist");
899 std::shared_ptr<EFilter> efilter = EFilterFactory::Instance()->Restore(name, efilterInfo, nullptr);
900 imageEffect->AddEFilter(efilter);
901 }
902 return imageEffect;
903 }
904
SetOutputPixelMap(PixelMap * pixelMap)905 ErrorCode ImageEffect::SetOutputPixelMap(PixelMap* pixelMap)
906 {
907 std::unique_lock<std::mutex> lock(innerEffectMutex_);
908 EFFECT_LOGD("ImageEffect::SetOutputPixelMap");
909 ClearDataInfo(outDateInfo_);
910 if (pixelMap == nullptr) {
911 EFFECT_LOGI("SetOutputPixelMap: pixelMap set to null!");
912 return ErrorCode::SUCCESS;
913 }
914
915 outDateInfo_.dataType_ = DataType::PIXEL_MAP;
916 outDateInfo_.pixelMap_ = pixelMap;
917
918 return ErrorCode::SUCCESS;
919 }
920
SetOutputSurface(sptr<Surface> & surface)921 ErrorCode ImageEffect::SetOutputSurface(sptr<Surface>& surface)
922 {
923 std::unique_lock<std::mutex> lock(innerEffectMutex_);
924 if (surface == nullptr) {
925 EFFECT_LOGE("surface is null.");
926 return ErrorCode::ERR_INPUT_NULL;
927 }
928 outDateInfo_.dataType_ = DataType::SURFACE;
929 toProducerSurface_ = surface;
930
931 if (impl_->surfaceAdapter_ == nullptr) {
932 impl_->surfaceAdapter_ = std::make_unique<EffectSurfaceAdapter>();
933 }
934 impl_->surfaceAdapter_->SetOutputSurfaceDefaultUsage(toProducerSurface_->GetDefaultUsage());
935
936 toProducerSurface_->SetTransform(GRAPHIC_ROTATE_BUTT);
937 return ErrorCode::SUCCESS;
938 }
939
UpdateProducerSurfaceInfo()940 void ImageEffect::UpdateProducerSurfaceInfo()
941 {
942 if (impl_->surfaceAdapter_ == nullptr) {
943 EFFECT_LOGE("impl surfaceAdapter is nullptr!");
944 return;
945 }
946 auto transform = impl_->surfaceAdapter_->GetTransform();
947 if (transform == toProducerTransform_) {
948 return;
949 }
950 toProducerTransform_ = transform;
951 EFFECT_LOGI("Set toProducerSurface transform %{public}d, GRAPHIC_ROTATE_270: %{public}d",
952 transform, GRAPHIC_ROTATE_270);
953
954 if (toProducerSurface_ == nullptr) {
955 EFFECT_LOGE("toProducerSurface_ is nullptr!");
956 return;
957 }
958 toProducerSurface_->SetTransform(transform);
959 }
960
ConsumerBufferWithGPU(sptr<SurfaceBuffer> & buffer)961 void ImageEffect::ConsumerBufferWithGPU(sptr<SurfaceBuffer>& buffer)
962 {
963 inDateInfo_.surfaceBufferInfo_.surfaceBuffer_ = buffer;
964 GraphicTransformType transform = impl_->surfaceAdapter_->GetTransform();
965 buffer->SetSurfaceBufferTransform(transform);
966 if (impl_->effectState_ == EffectState::RUNNING) {
967 impl_->effectContext_->renderEnvironment_->NotifyInputChanged();
968 this->Render();
969 } else {
970 auto task = std::make_shared<RenderTask<>>([buffer, this, transform]() {
971 if (impl_->effectContext_->renderEnvironment_->GetEGLStatus() != EGLStatus::READY) {
972 impl_->effectContext_->renderEnvironment_->Init();
973 impl_->effectContext_->renderEnvironment_->Prepare();
974 }
975 int tex = GLUtils::CreateTextureFromSurfaceBuffer(buffer);
976 impl_->effectContext_->renderEnvironment_->UpdateCanvas();
977 impl_->effectContext_->renderEnvironment_->DrawFrame(tex, transform);
978 }, COMMON_TASK_TAG, RequestTaskId());
979 m_renderThread->AddTask(task);
980 task->Wait();
981 }
982 }
983
MemoryCopyForSurfaceBuffer(sptr<SurfaceBuffer> & buffer,OHOS::sptr<SurfaceBuffer> & outBuffer)984 void MemoryCopyForSurfaceBuffer(sptr<SurfaceBuffer> &buffer, OHOS::sptr<SurfaceBuffer> &outBuffer)
985 {
986 CopyInfo src = {
987 .bufferInfo = {
988 .width_ = static_cast<uint32_t>(buffer->GetWidth()),
989 .height_ = static_cast<uint32_t>(buffer->GetHeight()),
990 .len_ = buffer->GetSize(),
991 .formatType_ = CommonUtils::SwitchToEffectFormat((GraphicPixelFormat)buffer->GetFormat()),
992 .rowStride_ = static_cast<uint32_t>(buffer->GetStride()),
993 },
994 .data = static_cast<uint8_t *>(buffer->GetVirAddr()),
995 };
996 CopyInfo dst = {
997 .bufferInfo = {
998 .width_ = static_cast<uint32_t>(outBuffer->GetWidth()),
999 .height_ = static_cast<uint32_t>(outBuffer->GetHeight()),
1000 .len_ = outBuffer->GetSize(),
1001 .formatType_ = CommonUtils::SwitchToEffectFormat((GraphicPixelFormat)outBuffer->GetFormat()),
1002 .rowStride_ = static_cast<uint32_t>(outBuffer->GetStride()),
1003 },
1004 .data = static_cast<uint8_t *>(outBuffer->GetVirAddr()),
1005 };
1006 MemcpyHelper::CopyData(src, dst);
1007 }
1008
IsSurfaceBufferHebc(sptr<SurfaceBuffer> & buffer)1009 bool IsSurfaceBufferHebc(sptr<SurfaceBuffer> &buffer)
1010 {
1011 V1_1::BufferHandleAttrKey key = V1_1::BufferHandleAttrKey::ATTRKEY_ACCESS_TYPE;
1012 std::vector<uint8_t> values;
1013 auto res = buffer->GetMetadata(key, values);
1014 CHECK_AND_RETURN_RET(res == 0, false);
1015
1016 V1_1::HebcAccessType hebcAccessType = V1_1::HebcAccessType::HEBC_ACCESS_UNINIT;
1017 res = MetadataHelper::ConvertVecToMetadata(values, hebcAccessType);
1018 CHECK_AND_RETURN_RET(res == 0, false);
1019
1020 if (hebcAccessType == V1_1::HEBC_ACCESS_HW_ONLY) {
1021 EFFECT_LOGD("IsSurfaceBufferHebc: surface buffer is Hebc data!");
1022 return true;
1023 }
1024 return false;
1025 }
1026
SetSurfaceBufferHebcAccessType(sptr<SurfaceBuffer> & buffer,V1_1::HebcAccessType hebcAccessType)1027 void SetSurfaceBufferHebcAccessType(sptr<SurfaceBuffer> &buffer, V1_1::HebcAccessType hebcAccessType)
1028 {
1029 std::vector<uint8_t> values;
1030 auto res = MetadataHelper::ConvertMetadataToVec(hebcAccessType, values);
1031 CHECK_AND_RETURN_LOG(res == 0, "SetSurfaceBufferHebcAccessType: ConvertVecToMetadata fail! res=%{public}d", res);
1032
1033 V1_1::BufferHandleAttrKey key = V1_1::BufferHandleAttrKey::ATTRKEY_ACCESS_TYPE;
1034 res = buffer->SetMetadata(key, values, false);
1035 CHECK_AND_RETURN_LOG(res == 0, "SetSurfaceBufferHebcAccessType: SetMetadata fail! res=%{public}d", res);
1036 }
1037
RenderBuffer(sptr<SurfaceBuffer> & inBuffer,sptr<SurfaceBuffer> & outBuffer,int64_t & timestamp)1038 bool ImageEffect::RenderBuffer(sptr<SurfaceBuffer> &inBuffer, sptr<SurfaceBuffer> &outBuffer, int64_t& timestamp)
1039 {
1040 std::vector<uint32_t> keys = {};
1041 CHECK_AND_RETURN_RET_LOG(inBuffer != nullptr, true, "CopyMetaData: inBuffer is nullptr");
1042 auto ret = inBuffer->ListMetadataKeys(keys);
1043 CHECK_AND_RETURN_RET_LOG(ret == GSError::GSERROR_OK, true,
1044 "CopyMetaData: ListMetadataKeys fail! res=%{public}d", ret);
1045 for (uint32_t key : keys) {
1046 std::vector<uint8_t> values;
1047 ret = inBuffer->GetMetadata(key, values);
1048 if (ret != 0) {
1049 EFFECT_LOGE("GetMetadata fail! key = %{public}d res = %{public}d", key, ret);
1050 continue;
1051 }
1052 auto isNeedUpdate = !(key == VIDEO_SINK_FILTER_STATUS && values[0] == VIDEO_SINK_FILTER_STATUS);
1053 impl_->effectContext_->metaInfoNegotiate_->SetNeedUpdate(isNeedUpdate);
1054 ret = outBuffer->SetMetadata(key, values);
1055 if (ret != 0) {
1056 EFFECT_LOGE("SetMetadata fail! key = %{public}d res = %{public}d", key, ret);
1057 continue;
1058 }
1059 }
1060 inDateInfo_.surfaceBufferInfo_ = {
1061 .surfaceBuffer_ = inBuffer,
1062 .timestamp_ = timestamp,
1063 };
1064 outDateInfo_.surfaceBufferInfo_ = {
1065 .surfaceBuffer_ = outBuffer,
1066 .timestamp_ = timestamp,
1067 };
1068 impl_->effectContext_->renderEnvironment_->NotifyInputChanged();
1069 ErrorCode res = this->Render();
1070 return res != ErrorCode::SUCCESS;
1071 }
1072
GetBufferRequestConfig(const sptr<SurfaceBuffer> & buffer)1073 BufferRequestConfig ImageEffect::GetBufferRequestConfig(const sptr<SurfaceBuffer>& buffer)
1074 {
1075 return {
1076 .width = buffer->GetWidth(),
1077 .height = buffer->GetHeight(),
1078 .strideAlignment = 0x8,
1079 .format = buffer->GetFormat(),
1080 .usage = buffer->GetUsage(),
1081 .timeout = 0,
1082 .colorGamut = buffer->GetSurfaceBufferColorGamut(),
1083 .transform = buffer->GetSurfaceBufferTransform(),
1084 };
1085 }
1086
FlushBuffer(sptr<SurfaceBuffer> & flushBuffer,sptr<SyncFence> & syncFence,bool isNeedAttach,bool isSendFence,int64_t & timestamp)1087 GSError ImageEffect::FlushBuffer(sptr<SurfaceBuffer>& flushBuffer, sptr<SyncFence>& syncFence, bool isNeedAttach,
1088 bool isSendFence, int64_t& timestamp)
1089 {
1090 BufferFlushConfig flushConfig = {
1091 .damage = {
1092 .w = flushBuffer->GetWidth(),
1093 .h = flushBuffer->GetHeight(),
1094 },
1095 .timestamp = timestamp,
1096 };
1097
1098 CHECK_AND_RETURN_RET_LOG(imageEffectFlag_ == STRUCT_IMAGE_EFFECT_CONSTANT, GSERROR_NOT_INIT,
1099 "ProcessRender: ImageEffect not exist.");
1100 CHECK_AND_RETURN_RET_LOG(toProducerSurface_ != nullptr, GSERROR_NOT_INIT,
1101 "ProcessRender: toProducerSurface is nullptr.");
1102
1103 auto ret = GSError::GSERROR_OK;
1104 const sptr<SyncFence> invalidFence = SyncFence::InvalidFence();
1105 if (isNeedAttach) {
1106 ret = toProducerSurface_->AttachAndFlushBuffer(flushBuffer, isSendFence ? syncFence : invalidFence,
1107 flushConfig, false);
1108 if (ret != GSError::GSERROR_OK) {
1109 EFFECT_LOGE("AttachAndFlushBuffer: attach and flush buffer failed. %{public}d", ret);
1110 }
1111 } else {
1112 ret = toProducerSurface_->FlushBuffer(flushBuffer, isSendFence ? syncFence : invalidFence, flushConfig);
1113 if (ret != GSError::GSERROR_OK) {
1114 EFFECT_LOGE("FlushBuffer: flush buffer failed. %{public}d", ret);
1115 }
1116 }
1117
1118 return ret;
1119 }
1120
ReleaseBuffer(sptr<OHOS::SurfaceBuffer> & buffer,sptr<OHOS::SyncFence> & fence)1121 GSError ImageEffect::ReleaseBuffer(sptr<OHOS::SurfaceBuffer> &buffer, sptr<OHOS::SyncFence> &fence)
1122 {
1123 auto ret = impl_->ReleaseConsumerSurfaceBuffer(buffer, fence);
1124 if (ret != GSError::GSERROR_OK) {
1125 EFFECT_LOGE("ReleaseBuffer: ReleaseConsumerSurfaceBuffer failed. %{public}d", ret);
1126 }
1127 return ret;
1128 }
1129
ProcessRender(BufferProcessInfo & bufferProcessInfo,bool & isNeedSwap,int64_t & timestamp)1130 void ImageEffect::ProcessRender(BufferProcessInfo& bufferProcessInfo, bool& isNeedSwap, int64_t& timestamp)
1131 {
1132 sptr<SurfaceBuffer> inBuffer = bufferProcessInfo.inBuffer_;
1133 sptr<SurfaceBuffer> outBuffer = bufferProcessInfo.outBuffer_;
1134 sptr<SyncFence> inBufferSyncFence = bufferProcessInfo.inBufferSyncFence_;
1135 sptr<SyncFence> outBufferSyncFence = bufferProcessInfo.outBufferSyncFence_;
1136
1137 constexpr uint32_t waitForEver = -1;
1138 (void)inBufferSyncFence->Wait(waitForEver);
1139
1140 {
1141 EFFECT_TRACE_BEGIN("ProcessRender: InvalidateCache");
1142 (void)inBuffer->InvalidateCache();
1143 EFFECT_TRACE_END();
1144 }
1145
1146 CHECK_AND_RETURN_LOG(toProducerSurface_ != nullptr, "ProcessRender: toProducerSurface is nullptr.");
1147 auto requestConfig = GetBufferRequestConfig(inBuffer);
1148 auto ret = toProducerSurface_->RequestBuffer(outBuffer, outBufferSyncFence, requestConfig);
1149 if (ret != 0 || outBuffer == nullptr) {
1150 EFFECT_LOGE("ProcessRender::RequestBuffer failed. %{public}d", ret);
1151 ret = impl_->ReleaseConsumerSurfaceBuffer(inBuffer, SyncFence::INVALID_FENCE);
1152 if (ret != GSError::GSERROR_OK) {
1153 EFFECT_LOGE("ProcessRender::ReleaseBuffer caused by RequestBuffer failed. %{public}d", ret);
1154 }
1155 return;
1156 }
1157 CHECK_AND_RETURN_LOG(inBuffer != nullptr && outBuffer != nullptr,
1158 "ProcessRender: inBuffer or outBuffer is nullptr");
1159 EFFECT_LOGD("ProcessRender: inBuffer: %{public}d, outBuffer: %{public}d",
1160 inBuffer->GetSeqNum(), outBuffer->GetSeqNum());
1161
1162 (void)outBufferSyncFence->Wait(waitForEver);
1163
1164 SetSurfaceBufferHebcAccessType(outBuffer, bufferProcessInfo.isSrcHebcData_ ?
1165 V1_1::HebcAccessType::HEBC_ACCESS_HW_ONLY : V1_1::HebcAccessType::HEBC_ACCESS_CPU_ACCESS);
1166
1167 isNeedSwap = RenderBuffer(inBuffer, outBuffer, timestamp);
1168 if (isNeedSwap) return;
1169
1170 {
1171 EFFECT_TRACE_BEGIN("ProcessRender: FlushCache");
1172 (void)outBuffer->FlushCache();
1173 EFFECT_TRACE_END();
1174 }
1175
1176 EFFECT_LOGD("ProcessRender: ReleaseBuffer: %{public}d, FlushBuffer: %{public}d",
1177 inBuffer->GetSeqNum(), outBuffer->GetSeqNum());
1178
1179 ret = impl_->ReleaseConsumerSurfaceBuffer(inBuffer, SyncFence::INVALID_FENCE);
1180 CHECK_AND_PRINT_LOG(ret == GSError::GSERROR_OK,
1181 "ProcessRender: ReleaseConsumerSurfaceBuffer failed. %{public}d", ret);
1182
1183 ret = FlushBuffer(outBuffer, outBufferSyncFence, false, false, timestamp);
1184 CHECK_AND_RETURN_LOG(ret == GSError::GSERROR_OK, "ProcessRender: FlushBuffer failed. %{public}d", ret);
1185 }
1186
ProcessSwapBuffers(BufferProcessInfo & bufferProcessInfo,int64_t & timestamp)1187 void ImageEffect::ProcessSwapBuffers(BufferProcessInfo& bufferProcessInfo, int64_t& timestamp)
1188 {
1189 sptr<SurfaceBuffer> inBuffer = bufferProcessInfo.inBuffer_;
1190 sptr<SurfaceBuffer> outBuffer = bufferProcessInfo.outBuffer_;
1191 sptr<SyncFence> inBufferSyncFence = bufferProcessInfo.inBufferSyncFence_;
1192 sptr<SyncFence> outBufferSyncFence = bufferProcessInfo.outBufferSyncFence_;
1193 // inBuffer aquired from impl
1194 auto requestConfig = GetBufferRequestConfig(inBuffer);
1195 auto ret = toProducerSurface_->RequestAndDetachBuffer(outBuffer, outBufferSyncFence, requestConfig);
1196 if (ret != 0 || outBuffer == nullptr) {
1197 EFFECT_LOGE("ProcessSwapBuffers::RequestAndDetachBuffer failed. %{public}d", ret);
1198 ReleaseBuffer(inBuffer, inBufferSyncFence);
1199 return;
1200 }
1201 CHECK_AND_RETURN_LOG(inBuffer != nullptr && outBuffer != nullptr,
1202 "ProcessRender: inBuffer or outBuffer is nullptr");
1203 // outBuffer requestAndDetached from XC
1204 EFFECT_LOGD("ProcessRender: inBuffer: %{public}d, outBuffer: %{public}d",
1205 inBuffer->GetSeqNum(), outBuffer->GetSeqNum());
1206
1207 ret = impl_->DetachConsumerSurfaceBuffer(inBuffer);
1208 if (ret != GSError::GSERROR_OK) {
1209 EFFECT_LOGE("ProcessSwapBuffers: DetachConsumerSurfaceBuffer failed. %{public}d", ret);
1210 ReleaseBuffer(inBuffer, inBufferSyncFence);
1211 FlushBuffer(outBuffer, outBufferSyncFence, true, true, timestamp);
1212 return;
1213 }
1214 // inBuffer detached from impl
1215 ret = impl_->AttachConsumerSurfaceBuffer(outBuffer);
1216 if (ret != GSError::GSERROR_OK) {
1217 EFFECT_LOGE("ProcessSwapBuffers: AttachConsumerSurfaceBuffer failed. %{public}d", ret);
1218 failureCount_++;
1219 impl_->AttachConsumerSurfaceBuffer(inBuffer);
1220 ReleaseBuffer(inBuffer, inBufferSyncFence);
1221 FlushBuffer(outBuffer, inBufferSyncFence, true, false, timestamp);
1222 return;
1223 }
1224 // outBuffer attached in Impl
1225 ret = FlushBuffer(inBuffer, inBufferSyncFence, true, true, timestamp);
1226 if (ret != GSError::GSERROR_OK) {
1227 EFFECT_LOGE("ProcessSwapBuffers: FlushBuffer failed. %{public}d", ret);
1228 ReleaseBuffer(outBuffer, outBufferSyncFence);
1229 return;
1230 }
1231 // inBuffer attachAndFlushed in XC
1232 ret = ReleaseBuffer(outBuffer, outBufferSyncFence);
1233 // outBuffer release in impl
1234 CHECK_AND_RETURN_LOG(ret == GSError::GSERROR_OK,
1235 "ProcessSwapBuffers: ReleaseConsumerSurfaceBuffer failed. %{public}d", ret);
1236 }
1237
OnBufferAvailableWithCPU()1238 void ImageEffect::OnBufferAvailableWithCPU()
1239 {
1240 sptr<SurfaceBuffer> inBuffer = nullptr;
1241 sptr<SurfaceBuffer> outBuffer = nullptr;
1242 int64_t timestamp = 0;
1243 OHOS::Rect damages = {};
1244 sptr<SyncFence> inBufferSyncFence = SyncFence::INVALID_FENCE;
1245
1246 CHECK_AND_RETURN_LOG(impl_->CheckEffectSurface(),
1247 "OnBufferAvailableToProcess: onBufferAvailableToProcess consumerSurface_ not exist");
1248
1249 auto ret = impl_->AcquireConsumerSurfaceBuffer(inBuffer, inBufferSyncFence, timestamp, damages);
1250 CHECK_AND_RETURN_LOG(ret == 0 && inBuffer != nullptr, "AcquireBuffer failed. %{public}d", ret);
1251
1252 outDateInfo_.dataType_ = DataType::SURFACE;
1253 UpdateProducerSurfaceInfo();
1254
1255 bool isSrcHebcData = false;
1256 CHECK_AND_RETURN_LOG(impl_ != nullptr, "OnBufferAvailableWithCPU: impl is nullptr.");
1257 UpdateConsumedrBuffersNumber();
1258 UpdateCycleBuffersNumber();
1259 bool isNeedSwap = true;
1260 bool isNeedRender = impl_->effectState_ == EffectState::RUNNING;
1261 if (isNeedRender) {
1262 isSrcHebcData = IsSurfaceBufferHebc(inBuffer);
1263 isNeedRender = !isSrcHebcData;
1264 }
1265
1266 BufferProcessInfo bufferProcessInfo = {
1267 .inBuffer_ = inBuffer,
1268 .outBuffer_ = outBuffer,
1269 .inBufferSyncFence_ = inBufferSyncFence,
1270 .outBufferSyncFence_ = SyncFence::INVALID_FENCE,
1271 .isSrcHebcData_ = isSrcHebcData,
1272 };
1273
1274 if (isNeedRender) {
1275 EFFECT_TRACE_BEGIN("ProcessRender");
1276 ProcessRender(bufferProcessInfo, isNeedSwap, timestamp);
1277 EFFECT_TRACE_END();
1278 }
1279 if (isNeedSwap) {
1280 EFFECT_TRACE_BEGIN("ProcessSwapBuffers");
1281 ProcessSwapBuffers(bufferProcessInfo, timestamp);
1282 EFFECT_TRACE_END();
1283 }
1284 }
1285
ConsumerBufferAvailable()1286 void ImageEffect::ConsumerBufferAvailable()
1287 {
1288 CHECK_AND_RETURN_LOG(imageEffectFlag_ == STRUCT_IMAGE_EFFECT_CONSTANT,
1289 "ImageEffect::ConsumerBufferAvailable ImageEffect not exist.");
1290 auto taskId = m_currentTaskId.fetch_add(1);
1291 auto task = std::make_shared<RenderTask<>>([this] () {
1292 if (!impl_->isQosEnabled_) {
1293 OHOS::QOS::SetThreadQos(OHOS::QOS::QosLevel::QOS_USER_INTERACTIVE);
1294 impl_->isQosEnabled_ = true;
1295 }
1296 std::unique_lock<std::mutex> lock(innerEffectMutex_);
1297 CHECK_AND_RETURN_LOG(imageEffectFlag_ == STRUCT_IMAGE_EFFECT_CONSTANT,
1298 "ImageEffect::ConsumerBufferAvailable ImageEffect not exist.");
1299 OnBufferAvailableWithCPU();
1300 }, 0, taskId);
1301 m_renderThread->AddTask(task);
1302 task->Wait();
1303 }
1304
GetInputSurface()1305 sptr<Surface> ImageEffect::GetInputSurface()
1306 {
1307 inDateInfo_.dataType_ = DataType::SURFACE;
1308 if (fromProducerSurface_ != nullptr) {
1309 return fromProducerSurface_;
1310 }
1311
1312 if (impl_->surfaceAdapter_ == nullptr) {
1313 impl_->surfaceAdapter_ = std::make_unique<EffectSurfaceAdapter>();
1314 }
1315
1316 if (impl_->surfaceAdapter_) {
1317 fromProducerSurface_ = impl_->surfaceAdapter_->GetProducerSurface();
1318 }
1319
1320 auto consumerListener = [this]() {
1321 return ConsumerBufferAvailable();
1322 };
1323
1324 if (impl_->surfaceAdapter_) {
1325 impl_->surfaceAdapter_->SetConsumerListener(std::move(consumerListener));
1326 }
1327
1328 return fromProducerSurface_;
1329 }
1330
SetOutNativeWindow(OHNativeWindow * nativeWindow)1331 ErrorCode ImageEffect::SetOutNativeWindow(OHNativeWindow *nativeWindow)
1332 {
1333 std::unique_lock<std::mutex> lock(innerEffectMutex_);
1334 CHECK_AND_RETURN_RET_LOG(nativeWindow != nullptr, ErrorCode::ERR_INPUT_NULL, "nativeWindow is nullptr");
1335 OHOS::sptr<OHOS::Surface> surface = nativeWindow->surface;
1336 CHECK_AND_RETURN_RET_LOG(surface != nullptr, ErrorCode::ERR_INPUT_NULL, "surface is nullptr");
1337 toProducerSurface_ = surface;
1338 outDateInfo_.dataType_ = DataType::NATIVE_WINDOW;
1339 impl_->effectContext_->renderEnvironment_->InitEngine(nativeWindow);
1340 if (impl_->surfaceAdapter_ == nullptr) {
1341 impl_->surfaceAdapter_ = std::make_unique<EffectSurfaceAdapter>();
1342 }
1343 impl_->surfaceAdapter_->SetOutputSurfaceDefaultUsage(toProducerSurface_->GetDefaultUsage());
1344
1345 toProducerSurface_->SetTransform(GRAPHIC_ROTATE_BUTT);
1346 return ErrorCode::SUCCESS;
1347 }
1348
Configure(const std::string & key,const Plugin::Any & value)1349 ErrorCode ImageEffect::Configure(const std::string &key, const Plugin::Any &value)
1350 {
1351 if (FUNCTION_FLUSH_SURFACE_BUFFER.compare(key) == 0) {
1352 EFFECT_LOGI("ImageEffect Configure FlushCache");
1353 needPreFlush_ = true;
1354 return ErrorCode::SUCCESS;
1355 }
1356 auto configTypeIt = std::find_if(configTypeTab_.begin(), configTypeTab_.end(),
1357 [&key](const std::pair<std::string, ConfigType> &item) { return item.first.compare(key) == 0; });
1358
1359 CHECK_AND_RETURN_RET_LOG(configTypeIt != configTypeTab_.end(), ErrorCode::ERR_UNSUPPORTED_CONFIG_TYPE,
1360 "config key is not support! key=%{public}s", key.c_str());
1361
1362 ConfigType configType = configTypeIt->second;
1363 switch (configType) {
1364 case ConfigType::IPTYPE: {
1365 int32_t runningType;
1366 ErrorCode result = CommonUtils::ParseAny(value, runningType);
1367 CHECK_AND_RETURN_RET_LOG(result == ErrorCode::SUCCESS, result,
1368 "parse any fail! expect type is uint32_t! key=%{public}s", key.c_str());
1369 auto it = std::find_if(runningTypeTab_.begin(), runningTypeTab_.end(),
1370 [&runningType](const std::pair<int32_t, std::vector<IPType>> &item) {
1371 return item.first == runningType;
1372 });
1373 CHECK_AND_RETURN_RET_LOG(it != runningTypeTab_.end(), ErrorCode::ERR_UNSUPPORTED_RUNNINGTYPE,
1374 "not support runningType! key=%{public}s, runningType=%{public}d", key.c_str(), runningType);
1375 config_[configType] = it->second;
1376 break;
1377 }
1378 default:
1379 EFFECT_LOGE("config type is not support! configType=%{public}d", configType);
1380 return ErrorCode::ERR_UNSUPPORTED_CONFIG_TYPE;
1381 }
1382 return ErrorCode::SUCCESS;
1383 }
1384
ClearDataInfo(DataInfo & dataInfo)1385 void ImageEffect::ClearDataInfo(DataInfo &dataInfo)
1386 {
1387 dataInfo.dataType_ = DataType::UNKNOWN;
1388 dataInfo.pixelMap_ = nullptr;
1389 dataInfo.surfaceBufferInfo_.surfaceBuffer_ = nullptr;
1390 dataInfo.surfaceBufferInfo_.timestamp_ = 0;
1391 dataInfo.uri_ = "";
1392 dataInfo.path_ = "";
1393 }
1394
IsSameInOutputData(const DataInfo & inDataInfo,const DataInfo & outDataInfo)1395 bool IsSameInOutputData(const DataInfo &inDataInfo, const DataInfo &outDataInfo)
1396 {
1397 if (inDataInfo.dataType_ != outDataInfo.dataType_) {
1398 return false;
1399 }
1400
1401 switch (inDataInfo.dataType_) {
1402 case DataType::PIXEL_MAP:
1403 return inDataInfo.pixelMap_ == outDataInfo.pixelMap_;
1404 case DataType::SURFACE_BUFFER:
1405 return inDataInfo.surfaceBufferInfo_.surfaceBuffer_ == outDataInfo.surfaceBufferInfo_.surfaceBuffer_;
1406 case DataType::PATH:
1407 return inDataInfo.path_ == outDataInfo.path_;
1408 case DataType::URI:
1409 return inDataInfo.uri_ == outDataInfo.uri_;
1410 case DataType::PICTURE:
1411 return inDataInfo.picture_ == outDataInfo.picture_;
1412 default:
1413 return false;
1414 }
1415 }
1416
LockAll(std::shared_ptr<EffectBuffer> & srcEffectBuffer,std::shared_ptr<EffectBuffer> & dstEffectBuffer,IEffectFormat format)1417 ErrorCode ImageEffect::LockAll(std::shared_ptr<EffectBuffer> &srcEffectBuffer,
1418 std::shared_ptr<EffectBuffer> &dstEffectBuffer, IEffectFormat format)
1419 {
1420 ErrorCode res = ParseDataInfo(inDateInfo_, srcEffectBuffer, false, format);
1421 if (res != ErrorCode::SUCCESS) {
1422 EFFECT_LOGE("ParseDataInfo inData fail! res=%{public}d", res);
1423 return res;
1424 }
1425 EFFECT_LOGI("input data set, parse data info success! dataType=%{public}d", inDateInfo_.dataType_);
1426
1427 if (outDateInfo_.dataType_ != DataType::UNKNOWN && !IsSameInOutputData(inDateInfo_, outDateInfo_)) {
1428 EFFECT_LOGI("output data set, start parse data info. dataType=%{public}d", outDateInfo_.dataType_);
1429 res = ParseDataInfo(outDateInfo_, dstEffectBuffer, true, format);
1430 if (res != ErrorCode::SUCCESS) {
1431 EFFECT_LOGE("ParseDataInfo outData fail! res=%{public}d", res);
1432 return res;
1433 }
1434 EFFECT_LOGI("output data set, parse data info success! dataType=%{public}d", outDateInfo_.dataType_);
1435 }
1436
1437 return ErrorCode::SUCCESS;
1438 }
1439
ParseDataInfo(DataInfo & dataInfo,std::shared_ptr<EffectBuffer> & effectBuffer,bool isOutputData,IEffectFormat format)1440 ErrorCode ImageEffect::ParseDataInfo(DataInfo &dataInfo, std::shared_ptr<EffectBuffer> &effectBuffer,
1441 bool isOutputData, IEffectFormat format)
1442 {
1443 switch (dataInfo.dataType_) {
1444 case DataType::PIXEL_MAP:
1445 return CommonUtils::LockPixelMap(dataInfo.pixelMap_, effectBuffer);
1446 case DataType::SURFACE:
1447 case DataType::SURFACE_BUFFER:
1448 return CommonUtils::ParseSurfaceData(dataInfo.surfaceBufferInfo_.surfaceBuffer_, effectBuffer,
1449 dataInfo.dataType_, dataInfo.surfaceBufferInfo_.timestamp_);
1450 case DataType::URI:
1451 return CommonUtils::ParseUri(dataInfo.uri_, effectBuffer, isOutputData, format);
1452 case DataType::PATH:
1453 return CommonUtils::ParsePath(dataInfo.path_, effectBuffer, isOutputData, format);
1454 case DataType::NATIVE_WINDOW:
1455 return CommonUtils::ParseNativeWindowData(effectBuffer, dataInfo.dataType_);
1456 case DataType::PICTURE:
1457 return CommonUtils::ParsePicture(dataInfo.picture_, effectBuffer);
1458 case DataType::UNKNOWN:
1459 EFFECT_LOGW("dataType is unknown! Data is not set!");
1460 return ErrorCode::ERR_NO_DATA;
1461 default:
1462 EFFECT_LOGW("dataType is not support! dataType=%{public}d", dataInfo.dataType_);
1463 return ErrorCode::ERR_UNSUPPORTED_DATA_TYPE;
1464 }
1465 }
1466
UnLockAll()1467 void ImageEffect::UnLockAll()
1468 {
1469 UnLockData(inDateInfo_);
1470 UnLockData(outDateInfo_);
1471 }
1472
UnLockData(DataInfo & dataInfo)1473 void ImageEffect::UnLockData(DataInfo &dataInfo)
1474 {
1475 switch (dataInfo.dataType_) {
1476 case DataType::PIXEL_MAP: {
1477 CommonUtils::UnlockPixelMap(dataInfo.pixelMap_);
1478 return;
1479 }
1480 default:
1481 return;
1482 }
1483 }
1484
InitEGLEnv()1485 void ImageEffect::InitEGLEnv()
1486 {
1487 EFFECT_TRACE_NAME("ImageEffect::InitEGLEnv");
1488 impl_->effectContext_->renderEnvironment_->Init();
1489 impl_->effectContext_->renderEnvironment_->Prepare();
1490 }
1491
DestroyEGLEnv()1492 void ImageEffect::DestroyEGLEnv()
1493 {
1494 EFFECT_LOGI("ImageEffect DestroyEGLEnv enter!");
1495 if (impl_->effectContext_->renderEnvironment_ == nullptr) {
1496 return;
1497 }
1498 impl_->effectContext_->renderEnvironment_->ReleaseParam();
1499 impl_->effectContext_->renderEnvironment_->Release();
1500 EFFECT_LOGI("ImageEffect DestroyEGLEnv end!");
1501 }
1502
SetExtraInfo(EffectJsonPtr res)1503 ErrorCode ImageEffect::SetExtraInfo(EffectJsonPtr res)
1504 {
1505 extraInfo_ = res;
1506 return ErrorCode::SUCCESS;
1507 }
1508
ExtInitModule()1509 void ImageEffect::ExtInitModule()
1510 {
1511 }
1512
ExtDeinitModule()1513 void ImageEffect::ExtDeinitModule()
1514 {
1515 }
1516
SetInputPicture(Picture * picture)1517 ErrorCode ImageEffect::SetInputPicture(Picture *picture)
1518 {
1519 EFFECT_LOGD("ImageEffect::SetInputPicture");
1520 CHECK_AND_RETURN_RET_LOG(picture != nullptr, ErrorCode::ERR_INPUT_NULL,
1521 "ImageEffect::SetInputPicture: picture is null!");
1522
1523 impl_->effectContext_->renderEnvironment_->NotifyInputChanged();
1524 ClearDataInfo(inDateInfo_);
1525 inDateInfo_.dataType_ = DataType::PICTURE;
1526 inDateInfo_.picture_ = picture;
1527
1528 return ErrorCode::SUCCESS;
1529 }
1530
SetOutputPicture(Picture * picture)1531 ErrorCode ImageEffect::SetOutputPicture(Picture *picture)
1532 {
1533 EFFECT_LOGD("ImageEffect::SetOutputPicture");
1534 ClearDataInfo(outDateInfo_);
1535
1536 if (picture == nullptr) {
1537 EFFECT_LOGI("SetOutputPicture:picture set to null!");
1538 return ErrorCode::SUCCESS;
1539 }
1540
1541 outDateInfo_.dataType_ = DataType::PICTURE;
1542 outDateInfo_.picture_ = picture;
1543
1544 return ErrorCode::SUCCESS;
1545 }
1546
UpdateConsumedrBuffersNumber()1547 void ImageEffect::UpdateConsumedrBuffersNumber()
1548 {
1549 if (setConsumerBufferSize_) {
1550 return;
1551 }
1552
1553 if (!toProducerSurface_ || !fromProducerSurface_) {
1554 EFFECT_LOGE("UpdateConsumedrBuffersNumber: toProducerSurface_ or fromProducerSurface_ is null!");
1555 return;
1556 }
1557
1558 auto errorCode = toProducerSurface_->SetQueueSize(fromProducerSurface_->GetQueueSize());
1559 if (errorCode != 0) {
1560 EFFECT_LOGE("UpdateConsumedrBuffersNumber: SetQueueSize failed! code: %{public}d", errorCode);
1561 return;
1562 }
1563
1564 EFFECT_LOGI("UpdateConsumedrBuffersNumber: SetQueueSize success! ConsumedrBuffersNumber: %{public}d",
1565 fromProducerSurface_->GetQueueSize());
1566 setConsumerBufferSize_ = true;
1567 return;
1568 }
1569
UpdateCycleBuffersNumber()1570 void ImageEffect::UpdateCycleBuffersNumber()
1571 {
1572 if (setCycleBuffersNumber_) {
1573 return;
1574 }
1575
1576 if (!toProducerSurface_ || !fromProducerSurface_) {
1577 EFFECT_LOGE("UpdateCycleBuffersNumber: toProducerSurface_ or fromProducerSurface_ is null!");
1578 return;
1579 }
1580
1581 uint32_t cycleBuffersNumber = toProducerSurface_->GetQueueSize() + fromProducerSurface_->GetQueueSize();
1582 auto errorCode = toProducerSurface_->SetCycleBuffersNumber(cycleBuffersNumber);
1583 if (errorCode != 0) {
1584 EFFECT_LOGE("UpdateCycleBuffersNumber: SetCycleBuffersNumber failed! code: %{public}d", errorCode);
1585 return;
1586 }
1587
1588 EFFECT_LOGI("UpdateCycleBuffersNumber: SetCycleBuffersNumber success! cycleBuffersNumber: %{public}d",
1589 cycleBuffersNumber);
1590 setCycleBuffersNumber_ = true;
1591 return;
1592 }
1593 } // namespace Effect
1594 } // namespace Media
1595 } // namespace OHOS
1596