• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "output/video_output_napi.h"
17 
18 #include <uv.h>
19 
20 #include "camera_napi_const.h"
21 #include "camera_napi_object_types.h"
22 #include "camera_napi_param_parser.h"
23 #include "camera_napi_security_utils.h"
24 #include "camera_napi_template_utils.h"
25 #include "camera_napi_utils.h"
26 #include "camera_napi_worker_queue_keeper.h"
27 #include "camera_output_capability.h"
28 #include "listener_base.h"
29 #include "napi/native_api.h"
30 #include "napi/native_common.h"
31 
32 namespace OHOS {
33 namespace CameraStandard {
34 namespace {
AsyncCompleteCallback(napi_env env,napi_status status,void * data)35 void AsyncCompleteCallback(napi_env env, napi_status status, void* data)
36 {
37     auto context = static_cast<VideoOutputAsyncContext*>(data);
38     CHECK_ERROR_RETURN_LOG(context == nullptr, "VideoOutputNapi AsyncCompleteCallback context is null");
39     MEDIA_INFO_LOG("VideoOutputNapi AsyncCompleteCallback %{public}s, status = %{public}d", context->funcName.c_str(),
40         context->status);
41     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
42     jsContext->status = context->status;
43     if (!context->status) {
44         CameraNapiUtils::CreateNapiErrorObject(env, context->errorCode, context->errorMsg.c_str(), jsContext);
45     } else {
46         napi_get_undefined(env, &jsContext->data);
47     }
48     if (!context->funcName.empty() && context->taskId > 0) {
49         // Finish async trace
50         CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
51         jsContext->funcName = context->funcName;
52     }
53     if (context->work != nullptr) {
54         CameraNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef, context->work, *jsContext);
55     }
56     context->FreeHeldNapiValue(env);
57     delete context;
58 }
59 } // namespace
60 
61 thread_local napi_ref VideoOutputNapi::sConstructor_ = nullptr;
62 thread_local sptr<VideoOutput> VideoOutputNapi::sVideoOutput_ = nullptr;
63 thread_local uint32_t VideoOutputNapi::videoOutputTaskId = CAMERA_VIDEO_OUTPUT_TASKID;
64 
VideoCallbackListener(napi_env env)65 VideoCallbackListener::VideoCallbackListener(napi_env env) : ListenerBase(env) {}
66 
UpdateJSCallbackAsync(VideoOutputEventType eventType,const VideoCallbackInfo & info) const67 void VideoCallbackListener::UpdateJSCallbackAsync(VideoOutputEventType eventType, const VideoCallbackInfo& info) const
68 {
69     MEDIA_DEBUG_LOG("UpdateJSCallbackAsync is called");
70     uv_loop_s* loop = nullptr;
71     napi_get_uv_event_loop(env_, &loop);
72     if (!loop) {
73         MEDIA_ERR_LOG("failed to get event loop");
74         return;
75     }
76     uv_work_t* work = new(std::nothrow) uv_work_t;
77     if (!work) {
78         MEDIA_ERR_LOG("failed to allocate work");
79         return;
80     }
81     std::unique_ptr<VideoOutputCallbackInfo> callbackInfo =
82         std::make_unique<VideoOutputCallbackInfo>(eventType, info, shared_from_this());
83     work->data = callbackInfo.get();
84     int ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t* work) {}, [] (uv_work_t* work, int status) {
85         VideoOutputCallbackInfo* callbackInfo = reinterpret_cast<VideoOutputCallbackInfo *>(work->data);
86         if (callbackInfo) {
87             auto listener = callbackInfo->listener_.lock();
88             if (listener) {
89                 listener->UpdateJSCallback(callbackInfo->eventType_, callbackInfo->info_);
90             }
91             delete callbackInfo;
92         }
93         delete work;
94     }, uv_qos_user_initiated);
95     if (ret) {
96         MEDIA_ERR_LOG("failed to execute work");
97         delete work;
98     }  else {
99         callbackInfo.release();
100     }
101 }
102 
OnFrameStarted() const103 void VideoCallbackListener::OnFrameStarted() const
104 {
105     CAMERA_SYNC_TRACE;
106     MEDIA_DEBUG_LOG("OnFrameStarted is called");
107     VideoCallbackInfo info;
108     UpdateJSCallbackAsync(VideoOutputEventType::VIDEO_FRAME_START, info);
109 }
110 
OnFrameEnded(const int32_t frameCount) const111 void VideoCallbackListener::OnFrameEnded(const int32_t frameCount) const
112 {
113     CAMERA_SYNC_TRACE;
114     MEDIA_DEBUG_LOG("OnFrameEnded is called, frameCount: %{public}d", frameCount);
115     VideoCallbackInfo info;
116     info.frameCount = frameCount;
117     UpdateJSCallbackAsync(VideoOutputEventType::VIDEO_FRAME_END, info);
118 }
119 
OnError(const int32_t errorCode) const120 void VideoCallbackListener::OnError(const int32_t errorCode) const
121 {
122     MEDIA_DEBUG_LOG("OnError is called, errorCode: %{public}d", errorCode);
123     VideoCallbackInfo info;
124     info.errorCode = errorCode;
125     UpdateJSCallbackAsync(VideoOutputEventType::VIDEO_FRAME_ERROR, info);
126 }
127 
OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt captureEndedInfo) const128 void VideoCallbackListener::OnDeferredVideoEnhancementInfo(const CaptureEndedInfoExt captureEndedInfo) const
129 {
130     MEDIA_DEBUG_LOG("OnDeferredVideoEnhancementInfo is called");
131     VideoCallbackInfo info;
132     info.isDeferredVideoEnhancementAvailable = captureEndedInfo.isDeferredVideoEnhancementAvailable;
133     info.videoId = captureEndedInfo.videoId;
134     MEDIA_INFO_LOG("OnDeferredVideoEnhancementInfo isDeferredVideo:%{public}d videoId:%{public}s ",
135         info.isDeferredVideoEnhancementAvailable, info.videoId.c_str());
136     UpdateJSCallbackAsync(VideoOutputEventType::VIDEO_DEFERRED_ENHANCEMENT, info);
137 }
138 
ExecuteOnDeferredVideoCb(const VideoCallbackInfo & info) const139 void VideoCallbackListener::ExecuteOnDeferredVideoCb(const VideoCallbackInfo& info) const
140 {
141     MEDIA_INFO_LOG("ExecuteOnDeferredVideoCb");
142     napi_value result[ARGS_TWO] = {nullptr, nullptr};
143     napi_value retVal;
144 
145     napi_get_undefined(env_, &result[PARAM0]);
146     napi_get_undefined(env_, &result[PARAM1]);
147 
148     napi_value propValue;
149     napi_create_object(env_, &result[PARAM1]);
150     napi_get_boolean(env_, info.isDeferredVideoEnhancementAvailable, &propValue);
151     napi_set_named_property(env_, result[PARAM1], "isDeferredVideoEnhancementAvailable", propValue);
152     napi_create_string_utf8(env_, info.videoId.c_str(), NAPI_AUTO_LENGTH, &propValue);
153     napi_set_named_property(env_, result[PARAM1], "videoId", propValue);
154 
155     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
156     ExecuteCallback(CONST_VIDEO_DEFERRED_ENHANCEMENT, callbackNapiPara);
157 }
158 
UpdateJSCallback(VideoOutputEventType eventType,const VideoCallbackInfo & info) const159 void VideoCallbackListener::UpdateJSCallback(VideoOutputEventType eventType, const VideoCallbackInfo& info) const
160 {
161     MEDIA_DEBUG_LOG("UpdateJSCallback is called");
162     switch (eventType) {
163         // case VideoOutputEventType::VIDEO_FRAME_START:
164         // case VideoOutputEventType::VIDEO_FRAME_END:
165         // case VideoOutputEventType::VIDEO_FRAME_ERROR:
166         // case VideoOutputEventType::VIDEO_INVALID_TYPE:
167         //     break;
168         case VideoOutputEventType::VIDEO_DEFERRED_ENHANCEMENT:
169             ExecuteOnDeferredVideoCb(info);
170             break;
171         default:
172             MEDIA_ERR_LOG("Incorrect photo callback event type received from JS");
173     }
174 
175     napi_value result[ARGS_ONE];
176     napi_value retVal;
177     napi_value propValue;
178     std::string eventName = VideoOutputEventTypeHelper.GetKeyString(eventType);
179     if (eventName.empty()) {
180         MEDIA_WARNING_LOG(
181             "VideoCallbackListener::UpdateJSCallback, event type is invalid %d", static_cast<int32_t>(eventType));
182         return;
183     }
184     if (eventType == VideoOutputEventType::VIDEO_FRAME_ERROR) {
185         napi_create_object(env_, &result[PARAM0]);
186         napi_create_int32(env_, info.errorCode, &propValue);
187         napi_set_named_property(env_, result[PARAM0], "code", propValue);
188     } else {
189         napi_get_undefined(env_, &result[PARAM0]);
190     }
191     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
192     ExecuteCallback(eventName, callbackNapiPara);
193 }
194 
VideoOutputNapi()195 VideoOutputNapi::VideoOutputNapi() : env_(nullptr) {}
196 
~VideoOutputNapi()197 VideoOutputNapi::~VideoOutputNapi()
198 {
199     MEDIA_DEBUG_LOG("~VideoOutputNapi is called");
200 }
201 
VideoOutputNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)202 void VideoOutputNapi::VideoOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
203 {
204     MEDIA_DEBUG_LOG("VideoOutputNapiDestructor is called");
205     VideoOutputNapi* videoOutput = reinterpret_cast<VideoOutputNapi*>(nativeObject);
206     if (videoOutput != nullptr) {
207         delete videoOutput;
208     }
209 }
210 
Init(napi_env env,napi_value exports)211 napi_value VideoOutputNapi::Init(napi_env env, napi_value exports)
212 {
213     MEDIA_DEBUG_LOG("Init is called");
214     napi_status status;
215     napi_value ctorObj;
216     int32_t refCount = 1;
217 
218     napi_property_descriptor video_output_props[] = {
219         DECLARE_NAPI_FUNCTION("start", Start),
220         DECLARE_NAPI_FUNCTION("stop", Stop),
221         DECLARE_NAPI_FUNCTION("setFrameRate", SetFrameRate),
222         DECLARE_NAPI_FUNCTION("getActiveFrameRate", GetActiveFrameRate),
223         DECLARE_NAPI_FUNCTION("getSupportedFrameRates", GetSupportedFrameRates),
224         DECLARE_NAPI_FUNCTION("isMirrorSupported", IsMirrorSupported),
225         DECLARE_NAPI_FUNCTION("enableMirror", EnableMirror),
226         DECLARE_NAPI_FUNCTION("release", Release),
227         DECLARE_NAPI_FUNCTION("on", On),
228         DECLARE_NAPI_FUNCTION("once", Once),
229         DECLARE_NAPI_FUNCTION("off", Off),
230         DECLARE_NAPI_FUNCTION("getActiveProfile", GetActiveProfile),
231         DECLARE_NAPI_FUNCTION("getSupportedVideoMetaTypes", GetSupportedVideoMetaTypes),
232         DECLARE_NAPI_FUNCTION("attachMetaSurface", AttachMetaSurface),
233         DECLARE_NAPI_FUNCTION("getVideoRotation", GetVideoRotation),
234         DECLARE_NAPI_FUNCTION("isAutoDeferredVideoEnhancementSupported", IsAutoDeferredVideoEnhancementSupported),
235         DECLARE_NAPI_FUNCTION("isAutoDeferredVideoEnhancementEnabled", IsAutoDeferredVideoEnhancementEnabled),
236         DECLARE_NAPI_FUNCTION("enableAutoDeferredVideoEnhancement", EnableAutoDeferredVideoEnhancement)
237     };
238 
239     status = napi_define_class(env, CAMERA_VIDEO_OUTPUT_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
240                                VideoOutputNapiConstructor, nullptr,
241                                sizeof(video_output_props) / sizeof(video_output_props[PARAM0]),
242                                video_output_props, &ctorObj);
243     if (status == napi_ok) {
244         status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
245         if (status == napi_ok) {
246             status = napi_set_named_property(env, exports, CAMERA_VIDEO_OUTPUT_NAPI_CLASS_NAME, ctorObj);
247             if (status == napi_ok) {
248                 return exports;
249             }
250         }
251     }
252     MEDIA_ERR_LOG("Init call Failed!");
253     return nullptr;
254 }
255 
256 // Constructor callback
VideoOutputNapiConstructor(napi_env env,napi_callback_info info)257 napi_value VideoOutputNapi::VideoOutputNapiConstructor(napi_env env, napi_callback_info info)
258 {
259     MEDIA_DEBUG_LOG("VideoOutputNapiConstructor is called");
260     napi_status status;
261     napi_value result = nullptr;
262     napi_value thisVar = nullptr;
263 
264     napi_get_undefined(env, &result);
265     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
266 
267     if (status == napi_ok && thisVar != nullptr) {
268         std::unique_ptr<VideoOutputNapi> obj = std::make_unique<VideoOutputNapi>();
269         if (obj != nullptr) {
270             obj->env_ = env;
271             obj->videoOutput_ = sVideoOutput_;
272 
273             status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
274                                VideoOutputNapi::VideoOutputNapiDestructor, nullptr, nullptr);
275             if (status == napi_ok) {
276                 obj.release();
277                 return thisVar;
278             } else {
279                 MEDIA_ERR_LOG("Failure wrapping js to native napi");
280             }
281         }
282     }
283     MEDIA_ERR_LOG("VideoOutputNapiConstructor call Failed!");
284     return result;
285 }
286 
GetVideoOutput()287 sptr<VideoOutput> VideoOutputNapi::GetVideoOutput()
288 {
289     return videoOutput_;
290 }
291 
IsVideoOutput(napi_env env,napi_value obj)292 bool VideoOutputNapi::IsVideoOutput(napi_env env, napi_value obj)
293 {
294     MEDIA_DEBUG_LOG("IsVideoOutput is called");
295     bool result = false;
296     napi_status status;
297     napi_value constructor = nullptr;
298 
299     status = napi_get_reference_value(env, sConstructor_, &constructor);
300     if (status == napi_ok) {
301         status = napi_instanceof(env, obj, constructor, &result);
302         if (status != napi_ok) {
303             result = false;
304         }
305     }
306     return result;
307 }
308 
GetActiveProfile(napi_env env,napi_callback_info info)309 napi_value VideoOutputNapi::GetActiveProfile(napi_env env, napi_callback_info info)
310 {
311     MEDIA_DEBUG_LOG("VideoOutputNapi::GetActiveProfile is called");
312     VideoOutputNapi* videoOutputNapi = nullptr;
313     CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
314     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
315         MEDIA_ERR_LOG("VideoOutputNapi::GetActiveProfile parse parameter occur error");
316         return nullptr;
317     }
318     auto profile = videoOutputNapi->videoOutput_->GetVideoProfile();
319     if (profile == nullptr) {
320         return CameraNapiUtils::GetUndefinedValue(env);
321     }
322     return CameraNapiObjVideoProfile(*profile).GenerateNapiValue(env);
323 }
324 
CreateJSArray(napi_env env,napi_status status,std::vector<VideoMetaType> nativeArray)325 static napi_value CreateJSArray(napi_env env, napi_status status, std::vector<VideoMetaType> nativeArray)
326 {
327     MEDIA_DEBUG_LOG("CreateJSArray is called");
328     napi_value jsArray = nullptr;
329     napi_value item = nullptr;
330 
331     if (nativeArray.empty()) {
332         MEDIA_ERR_LOG("nativeArray is empty");
333     }
334 
335     status = napi_create_array(env, &jsArray);
336     if (status == napi_ok) {
337         for (size_t i = 0; i < nativeArray.size(); i++) {
338             napi_create_int32(env, nativeArray[i], &item);
339             if (napi_set_element(env, jsArray, i, item) != napi_ok) {
340                 MEDIA_ERR_LOG("Failed to create profile napi wrapper object");
341                 return nullptr;
342             }
343         }
344     }
345     return jsArray;
346 }
347 
GetSupportedVideoMetaTypes(napi_env env,napi_callback_info info)348 napi_value VideoOutputNapi::GetSupportedVideoMetaTypes(napi_env env, napi_callback_info info)
349 {
350     MEDIA_DEBUG_LOG("GetSupportedVideoMetaTypes is called");
351     napi_status status;
352     napi_value result;
353     size_t argc = ARGS_ZERO;
354     napi_value argv[ARGS_ZERO];
355     napi_value thisVar = nullptr;
356 
357     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
358     NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
359 
360     napi_get_undefined(env, &result);
361     VideoOutputNapi* videoOutputNapi = nullptr;
362     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
363     if (status == napi_ok && videoOutputNapi != nullptr) {
364         std::vector<VideoMetaType> videoMetaType = videoOutputNapi->videoOutput_->GetSupportedVideoMetaTypes();
365         result = CreateJSArray(env, status, videoMetaType);
366     } else {
367         MEDIA_ERR_LOG("GetSupportedVideoMetaTypes call failed!");
368     }
369     return result;
370 }
371 
AttachMetaSurface(napi_env env,napi_callback_info info)372 napi_value VideoOutputNapi::AttachMetaSurface(napi_env env, napi_callback_info info)
373 {
374     CAMERA_SYNC_TRACE;
375     napi_status status;
376     napi_value result;
377     size_t argc = ARGS_TWO;
378     napi_value argv[ARGS_TWO] = {0};
379     napi_value thisVar = nullptr;
380 
381     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
382 
383     napi_get_undefined(env, &result);
384     VideoOutputNapi* videoOutputNapi = nullptr;
385     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
386     if (status == napi_ok && videoOutputNapi != nullptr) {
387         char buffer[PATH_MAX];
388         size_t surfaceId;
389         napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &surfaceId);
390         uint32_t videoMetaType;
391         napi_get_value_uint32(env, argv[PARAM1], &videoMetaType);
392 
393         uint64_t iSurfaceId;
394         std::istringstream iss((std::string(buffer)));
395         iss >> iSurfaceId;
396         sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
397         if (surface == nullptr) {
398             MEDIA_ERR_LOG("failed to get surface from SurfaceUtils");
399         }
400         videoOutputNapi->videoOutput_->AttachMetaSurface(surface, static_cast<VideoMetaType>(videoMetaType));
401     } else {
402         MEDIA_ERR_LOG("VideoOutputNapi::AttachMetaSurface failed!");
403     }
404     return result;
405 }
406 
CreateVideoOutput(napi_env env,VideoProfile & profile,std::string surfaceId)407 napi_value VideoOutputNapi::CreateVideoOutput(napi_env env, VideoProfile &profile, std::string surfaceId)
408 {
409     MEDIA_DEBUG_LOG("CreateVideoOutput is called");
410     CAMERA_SYNC_TRACE;
411     napi_status status;
412     napi_value result = nullptr;
413     napi_value constructor;
414 
415     status = napi_get_reference_value(env, sConstructor_, &constructor);
416     if (status == napi_ok) {
417         uint64_t iSurfaceId;
418         std::istringstream iss(surfaceId);
419         iss >> iSurfaceId;
420         sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
421         if (surface == nullptr) {
422             MEDIA_ERR_LOG("failed to get surface from SurfaceUtils");
423             return result;
424         }
425         surface->SetUserData(CameraManager::surfaceFormat, std::to_string(profile.GetCameraFormat()));
426         int retCode = CameraManager::GetInstance()->CreateVideoOutput(profile, surface, &sVideoOutput_);
427         if (!CameraNapiUtils::CheckError(env, retCode)) {
428             return nullptr;
429         }
430         if (sVideoOutput_ == nullptr) {
431             MEDIA_ERR_LOG("failed to create VideoOutput");
432             return result;
433         }
434         status = napi_new_instance(env, constructor, 0, nullptr, &result);
435         sVideoOutput_ = nullptr;
436         if (status == napi_ok && result != nullptr) {
437             return result;
438         } else {
439             MEDIA_ERR_LOG("Failed to create video output instance");
440         }
441     }
442     napi_get_undefined(env, &result);
443     MEDIA_ERR_LOG("CreateVideoOutput call Failed!");
444     return result;
445 }
446 
CreateVideoOutput(napi_env env,std::string surfaceId)447 napi_value VideoOutputNapi::CreateVideoOutput(napi_env env, std::string surfaceId)
448 {
449     MEDIA_DEBUG_LOG("VideoOutputNapi::CreateVideoOutput is called");
450     CAMERA_SYNC_TRACE;
451     napi_status status;
452     napi_value result = nullptr;
453     napi_value constructor;
454 
455     status = napi_get_reference_value(env, sConstructor_, &constructor);
456     if (status == napi_ok) {
457         uint64_t iSurfaceId;
458         std::istringstream iss(surfaceId);
459         iss >> iSurfaceId;
460         sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(iSurfaceId);
461         if (surface == nullptr) {
462             MEDIA_ERR_LOG("failed to get surface from SurfaceUtils");
463             return result;
464         }
465         int retCode = CameraManager::GetInstance()->CreateVideoOutputWithoutProfile(surface, &sVideoOutput_);
466         if (!CameraNapiUtils::CheckError(env, retCode)) {
467             return nullptr;
468         }
469         if (sVideoOutput_ == nullptr) {
470             MEDIA_ERR_LOG("failed to create VideoOutput");
471             return result;
472         }
473         status = napi_new_instance(env, constructor, 0, nullptr, &result);
474         sVideoOutput_ = nullptr;
475         if (status == napi_ok && result != nullptr) {
476             return result;
477         } else {
478             MEDIA_ERR_LOG("Failed to create video output instance");
479         }
480     }
481     napi_get_undefined(env, &result);
482     MEDIA_ERR_LOG("CreateVideoOutput call Failed!");
483     return result;
484 }
485 
Start(napi_env env,napi_callback_info info)486 napi_value VideoOutputNapi::Start(napi_env env, napi_callback_info info)
487 {
488     MEDIA_INFO_LOG("Start is called");
489     std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
490         "VideoOutputNapi::Start", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
491     auto asyncFunction =
492         std::make_shared<CameraNapiAsyncFunction>(env, "Start", asyncContext->callbackRef, asyncContext->deferred);
493     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
494     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
495         MEDIA_ERR_LOG("VideoOutputNapi::Start invalid argument");
496         return nullptr;
497     }
498     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
499     napi_status status = napi_create_async_work(
500         env, nullptr, asyncFunction->GetResourceName(),
501         [](napi_env env, void* data) {
502             MEDIA_INFO_LOG("VideoOutputNapi::Start running on worker");
503             auto context = static_cast<VideoOutputAsyncContext*>(data);
504             CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Start async info is nullptr");
505             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
506             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
507                 context->errorCode = context->objectInfo->videoOutput_->Start();
508                 context->status = true;
509                 MEDIA_INFO_LOG("VideoOutputNapi::Start errorCode:%{public}d", context->errorCode);
510             });
511         },
512         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
513     if (status != napi_ok) {
514         MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Start");
515         asyncFunction->Reset();
516     } else {
517         asyncContext->queueTask =
518             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Start");
519         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
520         asyncContext.release();
521     }
522     if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
523         return asyncFunction->GetPromise();
524     }
525     return CameraNapiUtils::GetUndefinedValue(env);
526 }
527 
Stop(napi_env env,napi_callback_info info)528 napi_value VideoOutputNapi::Stop(napi_env env, napi_callback_info info)
529 {
530     MEDIA_INFO_LOG("Stop is called");
531     std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
532         "VideoOutputNapi::Stop", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
533     auto asyncFunction =
534         std::make_shared<CameraNapiAsyncFunction>(env, "Stop", asyncContext->callbackRef, asyncContext->deferred);
535     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
536     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
537         MEDIA_ERR_LOG("VideoOutputNapi::Stop invalid argument");
538         return nullptr;
539     }
540     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
541     napi_status status = napi_create_async_work(
542         env, nullptr, asyncFunction->GetResourceName(),
543         [](napi_env env, void* data) {
544             MEDIA_INFO_LOG("VideoOutputNapi::Stop running on worker");
545             auto context = static_cast<VideoOutputAsyncContext*>(data);
546             CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Stop async info is nullptr");
547             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
548             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
549                 context->errorCode = context->objectInfo->videoOutput_->Stop();
550                 context->status = true;
551                 MEDIA_INFO_LOG("VideoOutputNapi::Stop errorCode:%{public}d", context->errorCode);
552             });
553         },
554         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
555     if (status != napi_ok) {
556         MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Stop");
557         asyncFunction->Reset();
558     } else {
559         asyncContext->queueTask =
560             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Stop");
561         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
562         asyncContext.release();
563     }
564     if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
565         return asyncFunction->GetPromise();
566     }
567     return CameraNapiUtils::GetUndefinedValue(env);
568 }
569 
SetFrameRate(napi_env env,napi_callback_info info)570 napi_value VideoOutputNapi::SetFrameRate(napi_env env, napi_callback_info info)
571 {
572     MEDIA_DEBUG_LOG("SetFrameRate is called");
573     CAMERA_SYNC_TRACE;
574     napi_status status;
575     napi_value result;
576     size_t argc = ARGS_TWO;
577     napi_value argv[ARGS_TWO] = {0};
578     napi_value thisVar = nullptr;
579 
580     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
581     NAPI_ASSERT(env, (argc == ARGS_TWO), "requires 2 parameters maximum.");
582 
583     napi_get_undefined(env, &result);
584     VideoOutputNapi* videoOutputNapi = nullptr;
585     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
586     if (status == napi_ok && videoOutputNapi != nullptr) {
587         int32_t minFrameRate;
588         napi_get_value_int32(env, argv[PARAM0], &minFrameRate);
589         int32_t maxFrameRate;
590         napi_get_value_int32(env, argv[PARAM1], &maxFrameRate);
591         int32_t retCode = videoOutputNapi->videoOutput_->SetFrameRate(minFrameRate, maxFrameRate);
592         if (!CameraNapiUtils::CheckError(env, retCode)) {
593             MEDIA_ERR_LOG("VideoOutputNapi::SetFrameRate! %{public}d", retCode);
594             return result;
595         }
596     } else {
597         MEDIA_ERR_LOG("SetFrameRate call Failed!");
598     }
599     return result;
600 }
601 
GetActiveFrameRate(napi_env env,napi_callback_info info)602 napi_value VideoOutputNapi::GetActiveFrameRate(napi_env env, napi_callback_info info)
603 {
604     MEDIA_DEBUG_LOG("GetFrameRate is called");
605     CAMERA_SYNC_TRACE;
606     napi_status status;
607     napi_value result;
608     size_t argc = ARGS_ZERO;
609     napi_value argv[ARGS_ZERO];
610     napi_value thisVar = nullptr;
611 
612     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
613     NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
614 
615     napi_get_undefined(env, &result);
616     VideoOutputNapi* videoOutputNapi = nullptr;
617     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
618     if (status == napi_ok && videoOutputNapi != nullptr) {
619         std::vector<int32_t> frameRateRange = videoOutputNapi->videoOutput_->GetFrameRateRange();
620         CameraNapiUtils::CreateFrameRateJSArray(env, frameRateRange, result);
621     } else {
622         MEDIA_ERR_LOG("GetFrameRate call failed!");
623     }
624     return result;
625 }
626 
GetSupportedFrameRates(napi_env env,napi_callback_info info)627 napi_value VideoOutputNapi::GetSupportedFrameRates(napi_env env, napi_callback_info info)
628 {
629     MEDIA_DEBUG_LOG("GetSupportedFrameRates is called");
630 
631     CAMERA_SYNC_TRACE;
632     napi_status status;
633     napi_value result;
634     size_t argc = ARGS_ZERO;
635     napi_value argv[ARGS_ZERO];
636     napi_value thisVar = nullptr;
637 
638     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
639     NAPI_ASSERT(env, (argc == ARGS_ZERO), "requires no parameter.");
640     napi_get_undefined(env, &result);
641     VideoOutputNapi* videoOutputNapi = nullptr;
642     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
643     if (status == napi_ok && videoOutputNapi != nullptr) {
644         std::vector<std::vector<int32_t>> supportedFrameRatesRange =
645                                           videoOutputNapi->videoOutput_->GetSupportedFrameRates();
646         result = CameraNapiUtils::CreateSupportFrameRatesJSArray(env, supportedFrameRatesRange);
647     } else {
648         MEDIA_ERR_LOG("GetSupportedFrameRates call failed!");
649     }
650     return result;
651 }
652 
GetVideoRotation(napi_env env,napi_callback_info info)653 napi_value VideoOutputNapi::GetVideoRotation(napi_env env, napi_callback_info info)
654 {
655     MEDIA_DEBUG_LOG("GetVideoRotation is called!");
656     CAMERA_SYNC_TRACE;
657     napi_status status;
658     napi_value result = nullptr;
659     size_t argc = ARGS_ONE;
660     napi_value argv[ARGS_ONE] = {0};
661     napi_value thisVar = nullptr;
662     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
663 
664     napi_get_undefined(env, &result);
665     VideoOutputNapi* videoOutputNapi = nullptr;
666     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
667     if (status == napi_ok && videoOutputNapi != nullptr) {
668         int32_t imageRotation;
669         napi_status ret = napi_get_value_int32(env, argv[PARAM0], &imageRotation);
670         if (ret != napi_ok) {
671             CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT,
672                 "GetVideoRotation parameter missing or parameter type incorrect.");
673             return result;
674         }
675         int32_t retCode = videoOutputNapi->videoOutput_->GetVideoRotation(imageRotation);
676         if (retCode == SERVICE_FATL_ERROR) {
677             CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR,
678                 "GetVideoRotation Camera service fatal error.");
679             return result;
680         }
681         napi_create_int32(env, retCode, &result);
682         MEDIA_INFO_LOG("VideoOutputNapi GetVideoRotation! %{public}d", retCode);
683     } else {
684         MEDIA_ERR_LOG("VideoOutputNapi GetVideoRotation! called failed!");
685     }
686     return result;
687 }
688 
IsMirrorSupported(napi_env env,napi_callback_info info)689 napi_value VideoOutputNapi::IsMirrorSupported(napi_env env, napi_callback_info info)
690 {
691     auto result = CameraNapiUtils::GetUndefinedValue(env);
692     if (!CameraNapiSecurity::CheckSystemApp(env)) {
693         MEDIA_ERR_LOG("SystemApi IsMirrorSupported is called!");
694         return result;
695     }
696     MEDIA_DEBUG_LOG("VideoOutputNapi::IsMirrorSupported is called");
697 
698     VideoOutputNapi* videoOutputNapi = nullptr;
699     CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
700     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
701         MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported parse parameter occur error");
702         return result;
703     }
704     if (videoOutputNapi->videoOutput_ == nullptr) {
705         MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported get native object fail");
706         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
707         return result;
708     }
709     bool isMirrorSupported = videoOutputNapi->videoOutput_->IsMirrorSupported();
710     if (isMirrorSupported) {
711         napi_get_boolean(env, true, &result);
712         return result;
713     }
714     MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported is not supported");
715     napi_get_boolean(env, false, &result);
716     return result;
717 }
718 
EnableMirror(napi_env env,napi_callback_info info)719 napi_value VideoOutputNapi::EnableMirror(napi_env env, napi_callback_info info)
720 {
721     auto result = CameraNapiUtils::GetUndefinedValue(env);
722     if (!CameraNapiSecurity::CheckSystemApp(env)) {
723         MEDIA_ERR_LOG("SystemApi EnableMirror is called!");
724         return result;
725     }
726     MEDIA_DEBUG_LOG("VideoOutputNapi::EnableMirror is called");
727     VideoOutputNapi* videoOutputNapi = nullptr;
728     bool isEnable;
729     CameraNapiParamParser jsParamParser(env, info, videoOutputNapi, isEnable);
730     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error")) {
731         MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported parse parameter occur error");
732         return result;
733     }
734     if (videoOutputNapi->videoOutput_ == nullptr) {
735         MEDIA_ERR_LOG("VideoOutputNapi::IsMirrorSupported get native object fail");
736         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "get native object fail");
737         return result;
738     }
739 
740     int32_t retCode = videoOutputNapi->videoOutput_->enableMirror(isEnable);
741     if (!CameraNapiUtils::CheckError(env, retCode)) {
742         MEDIA_ERR_LOG("PhotoOutputNapi::EnableAutoHighQualityPhoto fail %{public}d", retCode);
743     }
744     return result;
745 }
746 
Release(napi_env env,napi_callback_info info)747 napi_value VideoOutputNapi::Release(napi_env env, napi_callback_info info)
748 {
749     MEDIA_INFO_LOG("VideoOutputNapi::Release is called");
750     std::unique_ptr<VideoOutputAsyncContext> asyncContext = std::make_unique<VideoOutputAsyncContext>(
751         "VideoOutputNapi::Release", CameraNapiUtils::IncrementAndGet(videoOutputTaskId));
752     auto asyncFunction =
753         std::make_shared<CameraNapiAsyncFunction>(env, "Release", asyncContext->callbackRef, asyncContext->deferred);
754     CameraNapiParamParser jsParamParser(env, info, asyncContext->objectInfo, asyncFunction);
755     if (!jsParamParser.AssertStatus(INVALID_ARGUMENT, "invalid argument")) {
756         MEDIA_ERR_LOG("VideoOutputNapi::Release invalid argument");
757         return nullptr;
758     }
759     asyncContext->HoldNapiValue(env, jsParamParser.GetThisVar());
760     napi_status status = napi_create_async_work(
761         env, nullptr, asyncFunction->GetResourceName(),
762         [](napi_env env, void* data) {
763             MEDIA_INFO_LOG("VideoOutputNapi::Release running on worker");
764             auto context = static_cast<VideoOutputAsyncContext*>(data);
765             CHECK_ERROR_RETURN_LOG(context->objectInfo == nullptr, "VideoOutputNapi::Release async info is nullptr");
766             CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
767             CameraNapiWorkerQueueKeeper::GetInstance()->ConsumeWorkerQueueTask(context->queueTask, [&context]() {
768                 context->errorCode = context->objectInfo->videoOutput_->Release();
769                 context->status = context->errorCode == CameraErrorCode::SUCCESS;
770             });
771         },
772         AsyncCompleteCallback, static_cast<void*>(asyncContext.get()), &asyncContext->work);
773     if (status != napi_ok) {
774         MEDIA_ERR_LOG("Failed to create napi_create_async_work for VideoOutputNapi::Release");
775         asyncFunction->Reset();
776     } else {
777         asyncContext->queueTask =
778             CameraNapiWorkerQueueKeeper::GetInstance()->AcquireWorkerQueueTask("VideoOutputNapi::Release");
779         napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
780         asyncContext.release();
781     }
782     if (asyncFunction->GetAsyncFunctionType() == ASYNC_FUN_TYPE_PROMISE) {
783         return asyncFunction->GetPromise();
784     }
785     return CameraNapiUtils::GetUndefinedValue(env);
786 }
787 
RegisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)788 void VideoOutputNapi::RegisterFrameStartCallbackListener(
789     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
790 {
791     if (videoCallback_ == nullptr) {
792         videoCallback_ = make_shared<VideoCallbackListener>(env);
793         videoOutput_->SetCallback(videoCallback_);
794     }
795     videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_START, callback, isOnce);
796 }
797 
UnregisterFrameStartCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)798 void VideoOutputNapi::UnregisterFrameStartCallbackListener(
799     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
800 {
801     if (videoCallback_ == nullptr) {
802         MEDIA_ERR_LOG("videoCallback is null");
803         return;
804     }
805     videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_START, callback);
806 }
807 
RegisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)808 void VideoOutputNapi::RegisterFrameEndCallbackListener(
809     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
810 {
811     if (videoCallback_ == nullptr) {
812         videoCallback_ = make_shared<VideoCallbackListener>(env);
813         videoOutput_->SetCallback(videoCallback_);
814     }
815     videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_END, callback, isOnce);
816 }
UnregisterFrameEndCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)817 void VideoOutputNapi::UnregisterFrameEndCallbackListener(
818     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
819 {
820     if (videoCallback_ == nullptr) {
821         MEDIA_ERR_LOG("videoCallback is null");
822         return;
823     }
824     videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_END, callback);
825 }
826 
RegisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)827 void VideoOutputNapi::RegisterErrorCallbackListener(
828     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
829 {
830     if (videoCallback_ == nullptr) {
831         videoCallback_ = make_shared<VideoCallbackListener>(env);
832         videoOutput_->SetCallback(videoCallback_);
833     }
834     videoCallback_->SaveCallbackReference(CONST_VIDEO_FRAME_ERROR, callback, isOnce);
835 }
836 
UnregisterErrorCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)837 void VideoOutputNapi::UnregisterErrorCallbackListener(
838     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
839 {
840     if (videoCallback_ == nullptr) {
841         MEDIA_ERR_LOG("videoCallback is null");
842         return;
843     }
844     videoCallback_->RemoveCallbackRef(CONST_VIDEO_FRAME_ERROR, callback);
845 }
846 
RegisterDeferredVideoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)847 void VideoOutputNapi::RegisterDeferredVideoCallbackListener(
848     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
849 {
850     if (videoCallback_ == nullptr) {
851         videoCallback_ = make_shared<VideoCallbackListener>(env);
852         videoOutput_->SetCallback(videoCallback_);
853     }
854     videoCallback_->SaveCallbackReference(CONST_VIDEO_DEFERRED_ENHANCEMENT, callback, isOnce);
855 }
856 
UnregisterDeferredVideoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)857 void VideoOutputNapi::UnregisterDeferredVideoCallbackListener(
858     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
859 {
860     if (videoCallback_ == nullptr) {
861         MEDIA_ERR_LOG("videoCallback is null");
862         return;
863     }
864     videoCallback_->RemoveCallbackRef(CONST_VIDEO_DEFERRED_ENHANCEMENT, callback);
865 }
866 
GetEmitterFunctions()867 const VideoOutputNapi::EmitterFunctions& VideoOutputNapi::GetEmitterFunctions()
868 {
869     static const EmitterFunctions funMap = {
870         { CONST_VIDEO_FRAME_START, {
871             &VideoOutputNapi::RegisterFrameStartCallbackListener,
872             &VideoOutputNapi::UnregisterFrameStartCallbackListener } },
873         { CONST_VIDEO_FRAME_END, {
874             &VideoOutputNapi::RegisterFrameEndCallbackListener,
875             &VideoOutputNapi::UnregisterFrameEndCallbackListener } },
876         { CONST_VIDEO_FRAME_ERROR, {
877             &VideoOutputNapi::RegisterErrorCallbackListener,
878             &VideoOutputNapi::UnregisterErrorCallbackListener } },
879         { CONST_VIDEO_DEFERRED_ENHANCEMENT, {
880             &VideoOutputNapi::RegisterDeferredVideoCallbackListener,
881             &VideoOutputNapi::UnregisterDeferredVideoCallbackListener } }};
882     return funMap;
883 }
884 
On(napi_env env,napi_callback_info info)885 napi_value VideoOutputNapi::On(napi_env env, napi_callback_info info)
886 {
887     return ListenerTemplate<VideoOutputNapi>::On(env, info);
888 }
889 
Once(napi_env env,napi_callback_info info)890 napi_value VideoOutputNapi::Once(napi_env env, napi_callback_info info)
891 {
892     return ListenerTemplate<VideoOutputNapi>::Once(env, info);
893 }
894 
Off(napi_env env,napi_callback_info info)895 napi_value VideoOutputNapi::Off(napi_env env, napi_callback_info info)
896 {
897     return ListenerTemplate<VideoOutputNapi>::Off(env, info);
898 }
899 
IsAutoDeferredVideoEnhancementSupported(napi_env env,napi_callback_info info)900 napi_value VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported(napi_env env, napi_callback_info info)
901 {
902     napi_value result = CameraNapiUtils::GetUndefinedValue(env);
903     if (!CameraNapiSecurity::CheckSystemApp(env)) {
904         MEDIA_ERR_LOG("SystemApi IsAutoDeferredVideoEnhancementSupported is called!");
905         return result;
906     }
907     MEDIA_DEBUG_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported is called");
908 
909     VideoOutputNapi* videoOutputNapi = nullptr;
910     CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
911     if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
912         MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported parse parameter occur error");
913         return result;
914     }
915     if (videoOutputNapi->videoOutput_ == nullptr) {
916         MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementSupported get native object fail");
917         CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
918         return result;
919     }
920     int32_t res = videoOutputNapi->videoOutput_->IsAutoDeferredVideoEnhancementSupported();
921     if (res > 1) {
922         CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
923         return result;
924     }
925     napi_get_boolean(env, res, &result);
926     return result;
927 }
928 
IsAutoDeferredVideoEnhancementEnabled(napi_env env,napi_callback_info info)929 napi_value VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled(napi_env env, napi_callback_info info)
930 {
931     napi_value result = CameraNapiUtils::GetUndefinedValue(env);
932     if (!CameraNapiSecurity::CheckSystemApp(env)) {
933         MEDIA_ERR_LOG("SystemApi IsAutoDeferredVideoEnhancementEnabled is called!");
934         return result;
935     }
936     MEDIA_DEBUG_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled is called");
937 
938     VideoOutputNapi* videoOutputNapi = nullptr;
939     CameraNapiParamParser jsParamParser(env, info, videoOutputNapi);
940     if (!jsParamParser.AssertStatus(SERVICE_FATL_ERROR, "parse parameter occur error")) {
941         MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled parse parameter occur error");
942         return result;
943     }
944     if (videoOutputNapi->videoOutput_ == nullptr) {
945         MEDIA_ERR_LOG("VideoOutputNapi::IsAutoDeferredVideoEnhancementEnabled get native object fail");
946         CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "get native object fail");
947         return result;
948     }
949     int32_t res = videoOutputNapi->videoOutput_->IsAutoDeferredVideoEnhancementEnabled();
950     if (res > 1) {
951         CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
952         return result;
953     }
954     napi_get_boolean(env, res, &result);
955     return result;
956 }
957 
EnableAutoDeferredVideoEnhancement(napi_env env,napi_callback_info info)958 napi_value VideoOutputNapi::EnableAutoDeferredVideoEnhancement(napi_env env, napi_callback_info info)
959 {
960     napi_value result = CameraNapiUtils::GetUndefinedValue(env);
961     if (!CameraNapiSecurity::CheckSystemApp(env)) {
962         MEDIA_ERR_LOG("SystemApi EnableAutoDeferredVideoEnhancement is called!");
963         return result;
964     }
965     napi_status status;
966     size_t argc = ARGS_ONE;
967     napi_value argv[ARGS_ONE] = {0};
968     napi_value thisVar = nullptr;
969     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
970     if (argc != ARGS_ONE) {
971         CameraNapiUtils::ThrowError(env, INVALID_ARGUMENT, "requires one parameter");
972         return result;
973     }
974     int32_t res = 0;
975     napi_get_undefined(env, &result);
976     VideoOutputNapi* videoOutputNapi = nullptr;
977     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&videoOutputNapi));
978     if (status == napi_ok && videoOutputNapi != nullptr) {
979         bool isEnable;
980         napi_get_value_bool(env, argv[PARAM0], &isEnable);
981         res = videoOutputNapi->videoOutput_->EnableAutoDeferredVideoEnhancement(isEnable);
982     }
983     if (res > 0) {
984         CameraNapiUtils::ThrowError(env, SERVICE_FATL_ERROR, "inner fail");
985     }
986     return result;
987 }
988 } // namespace CameraStandard
989 } // namespace OHOS
990