• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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